diff -urN midi_prog-/Makefile midi_prog/Makefile --- midi_prog-/Makefile 2015-04-11 00:00:00.000000000 +0900 +++ midi_prog/Makefile 2015-04-16 00:00:00.000000000 +0900 @@ -1,19 +1,20 @@ CC = gcc LIB = -lm -lpthread -L../cui -lcui -TARG = prog54 +TARG = prog55 OBJS = main.o vcf.o ch.o delay.o stat.o note.o env.o tone.o filter.o lfo.o modu.o vco.o wave.o out.o rd.o util.o +OBJS += rec.o OBJS += cui_tone.o CFLAGS += -Wall -I.. -all: $(TARG) txprm +all: $(TARG) $(TARG): $(OBJS) $(CC) -o $@ $(OBJS) $(LIB) -txprm: txprm.c util.o - $(CC) -o $@ txprm.c util.o -lm +#txprm: txprm.c util.o +# $(CC) -o $@ txprm.c util.o -lm clean: - rm -f $(TARG) $(OBJS) txprm *~ + rm -f $(TARG) $(OBJS) *~ # EOF diff -urN midi_prog-/rec.c midi_prog/rec.c --- midi_prog-/rec.c 1970-01-01 09:00:00.000000000 +0900 +++ midi_prog/rec.c 2015-04-16 00:00:00.000000000 +0900 @@ -0,0 +1,260 @@ +#include "tone.h" +#include "rec.h" + +#define TYPE_MAX 1024 + +struct rec recs[] = { + { + REC(struct tone_rec), + (struct memb []){ + MEMB(struct tone_rec, char*, name), + MEMB(struct tone_rec, struct vco_rec, vco), + MEMB(struct tone_rec, struct filter_rec, fl1), + MEMB(struct tone_rec, struct filter_rec, fl2), + MEMB(struct tone_rec, struct env_rec, env), + MEMB(struct tone_rec, double, level), + MEMB(struct tone_rec, struct modu_rec, lfo_modu), + MEMB(struct tone_rec, struct lfo_rec, lfo), + MEMB(struct tone_rec, struct modu_rec, env_modu), + MEMB(struct tone_rec, struct delay_rec, delay), + MEMB(struct tone_rec, int, chorus), + { NULL } + } + },{ + REC(struct vco_rec), + (struct memb []){ + MEMB(struct vco_rec, int, wave1), + MEMB(struct vco_rec, int, wave2), + MEMB(struct vco_rec, int, tune), + MEMB(struct vco_rec, double, mix), + MEMB(struct vco_rec, int, ring), + MEMB(struct vco_rec, int, alias_noise1), + MEMB(struct vco_rec, int, alias_noise2), + { NULL } + } + },{ + REC(struct filter_rec), + (struct memb []){ + MEMB(struct filter_rec, int, type), + MEMB(struct filter_rec, double, freq), + MEMB(struct filter_rec, double, Q), + { NULL } + } + },{ + REC(struct env_rec), + (struct memb []){ + MEMB(struct env_rec, double, attack), + MEMB(struct env_rec, double, decay), + MEMB(struct env_rec, double, sustain), + MEMB(struct env_rec, double, release), + { NULL } + } + },{ + REC(struct modu_rec), + (struct memb []){ + MEMB(struct modu_rec, int, pitch1), + MEMB(struct modu_rec, int, pitch2), + MEMB(struct modu_rec, int, filter1), + MEMB(struct modu_rec, int, filter2), + { NULL } + } + },{ + REC(struct lfo_rec), + (struct memb []){ + MEMB(struct lfo_rec, int, wave), + MEMB(struct lfo_rec, double, freq), + MEMB(struct lfo_rec, double, delay), + { NULL } + } + },{ + REC(struct delay_rec), + (struct memb []){ + MEMB(struct delay_rec, int, onoff), + MEMB(struct delay_rec, double, sec), + MEMB(struct delay_rec, double, gain), + { NULL } + } + },{ + REC(struct tone_compo_rec), + (struct memb []){ + MEMB(struct tone_compo_rec, char*, name), + MEMB(struct tone_compo_rec, int, note), + MEMB(struct tone_compo_rec, double, rate), + { NULL } + } + },{ + REC(struct tones_lst_rec), + (struct memb []){ + MEMB(struct tones_lst_rec, int, prog), + MEMB(struct tones_lst_rec, int, note), + MEMB(struct tones_lst_rec, struct tone_compo_rec*, tone_compo), + { NULL } + } + },{ + REC(struct tone_all_rec), + (struct memb []){ + MEMB(struct tone_all_rec, struct tone_rec*, tone), + MEMB(struct tone_all_rec, struct tones_lst_rec*, tones_lst), + { NULL } + } + },{ + NULL + } +}; + +struct rec * +rec_get(char *name) +{ + struct rec *rec; + + for(rec=recs; rec->name; rec++){ + if(strcmp(rec->name, name) == 0) return rec; + } + return NULL; +} + +void * +memb_addr(void *obj, struct memb *memb) +{ + return ((char*)obj) + memb->offset; +} + +int +type_is_rec(char *type) +{ + char *k = "struct "; + return strncmp(type, k, strlen(k)) == 0; +} + +int +type_is_pointer(char *type) +{ + return type[ strlen(type) - 1] == '*'; +} + +void * +memb_get_pointer(void *obj, struct memb *memb) +{ + return *(void **)memb_addr(obj, memb); +} + +int rec_is_tail(void *obj, struct rec *rec); + +int +memb_is_tail(void *obj, struct memb *memb) +{ + char *type = memb->type; + if(type_is_pointer(type)) return memb_get_pointer(obj, memb) == NULL; + if(type_is_rec(type)) return rec_is_tail(memb_addr(obj, memb), rec_get(type)); + return 0; +} + +int +rec_is_tail(void *obj, struct rec *rec) +{ + int i; + for(i=0; rec->membs[i].type; i++){ + if(memb_is_tail(obj, &rec->membs[i])) return 1; + } + return 0; +} + +static void +idt_out(int idt, char *s, FILE *fp) +{ + int i; + for(i=0; itype; + void *addr = memb_addr(obj, memb); + void *p; + char strip_type[ TYPE_MAX ]; + + idt_out(idt, memb->name, fp); + + if(!type_is_pointer(type)){ + if(type_is_rec(type)){ + fputc('\n', fp); + rec_save(memb_addr(obj, memb), rec_get(memb->type), fp, idt+2); + return; + } + fputc(' ', fp); + non_rec_out(type, addr, fp); + fputc('\n', fp); + return; + } + + /* type is pointer */ + + if((p = memb_get_pointer(obj, memb)) == NULL){ + fputs(" NULL\n", fp); + return; + } + memset(strip_type, 0, sizeof(strip_type)); + memcpy(strip_type, type, strlen(type)-1); + + if(type_is_rec(strip_type)){ + struct rec *rec = rec_get(strip_type); + fputc('\n', fp); + idt_out(idt, "{\n", fp); + for(;;){ + rec_save(p, rec, fp, idt+2); + if(rec_is_tail(p, rec)) break; + idt_out(idt, ",\n", fp); + p = ((char*)p) + rec->size; + } + idt_out(idt, "}\n", fp); + return; + } + fputc(' ', fp); + if(strcmp(strip_type, "char") == 0){ + fprintf(fp, "\"%s\"", (char*)p); + }else{ + non_rec_out(strip_type, p, fp); + } + fputc('\n', fp); +} + +void +rec_save(void *obj, struct rec *rec, FILE *fp, int idt) +{ + int i; + + for(i=0; rec->membs[i].type; i++) memb_save(obj, &rec->membs[i], fp, idt); +} + +void +rec_save_text(void *obj, char *name, FILE *fp) +{ + struct rec *rec; + + if((rec = rec_get(name)) == NULL){ + MSG(name); + ERR("not found"); + } + fprintf(fp, "%s\n", name); + + rec_save(obj, rec, fp, 0); +} diff -urN midi_prog-/rec.h midi_prog/rec.h --- midi_prog-/rec.h 1970-01-01 09:00:00.000000000 +0900 +++ midi_prog/rec.h 2015-04-16 00:00:00.000000000 +0900 @@ -0,0 +1,24 @@ +#ifndef __REC_H__ +#define __REC_H__ + +#include + +struct memb{ + char *type, *name; + int offset, size; +}; + +struct rec{ + char *name; + int size; + struct memb *membs; +}; + +#define REC(rec) #rec, sizeof(rec) +#define membsizeof(rec, memb) sizeof(((rec *)NULL)->memb) +#define MEMB(rec, type, memb) { #type, #memb, offsetof(rec, memb), membsizeof(rec, memb) } + +struct rec *rec_get(char *name); +void rec_save_text(void *rec, char *name, FILE *fp); + +#endif diff -urN midi_prog-/tone.c midi_prog/tone.c --- midi_prog-/tone.c 2015-04-11 00:00:00.000000000 +0900 +++ midi_prog/tone.c 2015-04-16 00:00:00.000000000 +0900 @@ -3,6 +3,7 @@ #include "vcf.h" #include "stat.h" #include "rd.h" +#include "rec.h" static struct tone_rec tone_inf_default[] = { { @@ -109,14 +110,10 @@ } }, *tone_inf = tone_inf_default; -static int tone_inf_n; #define PROG_DRUM 0 -static struct{ - int prog, note; /* note for ch 9 */ - struct tone_compo_rec *tone_compo; -} tones_lst_default[] = { +static struct tones_lst_rec tones_lst_default[] = { { PROG_DRUM, 36, /* bass drum1 */ (struct tone_compo_rec []){ @@ -368,35 +365,10 @@ { "cymbal", 75, 1.0 }, { NULL, } } },{ - -1, /* tail */ + -1, -1, NULL /* tail */ } }, *tones_lst = tones_lst_default; -static int tones_lst_n; - -struct name_lst{ - char *name; - int offset; -}; - -static struct{ - int n; - struct name_lst *lst; - int area_sz; - char *area; -} name_inf; - -struct compo_lst{ - struct tone_compo_rec *tone_compo; - int idx; -}; - -static struct{ - int n; - struct compo_lst *lst; - int arr_n; - struct tone_compo_rec *arr; -} compo_inf; static struct tone_rec * name_search(char *name) @@ -410,57 +382,6 @@ } static void -name_inf_setup(void) -{ - struct tone_rec *tone; - int i, offset; - - name_inf.n = 0; - name_inf.area_sz = 0; - for(tone=tone_inf; tone->name; tone++){ - name_inf.n++; - name_inf.area_sz += strlen(tone->name) + 1; - } - if((name_inf.lst = malloc(sizeof(struct name_lst) * name_inf.n)) == NULL) ERR("No Mem"); - if((name_inf.area = malloc(name_inf.area_sz)) == NULL) ERR("No Mem"); - offset = 0; - for(tone=tone_inf, i=0; tone->name; tone++, i++){ - name_inf.lst[i].name = tone->name; - name_inf.lst[i].offset = offset; - strcpy(name_inf.area + offset, tone->name); - offset += strlen(tone->name) + 1; - } -} - -static void -compo_inf_setup(void) -{ - struct tone_compo_rec *tone_compo; - int i, idx; - - compo_inf.n = 0; - compo_inf.arr_n = 0; - for(i=0; tones_lst[i].prog >= 0; i++){ - compo_inf.n++; - for(tone_compo=tones_lst[i].tone_compo; tone_compo->name; tone_compo++){ - compo_inf.arr_n++; - } - compo_inf.arr_n++; - } - if((compo_inf.lst = malloc(sizeof(struct compo_lst) * compo_inf.n)) == NULL) ERR("No Mem"); - if((compo_inf.arr = malloc(sizeof(struct tone_compo_rec) * compo_inf.arr_n)) == NULL) ERR("No Mem"); - idx = 0; - for(i=0; tones_lst[i].prog >= 0; i++){ - compo_inf.lst[i].tone_compo = tone_compo = tones_lst[i].tone_compo; - compo_inf.lst[i].idx = idx; - for(; tone_compo->name; tone_compo++){ - memcpy(&compo_inf.arr[idx++], tone_compo, sizeof(*tone_compo)); - } - memcpy(&compo_inf.arr[idx++], tone_compo, sizeof(*tone_compo)); - } -} - -static void try_load(void) { char *load_hd = "load\n"; @@ -474,19 +395,15 @@ tone_init(void) { struct tone_compo_rec *tone_compo; - struct tone_rec *tone; int i; - for(i=0; tones_lst[i].prog >= 0; i++){ + try_load(); + + for(i=0; tones_lst[i].tone_compo; i++){ for(tone_compo=tones_lst[i].tone_compo; tone_compo->name; tone_compo++){ - tone_compo->tone = tone = name_search(tone_compo->name); - if(tone) tone_compo->name = tone->name; - } + tone_compo->tone = name_search(tone_compo->name); + } } - - name_inf_setup(); - compo_inf_setup(); - try_load(); } #define CH_PROG(ch) ( (ch) == 9 ? 0 : ch_inf[ch].prog ) @@ -498,11 +415,11 @@ int prog, i; prog = CH_PROG(ch); - for(i=0; tones_lst[i].prog >= 0; i++){ + for(i=0; tones_lst[i].tone_compo; i++){ if(tones_lst[i].prog == prog && (tones_lst[i].note == note || tones_lst[i].note < 0)) break; } - if(tones_lst[i].prog < 0) return NULL; /* not found */ + if(tones_lst[i].tone_compo == NULL) return NULL; /* not found */ tone_compo = tones_lst[i].tone_compo; if(ret_n){ for(i=0; tone_compo[i].tone; i++); @@ -548,108 +465,19 @@ return v; } -static void -save_n_data(int n, int usz, void *p, FILE *fp) -{ - if(fwrite(&n, sizeof(n), 1, fp) != 1) ERR("write"); - if(fwrite(p, usz, n, fp) != n) ERR("write"); -} - void tone_save(char *path) { FILE *fp; - int sz, n; + struct tone_all_rec all = { tone_inf, tones_lst }; if((fp = fopen(path, "w")) == NULL){ MSG(path); ERR("open"); } - - sz = sizeof(tone_inf[0]); - n = (tone_inf == tone_inf_default) ? sizeof(tone_inf_default)/sz : tone_inf_n; - save_n_data(n, sz, tone_inf, fp); - - sz = sizeof(tones_lst[0]); - n = (tones_lst == tones_lst_default) ? sizeof(tones_lst_default)/sz : tones_lst_n; - save_n_data(n, sz, tones_lst, fp); - - sz = sizeof(compo_inf.lst[0]); - save_n_data(compo_inf.n, sz, compo_inf.lst, fp); - - sz = sizeof(compo_inf.arr[0]); - save_n_data(compo_inf.arr_n, sz, compo_inf.arr, fp); - - sz = sizeof(name_inf.lst[0]); - save_n_data(name_inf.n, sz, name_inf.lst, fp); - - save_n_data(name_inf.area_sz, 1, name_inf.area, fp); - + rec_save_text(&all, "struct tone_all_rec", fp); fclose(fp); } -static void * -load_n_data(int *np, int usz, FILE *fp) -{ - int n; - void *p = NULL; - - if(fread(np, sizeof(*np), 1, fp) != 1) ERR("read"); - n = *np; - if((p = malloc(usz * n)) == NULL) ERR("No Mem"); - if(fread(p, usz, n, fp) != n) ERR("read"); - return p; -} - -static char * -id_to_name(char *id) -{ - int i; - - for(i=0; iname; tone++){ - tone->name = id_to_name(tone->name); - } - - for(i=0; tones_lst[i].prog >= 0; i++){ - tones_lst[i].tone_compo = id_to_compo(tones_lst[i].tone_compo); - if(tones_lst[i].tone_compo == NULL) continue; - for(tone_compo=tones_lst[i].tone_compo; tone_compo->name; tone_compo++){ - tone_compo->name = id_to_name(tone_compo->name); - tone_compo->tone = name_search(tone_compo->name); - } - } - - for(i=0; i