From e2963d7c0507a0ab7ca2e64abd4c59d932e416be Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Sun, 9 Feb 2025 18:52:54 +0100 Subject: [PATCH 1/5] implementation of more file load/save routines for the loaders --- dmp_file.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++---- dmp_file.h | 4 +- ins_file.c | 2 +- md5.c | 2 +- md5.h | 2 +- op3_file.c | 68 +++++++++++++++++++++++++++++++- opm_file.c | 1 + sbi_file.c | 44 ++++++++++++++++++++- tfi_file.c | 52 ++++++++++++++++++++++++- y12_file.c | 44 ++++++++++++++++++++- 10 files changed, 311 insertions(+), 20 deletions(-) diff --git a/dmp_file.c b/dmp_file.c index 3a9cdad..fab68bc 100644 --- a/dmp_file.c +++ b/dmp_file.c @@ -5,10 +5,17 @@ #include "dmp_file.h" #include "tools.h" -int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system) { +#define SYSTEM_YM2612_OPN 0x02 +#define SYSTEM_YM2151_OPM 0x08 + +void dmp_file_init(struct dmp_file *f) { + memset(f, 0, sizeof(*f)); +} + +int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len) { memset(f, 0, sizeof(struct dmp_file)); - if(data[0] != 9) { + if(data[0] < 9) { fprintf(stderr, "Unsupported version 0x%02x (%d)\n", data[0], data[0]); return -1; } @@ -18,17 +25,34 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system return -1; } + f->system = SYSTEM_YM2612_OPN; f->version = data[0]; - f->mode = data[1]; + if (data[0] <= 10) { + f->mode = data[1]; + } else { + f->system = data[1]; + f->mode = data[2]; + } + + if (f->system != SYSTEM_YM2612_OPN && f->system != SYSTEM_YM2151_OPM) { + fprintf(stderr, "Unsupported system %d\n", f->system); + return -1; + } if(f->mode == 1) { uint8_t *p = data + 2; - f->num_operators = *p++ == 0 ? 2 : 4; + if (f->version < 10) { + f->num_operators = *p++ == 0 ? 2 : 4; + } else { + f->num_operators = 4; + } f->lfo = *p++; f->fb = *p++; f->alg = *p++; - if(system == DMP_FILE_GENESIS) { + if(f->version >= 10) { f->lfo2 = *p++; + } else { + f->lfo2 = 0; } for(int i = 0; i < f->num_operators; i++) { @@ -39,7 +63,7 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system f->operators[i].sl = *p++; f->operators[i].rr = *p++; f->operators[i].am = *p++; - if(system == DMP_FILE_GENESIS) { + if(f->version >= 10) { f->operators[i].ksr = *p++; f->operators[i].dt = *p++; f->operators[i].d2r = *p++; @@ -54,6 +78,31 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system return 0; } +int dmp_file_save(struct dmp_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + uint8_t buf[50] = { 0 }; + int bc = 0; + buf[bc++] = 0x0a; // version 10 + buf[bc++] = 1; // instrument type, 1 = FM + buf[bc++] = f->lfo; + buf[bc++] = f->fb; + buf[bc++] = f->alg; + buf[bc++] = f->lfo2; + for(int i = 0; i < f->num_operators; i++) { + buf[bc++] = f->operators[i].mult; + buf[bc++] = f->operators[i].tl; + buf[bc++] = f->operators[i].ar; + buf[bc++] = f->operators[i].dr; + buf[bc++] = f->operators[i].sl; + buf[bc++] = f->operators[i].rr; + buf[bc++] = f->operators[i].am; + buf[bc++] = f->operators[i].ksr; + buf[bc++] = f->operators[i].dt; + buf[bc++] = f->operators[i].d2r; + buf[bc++] = f->operators[i].ssg; + } + return write_fn(buf, 50, data_ptr); +} + #ifdef HAVE_STDIO void dmp_file_dump(struct dmp_file *dmp) { printf("version=%d mode=%d\n", dmp->version, dmp->mode); @@ -85,11 +134,58 @@ void dmp_file_dump(struct dmp_file *dmp) { #include "loader.h" static int load(void *data, int data_len, struct fm_voice_bank *bank) { - return -1; + struct dmp_file f; + int r = dmp_file_load(&f, (uint8_t*)data, data_len); + if(r) return r; + struct opn_voice *voice = fm_voice_bank_reserve_opn_voices(bank, 1); + if(!voice) return -1; + voice->slot = 0x0f; + voice->fb_con = (f.fb & 0x07) << 3 | (f.alg & 0x07); + voice->lr_ams_pms = (f.lfo & 0x07) << 4 | (f.lfo2 & 0x03); + for(int i = 0; i < f.num_operators; i++) { + struct opn_voice_operator *op = &voice->operators[i]; + struct dmp_file_operator *fop = &f.operators[i]; + op->dt_mul = (fop->dt & 0x07) << 3 | (fop->mult & 0x07); + op->tl = fop->tl & 0x7f; + op->ks_ar = fop->ksr << 6 | (fop->ar & 0x1f); + op->am_dr = fop->dr & 0x1f; + op->sr = fop->d2r; + op->sl_rr = fop->sl << 4 | (fop->rr & 0x0f); + op->ssg_eg = fop->ssg; + } + return 0; } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - return -1; + if(bank->num_opn_voices <= pos->opn) return -1; + struct dmp_file f; + dmp_file_init(&f); + struct opn_voice* voice = &bank->opn_voices[pos->opn]; + if (!voice) return -1; + + f.fb = opn_voice_get_fb(voice); + f.alg = opn_voice_get_con(voice); + f.lfo = opn_voice_get_ams(voice); + f.lfo2 = opn_voice_get_pms(voice); + for(int i = 0; i < 4; i++) { + struct opn_voice_operator *op = &voice->operators[i]; + struct dmp_file_operator *fop = &f.operators[i]; + fop->dt = opn_voice_get_operator_dt(voice, i); + fop->mult = opn_voice_get_operator_mul(voice, i); + fop->tl = opn_voice_get_operator_tl(voice, i); + fop->ksr = opn_voice_get_operator_ks(voice, i); + fop->ar = opn_voice_get_operator_ar(voice, i); + fop->dr = opn_voice_get_operator_dr(voice, i); + fop->am = opn_voice_get_operator_am(voice, i); + fop->d2r = opn_voice_get_operator_sr(voice, i); + fop->sl = opn_voice_get_operator_sl(voice, i); + fop->rr = opn_voice_get_operator_rr(voice, i); + fop->ssg = opn_voice_get_operator_ssg_eg(voice, i); + + + } + pos->opn++; + return dmp_file_save(&f, write_fn, data_ptr); } struct loader dmp_file_loader = { diff --git a/dmp_file.h b/dmp_file.h index f24643f..f757d75 100644 --- a/dmp_file.h +++ b/dmp_file.h @@ -3,8 +3,6 @@ #include -#define DMP_FILE_GENESIS 1 - struct dmp_file_operator { uint8_t mult, tl, @@ -13,7 +11,7 @@ struct dmp_file_operator { }; struct dmp_file { - uint8_t version, mode; + uint8_t version, mode, system; uint8_t num_operators, lfo, fb, alg; uint8_t lfo2; struct dmp_file_operator operators[4]; diff --git a/ins_file.c b/ins_file.c index f893e0d..6bd9667 100644 --- a/ins_file.c +++ b/ins_file.c @@ -128,8 +128,8 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - struct ins_file ins; if(bank->num_opn_voices <= pos->opn) return -1; + struct ins_file ins; ins.name = strdup(bank->opn_voices[pos->opn].name); if(!ins.name) return -1; ins.name_len = strlen(bank->opn_voices[pos->opn].name); diff --git a/md5.c b/md5.c index 462a579..d8fe3da 100644 --- a/md5.c +++ b/md5.c @@ -28,7 +28,7 @@ #include # include -#if STDC_HEADERS || defined _LIBC +#if STDC_HEADERS || defined _LIBC || defined _MSC_VER # include #else # ifndef HAVE_MEMCPY diff --git a/md5.h b/md5.h index 2188677..37e4dce 100644 --- a/md5.h +++ b/md5.h @@ -23,7 +23,7 @@ #include -#if defined HAVE_LIMITS_H || _LIBC +#if defined HAVE_LIMITS_H || defined _LIBC || defined _MSC_VER # include #endif diff --git a/op3_file.c b/op3_file.c index 0b61f9a..1ee153c 100644 --- a/op3_file.c +++ b/op3_file.c @@ -43,6 +43,43 @@ int op3_file_load(struct op3_file *f, uint8_t *data, size_t data_len) { return 0; } +int op3_file_save(struct op3_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + uint8_t buf[8192] = { 0 }; + strcpy((char*)&buf[0], "Junglevision Patch File\x1A"); + int bc = 32; + buf[bc++] = f->count_melodic & 0xff; + buf[bc++] = f->count_melodic >> 8; + buf[bc++] = f->count_percussive & 0xff; + buf[bc++] = f->count_percussive >> 8; + buf[bc++] = f->start_melodic & 0xff; + buf[bc++] = f->start_melodic >> 8; + buf[bc++] = f->start_percussive & 0xff; + buf[bc++] = f->start_percussive >> 8; + +#define WRITE_OP(o) \ + buf[bc++] = inst->op[o].ave_kvm; \ + buf[bc++] = inst->op[o].ksl_tl; \ + buf[bc++] = inst->op[o].ar_dr; \ + buf[bc++] = inst->op[o].sl_rr; \ + buf[bc++] = inst->op[o].ws; + +#define WRITE_SET(type) \ + for(int i = 0; i < f->count_##type; i++) { \ + struct op3_file_instrument *inst = &f->type[i]; \ + buf[bc++] = inst->en_4op; \ + buf[bc++] = inst->percnotenum; \ + WRITE_OP(0) \ + buf[bc++] = inst->fb_con12; \ + WRITE_OP(1) \ + WRITE_OP(2) \ + buf[bc++] = inst->fb_con34; \ + WRITE_OP(3) \ + } + + WRITE_SET(melodic) + WRITE_SET(percussive) + return 0; +} #ifdef HAVE_STDIO static void op3_dump_instrument(struct op3_file_instrument *inst) { printf("en_4op=%d percnotenum=%d\n", inst->en_4op, inst->percnotenum); @@ -107,6 +144,22 @@ static int opl_voice_from_op3_file_instrument(struct opl_voice *v, struct op3_fi return 0; } +static int op3_file_instrument_from_opl_voice(struct op3_file_instrument *inst, struct opl_voice *v) { + inst->en_4op = v->en_4op; + inst->percnotenum = v->perc_inst; + inst->fb_con12 = v->ch_fb_cnt[0] & ~0xf0; + inst->fb_con34 = v->ch_fb_cnt[1] & ~0xf0; + for(int i = 0; i < 4; i++) { + struct opl_voice_operator *op = &v->operators[i]; + struct op3_file_instrument_op *op3 = &inst->op[i]; + op3->ave_kvm = op->am_vib_eg_ksr_mul; + op3->ksl_tl = op->ksl_tl; + op3->ar_dr = op->ar_dr; + op3->sl_rr = op->sl_rr; + op3->ws = op->ws; + } + return 0; +} static int load(void *data, int data_len, struct fm_voice_bank *bank) { struct op3_file f; int r = op3_file_load(&f, data, data_len); @@ -125,7 +178,20 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - return -1; + if(bank->num_opl_voices <= pos->opl) return -1; + struct op3_file f; + op3_file_init(&f); + struct opl_voice *voice = &bank->opl_voices[pos->opl]; + f.count_melodic = bank->num_opl_voices; + f.count_percussive = 0; + f.start_melodic = 0; + f.start_percussive = 0; + for(int i = 0; i < f.count_melodic; i++) { + op3_file_instrument_from_opl_voice(&f.melodic[i], voice); + voice++; + } + pos->opl++; + return op3_file_save(&f, write_fn, data_ptr); } struct loader op3_file_loader = { diff --git a/opm_file.c b/opm_file.c index c22a903..1657fc8 100644 --- a/opm_file.c +++ b/opm_file.c @@ -391,6 +391,7 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + if(bank->num_opm_voices <= pos->opm) return -1; struct opm_file opm_file; opm_file_init(&opm_file); for(int i = pos->opm; i < bank->num_opm_voices; i++) { diff --git a/sbi_file.c b/sbi_file.c index 3e940e5..71cf064 100644 --- a/sbi_file.c +++ b/sbi_file.c @@ -33,6 +33,32 @@ int sbi_file_load(struct sbi_file *f, uint8_t *data, size_t data_len) { return 0; } +int sbi_file_save(struct sbi_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + uint8_t buf[52] = { 0 }; + int bc = 0; + buf[bc++] = 'S'; + buf[bc++] = 'B'; + buf[bc++] = 'I'; + buf[bc++] = 0x1a; + memcpy(&buf[bc], f->name, 32); + bc += 32; + buf[bc++] = f->am_vib_eg_ksr_mul[0]; + buf[bc++] = f->am_vib_eg_ksr_mul[1]; + buf[bc++] = f->ksl_tl[0]; + buf[bc++] = f->ksl_tl[1]; + buf[bc++] = f->ar_dr[0]; + buf[bc++] = f->ar_dr[1]; + buf[bc++] = f->sl_rr[0]; + buf[bc++] = f->sl_rr[1]; + buf[bc++] = f->ws[0]; + buf[bc++] = f->ws[1]; + buf[bc++] = f->fb_con; + buf[bc++] = f->perc_voice; + buf[bc++] = f->transpose; + buf[bc++] = f->perc_pitch; + return write_fn(buf, 52, data_ptr); +} + #ifdef HAVE_STDIO void sbi_file_dump(struct sbi_file *f) { printf("name=%.32s\n", f->name); @@ -84,7 +110,23 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - return -1; + if(bank->num_opl_voices <= pos->opl) return -1; + struct sbi_file f; + sbi_file_init(&f); + struct opl_voice *voice = &bank->opl_voices[pos->opl]; + memcpy(f.name, voice->name, 32); + f.perc_voice = voice->perc_inst; + f.fb_con = voice->ch_fb_cnt[0]; + for(int i = 0; i < 2; i++) { + struct opl_voice_operator *op = &voice->operators[i]; + f.am_vib_eg_ksr_mul[i] = op->am_vib_eg_ksr_mul; + f.ksl_tl[i] = op->ksl_tl; + f.ar_dr[i] = op->ar_dr; + f.sl_rr[i] = op->sl_rr; + f.ws[i] = op->ws; + } + pos->opl++; + return sbi_file_save(&f, write_fn, data_ptr); } struct loader sbi_file_loader = { diff --git a/tfi_file.c b/tfi_file.c index d0f10dd..3173f1e 100644 --- a/tfi_file.c +++ b/tfi_file.c @@ -21,6 +21,19 @@ per-operator: } */ +// get signed DT from unsigned DT +static int DT_u2s(int dt_unsigned) { + int dt_signed = dt_unsigned & 3; + if (dt_unsigned & 4) return -dt_signed; + else return dt_signed; +} + +// get unsigned DT from signed DT +static int DT_s2u(int dt_signed) { + if (dt_signed < 0) return ((-dt_signed) & 3) | 4; + else return dt_signed & 3; +} + void tfi_file_init(struct tfi_file *f) { memset(f, 0, sizeof(*f)); } @@ -35,7 +48,8 @@ int tfi_file_load(struct tfi_file *tfi, uint8_t *data, size_t data_len) { for(int i = 0; i < 4; i++) { tfi->operators[i].mul = *p++; - tfi->operators[i].dt = *p++; + // tfi->operators[i].dt = *p++; + tfi->operators[i].dt = DT_s2u((*p++ & 7) - 3); tfi->operators[i].tl = *p++; tfi->operators[i].rs = *p++; tfi->operators[i].ar = *p++; @@ -50,7 +64,24 @@ int tfi_file_load(struct tfi_file *tfi, uint8_t *data, size_t data_len) { } int tfi_file_save(struct tfi_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - return -1; + uint8_t buf[42] = { 0 }; + int bc = 0; + buf[bc++] = f->alg; + buf[bc++] = f->fb; + for(int i = 0; i < 4; i++) { + buf[bc++] = f->operators[i].mul; + //buf[bc++] = f->operators[i].dt; + buf[bc++] = 3 + DT_u2s(f->operators[i].dt); + buf[bc++] = f->operators[i].tl; + buf[bc++] = f->operators[i].rs; + buf[bc++] = f->operators[i].ar; + buf[bc++] = f->operators[i].dr; + buf[bc++] = f->operators[i].sr; + buf[bc++] = f->operators[i].rr; + buf[bc++] = f->operators[i].sl; + buf[bc++] = f->operators[i].ssg_eg; + } + return write_fn(buf, 42, data_ptr); } #ifdef HAVE_STDIO @@ -91,7 +122,24 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + if(bank->num_opn_voices <= pos->opn) return -1; struct tfi_file f; + tfi_file_init(&f); + struct opn_voice* voice = &bank->opn_voices[pos->opn]; + if (!voice) return - 1; + f.fb = opn_voice_get_fb(voice); + f.alg = opn_voice_get_con(voice); + for(int i = 0; i < 4; i++) { + f.operators[i].dt = opn_voice_get_operator_dt(voice, i); + f.operators[i].mul = opn_voice_get_operator_mul(voice, i); + f.operators[i].tl = opn_voice_get_operator_tl(voice, i); + f.operators[i].rs = opn_voice_get_operator_ks(voice, i); + f.operators[i].ar = opn_voice_get_operator_ar(voice, i); + f.operators[i].dr = opn_voice_get_operator_dr(voice, i); + f.operators[i].sr = opn_voice_get_operator_sr(voice, i); + f.operators[i].sl = opn_voice_get_operator_sl(voice, i); + f.operators[i].rr = opn_voice_get_operator_rr(voice, i); + } pos->opn++; return tfi_file_save(&f, write_fn, data_ptr); } diff --git a/y12_file.c b/y12_file.c index 08ed8a3..02fb2a9 100644 --- a/y12_file.c +++ b/y12_file.c @@ -37,7 +37,28 @@ int y12_file_load(struct y12_file *f, uint8_t *data, size_t data_len) { } int y12_file_save(struct y12_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { - return -1; + uint8_t buf[128] = { 0 }; + int bc = 0; + for(int i = 0; i < 4; i++) { + buf[bc++] = f->operators[i].mul_dt; + buf[bc++] = f->operators[i].tl; + buf[bc++] = f->operators[i].ar_rs; + buf[bc++] = f->operators[i].dr_am; + buf[bc++] = f->operators[i].sr; + buf[bc++] = f->operators[i].rr_sl; + buf[bc++] = f->operators[i].ssg; + bc += 9; + } + buf[bc++] = f->alg; + buf[bc++] = f->fb; + bc += 14; + memcpy(&buf[bc], f->name, 16); + bc += 16; + memcpy(&buf[bc], f->dumper, 16); + bc += 16; + memcpy(&buf[bc], f->game, 16); + bc += 16; + return write_fn(buf, 128, data_ptr); } #ifdef HAVE_STDIO @@ -111,8 +132,27 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) { } static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) { + if(bank->num_opn_voices <= pos->opn) return -1; struct y12_file f; - + y12_file_init(&f); + struct opn_voice* voice = &bank->opn_voices[pos->opn]; + if (!voice) return -1; + memcpy(f.name, voice->name, 15); + memcpy(f.dumper, voice->dumper, 15); + memcpy(f.game, voice->game, 15); + f.name_len = strlen(f.name); + f.dumper_len = strlen(f.dumper); + f.game_len = strlen(f.game); + f.fb = opn_voice_get_fb(voice); + f.alg = opn_voice_get_con(voice); + for(int i = 0; i < 4; i++) { + f.operators[i].mul_dt = voice->operators[i].dt_mul; + f.operators[i].tl = opn_voice_get_operator_tl(bank->opn_voices + pos->opn, i); + f.operators[i].ar_rs = voice->operators[i].ks_ar; + f.operators[i].dr_am = voice->operators[i].am_dr; + f.operators[i].sr = opn_voice_get_operator_sr(bank->opn_voices + pos->opn, i); + f.operators[i].rr_sl = voice->operators[i].sl_rr; + } pos->opn++; return y12_file_save(&f, write_fn, data_ptr); } From 2973a1b21648cb1e465aa41b02e1f1712855dfed Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Sun, 9 Feb 2025 18:56:31 +0100 Subject: [PATCH 2/5] changed function signature, as "system" parameter is part of the DMP file spec anyway --- dmp_file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmp_file.h b/dmp_file.h index f757d75..c0c3664 100644 --- a/dmp_file.h +++ b/dmp_file.h @@ -18,7 +18,7 @@ struct dmp_file { }; void dmp_file_init(struct dmp_file *f); -int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system); +int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len); int dmp_file_save(struct dmp_file *f, int (*write_fn)(void *buf, size_t len, void *data_ptr), void *data_ptr); void dmp_file_dump(struct dmp_file *f); From 585272c02347e6220b5ccb03b5b3056e075d684b Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Sun, 9 Feb 2025 18:57:54 +0100 Subject: [PATCH 3/5] another tiny update to the DMP loader signature --- dmpdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmpdump.c b/dmpdump.c index 4c1c494..3b156b5 100644 --- a/dmpdump.c +++ b/dmpdump.c @@ -12,7 +12,7 @@ int main(int argc, char **argv) { continue; } struct dmp_file dmp; - if(dmp_file_load(&dmp, data, data_len, DMP_FILE_GENESIS) != 0) { + if(dmp_file_load(&dmp, data, data_len) != 0) { fprintf(stderr, "Could not load %s\n", argv[i]); continue; } From 3c832327c4e2fe51f6292d5289e72c9fd24571e1 Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Wed, 12 Feb 2025 08:49:19 +0100 Subject: [PATCH 4/5] updated to code guidelines and suggestions from the PR --- dmp_file.c | 50 ++++++++++++++++++++++---------------------------- dmp_file.h | 3 +++ op3_file.c | 37 +++++++++++++++++++------------------ tfi_file.c | 38 ++++++++++++++++---------------------- y12_file.c | 39 +++++++++++++++++++-------------------- 5 files changed, 79 insertions(+), 88 deletions(-) diff --git a/dmp_file.c b/dmp_file.c index fab68bc..ab3e5c1 100644 --- a/dmp_file.c +++ b/dmp_file.c @@ -5,9 +5,6 @@ #include "dmp_file.h" #include "tools.h" -#define SYSTEM_YM2612_OPN 0x02 -#define SYSTEM_YM2151_OPM 0x08 - void dmp_file_init(struct dmp_file *f) { memset(f, 0, sizeof(*f)); } @@ -25,7 +22,7 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len) { return -1; } - f->system = SYSTEM_YM2612_OPN; + f->system = DMP_SYSTEM_YM2612_OPN; f->version = data[0]; if (data[0] <= 10) { f->mode = data[1]; @@ -34,7 +31,7 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len) { f->mode = data[2]; } - if (f->system != SYSTEM_YM2612_OPN && f->system != SYSTEM_YM2151_OPM) { + if (f->system != DMP_SYSTEM_YM2612_OPN && f->system != DMP_SYSTEM_YM2151_OPM) { fprintf(stderr, "Unsupported system %d\n", f->system); return -1; } @@ -80,25 +77,25 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len) { int dmp_file_save(struct dmp_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { uint8_t buf[50] = { 0 }; - int bc = 0; - buf[bc++] = 0x0a; // version 10 - buf[bc++] = 1; // instrument type, 1 = FM - buf[bc++] = f->lfo; - buf[bc++] = f->fb; - buf[bc++] = f->alg; - buf[bc++] = f->lfo2; + uint8_t* p = buf; + *p++ = 0x0a; // version 10 + *p++ = 1; // instrument type, 1 = FM + *p++ = f->lfo; + *p++ = f->fb; + *p++ = f->alg; + *p++ = f->lfo2; for(int i = 0; i < f->num_operators; i++) { - buf[bc++] = f->operators[i].mult; - buf[bc++] = f->operators[i].tl; - buf[bc++] = f->operators[i].ar; - buf[bc++] = f->operators[i].dr; - buf[bc++] = f->operators[i].sl; - buf[bc++] = f->operators[i].rr; - buf[bc++] = f->operators[i].am; - buf[bc++] = f->operators[i].ksr; - buf[bc++] = f->operators[i].dt; - buf[bc++] = f->operators[i].d2r; - buf[bc++] = f->operators[i].ssg; + *p++ = f->operators[i].mult; + *p++ = f->operators[i].tl; + *p++ = f->operators[i].ar; + *p++ = f->operators[i].dr; + *p++ = f->operators[i].sl; + *p++ = f->operators[i].rr; + *p++ = f->operators[i].am; + *p++ = f->operators[i].ksr; + *p++ = f->operators[i].dt; + *p++ = f->operators[i].d2r; + *p++ = f->operators[i].ssg; } return write_fn(buf, 50, data_ptr); } @@ -168,7 +165,6 @@ static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, f.lfo = opn_voice_get_ams(voice); f.lfo2 = opn_voice_get_pms(voice); for(int i = 0; i < 4; i++) { - struct opn_voice_operator *op = &voice->operators[i]; struct dmp_file_operator *fop = &f.operators[i]; fop->dt = opn_voice_get_operator_dt(voice, i); fop->mult = opn_voice_get_operator_mul(voice, i); @@ -181,8 +177,6 @@ static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, fop->sl = opn_voice_get_operator_sl(voice, i); fop->rr = opn_voice_get_operator_rr(voice, i); fop->ssg = opn_voice_get_operator_ssg_eg(voice, i); - - } pos->opn++; return dmp_file_save(&f, write_fn, data_ptr); @@ -194,8 +188,8 @@ struct loader dmp_file_loader = { .name = "DMP", .description = "DefleMask Preset Format", .file_ext = "dmp", - .max_opl_voices = 1, + .max_opl_voices = 0, .max_opm_voices = 0, - .max_opn_voices = 0, + .max_opn_voices = 1, }; #endif diff --git a/dmp_file.h b/dmp_file.h index c0c3664..ba1031e 100644 --- a/dmp_file.h +++ b/dmp_file.h @@ -3,6 +3,9 @@ #include +#define DMP_SYSTEM_YM2612_OPN 0x02 +#define DMP_SYSTEM_YM2151_OPM 0x08 + struct dmp_file_operator { uint8_t mult, tl, diff --git a/op3_file.c b/op3_file.c index 1ee153c..819f788 100644 --- a/op3_file.c +++ b/op3_file.c @@ -46,33 +46,33 @@ int op3_file_load(struct op3_file *f, uint8_t *data, size_t data_len) { int op3_file_save(struct op3_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { uint8_t buf[8192] = { 0 }; strcpy((char*)&buf[0], "Junglevision Patch File\x1A"); - int bc = 32; - buf[bc++] = f->count_melodic & 0xff; - buf[bc++] = f->count_melodic >> 8; - buf[bc++] = f->count_percussive & 0xff; - buf[bc++] = f->count_percussive >> 8; - buf[bc++] = f->start_melodic & 0xff; - buf[bc++] = f->start_melodic >> 8; - buf[bc++] = f->start_percussive & 0xff; - buf[bc++] = f->start_percussive >> 8; + uint8_t* p = buf; + *p++ = f->count_melodic & 0xff; + *p++ = f->count_melodic >> 8; + *p++ = f->count_percussive & 0xff; + *p++ = f->count_percussive >> 8; + *p++ = f->start_melodic & 0xff; + *p++ = f->start_melodic >> 8; + *p++ = f->start_percussive & 0xff; + *p++ = f->start_percussive >> 8; #define WRITE_OP(o) \ - buf[bc++] = inst->op[o].ave_kvm; \ - buf[bc++] = inst->op[o].ksl_tl; \ - buf[bc++] = inst->op[o].ar_dr; \ - buf[bc++] = inst->op[o].sl_rr; \ - buf[bc++] = inst->op[o].ws; + *p++ = inst->op[o].ave_kvm; \ + *p++ = inst->op[o].ksl_tl; \ + *p++ = inst->op[o].ar_dr; \ + *p++ = inst->op[o].sl_rr; \ + *p++ = inst->op[o].ws; #define WRITE_SET(type) \ for(int i = 0; i < f->count_##type; i++) { \ struct op3_file_instrument *inst = &f->type[i]; \ - buf[bc++] = inst->en_4op; \ - buf[bc++] = inst->percnotenum; \ + *p++ = inst->en_4op; \ + *p++ = inst->percnotenum; \ WRITE_OP(0) \ - buf[bc++] = inst->fb_con12; \ + *p++ = inst->fb_con12; \ WRITE_OP(1) \ WRITE_OP(2) \ - buf[bc++] = inst->fb_con34; \ + *p++ = inst->fb_con34; \ WRITE_OP(3) \ } @@ -160,6 +160,7 @@ static int op3_file_instrument_from_opl_voice(struct op3_file_instrument *inst, } return 0; } + static int load(void *data, int data_len, struct fm_voice_bank *bank) { struct op3_file f; int r = op3_file_load(&f, data, data_len); diff --git a/tfi_file.c b/tfi_file.c index 3173f1e..51a6c2b 100644 --- a/tfi_file.c +++ b/tfi_file.c @@ -22,14 +22,14 @@ per-operator: */ // get signed DT from unsigned DT -static int DT_u2s(int dt_unsigned) { +static int convert_dt_u2s(int dt_unsigned) { int dt_signed = dt_unsigned & 3; if (dt_unsigned & 4) return -dt_signed; else return dt_signed; } // get unsigned DT from signed DT -static int DT_s2u(int dt_signed) { +static int convert_dt_s2u(int dt_signed) { if (dt_signed < 0) return ((-dt_signed) & 3) | 4; else return dt_signed & 3; } @@ -40,16 +40,12 @@ void tfi_file_init(struct tfi_file *f) { int tfi_file_load(struct tfi_file *tfi, uint8_t *data, size_t data_len) { if(data_len != 42) return -1; - uint8_t *p = data; - tfi->alg = *p++; tfi->fb = *p++; - for(int i = 0; i < 4; i++) { tfi->operators[i].mul = *p++; - // tfi->operators[i].dt = *p++; - tfi->operators[i].dt = DT_s2u((*p++ & 7) - 3); + tfi->operators[i].dt = convert_dt_s2u((*p++ & 7) - 3); tfi->operators[i].tl = *p++; tfi->operators[i].rs = *p++; tfi->operators[i].ar = *p++; @@ -59,27 +55,25 @@ int tfi_file_load(struct tfi_file *tfi, uint8_t *data, size_t data_len) { tfi->operators[i].sl = *p++; tfi->operators[i].ssg_eg = *p++; } - return 0; } int tfi_file_save(struct tfi_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { uint8_t buf[42] = { 0 }; - int bc = 0; - buf[bc++] = f->alg; - buf[bc++] = f->fb; + uint8_t *p = buf; + *p++ = f->alg; + *p++ = f->fb; for(int i = 0; i < 4; i++) { - buf[bc++] = f->operators[i].mul; - //buf[bc++] = f->operators[i].dt; - buf[bc++] = 3 + DT_u2s(f->operators[i].dt); - buf[bc++] = f->operators[i].tl; - buf[bc++] = f->operators[i].rs; - buf[bc++] = f->operators[i].ar; - buf[bc++] = f->operators[i].dr; - buf[bc++] = f->operators[i].sr; - buf[bc++] = f->operators[i].rr; - buf[bc++] = f->operators[i].sl; - buf[bc++] = f->operators[i].ssg_eg; + *p++ = f->operators[i].mul; + *p++ = 3 + convert_dt_u2s(f->operators[i].dt); + *p++ = f->operators[i].tl; + *p++ = f->operators[i].rs; + *p++ = f->operators[i].ar; + *p++ = f->operators[i].dr; + *p++ = f->operators[i].sr; + *p++ = f->operators[i].rr; + *p++ = f->operators[i].sl; + *p++ = f->operators[i].ssg_eg; } return write_fn(buf, 42, data_ptr); } diff --git a/y12_file.c b/y12_file.c index 02fb2a9..a53466a 100644 --- a/y12_file.c +++ b/y12_file.c @@ -38,26 +38,25 @@ int y12_file_load(struct y12_file *f, uint8_t *data, size_t data_len) { int y12_file_save(struct y12_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { uint8_t buf[128] = { 0 }; - int bc = 0; + uint8_t* p = buf; for(int i = 0; i < 4; i++) { - buf[bc++] = f->operators[i].mul_dt; - buf[bc++] = f->operators[i].tl; - buf[bc++] = f->operators[i].ar_rs; - buf[bc++] = f->operators[i].dr_am; - buf[bc++] = f->operators[i].sr; - buf[bc++] = f->operators[i].rr_sl; - buf[bc++] = f->operators[i].ssg; - bc += 9; + *p++ = f->operators[i].mul_dt; + *p++ = f->operators[i].tl; + *p++ = f->operators[i].ar_rs; + *p++ = f->operators[i].dr_am; + *p++ = f->operators[i].sr; + *p++ = f->operators[i].rr_sl; + *p++ = f->operators[i].ssg; + p += 9; } - buf[bc++] = f->alg; - buf[bc++] = f->fb; - bc += 14; - memcpy(&buf[bc], f->name, 16); - bc += 16; - memcpy(&buf[bc], f->dumper, 16); - bc += 16; - memcpy(&buf[bc], f->game, 16); - bc += 16; + *p++ = f->alg; + *p++ = f->fb; + p += 14; + memcpy(p, f->name, 16); + p += 16; + memcpy(p, f->dumper, 16); + p += 16; + memcpy(p, f->game, 16); return write_fn(buf, 128, data_ptr); } @@ -164,7 +163,7 @@ struct loader y12_file_loader = { .description = "Y12", .file_ext = "y12", .max_opl_voices = 0, - .max_opm_voices = 1, - .max_opn_voices = 0, + .max_opm_voices = 0, + .max_opn_voices = 1, }; #endif From 27d9b1b9d52e17b2f0fe5975399a0e2b8db83c85 Mon Sep 17 00:00:00 2001 From: Tobias Fleischer Date: Wed, 12 Feb 2025 09:08:07 +0100 Subject: [PATCH 5/5] sbi update acc. to guidelines --- sbi_file.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/sbi_file.c b/sbi_file.c index 71cf064..d6737ef 100644 --- a/sbi_file.c +++ b/sbi_file.c @@ -10,9 +10,7 @@ void sbi_file_init(struct sbi_file *f) { int sbi_file_load(struct sbi_file *f, uint8_t *data, size_t data_len) { if(data_len < 47 || data_len > 52) return -1; - if(data[0] != 'S' || data[1] != 'B' || data[2] != 'I' || (data[3] != 0x1a && data[3] != 0x1d)) return -1; - memcpy(f->name, &data[4], 32); uint8_t *b = data + 36; @@ -35,27 +33,27 @@ int sbi_file_load(struct sbi_file *f, uint8_t *data, size_t data_len) { int sbi_file_save(struct sbi_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) { uint8_t buf[52] = { 0 }; - int bc = 0; - buf[bc++] = 'S'; - buf[bc++] = 'B'; - buf[bc++] = 'I'; - buf[bc++] = 0x1a; - memcpy(&buf[bc], f->name, 32); - bc += 32; - buf[bc++] = f->am_vib_eg_ksr_mul[0]; - buf[bc++] = f->am_vib_eg_ksr_mul[1]; - buf[bc++] = f->ksl_tl[0]; - buf[bc++] = f->ksl_tl[1]; - buf[bc++] = f->ar_dr[0]; - buf[bc++] = f->ar_dr[1]; - buf[bc++] = f->sl_rr[0]; - buf[bc++] = f->sl_rr[1]; - buf[bc++] = f->ws[0]; - buf[bc++] = f->ws[1]; - buf[bc++] = f->fb_con; - buf[bc++] = f->perc_voice; - buf[bc++] = f->transpose; - buf[bc++] = f->perc_pitch; + uint8_t* p = buf; + *p++ = 'S'; + *p++ = 'B'; + *p++ = 'I'; + *p++ = 0x1a; + memcpy(p, f->name, 32); + p += 32; + *p++ = f->am_vib_eg_ksr_mul[0]; + *p++ = f->am_vib_eg_ksr_mul[1]; + *p++ = f->ksl_tl[0]; + *p++ = f->ksl_tl[1]; + *p++ = f->ar_dr[0]; + *p++ = f->ar_dr[1]; + *p++ = f->sl_rr[0]; + *p++ = f->sl_rr[1]; + *p++ = f->ws[0]; + *p++ = f->ws[1]; + *p++ = f->fb_con; + *p++ = f->perc_voice; + *p++ = f->transpose; + *p++ = f->perc_pitch; return write_fn(buf, 52, data_ptr); }