comparison ym2612.c @ 370:5f215603d001

Fix register to operator mapping. Fix rate table generation. Add TL to envelope value rather than using it as a limit for the attack phase.
author Mike Pavone <pavone@retrodev.com>
date Sun, 02 Jun 2013 00:00:22 -0700
parents fc820ab1394b
children 0f8a759f1ff4
comparison
equal deleted inserted replaced
369:fc820ab1394b 370:5f215603d001
2 #include <math.h> 2 #include <math.h>
3 #include <stdio.h> 3 #include <stdio.h>
4 #include <stdlib.h> 4 #include <stdlib.h>
5 #include "ym2612.h" 5 #include "ym2612.h"
6 #include "render.h" 6 #include "render.h"
7
8 //#define DO_DEBUG_PRINT
9 #ifdef DO_DEBUG_PRINT
10 #define dfprintf fprintf
11 #define dfopen(var, fname, mode) var=fopen(fname, mode)
12 #else
13 #define dfprintf
14 #define dfopen(var, fname, mode)
15 #endif
7 16
8 #define BUSY_CYCLES 17 17 #define BUSY_CYCLES 17
9 #define OP_UPDATE_PERIOD 144 18 #define OP_UPDATE_PERIOD 144
10 19
11 enum { 20 enum {
82 uint16_t round_fixed_point(double value, int dec_bits) 91 uint16_t round_fixed_point(double value, int dec_bits)
83 { 92 {
84 return value * (1 << dec_bits) + 0.5; 93 return value * (1 << dec_bits) + 0.5;
85 } 94 }
86 95
96 FILE * debug_file = NULL;
97 uint32_t first_key_on=0;
98
87 void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t clock_rate, uint32_t sample_limit) 99 void ym_init(ym2612_context * context, uint32_t sample_rate, uint32_t clock_rate, uint32_t sample_limit)
88 { 100 {
101 dfopen(debug_file, "ym_debug.txt", "w");
89 memset(context, 0, sizeof(*context)); 102 memset(context, 0, sizeof(*context));
90 context->audio_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2); 103 context->audio_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2);
91 context->back_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2); 104 context->back_buffer = malloc(sizeof(*context->audio_buffer) * sample_limit*2);
92 context->buffer_inc = (double)sample_rate / (double)(clock_rate/OP_UPDATE_PERIOD); 105 context->buffer_inc = (double)sample_rate / (double)(clock_rate/OP_UPDATE_PERIOD);
93 context->sample_limit = sample_limit*2; 106 context->sample_limit = sample_limit*2;
119 } 132 }
120 pow_table[i] = tmp; 133 pow_table[i] = tmp;
121 } 134 }
122 //populate envelope generator rate table, from small base table 135 //populate envelope generator rate table, from small base table
123 for (int rate = 0; rate < 64; rate++) { 136 for (int rate = 0; rate < 64; rate++) {
124 for (int cycle = 0; cycle < 7; cycle++) { 137 for (int cycle = 0; cycle < 8; cycle++) {
125 uint16_t value; 138 uint16_t value;
126 if (rate < 3) { 139 if (rate < 2) {
127 value = 0; 140 value = 0;
128 } else if (rate >= 60) { 141 } else if (rate >= 60) {
129 value = 8; 142 value = 8;
130 } else if (rate < 8) { 143 } else if (rate < 8) {
131 value = rate_table_base[((rate & 6) == 6 ? 16 : 8) + cycle]; 144 value = rate_table_base[((rate & 6) == 6 ? 16 : 0) + cycle];
132 } else if (rate < 48) { 145 } else if (rate < 48) {
133 value = rate_table_base[(rate & 0x3) * 8 + cycle]; 146 value = rate_table_base[(rate & 0x3) * 8 + cycle];
134 } else { 147 } else {
135 value = rate_table_base[32 + (rate & 0x3) * 8 + cycle] << (rate >> 2); 148 value = rate_table_base[32 + (rate & 0x3) * 8 + cycle] << ((rate - 48) >> 2);
136 } 149 }
137 rate_table[rate * 8 + cycle] = value; 150 rate_table[rate * 8 + cycle] = value;
138 } 151 }
139 } 152 }
140 } 153 }
141 } 154 }
155
156 #define YM_VOLUME_DIVIDER 1
142 157
143 void ym_run(ym2612_context * context, uint32_t to_cycle) 158 void ym_run(ym2612_context * context, uint32_t to_cycle)
144 { 159 {
145 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle); 160 //printf("Running YM2612 from cycle %d to cycle %d\n", context->current_cycle, to_cycle);
146 //TODO: Fix channel update order OR remap channels in register write 161 //TODO: Fix channel update order OR remap channels in register write
184 if (rate > 63) { 199 if (rate > 63) {
185 rate = 63; 200 rate = 63;
186 } 201 }
187 } 202 }
188 //Deal with "infinite" rates 203 //Deal with "infinite" rates
189 //It's possible this should be handled in key-on as well 204 //According to Nemesis this should be handled in key-on instead
190 if (rate == 63 && operator->env_phase < PHASE_SUSTAIN) { 205 if (rate >= 62 && operator->env_phase == PHASE_ATTACK) {
191 if (operator->env_phase == PHASE_ATTACK) { 206 operator->env_phase = PHASE_DECAY;
192 operator->env_phase = PHASE_DECAY; 207 operator->envelope = 0;
193 operator->envelope = operator->total_level;
194 } else {
195 operator->env_phase = PHASE_SUSTAIN;
196 operator->envelope = operator->sustain_level;
197 }
198 } else { 208 } else {
199 break; 209 break;
200 } 210 }
201 } 211 }
202 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0; 212 uint32_t cycle_shift = rate < 0x30 ? ((0x2F - rate) >> 2) : 0;
213 if (first_key_on) {
214 dfprintf(debug_file, "Operator: %d, env rate: %d (2*%d+%d), env_cyc: %d, cycle_shift: %d, env_cyc & ((1 << cycle_shift) - 1): %d\n", op, rate, operator->rates[operator->env_phase], channel->keycode >> operator->key_scaling,env_cyc, cycle_shift, env_cyc & ((1 << cycle_shift) - 1));
215 }
203 if (!(env_cyc & ((1 << cycle_shift) - 1))) { 216 if (!(env_cyc & ((1 << cycle_shift) - 1))) {
204 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7; 217 uint32_t update_cycle = env_cyc >> cycle_shift & 0x7;
205 //envelope value is 10-bits, but it will be used as a 4.8 value 218 //envelope value is 10-bits, but it will be used as a 4.8 value
206 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle] << 2; 219 uint16_t envelope_inc = rate_table[rate * 8 + update_cycle] << 2;
207 if (operator->env_phase == PHASE_ATTACK) { 220 if (operator->env_phase == PHASE_ATTACK) {
208 //this can probably be optimized to a single shift rather than a multiply + shift 221 //this can probably be optimized to a single shift rather than a multiply + shift
222 if (first_key_on) {
223 dfprintf(debug_file, "Changing op %d envelope %d by %d(%d * %d) in attack phase\n", op, operator->envelope, (~operator->envelope * envelope_inc) >> 4, ~operator->envelope, envelope_inc);
224 }
209 operator->envelope += (~operator->envelope * envelope_inc) >> 4; 225 operator->envelope += (~operator->envelope * envelope_inc) >> 4;
210 operator->envelope &= MAX_ENVELOPE; 226 operator->envelope &= MAX_ENVELOPE;
211 if (operator->envelope <= operator->total_level) { 227 if (!operator->envelope) {
212 operator->envelope = operator->total_level; 228 operator->envelope = 0;
213 operator->env_phase = PHASE_DECAY; 229 operator->env_phase = PHASE_DECAY;
214 } 230 }
215 } else { 231 } else {
232 if (first_key_on) {
233 dfprintf(debug_file, "Changing op %d envelope %d by %d in %s phase\n", op, operator->envelope, envelope_inc,
234 operator->env_phase == PHASE_SUSTAIN ? "sustain" : (operator->env_phase == PHASE_DECAY ? "decay": "release"));
235 }
216 operator->envelope += envelope_inc; 236 operator->envelope += envelope_inc;
217 //clamp to max attenuation value 237 //clamp to max attenuation value
218 if (operator->envelope > MAX_ENVELOPE) { 238 if (operator->envelope > MAX_ENVELOPE) {
219 operator->envelope = MAX_ENVELOPE; 239 operator->envelope = MAX_ENVELOPE;
220 } 240 }
221 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) { 241 if (operator->env_phase == PHASE_DECAY && operator->envelope >= operator->sustain_level) {
222 operator->envelope = operator->sustain_level; 242 //operator->envelope = operator->sustain_level;
223 operator->env_phase = PHASE_SUSTAIN; 243 operator->env_phase = PHASE_SUSTAIN;
224 } 244 }
225 } 245 }
226 } 246 }
227 context->current_env_op++; 247 context->current_env_op++;
239 ym_operator * operator = context->operators + op; 259 ym_operator * operator = context->operators + op;
240 ym_channel * chan = context->channels + channel; 260 ym_channel * chan = context->channels + channel;
241 //TODO: Modulate phase by LFO if necessary 261 //TODO: Modulate phase by LFO if necessary
242 operator->phase_counter += operator->phase_inc; 262 operator->phase_counter += operator->phase_inc;
243 uint16_t phase = operator->phase_counter >> 10 & 0x3FF; 263 uint16_t phase = operator->phase_counter >> 10 & 0x3FF;
264 uint16_t mod = 0;
244 switch (op % 4) 265 switch (op % 4)
245 { 266 {
246 case 0://Operator 1 267 case 0://Operator 1
247 //TODO: Feedback 268 //TODO: Feedback
248 break; 269 break;
250 switch(chan->algorithm) 271 switch(chan->algorithm)
251 { 272 {
252 case 0: 273 case 0:
253 case 2: 274 case 2:
254 //modulate by operator 2 275 //modulate by operator 2
255 phase += context->operators[op+1].output >> 4; 276 mod = context->operators[op+1].output >> 4;
256 break; 277 break;
257 case 1: 278 case 1:
258 //modulate by operator 1+2 279 //modulate by operator 1+2
259 phase += (context->operators[op-1].output + context->operators[op+1].output) >> 4; 280 mod = (context->operators[op-1].output + context->operators[op+1].output) >> 4;
260 break; 281 break;
261 case 5: 282 case 5:
262 //modulate by operator 1 283 //modulate by operator 1
263 phase += context->operators[op-1].output >> 4; 284 mod = context->operators[op-1].output >> 4;
264 } 285 }
265 break; 286 break;
266 case 2://Operator 2 287 case 2://Operator 2
267 if (chan->algorithm != 1 && chan->algorithm != 2 || chan->algorithm != 7) { 288 if (chan->algorithm != 1 && chan->algorithm != 2 || chan->algorithm != 7) {
268 //modulate by Operator 1 289 //modulate by Operator 1
269 phase += context->operators[op-2].output >> 4; 290 mod = context->operators[op-2].output >> 4;
270 } 291 }
271 break; 292 break;
272 case 3://Operator 4 293 case 3://Operator 4
273 switch(chan->algorithm) 294 switch(chan->algorithm)
274 { 295 {
275 case 0: 296 case 0:
276 case 1: 297 case 1:
277 case 4: 298 case 4:
278 //modulate by operator 3 299 //modulate by operator 3
279 phase += context->operators[op-2].output >> 4; 300 mod = context->operators[op-2].output >> 4;
280 break; 301 break;
281 case 2: 302 case 2:
282 //modulate by operator 1+3 303 //modulate by operator 1+3
283 phase += (context->operators[op-3].output + context->operators[op-2].output) >> 4; 304 mod = (context->operators[op-3].output + context->operators[op-2].output) >> 4;
284 break; 305 break;
285 case 3: 306 case 3:
286 //modulate by operator 2+3 307 //modulate by operator 2+3
287 phase += (context->operators[op-1].output + context->operators[op-2].output) >> 4; 308 mod = (context->operators[op-1].output + context->operators[op-2].output) >> 4;
288 break; 309 break;
289 case 5: 310 case 5:
290 //modulate by operator 1 311 //modulate by operator 1
291 phase += context->operators[op-3].output >> 4; 312 mod = context->operators[op-3].output >> 4;
292 break; 313 break;
293 } 314 }
294 break; 315 break;
295 } 316 }
296 //printf("sine_table[%X] + %X = %X, sizeof(pow_table)/sizeof(*pow_table) = %X\n", phase & 0x1FF, operator->envelope, sine_table[phase & 0x1FF] + operator->envelope, sizeof(pow_table)/ sizeof(*pow_table)); 317 uint16_t env = operator->envelope + operator->total_level;
297 uint16_t output = pow_table[sine_table[phase & 0x1FF] + operator->envelope]; 318 if (env > MAX_ENVELOPE) {
319 env = MAX_ENVELOPE;
320 }
321 if (first_key_on) {
322 dfprintf(debug_file, "op %d, base phase: %d, mod: %d, sine: %d, out: %d\n", op, phase, mod, sine_table[(phase+mod) & 0x1FF], pow_table[sine_table[phase & 0x1FF] + env]);
323 }
324 phase += mod;
325
326 uint16_t output = pow_table[sine_table[phase & 0x1FF] + env];
298 if (phase & 0x200) { 327 if (phase & 0x200) {
299 output = -output; 328 output = -output;
300 } 329 }
301 operator->output = output; 330 operator->output = output;
302 //Update the channel output if we've updated all operators 331 //Update the channel output if we've updated all operators
310 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { 339 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
311 output += context->operators[op].output; 340 output += context->operators[op].output;
312 } 341 }
313 chan->output = output; 342 chan->output = output;
314 } 343 }
344 int16_t value = context->channels[channel].output & 0x3FE0;
345 if (value & 0x2000) {
346 value |= 0xC000;
347 }
348 if (first_key_on) {
349 dfprintf(debug_file, "channel %d output: %d\n", channel, value / 2);
350 }
315 } 351 }
316 //puts("operator update done"); 352 //puts("operator update done");
317 } 353 }
318 context->current_op++; 354 context->current_op++;
319 if (context->current_op == NUM_OPERATORS) { 355 if (context->current_op == NUM_OPERATORS) {
322 if (context->buffer_fraction > 1.0) { 358 if (context->buffer_fraction > 1.0) {
323 context->buffer_fraction -= 1.0; 359 context->buffer_fraction -= 1.0;
324 context->audio_buffer[context->buffer_pos] = 0; 360 context->audio_buffer[context->buffer_pos] = 0;
325 context->audio_buffer[context->buffer_pos + 1] = 0; 361 context->audio_buffer[context->buffer_pos + 1] = 0;
326 for (int i = 0; i < NUM_CHANNELS; i++) { 362 for (int i = 0; i < NUM_CHANNELS; i++) {
327 uint16_t value = context->channels[i].output & 0x3FE0; 363 int16_t value = context->channels[i].output & 0x3FE0;
328 if (value & 0x2000) { 364 if (value & 0x2000) {
329 value |= 0xC000; 365 value |= 0xC000;
330 } 366 }
331 if (context->channels[i].lr & 0x80) { 367 if (context->channels[i].lr & 0x80) {
332 context->audio_buffer[context->buffer_pos] += value / 2; 368 context->audio_buffer[context->buffer_pos] += value / YM_VOLUME_DIVIDER;
333 } 369 }
334 if (context->channels[i].lr & 0x40) { 370 if (context->channels[i].lr & 0x40) {
335 context->audio_buffer[context->buffer_pos+1] += value / 2; 371 context->audio_buffer[context->buffer_pos+1] += value / YM_VOLUME_DIVIDER;
336 } 372 }
337 } 373 }
338 context->buffer_pos += 2; 374 context->buffer_pos += 2;
339 if (context->buffer_pos == context->sample_limit) { 375 if (context->buffer_pos == context->sample_limit) {
340 render_wait_ym(context); 376 render_wait_ym(context);
440 void ym_data_write(ym2612_context * context, uint8_t value) 476 void ym_data_write(ym2612_context * context, uint8_t value)
441 { 477 {
442 if (context->selected_reg < 0x21 || context->selected_reg > 0xB6 || (context->selected_reg < 0x30 && context->selected_part)) { 478 if (context->selected_reg < 0x21 || context->selected_reg > 0xB6 || (context->selected_reg < 0x30 && context->selected_part)) {
443 return; 479 return;
444 } 480 }
445 //printf("write to reg %X in part %d\n", context->selected_reg, context->selected_part+1); 481 dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1);
446 if (context->selected_reg < 0x30) { 482 if (context->selected_reg < 0x30) {
447 //Shared regs 483 //Shared regs
448 switch (context->selected_reg) 484 switch (context->selected_reg)
449 { 485 {
450 //TODO: Test reg and LFO 486 //TODO: Test reg and LFO
465 case REG_KEY_ONOFF: { 501 case REG_KEY_ONOFF: {
466 uint8_t channel = value & 0x7; 502 uint8_t channel = value & 0x7;
467 if (channel < NUM_CHANNELS) { 503 if (channel < NUM_CHANNELS) {
468 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) { 504 for (uint8_t op = channel * 4, bit = 0x10; op < (channel + 1) * 4; op++, bit <<= 1) {
469 if (value & bit) { 505 if (value & bit) {
506 first_key_on = 1;
470 //printf("Key On for operator %d in channel %d\n", op, channel); 507 //printf("Key On for operator %d in channel %d\n", op, channel);
471 context->operators[op].phase_counter = 0; 508 context->operators[op].phase_counter = 0;
472 context->operators[op].env_phase = PHASE_ATTACK; 509 context->operators[op].env_phase = PHASE_ATTACK;
473 context->operators[op].envelope = MAX_ENVELOPE; 510 context->operators[op].envelope = MAX_ENVELOPE;
474 } else { 511 } else {
493 } else if (context->selected_reg < 0xA0) { 530 } else if (context->selected_reg < 0xA0) {
494 //part 531 //part
495 uint8_t op = context->selected_part ? (NUM_OPERATORS/2) : 0; 532 uint8_t op = context->selected_part ? (NUM_OPERATORS/2) : 0;
496 //channel in part 533 //channel in part
497 if ((context->selected_reg & 0x3) != 0x3) { 534 if ((context->selected_reg & 0x3) != 0x3) {
498 op += 4 * (context->selected_reg & 0x3); 535 op += 4 * (context->selected_reg & 0x3) + ((context->selected_reg & 0xC) / 4);
499 //operator in channel
500 switch (context->selected_reg & 0xC)
501 {
502 case 0:
503 break;
504 case 4:
505 op += 2;
506 break;
507 case 8:
508 op += 1;
509 break;
510 case 0xC:
511 op += 3;
512 break;
513 }
514 //printf("write targets operator %d (%d of channel %d)\n", op, op % 4, op / 4); 536 //printf("write targets operator %d (%d of channel %d)\n", op, op % 4, op / 4);
515 ym_operator * operator = context->operators + op; 537 ym_operator * operator = context->operators + op;
516 switch (context->selected_reg & 0xF0) 538 switch (context->selected_reg & 0xF0)
517 { 539 {
518 case REG_DETUNE_MULT: 540 case REG_DETUNE_MULT: