Skip to content

Commit bd176e4

Browse files
authored
Merge pull request #9 from tobybear/more_loaders
implementation of more file load/save routines for the loaders
2 parents da01958 + 27d9b1b commit bd176e4

10 files changed

Lines changed: 220 additions & 25 deletions

File tree

dmp_file.c

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
#include "dmp_file.h"
66
#include "tools.h"
77

8-
int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system) {
8+
void dmp_file_init(struct dmp_file *f) {
9+
memset(f, 0, sizeof(*f));
10+
}
11+
12+
int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len) {
913
memset(f, 0, sizeof(struct dmp_file));
1014

11-
if(data[0] != 9) {
15+
if(data[0] < 9) {
1216
fprintf(stderr, "Unsupported version 0x%02x (%d)\n", data[0], data[0]);
1317
return -1;
1418
}
@@ -18,17 +22,34 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system
1822
return -1;
1923
}
2024

25+
f->system = DMP_SYSTEM_YM2612_OPN;
2126
f->version = data[0];
22-
f->mode = data[1];
27+
if (data[0] <= 10) {
28+
f->mode = data[1];
29+
} else {
30+
f->system = data[1];
31+
f->mode = data[2];
32+
}
33+
34+
if (f->system != DMP_SYSTEM_YM2612_OPN && f->system != DMP_SYSTEM_YM2151_OPM) {
35+
fprintf(stderr, "Unsupported system %d\n", f->system);
36+
return -1;
37+
}
2338

2439
if(f->mode == 1) {
2540
uint8_t *p = data + 2;
26-
f->num_operators = *p++ == 0 ? 2 : 4;
41+
if (f->version < 10) {
42+
f->num_operators = *p++ == 0 ? 2 : 4;
43+
} else {
44+
f->num_operators = 4;
45+
}
2746
f->lfo = *p++;
2847
f->fb = *p++;
2948
f->alg = *p++;
30-
if(system == DMP_FILE_GENESIS) {
49+
if(f->version >= 10) {
3150
f->lfo2 = *p++;
51+
} else {
52+
f->lfo2 = 0;
3253
}
3354

3455
for(int i = 0; i < f->num_operators; i++) {
@@ -39,7 +60,7 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system
3960
f->operators[i].sl = *p++;
4061
f->operators[i].rr = *p++;
4162
f->operators[i].am = *p++;
42-
if(system == DMP_FILE_GENESIS) {
63+
if(f->version >= 10) {
4364
f->operators[i].ksr = *p++;
4465
f->operators[i].dt = *p++;
4566
f->operators[i].d2r = *p++;
@@ -54,6 +75,31 @@ int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system
5475
return 0;
5576
}
5677

78+
int dmp_file_save(struct dmp_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
79+
uint8_t buf[50] = { 0 };
80+
uint8_t* p = buf;
81+
*p++ = 0x0a; // version 10
82+
*p++ = 1; // instrument type, 1 = FM
83+
*p++ = f->lfo;
84+
*p++ = f->fb;
85+
*p++ = f->alg;
86+
*p++ = f->lfo2;
87+
for(int i = 0; i < f->num_operators; i++) {
88+
*p++ = f->operators[i].mult;
89+
*p++ = f->operators[i].tl;
90+
*p++ = f->operators[i].ar;
91+
*p++ = f->operators[i].dr;
92+
*p++ = f->operators[i].sl;
93+
*p++ = f->operators[i].rr;
94+
*p++ = f->operators[i].am;
95+
*p++ = f->operators[i].ksr;
96+
*p++ = f->operators[i].dt;
97+
*p++ = f->operators[i].d2r;
98+
*p++ = f->operators[i].ssg;
99+
}
100+
return write_fn(buf, 50, data_ptr);
101+
}
102+
57103
#ifdef HAVE_STDIO
58104
void dmp_file_dump(struct dmp_file *dmp) {
59105
printf("version=%d mode=%d\n", dmp->version, dmp->mode);
@@ -85,11 +131,55 @@ void dmp_file_dump(struct dmp_file *dmp) {
85131
#include "loader.h"
86132

87133
static int load(void *data, int data_len, struct fm_voice_bank *bank) {
88-
return -1;
134+
struct dmp_file f;
135+
int r = dmp_file_load(&f, (uint8_t*)data, data_len);
136+
if(r) return r;
137+
struct opn_voice *voice = fm_voice_bank_reserve_opn_voices(bank, 1);
138+
if(!voice) return -1;
139+
voice->slot = 0x0f;
140+
voice->fb_con = (f.fb & 0x07) << 3 | (f.alg & 0x07);
141+
voice->lr_ams_pms = (f.lfo & 0x07) << 4 | (f.lfo2 & 0x03);
142+
for(int i = 0; i < f.num_operators; i++) {
143+
struct opn_voice_operator *op = &voice->operators[i];
144+
struct dmp_file_operator *fop = &f.operators[i];
145+
op->dt_mul = (fop->dt & 0x07) << 3 | (fop->mult & 0x07);
146+
op->tl = fop->tl & 0x7f;
147+
op->ks_ar = fop->ksr << 6 | (fop->ar & 0x1f);
148+
op->am_dr = fop->dr & 0x1f;
149+
op->sr = fop->d2r;
150+
op->sl_rr = fop->sl << 4 | (fop->rr & 0x0f);
151+
op->ssg_eg = fop->ssg;
152+
}
153+
return 0;
89154
}
90155

91156
static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
92-
return -1;
157+
if(bank->num_opn_voices <= pos->opn) return -1;
158+
struct dmp_file f;
159+
dmp_file_init(&f);
160+
struct opn_voice* voice = &bank->opn_voices[pos->opn];
161+
if (!voice) return -1;
162+
163+
f.fb = opn_voice_get_fb(voice);
164+
f.alg = opn_voice_get_con(voice);
165+
f.lfo = opn_voice_get_ams(voice);
166+
f.lfo2 = opn_voice_get_pms(voice);
167+
for(int i = 0; i < 4; i++) {
168+
struct dmp_file_operator *fop = &f.operators[i];
169+
fop->dt = opn_voice_get_operator_dt(voice, i);
170+
fop->mult = opn_voice_get_operator_mul(voice, i);
171+
fop->tl = opn_voice_get_operator_tl(voice, i);
172+
fop->ksr = opn_voice_get_operator_ks(voice, i);
173+
fop->ar = opn_voice_get_operator_ar(voice, i);
174+
fop->dr = opn_voice_get_operator_dr(voice, i);
175+
fop->am = opn_voice_get_operator_am(voice, i);
176+
fop->d2r = opn_voice_get_operator_sr(voice, i);
177+
fop->sl = opn_voice_get_operator_sl(voice, i);
178+
fop->rr = opn_voice_get_operator_rr(voice, i);
179+
fop->ssg = opn_voice_get_operator_ssg_eg(voice, i);
180+
}
181+
pos->opn++;
182+
return dmp_file_save(&f, write_fn, data_ptr);
93183
}
94184

95185
struct loader dmp_file_loader = {
@@ -98,8 +188,8 @@ struct loader dmp_file_loader = {
98188
.name = "DMP",
99189
.description = "DefleMask Preset Format",
100190
.file_ext = "dmp",
101-
.max_opl_voices = 1,
191+
.max_opl_voices = 0,
102192
.max_opm_voices = 0,
103-
.max_opn_voices = 0,
193+
.max_opn_voices = 1,
104194
};
105195
#endif

dmp_file.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
#include <stdint.h>
55

6-
#define DMP_FILE_GENESIS 1
6+
#define DMP_SYSTEM_YM2612_OPN 0x02
7+
#define DMP_SYSTEM_YM2151_OPM 0x08
78

89
struct dmp_file_operator {
910
uint8_t
@@ -13,14 +14,14 @@ struct dmp_file_operator {
1314
};
1415

1516
struct dmp_file {
16-
uint8_t version, mode;
17+
uint8_t version, mode, system;
1718
uint8_t num_operators, lfo, fb, alg;
1819
uint8_t lfo2;
1920
struct dmp_file_operator operators[4];
2021
};
2122

2223
void dmp_file_init(struct dmp_file *f);
23-
int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len, int system);
24+
int dmp_file_load(struct dmp_file *f, uint8_t *data, size_t data_len);
2425
int dmp_file_save(struct dmp_file *f, int (*write_fn)(void *buf, size_t len, void *data_ptr), void *data_ptr);
2526
void dmp_file_dump(struct dmp_file *f);
2627

dmpdump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ int main(int argc, char **argv) {
1212
continue;
1313
}
1414
struct dmp_file dmp;
15-
if(dmp_file_load(&dmp, data, data_len, DMP_FILE_GENESIS) != 0) {
15+
if(dmp_file_load(&dmp, data, data_len) != 0) {
1616
fprintf(stderr, "Could not load %s\n", argv[i]);
1717
continue;
1818
}

ins_file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) {
128128
}
129129

130130
static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
131-
struct ins_file ins;
132131
if(bank->num_opn_voices <= pos->opn) return -1;
132+
struct ins_file ins;
133133
ins.name = strdup(bank->opn_voices[pos->opn].name);
134134
if(!ins.name) return -1;
135135
ins.name_len = strlen(bank->opn_voices[pos->opn].name);

md5.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#include <sys/types.h>
2929

3030
# include <string.h>
31-
#if STDC_HEADERS || defined _LIBC
31+
#if STDC_HEADERS || defined _LIBC || defined _MSC_VER
3232
# include <stdlib.h>
3333
#else
3434
# ifndef HAVE_MEMCPY

md5.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
#include <stdio.h>
2525

26-
#if defined HAVE_LIMITS_H || _LIBC
26+
#if defined HAVE_LIMITS_H || defined _LIBC || defined _MSC_VER
2727
# include <limits.h>
2828
#endif
2929

op3_file.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,43 @@ int op3_file_load(struct op3_file *f, uint8_t *data, size_t data_len) {
4343
return 0;
4444
}
4545

46+
int op3_file_save(struct op3_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
47+
uint8_t buf[8192] = { 0 };
48+
strcpy((char*)&buf[0], "Junglevision Patch File\x1A");
49+
uint8_t* p = buf;
50+
*p++ = f->count_melodic & 0xff;
51+
*p++ = f->count_melodic >> 8;
52+
*p++ = f->count_percussive & 0xff;
53+
*p++ = f->count_percussive >> 8;
54+
*p++ = f->start_melodic & 0xff;
55+
*p++ = f->start_melodic >> 8;
56+
*p++ = f->start_percussive & 0xff;
57+
*p++ = f->start_percussive >> 8;
58+
59+
#define WRITE_OP(o) \
60+
*p++ = inst->op[o].ave_kvm; \
61+
*p++ = inst->op[o].ksl_tl; \
62+
*p++ = inst->op[o].ar_dr; \
63+
*p++ = inst->op[o].sl_rr; \
64+
*p++ = inst->op[o].ws;
65+
66+
#define WRITE_SET(type) \
67+
for(int i = 0; i < f->count_##type; i++) { \
68+
struct op3_file_instrument *inst = &f->type[i]; \
69+
*p++ = inst->en_4op; \
70+
*p++ = inst->percnotenum; \
71+
WRITE_OP(0) \
72+
*p++ = inst->fb_con12; \
73+
WRITE_OP(1) \
74+
WRITE_OP(2) \
75+
*p++ = inst->fb_con34; \
76+
WRITE_OP(3) \
77+
}
78+
79+
WRITE_SET(melodic)
80+
WRITE_SET(percussive)
81+
return 0;
82+
}
4683
#ifdef HAVE_STDIO
4784
static void op3_dump_instrument(struct op3_file_instrument *inst) {
4885
printf("en_4op=%d percnotenum=%d\n", inst->en_4op, inst->percnotenum);
@@ -107,6 +144,23 @@ static int opl_voice_from_op3_file_instrument(struct opl_voice *v, struct op3_fi
107144
return 0;
108145
}
109146

147+
static int op3_file_instrument_from_opl_voice(struct op3_file_instrument *inst, struct opl_voice *v) {
148+
inst->en_4op = v->en_4op;
149+
inst->percnotenum = v->perc_inst;
150+
inst->fb_con12 = v->ch_fb_cnt[0] & ~0xf0;
151+
inst->fb_con34 = v->ch_fb_cnt[1] & ~0xf0;
152+
for(int i = 0; i < 4; i++) {
153+
struct opl_voice_operator *op = &v->operators[i];
154+
struct op3_file_instrument_op *op3 = &inst->op[i];
155+
op3->ave_kvm = op->am_vib_eg_ksr_mul;
156+
op3->ksl_tl = op->ksl_tl;
157+
op3->ar_dr = op->ar_dr;
158+
op3->sl_rr = op->sl_rr;
159+
op3->ws = op->ws;
160+
}
161+
return 0;
162+
}
163+
110164
static int load(void *data, int data_len, struct fm_voice_bank *bank) {
111165
struct op3_file f;
112166
int r = op3_file_load(&f, data, data_len);
@@ -125,7 +179,20 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) {
125179
}
126180

127181
static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
128-
return -1;
182+
if(bank->num_opl_voices <= pos->opl) return -1;
183+
struct op3_file f;
184+
op3_file_init(&f);
185+
struct opl_voice *voice = &bank->opl_voices[pos->opl];
186+
f.count_melodic = bank->num_opl_voices;
187+
f.count_percussive = 0;
188+
f.start_melodic = 0;
189+
f.start_percussive = 0;
190+
for(int i = 0; i < f.count_melodic; i++) {
191+
op3_file_instrument_from_opl_voice(&f.melodic[i], voice);
192+
voice++;
193+
}
194+
pos->opl++;
195+
return op3_file_save(&f, write_fn, data_ptr);
129196
}
130197

131198
struct loader op3_file_loader = {

opm_file.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) {
391391
}
392392

393393
static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
394+
if(bank->num_opm_voices <= pos->opm) return -1;
394395
struct opm_file opm_file;
395396
opm_file_init(&opm_file);
396397
for(int i = pos->opm; i < bank->num_opm_voices; i++) {

sbi_file.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ void sbi_file_init(struct sbi_file *f) {
1010

1111
int sbi_file_load(struct sbi_file *f, uint8_t *data, size_t data_len) {
1212
if(data_len < 47 || data_len > 52) return -1;
13-
1413
if(data[0] != 'S' || data[1] != 'B' || data[2] != 'I' || (data[3] != 0x1a && data[3] != 0x1d)) return -1;
15-
1614
memcpy(f->name, &data[4], 32);
1715

1816
uint8_t *b = data + 36;
@@ -33,6 +31,32 @@ int sbi_file_load(struct sbi_file *f, uint8_t *data, size_t data_len) {
3331
return 0;
3432
}
3533

34+
int sbi_file_save(struct sbi_file *f, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
35+
uint8_t buf[52] = { 0 };
36+
uint8_t* p = buf;
37+
*p++ = 'S';
38+
*p++ = 'B';
39+
*p++ = 'I';
40+
*p++ = 0x1a;
41+
memcpy(p, f->name, 32);
42+
p += 32;
43+
*p++ = f->am_vib_eg_ksr_mul[0];
44+
*p++ = f->am_vib_eg_ksr_mul[1];
45+
*p++ = f->ksl_tl[0];
46+
*p++ = f->ksl_tl[1];
47+
*p++ = f->ar_dr[0];
48+
*p++ = f->ar_dr[1];
49+
*p++ = f->sl_rr[0];
50+
*p++ = f->sl_rr[1];
51+
*p++ = f->ws[0];
52+
*p++ = f->ws[1];
53+
*p++ = f->fb_con;
54+
*p++ = f->perc_voice;
55+
*p++ = f->transpose;
56+
*p++ = f->perc_pitch;
57+
return write_fn(buf, 52, data_ptr);
58+
}
59+
3660
#ifdef HAVE_STDIO
3761
void sbi_file_dump(struct sbi_file *f) {
3862
printf("name=%.32s\n", f->name);
@@ -84,7 +108,23 @@ static int load(void *data, int data_len, struct fm_voice_bank *bank) {
84108
}
85109

86110
static int save(struct fm_voice_bank *bank, struct fm_voice_bank_position *pos, int (*write_fn)(void *, size_t, void *), void *data_ptr) {
87-
return -1;
111+
if(bank->num_opl_voices <= pos->opl) return -1;
112+
struct sbi_file f;
113+
sbi_file_init(&f);
114+
struct opl_voice *voice = &bank->opl_voices[pos->opl];
115+
memcpy(f.name, voice->name, 32);
116+
f.perc_voice = voice->perc_inst;
117+
f.fb_con = voice->ch_fb_cnt[0];
118+
for(int i = 0; i < 2; i++) {
119+
struct opl_voice_operator *op = &voice->operators[i];
120+
f.am_vib_eg_ksr_mul[i] = op->am_vib_eg_ksr_mul;
121+
f.ksl_tl[i] = op->ksl_tl;
122+
f.ar_dr[i] = op->ar_dr;
123+
f.sl_rr[i] = op->sl_rr;
124+
f.ws[i] = op->ws;
125+
}
126+
pos->opl++;
127+
return sbi_file_save(&f, write_fn, data_ptr);
88128
}
89129

90130
struct loader sbi_file_loader = {

0 commit comments

Comments
 (0)