# HG changeset patch # User Michael Pavone # Date 1648285315 25200 # Node ID 62a53c052d9b819b63ec3ce42a652ee7afada82e # Parent 10e4439d8f13446cea2b3a308e536a4a10990453 PCM channel add should saturate on overflow, not wrap around diff -r 10e4439d8f13 -r 62a53c052d9b rf5c164.c --- a/rf5c164.c Sat Mar 26 00:54:47 2022 -0700 +++ b/rf5c164.c Sat Mar 26 02:01:55 2022 -0700 @@ -139,7 +139,6 @@ int16_t left = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] >> 4)) >> 5; int16_t right = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] & 0xF)) >> 5; //printf("chan %d, raw %X, sample %d, left %d, right %d, ptr %X (raw %X)\n", pcm->cur_channel, pcm->channels[pcm->cur_channel].sample, sample, left, right, pcm->channels[pcm->cur_channel].cur_ptr >> 11, pcm->channels[pcm->cur_channel].cur_ptr); - //TODO: saturating add pcm->left += left; pcm->right += right; } @@ -155,6 +154,16 @@ pcm->cur_channel++; pcm->cur_channel &= 7; if (!pcm->cur_channel) { + if (pcm->left > INT16_MAX) { + pcm->left = INT16_MAX; + } else if (pcm->left < INT16_MIN) { + pcm->left = INT16_MIN; + } + if (pcm->right > INT16_MAX) { + pcm->right = INT16_MAX; + } else if (pcm->right < INT16_MIN) { + pcm->right = INT16_MIN; + } render_put_stereo_sample(pcm->audio, pcm->left, pcm->right); pcm->left = pcm->right = 0; } @@ -185,7 +194,7 @@ for (int i = 0; i < 8; i++) { int mask = 1 << i; - if (changed & mask & value) { + if ((changed & mask) && !(mask & value)) { pcm->channels[i].state = START; } } diff -r 10e4439d8f13 -r 62a53c052d9b rf5c164.h --- a/rf5c164.h Sat Mar 26 00:54:47 2022 -0700 +++ b/rf5c164.h Sat Mar 26 02:01:55 2022 -0700 @@ -17,8 +17,8 @@ uint16_t ram[64*1024]; uint16_t ram_bank; uint16_t pending_address; - int16_t left; - int16_t right; + int32_t left; + int32_t right; rf5c164_channel channels[8]; uint8_t pending_byte; uint8_t channel_enable;