Skip to content

Commit 0c64a8f

Browse files
author
vampirefrog
committed
fmtoy: YM2203 working
1 parent a4e82b5 commit 0c64a8f

File tree

2 files changed

+98
-36
lines changed

2 files changed

+98
-36
lines changed

fmtoy.c

Lines changed: 98 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "tools.h"
77
#include "opm_file.h"
88

9+
#include "chips/2203intf.h"
10+
911
static void fmtoy_set_buf_size(struct fmtoy *fmtoy, int size) {
1012
if(fmtoy->buf_size < size) {
1113
fmtoy->buf_size = size;
@@ -16,29 +18,38 @@ static void fmtoy_set_buf_size(struct fmtoy *fmtoy, int size) {
1618
}
1719
}
1820

19-
static void ssg_set_clock(void *param, int clock) { (void)param; (void) clock; }
20-
static void ssg_write(void *param, int address, int data) { (void)param; (void)address; (void)data; }
21-
static void ssg_read(void *param) { (void)param; }
22-
static void ssg_reset(void *param) { (void)param; }
21+
static void fmtoy_ssg_set_clock(void *param, int clock) { (void)param; (void) clock; }
22+
static void fmtoy_ssg_write(void *param, int address, int data) { (void)param; (void)address; (void)data; }
23+
static int fmtoy_ssg_read(void *param) { (void)param; return 0; }
24+
static void fmtoy_ssg_reset(void *param) { (void)param; }
25+
ssg_callbacks cb = {
26+
set_clock: fmtoy_ssg_set_clock,
27+
write: fmtoy_ssg_write,
28+
read: fmtoy_ssg_read,
29+
reset: fmtoy_ssg_reset
30+
};
31+
stream_sample_t DUMMYBUFL[16], DUMMYBUFR[16];
32+
stream_sample_t* DUMMYBUF[0x02] = {DUMMYBUFL, DUMMYBUFR};
33+
uint8_t IsVGMInit = 1;
34+
uint8_t CHIP_SAMPLING_MODE = 0;
35+
uint8_t CHIP_SAMPLE_RATE = 0;
2336

2437
void fmtoy_init(struct fmtoy *fmtoy, int sample_rate) {
2538
fmtoy->sample_rate = sample_rate;
39+
CHIP_SAMPLE_RATE = sample_rate;
2640

2741
fmtoy->render_buf_l = fmtoy->render_buf_r = 0;
2842
fmtoy->chip_buf_l = fmtoy->chip_buf_r = 0;
2943
fmtoy_set_buf_size(fmtoy, 1024);
3044

31-
ssg_callbacks cb = {
32-
set_clock: ssg_set_clock,
33-
write: ssg_write,
34-
read: ssg_read,
35-
reset: ssg_reset
36-
};
37-
3845
fmtoy->ym2151 = ym2151_init(4000000, sample_rate);
3946
ym2151_reset_chip(fmtoy->ym2151);
40-
fmtoy->ym2203 = ym2203_init(0, 3579545, sample_rate, 0, 0, &cb);
41-
ym2203_reset_chip(fmtoy->ym2203);
47+
48+
int ayrate;
49+
device_start_ym2203(0, 3579545,1, 0, &ayrate);
50+
ym2203_set_mute_mask(0, 0, 0);
51+
device_reset_ym2203(0);
52+
4253
fmtoy->ym2608 = ym2608_init(0, 3579545, sample_rate, 0, 0, &cb);
4354
ym2608_reset_chip(fmtoy->ym2608);
4455
fmtoy->ym2610 = ym2610_init(0, 3579545, sample_rate, 0, 0, &cb);
@@ -113,23 +124,25 @@ void fmtoy_load_voice(struct fmtoy *fmtoy, char *filename) {
113124
fop->d1l_rr = op->d1l << 4 | op->rr;
114125
}
115126

116-
printf("loaded opm voice %d\n", fmtoy->num_voices);
117127
fmtoy->num_voices++;
118128

119129
// OPN voices
120-
//struct fmtoy_opn_voice *opnv = &fmtoy->opn_voices[fmtoy->num_voices];
121-
// opnv->lr_fl_con = 3 << 6 | v->ch_fl << 3 | v->ch_con;
122-
// opnv->pms_ams = v->ch_pms << 4 | v->ch_ams;
123-
// for(int j = 0; j < 4; j++) {
124-
// struct fmtoy_opm_voice_operator *fop = fv->operators[j];
125-
// struct opm_file_voice_operator *op = v->operators[j];
126-
// fop->dt1_mul = op->dt1 << 4 | op->mul;
127-
// fop->tl = op->tl;
128-
// fop->ks_ar = op->ks << 6 | op->ar;
129-
// fop->ams_en_d1r = op->ams_en << 7 | op->d1r;
130-
// fop->dt2_d2r = op->dt2 << 6 | op->d2r;
131-
// fop->d1l_rr = op->d1l << 4 | op->rr;
132-
// }
130+
struct fmtoy_opn_voice *opnv = &fmtoy->opn_voices[fmtoy->num_voices];
131+
132+
opnv->lfo = v->lfo_lfrq >> 4;
133+
opnv->fb_connect = v->ch_fl << 3 | v->ch_con;
134+
opnv->lr_ams_pms = 3 << 6 | v->ch_ams << 4 | v->ch_pms;
135+
for(int j = 0; j < 4; j++) {
136+
struct fmtoy_opn_voice_operator *fop = &opnv->operators[j];
137+
struct opm_file_operator *op = &v->operators[ops[j]];
138+
fop->dt_multi = op->dt1 << 4 | op->mul;
139+
fop->tl = op->tl;
140+
fop->ks_ar = op->ks << 6 | op->ar;
141+
fop->am_dr = op->ams_en << 7 | op->d1r;
142+
fop->sr = op->d2r;
143+
fop->sl_rr = op->d1l << 4 | op->rr;
144+
fop->ssg_eg = 0;
145+
}
133146
}
134147
}
135148
}
@@ -153,7 +166,32 @@ void fmtoy_program_change(struct fmtoy *fmtoy, uint8_t channel, uint8_t program)
153166
}
154167
}
155168
break;
156-
case 1:
169+
case 1:{
170+
struct fmtoy_opn_voice *v = &fmtoy->opn_voices[program];
171+
for(int i = 0; i < 3; i++) {
172+
ym2203_w(0, 0, 0xb0 + i);
173+
ym2203_w(0, 1, v->fb_connect);
174+
ym2203_w(0, 0, 0xb4 + i);
175+
ym2203_w(0, 1, v->lr_ams_pms);
176+
for(int j = 0; j < 4; j++) {
177+
struct fmtoy_opn_voice_operator *op = &v->operators[j];
178+
ym2203_w(0, 0, 0x30 + i + j * 4);
179+
ym2203_w(0, 1, op->dt_multi);
180+
ym2203_w(0, 0, 0x40 + i + j * 4);
181+
ym2203_w(0, 1, op->tl);
182+
ym2203_w(0, 0, 0x50 + i + j * 4);
183+
ym2203_w(0, 1, op->ks_ar);
184+
ym2203_w(0, 0, 0x60 + i + j * 4);
185+
ym2203_w(0, 1, op->am_dr);
186+
ym2203_w(0, 0, 0x70 + i + j * 4);
187+
ym2203_w(0, 1, op->sr);
188+
ym2203_w(0, 0, 0x80 + i + j * 4);
189+
ym2203_w(0, 1, op->sl_rr);
190+
ym2203_w(0, 0, 0x90 + i + j * 4);
191+
ym2203_w(0, 1, op->ssg_eg);
192+
}
193+
}
194+
}
157195
break;
158196
case 2:
159197
break;
@@ -173,7 +211,7 @@ void fmtoy_cc(struct fmtoy *fmtoy, uint8_t channel, int cc, int value) {
173211
static int find_unused_channel(struct fmtoy_chip_channel *channels, int num_channels) {
174212
int chip_channel = 0;
175213
uint32_t min_frames = UINT32_MAX;
176-
for(int i = 0; i < 8; i++) {
214+
for(int i = 0; i < num_channels; i++) {
177215
if(!channels[i].on) {
178216
chip_channel = i;
179217
break;
@@ -218,6 +256,34 @@ void fmtoy_note_on(struct fmtoy *fmtoy, uint8_t channel, uint8_t note, uint8_t v
218256
fmtoy->ym2151_channels[chip_channel].note = note;
219257
}
220258
break;
259+
case 1: {
260+
int chip_channel = find_unused_channel(fmtoy->ym2203_channels, sizeof(fmtoy->ym2203_channels) / sizeof(fmtoy->ym2203_channels[0]));
261+
uint16_t opn_notes[12] = { 617, 653, 692, 733, 777, 823, 872, 924, 979, 1037, 1099, 1164 };
262+
263+
if(fmtoy->ym2203_channels[chip_channel].on) {
264+
// send a key off
265+
ym2203_w(0, 0, 0x28);
266+
ym2203_w(0, 1, chip_channel);
267+
}
268+
269+
uint8_t octave = note / 12;
270+
uint16_t semitones = opn_notes[note % 12];
271+
ym2203_w(0, 0, 0xa4 + chip_channel);
272+
ym2203_w(0, 1, octave << 3 | 0);
273+
ym2203_w(0, 0, 0xa0 + chip_channel);
274+
ym2203_w(0, 1, semitones >> 3);
275+
276+
// ym2203_w(0, 0, 0xa4 + chip_channel);
277+
// ym2203_w(0, 1, 0x2a);
278+
// ym2203_w(0, 0, 0xa0 + chip_channel);
279+
// ym2203_w(0, 1, 0x69);
280+
ym2203_w(0, 0, 0x28);
281+
ym2203_w(0, 1, 0xf0 + chip_channel);
282+
fmtoy->ym2203_channels[chip_channel].frames = frame_time();
283+
fmtoy->ym2203_channels[chip_channel].on = 1;
284+
fmtoy->ym2203_channels[chip_channel].note = note;
285+
}
286+
break;
221287
}
222288

223289
}
@@ -235,7 +301,8 @@ void fmtoy_note_off(struct fmtoy *fmtoy, uint8_t channel, uint8_t note, uint8_t
235301
case 1:
236302
chip_channel = find_used_channel(fmtoy->ym2203_channels, sizeof(fmtoy->ym2203_channels) / sizeof(fmtoy->ym2203_channels[0]), note);
237303
if(chip_channel >= 0) {
238-
ym2203_write(fmtoy->ym2203, 0x28, chip_channel < 3);
304+
ym2203_w(0, 0, 0x28);
305+
ym2203_w(0, 1, chip_channel);
239306
fmtoy->ym2203_channels[chip_channel].on = 0;
240307
}
241308
break;
@@ -279,7 +346,7 @@ void fmtoy_render(struct fmtoy *fmtoy, int samples) {
279346

280347
ym2151_update_one(fmtoy->ym2151, chipBufs, samples);
281348
MIX_CHIP
282-
ym2203_update_one(fmtoy->ym2203, chipBufs, samples);
349+
ym2203_stream_update(0, chipBufs, samples);
283350
MIX_CHIP
284351
ym2608_update_one(fmtoy->ym2608, chipBufs, samples);
285352
MIX_CHIP

fmtoy_jack.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ jack_port_t *output_ports[2];
1818
unsigned long sr;
1919

2020
struct fmtoy fmtoy;
21-
stream_sample_t* DUMMYBUF[0x02] = {NULL, NULL};
22-
uint8_t IsVGMInit = 1;
23-
uint8_t CHIP_SAMPLING_MODE = 0;
24-
uint8_t CHIP_SAMPLE_RATE = 0;
2521

2622
int process(jack_nframes_t nframes, void *arg) {
2723
sample_t *buffers[2];
@@ -171,7 +167,6 @@ static void init_jack(void) {
171167
output_ports[1] = jack_port_register(client, "Right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
172168

173169
sr = jack_get_sample_rate(client);
174-
CHIP_SAMPLE_RATE = sr;
175170
}
176171

177172
static void activate_jack(void) {

0 commit comments

Comments
 (0)