comparison ym2612.c @ 1798:5278b6e44fc1

Optionally emulate the offset around zero in the imperfect DAC of a discrete YM2612
author Michael Pavone <pavone@retrodev.com>
date Sun, 24 Mar 2019 19:59:41 -0700
parents 804f13c090b4
children 1d1198f16279
comparison
equal deleted inserted replaced
1797:5ff8f0d28188 1798:5278b6e44fc1
254 } 254 }
255 } 255 }
256 } 256 }
257 } 257 }
258 ym_reset(context); 258 ym_reset(context);
259 ym_enable_zero_offset(context, 1);
259 } 260 }
260 261
261 void ym_free(ym2612_context *context) 262 void ym_free(ym2612_context *context)
262 { 263 {
263 render_free_source(context->audio); 264 render_free_source(context->audio);
265 ym_finalize_log(); 266 ym_finalize_log();
266 } 267 }
267 free(context); 268 free(context);
268 } 269 }
269 270
270 #define YM_VOLUME_MULTIPLIER 2 271 void ym_enable_zero_offset(ym2612_context *context, uint8_t enabled)
271 #define YM_VOLUME_DIVIDER 3 272 {
273 if (enabled) {
274 context->zero_offset = 0x70;
275 context->volume_mult = 79;
276 context->volume_div = 120;
277 } else {
278 context->zero_offset = 0;
279 context->volume_mult = 2;
280 context->volume_div = 3;
281 }
282 }
272 #define YM_MOD_SHIFT 1 283 #define YM_MOD_SHIFT 1
273 284
274 #define CSM_MODE 0x80 285 #define CSM_MODE 0x80
275 286
276 #define SSG_ENABLE 8 287 #define SSG_ENABLE 8
547 if (first_key_on) { 558 if (first_key_on) {
548 int16_t value = context->channels[channel].output & 0x3FE0; 559 int16_t value = context->channels[channel].output & 0x3FE0;
549 if (value & 0x2000) { 560 if (value & 0x2000) {
550 value |= 0xC000; 561 value |= 0xC000;
551 } 562 }
552 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER); 563 dfprintf(debug_file, "channel %d output: %d\n", channel, (value * context->volume_mult) / context->volume_div);
553 } 564 }
554 } 565 }
555 //puts("operator update done"); 566 //puts("operator update done");
556 } 567 }
557 context->current_op++; 568 context->current_op++;
569 value &= 0x3FE0; 580 value &= 0x3FE0;
570 if (value & 0x2000) { 581 if (value & 0x2000) {
571 value |= 0xC000; 582 value |= 0xC000;
572 } 583 }
573 } 584 }
585 if (value >= 0) {
586 value += context->zero_offset;
587 } else {
588 value -= context->zero_offset;
589 }
574 if (context->channels[i].logfile) { 590 if (context->channels[i].logfile) {
575 fwrite(&value, sizeof(value), 1, context->channels[i].logfile); 591 fwrite(&value, sizeof(value), 1, context->channels[i].logfile);
576 } 592 }
577 if (context->channels[i].lr & 0x80) { 593 if (context->channels[i].lr & 0x80) {
578 left += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; 594 left += (value * context->volume_mult) / context->volume_div;
579 } 595 }
580 if (context->channels[i].lr & 0x40) { 596 if (context->channels[i].lr & 0x40) {
581 right += (value * YM_VOLUME_MULTIPLIER) / YM_VOLUME_DIVIDER; 597 right += (value * context->volume_mult) / context->volume_div;
582 } 598 }
583 } 599 }
584 render_put_stereo_sample(context->audio, left, right); 600 render_put_stereo_sample(context->audio, left, right);
585 } 601 }
586 602