123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include "math.h"
- #include "./st.h"
- #include "./config.h"
- /* lots o ambition to develop this project, for example, one could make use of pthread to generate a thread for each of the instruments,
- the args could represent filenames to files consisting of rhythms as well as the frequency and/or type of wave
- rhythms would be defined as 10001000 for example, where 0 translates to skip an iteration
- each of the threads would be generating output to be | into aplay, to generate music
- surely it works!
- if threading doesnt work out, work out how to add mutliple frequencies together? */
- void die() {
- printf("\
- usage: stunes <file> [<file> ...]\n\
- - up to 8 files can be specified\n");
- exit(1);
- }
- /* enums */
- /* data types */
- typedef struct {
- char type;
- char* load;
- } line;
- /* function declarations */
- int read_rhythm(FILE*, int);
- line parse_line(FILE*);
- /* variables */
- /* collection of error messages */
- static char* errmesgs[2] = {
- "all ok",
- "invalid syntax (check config.h for available symbols)",
- };
- /* function implementations */
- /* reads a line into a string, if the line is structured validly */
- /* skips the first character and all whitespaces up to the actual payload */
- /* before \n */
- /* returns a line struct with the probed character signifying the type of */
- /* line, as well as the additional contents of the line */
- /* returns -1 as the line type if the line type was not recognized */
- line parse_line(FILE* in)
- {
- char c;
- char ret = -1;
- long read;
- // TODO: fix parsing bug when comment immediately follows empty line
- c = probe_line(in, symbols, &read);
- if (c == -1) {
- line l1 = { -1, "" };
- return l1;
- }
- /* set recognized line type */
- if (in_array(symbols, c)) ret = c;
- /* skip whitespaces and comments */
- if (ret == '\n' || ret == '#') {
- /* set pointer in file to correct pos */
- skip(in, '\n');
- /* return 'ignore' line type */
- line l2 = { '-', "" };
- return l2;
- }
- /* line type was recognized, now scan for size of the line load */
- /* this doesn't check for whitespaces (which are later ignored), so the */
- /* char buffer will usually be a little bigger in size than the actual load */
- int chars = seek_char(in, '\n');
- char load[chars];
- char* loadp = load;
- if (ret != -1) {
- /* consume type character, since we already knwo the type */
- c = getc(in);
- while (!feof(in) && c != '\n') {
- c = getc(in);
- if (c == ' ') continue;
- *loadp = c;
- loadp++;
- }
- *loadp = '\0';
- }
- /* actual data */
- line l3 = { ret, load };
- return l3;
- }
- /* parses the rhythm of a rhythm file */
- /* on failure returns the error code that references an 'errmesgs' error, */
- /* otherwise 0 */
- int read_rhythm(FILE* in, int channel)
- {
- char* seq;
- char* t;
- int freq;
- // TODO: actually use the data and save structs
- line l;
- for (int i = 0; i < 5; i++) {
- l = parse_line(in);
- if (l.type == -1) return 1;
- if (l.type == '-') continue;
- printf("LOAD %s FIN\n", l.load);
- printf("TYPE %c FIN\n", l.type);
- printf("i %i\n", i);
- }
- return 0;
- /* old, replaced by function pointers soon */
- enum wav type;
- if (strcmp(t, "wcon") == 0) {
- type = wcon;
- } else if (strcmp(t, "wsin") == 0) {
- type = wsin;
- } else if (strcmp(t, "wcos") == 0) {
- type = wcos;
- } else if (strcmp(t, "wtan") == 0) {
- type = wtan;
- } else {
- type = wcon;
- }
- rhythm ch = { seq, type, freq };
- channels[channel] = ch;
- printf("parsed channel %i\n", channel);
- return 0;
- }
- int main(int argc, char **argv) {
- /* ensure user is not retarded */
- if (argc < 2 || argc > 9)
- die();
- int ret;
- /* loop argument files */
- for (int ch = 0; ch < argc-1; ch++) {
- int arg = ch + 1;
- FILE* f = fopen(argv[arg], "r");
- /* fopen returned NULL */
- if (f == NULL) {
- fprintf(stderr, "error while opening file %s for reading, ignoring...\n", argv[arg]);
- continue;
- }
- /* read rhythm of file */
- if ((ret = read_rhythm(f, ch))) {
- /* in case of error, print 'errmesgs' element specified by ret */
- fprintf(stderr, "error while reading file %s: %s\nignoring file %s...\n", argv[arg], errmesgs[ret], argv[arg]);
- continue;
- }
- }
- return 0;
- }
|