#include #include #include #include #include #include #include #include #include "strings.h" #include "dmx.h" #define ARGPARSE_DE #include "argparse.h" void dump_bank(bank_instr *instr, uint8_t prog, uint8_t name) { bank_instr *ins = &instr[prog]; if(ins->op == b_op0) { return; } printf("[] #%d - MIDI %s #%d\n", prog, (prog < 128) ? "program" : "drum", (prog < 128) ? prog : (prog - 128)); if(name) { printf(" [] name = '%s'\n", ins->name); } printf(" [] mode = %s\n", (ins->op == b_op22) ? "2x2OP" : ((ins->op == b_op4) ? "4OP" : "2OP")); printf(" [] notes = %s\n", ins->fixed ? "fixed" : "variable"); printf(" [] percussion number = %d\n", ins->percnum); for(int ch = 0; ch < ((ins->op == b_op2) ? 1 : 2); ch++) { bank_pair *chn = &ins->channels[ch]; printf(" [] voice %d\n", ch + 1); printf(" [] detune = %d\n", chn->detune); printf(" [] note offset = %d\n", chn->offset); printf(" [] feedback = %d\n", chn->feedback); printf(" [] algorithm = %s\n", chn->am ? "AM" : "FM"); for(int op = 0; op < 2; op++) { bank_operator *opr = &chn->ops[op]; printf(" [] %s\n", op ? "carrier" : "modulator"); printf(" [] freq. multiplier = %d\n", opr->mult); printf(" [] output level = %d\n", 63-opr->level); printf(" [] waveform = %d\n", opr->waveform); printf(" [] key scale level = %d\n", opr->ksl); printf(" [] attack rate = %d\n", opr->attack); printf(" [] decay rate = %d\n", opr->decay); printf(" [] sustain level = %d\n", 15-opr->sustain); printf(" [] release rate = %d\n", opr->release); printf(" [] tremolo = %s\n", opr->tremolo ? "ON" : "OFF"); printf(" [] vibrato = %s\n", opr->vibrato ? "ON" : "OFF"); printf(" [] envelope sustain = %s\n", opr->sustaining ? "ON" : "OFF"); printf(" [] key rate scale = %s\n", opr->ksr ? "ON" : "OFF"); } } } void dump_bank_header(uint8_t name) { printf(name ? "| |GLOBAL " : "| |GLOBAL "); for(int ch = 0; ch < 2; ch++) { printf("|VOICE %d |MODULATOR %d |CARRIER %d ", ch + 1, ch + 1, ch + 1); } printf("|\n"); printf(name ? "|ID#|MIDI|NAME |TP|FN|PCN" : "|ID#|MIDI|TP|FN|PCN"); for(int ch = 0; ch < 2; ch++) { printf("|DTNE|OFFS|FB|AL"); for(int op = 0; op < 2; op++) { printf("|ML|LV|WV|KL|AR|DR|SL|RR|TR|VB|ST|KS"); } } printf("|\n"); } void dump_bank_line(bank_instr *instr, uint8_t prog, uint8_t name) { bank_instr *ins = &instr[prog]; if(ins->op == b_op0) { return; } printf(name ? "|%03d|%c%03d|%-32s|%s|%s|%03d" : "|%03d|%c%03d|%s%s|%s|%03d", prog, (prog < 128) ? 'P' : 'D', (prog < 128) ? prog : (prog - 128), name ? ins->name : "", (ins->op == b_op22) ? "P4" : ((ins->op == b_op4) ? "4O" : "2O"), ins->fixed ? "+F" : "--", ins->percnum); for(int ch = 0; ch < ((ins->op == b_op2) ? 1 : 2); ch++) { bank_pair *chn = &ins->channels[ch]; printf("|%+04d|%+04d|%02d|%s", chn->detune, chn->offset, chn->feedback, chn->am ? "AM" : "FM"); for(int op = 0; op < 2; op++) { bank_operator *opr = &chn->ops[op]; printf("|%02d|%02d|%02d|%02d|%02d|%02d|%02d|%02d|%s|%s|%s|%s", opr->mult, 63-opr->level, opr->waveform, opr->ksl, opr->attack, opr->decay, 15-opr->sustain, opr->release, opr->tremolo ? "+T" : "--", opr->vibrato ? "+V" : "--", opr->sustaining ? "+S" : "--", opr->ksr ? "+K" : "--"); } } if(ins->op == b_op2) { printf("|....|....|..|.."); for(int op = 0; op < 2; op++) { printf("|..|..|..|..|..|..|..|..|..|..|..|.."); } } printf("|\n"); } int main(int argc, char **argv) { char *dmxname = NULL; char *drumname = NULL; int32_t usedrum = 0; int32_t prog = 256; int32_t table = 0; int32_t name = 0; argp_t *argspec = arg_alloc(6); arg_add_nstr(argspec, STR_ARGS_BANK, true, &dmxname); arg_add_nint(argspec, STR_ARGS_BANKN, false, 0, 255, &prog); arg_add_bool(argspec, 'l', STR_ARGS_NTABLE, &table); arg_add_bool(argspec, 'n', STR_ARGS_NONAME, &name); arg_add_str(argspec, 'q', STR_ARGS_DBANK, &drumname); arg_add_bool(argspec, 'Q', STR_ARGS_USEDRM, &usedrum); if(arg_parse(argspec, argc, argv) ^ 1) { return 1; } table ^= 1; name ^= 1; bank_instr *instr = bnk_read_banks(dmxname, drumname, usedrum); if(instr == NULL) { return 1; } if(prog == 256) { if(table) { dump_bank_header(name); } for(int i = 0; i < 256; i++) { if(table) { dump_bank_line(instr, i, name); } else { dump_bank(instr, i, name); } } } else { if(instr[prog].op == b_op0) { fprintf(stderr, STR_BNK_UNDEF"\n", prog); free(instr); return 1; } if(table) { dump_bank_header(name); dump_bank_line(instr, prog, name); } else { dump_bank(instr, prog, name); } } free(instr); return 0; }