comparison ym2612.c @ 2554:76259d246695

Fix YM2612 channel accumulator precision
author Michael Pavone <pavone@retrodev.com>
date Sat, 11 Jan 2025 17:58:58 -0800
parents 9fb04d29049e
children 78e1769efcdb
comparison
equal deleted inserted replaced
2553:35f765c2bc87 2554:76259d246695
583 } 583 }
584 operator->output = output; 584 operator->output = output;
585 //Update the channel output if we've updated all operators 585 //Update the channel output if we've updated all operators
586 if (op % 4 == 3) { 586 if (op % 4 == 3) {
587 if (chan->algorithm < 4) { 587 if (chan->algorithm < 4) {
588 chan->output = operator->output; 588 chan->output = operator->output & ~0x1F;
589 chan->phase_overflow = operator->phase_overflow; 589 chan->phase_overflow = operator->phase_overflow;
590 } else if(chan->algorithm == 4) { 590 } else if(chan->algorithm == 4) {
591 ym_operator *other_op = context->operators + channel * 4 + 2; 591 ym_operator *other_op = context->operators + channel * 4 + 2;
592 chan->output = operator->output + other_op->output; 592 chan->output = (operator->output & ~0x1F) + (other_op->output & ~0x1F);
593 if (chan->output > 0x1FE0) {
594 chan->output = 0x1FE0;
595 } else if (chan->output < -0x1FF0) {
596 chan->output = - 0x1FF0;
597 }
593 if (operator->phase_inc < other_op->phase_inc) { 598 if (operator->phase_inc < other_op->phase_inc) {
594 chan->phase_overflow = operator->phase_overflow; 599 chan->phase_overflow = operator->phase_overflow;
595 } else { 600 } else {
596 chan->phase_overflow = other_op->phase_overflow; 601 chan->phase_overflow = other_op->phase_overflow;
597 } 602 }
598 } else { 603 } else {
599 output = 0; 604 output = 0;
600 uint32_t lowest_phase_inc = 0xFFFFFFFF; 605 uint32_t lowest_phase_inc = 0xFFFFFFFF;
601 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) { 606 for (uint32_t op = ((chan->algorithm == 7) ? 0 : 1) + channel*4; op < (channel+1)*4; op++) {
602 output += context->operators[op].output; 607 output += context->operators[op].output & ~0x1F;
608 if (output > 0x1FE0) {
609 output = 0x1FE0;
610 } else if (output < -0x1FF0) {
611 output = - 0x1FF0;
612 }
603 if (context->operators[op].phase_inc < lowest_phase_inc) { 613 if (context->operators[op].phase_inc < lowest_phase_inc) {
604 lowest_phase_inc = context->operators[op].phase_inc; 614 lowest_phase_inc = context->operators[op].phase_inc;
605 chan->phase_overflow = context->operators[op].phase_overflow; 615 chan->phase_overflow = context->operators[op].phase_overflow;
606 } 616 }
607 } 617 }
615 void ym_output_sample(ym2612_context *context) 625 void ym_output_sample(ym2612_context *context)
616 { 626 {
617 int16_t left = 0, right = 0; 627 int16_t left = 0, right = 0;
618 for (int i = 0; i < NUM_CHANNELS; i++) { 628 for (int i = 0; i < NUM_CHANNELS; i++) {
619 int16_t value = context->channels[i].output; 629 int16_t value = context->channels[i].output;
620 if (value > 0x1FE0) {
621 value = 0x1FE0;
622 } else if (value < -0x1FF0) {
623 value = -0x1FF0;
624 } else {
625 value &= 0x3FE0;
626 if (value & 0x2000) {
627 value |= 0xC000;
628 }
629 }
630 if (value >= 0) { 630 if (value >= 0) {
631 value += context->zero_offset; 631 value += context->zero_offset;
632 } else { 632 } else {
633 value -= context->zero_offset; 633 value -= context->zero_offset;
634 } 634 }