From d3fa698c81eb372f9ab9e6843c8d571e6383a5de Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sat, 6 Feb 2016 01:00:17 -0800 Subject: [PATCH] GB Audio: Begin rewrite of frame counting --- src/gb/audio.c | 195 +++++++++++++++++++++++------------------------- src/gb/audio.h | 14 ++-- src/gba/audio.c | 24 +++--- 3 files changed, 114 insertions(+), 119 deletions(-) diff --git a/src/gb/audio.c b/src/gb/audio.c index 7f2cba9d1..120f93de1 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -9,9 +9,9 @@ #include "gb/gb.h" #include "gb/io.h" -#define SWEEP_CYCLES (DMG_LR35902_FREQUENCY >> 7) +#define FRAME_CYCLES (DMG_LR35902_FREQUENCY >> 9) -static const int CLOCKS_PER_FRAME = 0x1000; +static const int CLOCKS_PER_BLIP_FRAME = 0x1000; static const unsigned BLIP_BUFFER_SIZE = 0x4000; static void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value); @@ -50,11 +50,13 @@ void GBAudioReset(struct GBAudio* audio) { audio->nextCh2 = 0; audio->nextCh3 = 0; audio->nextCh4 = 0; - audio->ch1 = (struct GBAudioChannel1) { .envelope = { .nextStep = INT_MAX }, .nextSweep = INT_MAX }; - audio->ch2 = (struct GBAudioChannel2) { .envelope = { .nextStep = INT_MAX } }; + audio->ch1 = (struct GBAudioChannel1) { }; + audio->ch2 = (struct GBAudioChannel2) { }; audio->ch3 = (struct GBAudioChannel3) { .bank = 0 }; - audio->ch4 = (struct GBAudioChannel4) { .envelope = { .nextStep = INT_MAX } }; + audio->ch4 = (struct GBAudioChannel4) { }; audio->eventDiff = 0; + audio->nextFrame = 0; + audio->frame = 0; audio->nextSample = 0; audio->sampleInterval = 128; audio->volumeRight = 0; @@ -77,21 +79,20 @@ void GBAudioWriteNR10(struct GBAudio* audio, uint8_t value) { audio->ch1.shift = GBAudioRegisterSquareSweepGetShift(value); audio->ch1.direction = GBAudioRegisterSquareSweepGetDirection(value); audio->ch1.time = GBAudioRegisterSquareSweepGetTime(value); - if (audio->ch1.time) { - audio->ch1.nextSweep = audio->ch1.time * SWEEP_CYCLES; - } else { - audio->ch1.nextSweep = INT_MAX; - } } void GBAudioWriteNR11(struct GBAudio* audio, uint8_t value) { _writeDuty(&audio->ch1.envelope, value); - audio->ch1.control.endTime = (DMG_LR35902_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8; + audio->ch1.control.length = 64 - audio->ch1.envelope.length; } void GBAudioWriteNR12(struct GBAudio* audio, uint8_t value) { if (!_writeSweep(&audio->ch1.envelope, value)) { - audio->ch1.sample = 0; + audio->playingCh1 = false; + // TODO: Don't need p + if (audio->p) { + audio->p->memory.io[REG_NR52] &= ~0x0001; + } } } @@ -105,26 +106,20 @@ void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) { audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8); audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8); if (GBAudioRegisterControlIsRestart(value << 8)) { - if (audio->ch1.time) { - audio->ch1.nextSweep = audio->ch1.time * SWEEP_CYCLES; - } else { - audio->ch1.nextSweep = INT_MAX; - } if (audio->nextEvent == INT_MAX) { audio->eventDiff = 0; } if (!audio->playingCh1) { audio->nextCh1 = audio->eventDiff; } - audio->playingCh1 = 1; + audio->playingCh1 = audio->ch1.envelope.initialVolume || audio->ch1.envelope.direction; audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume; if (audio->ch1.envelope.currentVolume > 0) { audio->ch1.envelope.dead = 0; } - if (audio->ch1.envelope.stepTime) { - audio->ch1.envelope.nextStep = audio->eventDiff; - } else { - audio->ch1.envelope.nextStep = INT_MAX; + audio->ch1.sweepStep = audio->ch1.time; + if (!audio->ch1.control.length) { + audio->ch1.control.length = 64; } audio->nextEvent = 0; } @@ -132,12 +127,16 @@ void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR21(struct GBAudio* audio, uint8_t value) { _writeDuty(&audio->ch2.envelope, value); - audio->ch2.control.endTime = (DMG_LR35902_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8; + audio->ch2.control.length = 64 - audio->ch2.envelope.length; } void GBAudioWriteNR22(struct GBAudio* audio, uint8_t value) { if (!_writeSweep(&audio->ch2.envelope, value)) { - audio->ch2.sample = 0; + audio->playingCh2 = false; + // TODO: Don't need p + if (audio->p) { + audio->p->memory.io[REG_NR52] &= ~0x0002; + } } } @@ -151,7 +150,7 @@ void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8); audio->ch2.control.stop = GBAudioRegisterControlGetStop(value << 8); if (GBAudioRegisterControlIsRestart(value << 8)) { - audio->playingCh2 = 1; + audio->playingCh2 = audio->ch2.envelope.initialVolume || audio->ch2.envelope.direction; audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume; if (audio->ch2.envelope.currentVolume > 0) { audio->ch2.envelope.dead = 0; @@ -162,10 +161,8 @@ void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { if (!audio->playingCh2) { audio->nextCh2 = audio->eventDiff; } - if (audio->ch2.envelope.stepTime) { - audio->ch2.envelope.nextStep = audio->eventDiff; - } else { - audio->ch2.envelope.nextStep = INT_MAX; + if (!audio->ch2.control.length) { + audio->ch2.control.length = 64; } audio->nextEvent = 0; } @@ -173,14 +170,18 @@ void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR30(struct GBAudio* audio, uint8_t value) { audio->ch3.enable = GBAudioRegisterBankGetEnable(value); - if (audio->ch3.endTime >= 0) { - audio->playingCh3 = audio->ch3.enable; + if (!audio->ch3.enable) { + audio->playingCh3 = false; + // TODO: Don't need p + if (audio->p) { + audio->p->memory.io[REG_NR52] &= ~0x0004; + } } } void GBAudioWriteNR31(struct GBAudio* audio, uint8_t value) { audio->ch3.length = value; - audio->ch3.endTime = (DMG_LR35902_FREQUENCY * (256 - audio->ch3.length)) >> 8; + audio->ch3.lengthShadow = 256 - value; } void GBAudioWriteNR32(struct GBAudio* audio, uint8_t value) { @@ -198,6 +199,9 @@ void GBAudioWriteNR34(struct GBAudio* audio, uint8_t value) { audio->ch3.stop = GBAudioRegisterControlGetStop(value << 8); if (GBAudioRegisterControlIsRestart(value << 8)) { audio->playingCh3 = audio->ch3.enable; + if (!audio->ch3.lengthShadow) { + audio->ch3.lengthShadow = 256; + } } if (audio->playingCh3) { if (audio->nextEvent == INT_MAX) { @@ -210,12 +214,16 @@ void GBAudioWriteNR34(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR41(struct GBAudio* audio, uint8_t value) { _writeDuty(&audio->ch4.envelope, value); - audio->ch4.endTime = (DMG_LR35902_FREQUENCY * (64 - audio->ch4.envelope.length)) >> 8; + audio->ch4.length = 64 - audio->ch4.envelope.length; } void GBAudioWriteNR42(struct GBAudio* audio, uint8_t value) { if (!_writeSweep(&audio->ch4.envelope, value)) { - audio->ch4.sample = 0; + audio->playingCh4 = false; + // TODO: Don't need p + if (audio->p) { + audio->p->memory.io[REG_NR52] &= ~0x0008; + } } } @@ -228,16 +236,11 @@ void GBAudioWriteNR43(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR44(struct GBAudio* audio, uint8_t value) { audio->ch4.stop = GBAudioRegisterNoiseControlGetStop(value); if (GBAudioRegisterNoiseControlIsRestart(value)) { - audio->playingCh4 = 1; + audio->playingCh4 = audio->ch4.envelope.initialVolume || audio->ch4.envelope.direction; audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume; if (audio->ch4.envelope.currentVolume > 0) { audio->ch4.envelope.dead = 0; } - if (audio->ch4.envelope.stepTime) { - audio->ch4.envelope.nextStep = 0; - } else { - audio->ch4.envelope.nextStep = INT_MAX; - } if (audio->ch4.power) { audio->ch4.lfsr = 0x40; } else { @@ -249,6 +252,9 @@ void GBAudioWriteNR44(struct GBAudio* audio, uint8_t value) { if (!audio->playingCh4) { audio->nextCh4 = audio->eventDiff; } + if (!audio->ch4.length) { + audio->ch4.length = 64; + } audio->nextEvent = 0; } } @@ -331,28 +337,33 @@ int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) { while (audio->nextEvent <= 0) { audio->nextEvent = INT_MAX; if (audio->enable) { + audio->nextFrame -= audio->eventDiff; + int frame = -1; + if (audio->nextFrame <= 0) { + frame = (audio->frame + 1) & 7; + audio->frame = frame; + audio->nextFrame += FRAME_CYCLES; + if (audio->nextFrame < audio->nextEvent) { + audio->nextEvent = audio->nextFrame; + } + } + if (audio->playingCh1) { audio->nextCh1 -= audio->eventDiff; if (!audio->ch1.envelope.dead) { - if (audio->ch1.envelope.nextStep != INT_MAX) { - audio->ch1.envelope.nextStep -= audio->eventDiff; - if (audio->ch1.envelope.nextStep <= 0) { + if (frame == 7) { + --audio->ch1.envelope.nextStep; + if (audio->ch1.envelope.nextStep == 0) { int8_t sample = audio->ch1.control.hi * 0x10 - 0x8; _updateEnvelope(&audio->ch1.envelope); - if (audio->ch1.envelope.nextStep < audio->nextEvent) { - audio->nextEvent = audio->ch1.envelope.nextStep; - } audio->ch1.sample = sample * audio->ch1.envelope.currentVolume; } } - if (audio->ch1.nextSweep != INT_MAX) { - audio->ch1.nextSweep -= audio->eventDiff; - if (audio->ch1.nextSweep <= 0) { + if ((frame & 3) == 2) { + --audio->ch1.sweepStep; + if (audio->ch1.sweepStep == 0) { audio->playingCh1 = _updateSweep(&audio->ch1); - if (audio->ch1.nextSweep < audio->nextEvent) { - audio->nextEvent = audio->ch1.nextSweep; - } } } } @@ -363,25 +374,22 @@ int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) { if (audio->nextCh1 < audio->nextEvent) { audio->nextEvent = audio->nextCh1; } + } - if (audio->ch1.control.stop) { - audio->ch1.control.endTime -= audio->eventDiff; - if (audio->ch1.control.endTime <= 0) { - audio->playingCh1 = 0; - } + if (audio->ch1.control.length && audio->ch1.control.stop && !(frame & 1)) { + --audio->ch1.control.length; + if (audio->ch1.control.length == 0) { + audio->playingCh1 = 0; } } if (audio->playingCh2) { audio->nextCh2 -= audio->eventDiff; - if (!audio->ch2.envelope.dead && audio->ch2.envelope.nextStep != INT_MAX) { - audio->ch2.envelope.nextStep -= audio->eventDiff; - if (audio->ch2.envelope.nextStep <= 0) { + if (!audio->ch2.envelope.dead && frame == 7) { + --audio->ch2.envelope.nextStep; + if (audio->ch2.envelope.nextStep == 0) { int8_t sample = audio->ch2.control.hi * 0x10 - 0x8; _updateEnvelope(&audio->ch2.envelope); - if (audio->ch2.envelope.nextStep < audio->nextEvent) { - audio->nextEvent = audio->ch2.envelope.nextStep; - } audio->ch2.sample = sample * audio->ch2.envelope.currentVolume; } } @@ -392,12 +400,12 @@ int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) { if (audio->nextCh2 < audio->nextEvent) { audio->nextEvent = audio->nextCh2; } + } - if (audio->ch2.control.stop) { - audio->ch2.control.endTime -= audio->eventDiff; - if (audio->ch2.control.endTime <= 0) { - audio->playingCh2 = 0; - } + if (audio->ch2.control.length && audio->ch2.control.stop && !(frame & 1)) { + --audio->ch2.control.length; + if (audio->ch2.control.length == 0) { + audio->playingCh2 = 0; } } @@ -409,25 +417,22 @@ int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) { if (audio->nextCh3 < audio->nextEvent) { audio->nextEvent = audio->nextCh3; } + } - if (audio->ch3.stop) { - audio->ch3.endTime -= audio->eventDiff; - if (audio->ch3.endTime <= 0) { - audio->playingCh3 = 0; - } + if (audio->ch3.lengthShadow && audio->ch3.stop && !(frame & 1)) { + --audio->ch3.lengthShadow; + if (audio->ch3.lengthShadow == 0) { + audio->playingCh3 = 0; } } if (audio->playingCh4) { audio->nextCh4 -= audio->eventDiff; - if (!audio->ch4.envelope.dead && audio->ch4.envelope.nextStep != INT_MAX) { - audio->ch4.envelope.nextStep -= audio->eventDiff; - if (audio->ch4.envelope.nextStep <= 0) { + if (!audio->ch4.envelope.dead && frame == 7) { + --audio->ch4.envelope.nextStep; + if (audio->ch4.envelope.nextStep == 0) { int8_t sample = (audio->ch4.sample >> 31) * 0x8; _updateEnvelope(&audio->ch4.envelope); - if (audio->ch4.envelope.nextStep < audio->nextEvent) { - audio->nextEvent = audio->ch4.envelope.nextStep; - } audio->ch4.sample = sample * audio->ch4.envelope.currentVolume; } } @@ -438,12 +443,12 @@ int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) { if (audio->nextCh4 < audio->nextEvent) { audio->nextEvent = audio->nextCh4; } + } - if (audio->ch4.stop) { - audio->ch4.endTime -= audio->eventDiff; - if (audio->ch4.endTime <= 0) { - audio->playingCh4 = 0; - } + if (audio->ch4.length && audio->ch4.stop && !(frame & 1)) { + --audio->ch4.length; + if (audio->ch4.length == 0) { + audio->playingCh4 = 0; } } } @@ -532,10 +537,10 @@ void _sample(struct GBAudio* audio, int32_t cycles) { audio->lastLeft = sampleLeft; audio->lastRight = sampleRight; audio->clock += cycles; - if (audio->clock >= CLOCKS_PER_FRAME) { + if (audio->clock >= CLOCKS_PER_BLIP_FRAME) { blip_end_frame(audio->left, audio->clock); blip_end_frame(audio->right, audio->clock); - audio->clock -= CLOCKS_PER_FRAME; + audio->clock -= CLOCKS_PER_BLIP_FRAME; } } produced = blip_samples_avail(audio->left); @@ -554,16 +559,8 @@ bool _writeSweep(struct GBAudioEnvelope* envelope, uint8_t value) { envelope->direction = GBAudioRegisterSweepGetDirection(value); envelope->initialVolume = GBAudioRegisterSweepGetInitialVolume(value); envelope->dead = 0; - if (envelope->stepTime) { - envelope->nextStep = 0; - } else { - envelope->nextStep = INT_MAX; - if (envelope->initialVolume == 0) { - envelope->dead = 1; - return false; - } - } - return true; + envelope->nextStep = envelope->stepTime; + return envelope->initialVolume || envelope->direction; } static int32_t _updateSquareChannel(struct GBAudioSquareControl* control, int duty) { @@ -592,13 +589,11 @@ static void _updateEnvelope(struct GBAudioEnvelope* envelope) { } if (envelope->currentVolume >= 15) { envelope->currentVolume = 15; - envelope->nextStep = INT_MAX; } else if (envelope->currentVolume <= 0) { envelope->currentVolume = 0; envelope->dead = 1; - envelope->nextStep = INT_MAX; } else { - envelope->nextStep += envelope->stepTime * (DMG_LR35902_FREQUENCY >> 6); + envelope->nextStep = envelope->stepTime; } } @@ -618,7 +613,7 @@ static bool _updateSweep(struct GBAudioChannel1* ch) { return false; } } - ch->nextSweep += ch->time * SWEEP_CYCLES; + ch->sweepStep = ch->time; return true; } diff --git a/src/gb/audio.h b/src/gb/audio.h index 74ede7c6a..e2795d61c 100644 --- a/src/gb/audio.h +++ b/src/gb/audio.h @@ -78,24 +78,22 @@ struct GBAudioEnvelope { bool direction; int currentVolume; int dead; - int32_t nextStep; + uint8_t nextStep; }; struct GBAudioSquareControl { uint16_t frequency; + uint8_t length; bool stop; int hi; - int32_t nextStep; - int32_t endTime; }; struct GBAudioChannel1 { uint8_t shift; uint8_t time; + uint8_t sweepStep; bool direction; - int32_t nextSweep; - struct GBAudioEnvelope envelope; struct GBAudioSquareControl control; int8_t sample; @@ -113,11 +111,11 @@ struct GBAudioChannel3 { bool enable; unsigned length; + unsigned lengthShadow; uint8_t volume; uint16_t rate; bool stop; - int32_t endTime; uint32_t wavedata[8]; int8_t sample; @@ -130,7 +128,7 @@ struct GBAudioChannel4 { uint8_t frequency; bool power; bool stop; - int32_t endTime; + uint8_t length; uint32_t lfsr; int8_t sample; @@ -168,6 +166,8 @@ struct GBAudio { int32_t nextEvent; int32_t eventDiff; + int32_t nextFrame; + int frame; int32_t nextSample; int32_t sampleInterval; diff --git a/src/gba/audio.c b/src/gba/audio.c index 0d95d870c..879fb784e 100644 --- a/src/gba/audio.c +++ b/src/gba/audio.c @@ -331,29 +331,29 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* flags = GBASerializedAudioFlagsSetCh1Volume(flags, audio->psg.ch1.envelope.currentVolume); flags = GBASerializedAudioFlagsSetCh1Dead(flags, audio->psg.ch1.envelope.dead); flags = GBASerializedAudioFlagsSetCh1Hi(flags, audio->psg.ch1.control.hi); - STORE_32(audio->psg.ch1.envelope.nextStep, 0, &state->audio.ch1.envelopeNextStep); + /*STORE_32(audio->psg.ch1.envelope.nextStep, 0, &state->audio.ch1.envelopeNextStep); STORE_32(audio->psg.ch1.control.nextStep, 0, &state->audio.ch1.waveNextStep); STORE_32(audio->psg.ch1.nextSweep, 0, &state->audio.ch1.sweepNextStep); - STORE_32(audio->psg.ch1.control.endTime, 0, &state->audio.ch1.endTime); + STORE_32(audio->psg.ch1.control.endTime, 0, &state->audio.ch1.endTime);*/ STORE_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent); flags = GBASerializedAudioFlagsSetCh2Volume(flags, audio->psg.ch2.envelope.currentVolume); flags = GBASerializedAudioFlagsSetCh2Dead(flags, audio->psg.ch2.envelope.dead); flags = GBASerializedAudioFlagsSetCh2Hi(flags, audio->psg.ch2.control.hi); - STORE_32(audio->psg.ch2.envelope.nextStep, 0, &state->audio.ch2.envelopeNextStep); + /*STORE_32(audio->psg.ch2.envelope.nextStep, 0, &state->audio.ch2.envelopeNextStep); STORE_32(audio->psg.ch2.control.nextStep, 0, &state->audio.ch2.waveNextStep); - STORE_32(audio->psg.ch2.control.endTime, 0, &state->audio.ch2.endTime); + STORE_32(audio->psg.ch2.control.endTime, 0, &state->audio.ch2.endTime);*/ STORE_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent); memcpy(state->audio.ch3.wavebanks, audio->psg.ch3.wavedata, sizeof(state->audio.ch3.wavebanks)); - STORE_32(audio->psg.ch3.endTime, 0, &state->audio.ch3.endTime); + //STORE_32(audio->psg.ch3.endTime, 0, &state->audio.ch3.endTime); STORE_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent); state->audio.flags = GBASerializedAudioFlagsSetCh4Volume(flags, audio->psg.ch4.envelope.currentVolume); state->audio.flags = GBASerializedAudioFlagsSetCh4Dead(flags, audio->psg.ch4.envelope.dead); STORE_32(audio->psg.ch4.envelope.nextStep, 0, &state->audio.ch4.envelopeNextStep); STORE_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr); - STORE_32(audio->psg.ch4.endTime, 0, &state->audio.ch4.endTime); + //STORE_32(audio->psg.ch4.endTime, 0, &state->audio.ch4.endTime); STORE_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent); STORE_32(flags, 0, &state->audio.flags); @@ -375,29 +375,29 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState audio->psg.ch1.envelope.dead = GBASerializedAudioFlagsGetCh1Dead(flags); audio->psg.ch1.control.hi = GBASerializedAudioFlagsGetCh1Hi(flags); LOAD_32(audio->psg.ch1.envelope.nextStep, 0, &state->audio.ch1.envelopeNextStep); - LOAD_32(audio->psg.ch1.control.nextStep, 0, &state->audio.ch1.waveNextStep); + /*LOAD_32(audio->psg.ch1.control.nextStep, 0, &state->audio.ch1.waveNextStep); LOAD_32(audio->psg.ch1.nextSweep, 0, &state->audio.ch1.sweepNextStep); - LOAD_32(audio->psg.ch1.control.endTime, 0, &state->audio.ch1.endTime); + LOAD_32(audio->psg.ch1.control.endTime, 0, &state->audio.ch1.endTime);*/ LOAD_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent); audio->psg.ch2.envelope.currentVolume = GBASerializedAudioFlagsGetCh2Volume(flags); audio->psg.ch2.envelope.dead = GBASerializedAudioFlagsGetCh2Dead(flags); audio->psg.ch2.control.hi = GBASerializedAudioFlagsGetCh2Hi(flags); LOAD_32(audio->psg.ch2.envelope.nextStep, 0, &state->audio.ch2.envelopeNextStep); - LOAD_32(audio->psg.ch2.control.nextStep, 0, &state->audio.ch2.waveNextStep); - LOAD_32(audio->psg.ch2.control.endTime, 0, &state->audio.ch2.endTime); + /*LOAD_32(audio->psg.ch2.control.nextStep, 0, &state->audio.ch2.waveNextStep); + LOAD_32(audio->psg.ch2.control.endTime, 0, &state->audio.ch2.endTime);*/ LOAD_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent); // TODO: Big endian? memcpy(audio->psg.ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->psg.ch3.wavedata)); - LOAD_32(audio->psg.ch3.endTime, 0, &state->audio.ch3.endTime); + //LOAD_32(audio->psg.ch3.endTime, 0, &state->audio.ch3.endTime); LOAD_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent); audio->psg.ch4.envelope.currentVolume = GBASerializedAudioFlagsGetCh4Volume(flags); audio->psg.ch4.envelope.dead = GBASerializedAudioFlagsGetCh4Dead(flags); LOAD_32(audio->psg.ch4.envelope.nextStep, 0, &state->audio.ch4.envelopeNextStep); LOAD_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr); - LOAD_32(audio->psg.ch4.endTime, 0, &state->audio.ch4.endTime); + //LOAD_32(audio->psg.ch4.endTime, 0, &state->audio.ch4.endTime); LOAD_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent); CircleBufferClear(&audio->chA.fifo);