2020-09-17 18:03:24 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
split source in multiple files
diff --git a/map.c b/map.c new file mode 100644 index 0000000..3d4e42f --- /dev/null +++ b/map.c @@ -0,0 +1,56 @@ +#include <string.h> + +#include "seqt.h" + +int +map_find(char type, const char *key) +{ + int i; + for (i = 0; i < MAPSIZE; i++) { + if (!map[i][0]) + return i - MAPSIZE; + if (map[i][0] != type) + continue; + if (!strcmp(&map[i][1], key)) + break; + } + return i; +} + +int +map_next(char type, int *rec_index) +{ + for (; *rec_index < MAPSIZE; (*rec_index)++) + if (map[*rec_index][0] == type) + break; + return *rec_index; +} + +int +map_put(char type, const char *key, const char *val) +{ + int keylen = strlen(key); + int vallen = strlen(val); + int i; + if (keylen + vallen + 3 > RECSIZE) + return -1; + i = map_find(type, key); + if (i == MAPSIZE) + return -2; + if (i < 0) { + i += MAPSIZE; + map[i][0] = type; + strcpy(&map[i][1], key); + } + strcpy(&map[i][keylen+2], val); + return 0; +} + +char * +map_get(char type, const char *key) +{ + int i = map_find(type, key); + if (i < 0 || i == MAPSIZE) + return NULL; + return &map[i][strlen(key)+2]; +} diff --git a/seqt.c b/seqt.c index 0bcefc0..0cdf42b 100644 --- a/seqt.c +++ b/seqt.c @@ -1,204 +1,12 @@ #include <stdlib.h> -#include <string.h> -#include <ctype.h> #include <stdio.h> -#define MAXINDEX 0x1000 -#define MAXTRACK 0x0010 -#define MAXVOICE 0x0008 - -#define RECSIZE 0x20 -#define MAPSIZE 0x20 - -#define MAXINPUTLINE 0x400 - -#define REST 0 -#define CONT 1 +#include "seqt.h" int ntracks; char map[MAPSIZE][RECSIZE]; unsigned char matrix[MAXINDEX][MAXTRACK][MAXVOICE]; -/* search key in map - * if key is found, return record index, otherwise: - * return the index of the first empty record - MAPSIZE - * if map is full, return MAPSIZE */ -int -map_find(char type, const char *key) -{ - int i; - for (i = 0; i < MAPSIZE; i++) { - if (!map[i][0]) - return i - MAPSIZE; - if (map[i][0] != type) - continue; - if (!strcmp(&map[i][1], key)) - break; - } - return i; -} - -/* search for next record of given type, starting at *rec_index - * the index found or MAPSIZE is written to the given pointer - * return the new value of *rec_index */ -int -map_next(char type, int *rec_index) -{ - for (; *rec_index < MAPSIZE; (*rec_index)++) - if (map[*rec_index][0] == type) - break; - return *rec_index; -} - -/* put a key-value pair on the map - * if the key is already on the map, update its value - * return 0 on success, negative value on error: - * -1: key-value pair is too large to fit on a record - * -2: no record available on the map */ -int -map_put(char type, const char *key, const char *val) -{ - int keylen = strlen(key); - int vallen = strlen(val); - int i; - if (keylen + vallen + 3 > RECSIZE) - return -1; - i = map_find(type, key); - if (i == MAPSIZE) - return -2; - if (i < 0) { - i += MAPSIZE; - map[i][0] = type; - strcpy(&map[i][1], key); - } - strcpy(&map[i][keylen+2], val); - return 0; -} - -/* get the value associated with the given key on the map - * return a pointer to the value found or NULL if not found */ -char * -map_get(char type, const char *key) -{ - int i = map_find(type, key); - if (i < 0 || i == MAPSIZE) - return NULL; - return &map[i][strlen(key)+2]; -} - -typedef enum TxtStt {MTDT, TKNM, EVNT} TxtStt; - -int -load_txt(FILE *fp) -{ - char line[MAXINPUTLINE]; - char track_key[] = "1"; - TxtStt state = MTDT; - char *sep, *nl, *cell; - int index, track, voice; - unsigned char duration, pitch; - track = 1; - while (fgets(line, MAXINPUTLINE, fp)) { - if (line[0] == '\n') - continue; - switch (state) { - case MTDT: - if ((sep = strchr(line, ':'))) { - nl = strchr(line, '\n'); - *sep = *nl = '\0'; - map_put('#', line, sep + 1); - break; - } else { - state = TKNM; - } - /* fall through */ - case TKNM: - state = EVNT; -track_name: - nl = strchr(line, '\n'); - *nl = '\0'; - map_put('@', track_key, line); - *track_key = *track_key == '9' ? 'A' : *track_key + 1; - index = 0; - break; - case EVNT: - if (isdigit(line[0])) { - /* noteset */ - duration = (line[0] - '0' + 1) << ((~track & 1) << 2); - matrix[index][0][track >> 1] |= duration; - cell = &line[2]; - voice = 0; - while (*cell) { - switch (*cell) { - case '.': - /* matrix[index][track][voice] = REST; */ - break; - case '=': - matrix[index][track][voice] = CONT; - break; - default: - pitch = (cell[0] - '0') * 10 + cell[1] - '0'; - matrix[index][track][voice] = pitch | 0x80; - } - cell += 3; - voice++; - } - index++; - } else { - if (!strchr(line, ':')) { - track++; - goto track_name; - } - /* printf("ignoring metaevent: %s", line); */ - } - } - } - ntracks = track; - return 0; -} - -int -save_txt(FILE *fp) -{ - int index, track, voice; - int last_voice; - unsigned char cell, duration; - int rec_index, key_length; - char track_key[] = "1"; - for (rec_index = 0; map_next('#', &rec_index) < MAPSIZE; rec_index++) { - fprintf(fp, "%s:%n", &map[rec_index][1], &key_length); - fprintf(fp, "%s\n", &map[rec_index][key_length+1]); - } - for (track = 1; track <= ntracks; track++) { - fprintf(fp, "\n%s\n\n", map_get('@', track_key)); - for (index = 0; index < MAXINDEX; index++) { - duration = matrix[index][0][track >> 1]; - duration = track & 1 ? duration & 0x0F : duration >> 4; - if (!duration) - break; - fprintf(fp, "%c", duration + '0' - 1); - for (voice = MAXVOICE-1; voice >= 0; voice--) - if (matrix[index][track][voice]) - break; - last_voice = voice; - for (voice = 0; voice <= last_voice; voice++) { - cell = matrix[index][track][voice]; - if (cell & 0x80) - fprintf(fp, " %2u", cell & 0x7F); - else if (cell == REST) - fprintf(fp, " .."); - else if (cell == CONT) - fprintf(fp, " =="); - else - fprintf(fp, " ??"); - } - fprintf(fp, "\n"); - } - *track_key = *track_key == '9' ? 'A' : *track_key + 1; - } - return 0; -} - int main() { diff --git a/seqt.h b/seqt.h new file mode 100644 index 0000000..235d9c1 --- /dev/null +++ b/seqt.h @@ -0,0 +1,58 @@ +#ifndef SEQT_H +#define SEQT_H + +#include <stdio.h> + +/* ============================= Matrix ============================= */ + +#define MAXINDEX 0x1000 +#define MAXTRACK 0x0010 +#define MAXVOICE 0x0008 +extern unsigned char matrix[MAXINDEX][MAXTRACK][MAXVOICE]; + +#define REST 0 +#define CONT 1 + +/* =============================== Map ============================== */ + +#define RECSIZE 0x20 +#define MAPSIZE 0x20 +extern char map[MAPSIZE][RECSIZE]; + +/* search key in map + * if key is found, return record index, otherwise: + * return the index of the first empty record - MAPSIZE + * if map is full, return MAPSIZE */ +int map_find(char type, const char *key); + +/* search for next record of given type, starting at *rec_index + * the index found or MAPSIZE is written to the given pointer + * return the new value of *rec_index */ +int map_next(char type, int *rec_index); + +/* put a key-value pair on the map + * if the key is already on the map, update its value + * return 0 on success, negative value on error: + * -1: key-value pair is too large to fit on a record + * -2: no record available on the map */ +int map_put(char type, const char *key, const char *val); + +/* get the value associated with the given key on the map + * return a pointer to the value found or NULL if not found */ +char *map_get(char type, const char *key); + + +/* ======================== plain-text file ========================= */ + +#define MAXINPUTLINE 0x400 + +typedef enum TxtStt {MTDT, TKNM, EVNT} TxtStt; + +int load_txt(FILE *fp); +int save_txt(FILE *fp); + +/* ====================[=====+===== =====+=====]==================== */ + +extern int ntracks; + +#endif /* SEQT_H */ diff --git a/txt.c b/txt.c new file mode 100644 index 0000000..4af7639 --- /dev/null +++ b/txt.c @@ -0,0 +1,116 @@ +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "seqt.h" + +int +load_txt(FILE *fp) +{ + char line[MAXINPUTLINE]; + char track_key[] = "1"; + TxtStt state = MTDT; + char *sep, *nl, *cell; + int index, track, voice; + unsigned char duration, pitch; + track = 1; + while (fgets(line, MAXINPUTLINE, fp)) { + if (line[0] == '\n') + continue; + switch (state) { + case MTDT: + if ((sep = strchr(line, ':'))) { + nl = strchr(line, '\n'); + *sep = *nl = '\0'; + map_put('#', line, sep + 1); + break; + } else { + state = TKNM; + } + /* fall through */ + case TKNM: + state = EVNT; +track_name: + nl = strchr(line, '\n'); + *nl = '\0'; + map_put('@', track_key, line); + *track_key = *track_key == '9' ? 'A' : *track_key + 1; + index = 0; + break; + case EVNT: + if (isdigit(line[0])) { + /* noteset */ + duration = (line[0] - '0' + 1) << ((~track & 1) << 2); + matrix[index][0][track >> 1] |= duration; + cell = &line[2]; + voice = 0; + while (*cell) { + switch (*cell) { + case '.': + /* matrix[index][track][voice] = REST; */ + break; + case '=': + matrix[index][track][voice] = CONT; + break; + default: + pitch = (cell[0] - '0') * 10 + cell[1] - '0'; + matrix[index][track][voice] = pitch | 0x80; + } + cell += 3; + voice++; + } + index++; + } else { + if (!strchr(line, ':')) { + track++; + goto track_name; + } + /* printf("ignoring metaevent: %s", line); */ + } + } + } + ntracks = track; + return 0; +} + +int +save_txt(FILE *fp) +{ + int index, track, voice; + int last_voice; + unsigned char cell, duration; + int rec_index, key_length; + char track_key[] = "1"; + for (rec_index = 0; map_next('#', &rec_index) < MAPSIZE; rec_index++) { + fprintf(fp, "%s:%n", &map[rec_index][1], &key_length); + fprintf(fp, "%s\n", &map[rec_index][key_length+1]); + } + for (track = 1; track <= ntracks; track++) { + fprintf(fp, "\n%s\n\n", map_get('@', track_key)); + for (index = 0; index < MAXINDEX; index++) { + duration = matrix[index][0][track >> 1]; + duration = track & 1 ? duration & 0x0F : duration >> 4; + if (!duration) + break; + fprintf(fp, "%c", duration + '0' - 1); + for (voice = MAXVOICE-1; voice >= 0; voice--) + if (matrix[index][track][voice]) + break; + last_voice = voice; + for (voice = 0; voice <= last_voice; voice++) { + cell = matrix[index][track][voice]; + if (cell & 0x80) + fprintf(fp, " %2u", cell & 0x7F); + else if (cell == REST) + fprintf(fp, " .."); + else if (cell == CONT) + fprintf(fp, " =="); + else + fprintf(fp, " ??"); + } + fprintf(fp, "\n"); + } + *track_key = *track_key == '9' ? 'A' : *track_key + 1; + } + return 0; +}