stream.h, replace hacky rate change with proper fix

This commit is contained in:
dinkc64 2024-10-01 09:19:55 -04:00
parent 94dc5c01c4
commit 06b24bbe17
3 changed files with 14 additions and 10 deletions

View File

@ -957,7 +957,7 @@ static UINT8 __fastcall berzerk_read_port(UINT16 address)
switch (address & 0xff) switch (address & 0xff)
{ {
case 0x44: bprintf(0, _T("is busy? %x\n"), s14001a_busy_read()); case 0x44:
return (s14001a_busy_read()) ? 0x00 : 0x40; return (s14001a_busy_read()) ? 0x00 : 0x40;
case 0x48: // p1 case 0x48: // p1

View File

@ -386,7 +386,7 @@ void s14001a_start_write(INT32 state)
void s14001a_set_clock(INT32 clock) void s14001a_set_clock(INT32 clock)
{ {
chip.clock = clock; chip.clock = clock;
stream.set_rate(clock, 1); stream.set_rate(clock);
} }
void s14001a_set_volume(double volume) void s14001a_set_volume(double volume)

View File

@ -42,6 +42,8 @@ struct Stream {
#define MAX_CHANNELS 8 #define MAX_CHANNELS 8
INT32 nChannels; INT32 nChannels;
bool bAddStream; bool bAddStream;
bool bRateChange;
UINT32 nNewRate;
INT16 *in_buffer[MAX_CHANNELS]; // resampler in-buffers INT16 *in_buffer[MAX_CHANNELS]; // resampler in-buffers
INT32 out_buffer_size; INT32 out_buffer_size;
@ -52,20 +54,18 @@ struct Stream {
nSampleRateFrom = rate_from; nSampleRateFrom = rate_from;
nSampleRateTo = rate_to; nSampleRateTo = rate_to;
nChannels = channels; nChannels = channels;
set_rate(rate_from); set_rate_internal(rate_from);
stream_init(update_stream); stream_init(update_stream);
} }
void set_rate(INT32 rate_from, INT32 reposit_last_rate = 0) { void set_rate(INT32 rate_from) {
if (reposit_last_rate) { bRateChange = true;
// hack: if rate changes multiple times/frame, approximate new stream position nNewRate = rate_from;
nPosition = nPosition * rate_from / nSampleRateFrom;
} }
void set_rate_internal(INT32 rate_from) {
nSampleRateFrom = rate_from; nSampleRateFrom = rate_from;
nSampleSize = (UINT64)nSampleRateFrom * (1 << 16) / ((nSampleRateTo == 0) ? 44100 : nSampleRateTo); nSampleSize = (UINT64)nSampleRateFrom * (1 << 16) / ((nSampleRateTo == 0) ? 44100 : nSampleRateTo);
nSampleSize_Otherway = (UINT64)((nSampleRateTo == 0) ? 44100 : nSampleRateTo) * (1 << 16) / ((nSampleRateFrom == 0) ? 44100 : nSampleRateFrom); nSampleSize_Otherway = (UINT64)((nSampleRateTo == 0) ? 44100 : nSampleRateTo) * (1 << 16) / ((nSampleRateFrom == 0) ? 44100 : nSampleRateFrom);
// origially this restarted the frame (nPosition = 0), but this breaks
// qbert, as the game writes rate changes several times per frame.
} }
void exit() { void exit() {
nSampleSize = nFractionalPosition = 0; nSampleSize = nFractionalPosition = 0;
@ -116,6 +116,10 @@ struct Stream {
// mask off the whole samples from our accumulator // mask off the whole samples from our accumulator
nFractionalPosition &= 0xffff; nFractionalPosition &= 0xffff;
if (bRateChange) {
set_rate_internal(nNewRate);
bRateChange = false;
}
} }
void samplesample(INT16 *out_buffer, INT32 samples) { void samplesample(INT16 *out_buffer, INT32 samples) {
for (INT32 i = 0; i < samples; i++, out_buffer += 2, nFractionalPosition += nSampleSize) { for (INT32 i = 0; i < samples; i++, out_buffer += 2, nFractionalPosition += nSampleSize) {