mirror of https://github.com/mgba-emu/mgba.git
GB Audio: Skip frame if enabled when clock is high
This commit is contained in:
parent
0332db8961
commit
6158a4fb8d
|
@ -187,6 +187,7 @@ struct GBAudio {
|
|||
uint8_t* nr52;
|
||||
|
||||
int frame;
|
||||
bool skipFrame;
|
||||
|
||||
int32_t sampleInterval;
|
||||
enum GBAudioStyle style;
|
||||
|
|
|
@ -195,6 +195,7 @@ DECL_BITS(GBSerializedAudioFlags, Frame, 22, 3);
|
|||
DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25);
|
||||
DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26);
|
||||
DECL_BIT(GBSerializedAudioFlags, Ch3Readable, 27);
|
||||
DECL_BIT(GBSerializedAudioFlags, SkipFrame, 28);
|
||||
|
||||
DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t);
|
||||
DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7);
|
||||
|
|
|
@ -470,7 +470,15 @@ void GBAudioWriteNR52(struct GBAudio* audio, uint8_t value) {
|
|||
}
|
||||
*audio->nr52 &= ~0x000F;
|
||||
} else if (!wasEnable) {
|
||||
audio->skipFrame = false;
|
||||
audio->frame = 7;
|
||||
|
||||
if (audio->p) {
|
||||
unsigned timingFactor = 0x400 >> !audio->p->doubleSpeed;
|
||||
if (audio->p->timer.internalDiv & timingFactor) {
|
||||
audio->skipFrame = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,6 +491,13 @@ void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate) {
|
|||
}
|
||||
|
||||
void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) {
|
||||
if (!audio->enable) {
|
||||
return;
|
||||
}
|
||||
if (audio->skipFrame) {
|
||||
audio->skipFrame = false;
|
||||
return;
|
||||
}
|
||||
int frame = (audio->frame + 1) & 7;
|
||||
audio->frame = frame;
|
||||
|
||||
|
@ -929,6 +944,7 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat
|
|||
uint32_t ch4Flags = 0;
|
||||
|
||||
flags = GBSerializedAudioFlagsSetFrame(flags, audio->frame);
|
||||
flags = GBSerializedAudioFlagsSetSkipFrame(flags, audio->skipFrame);
|
||||
STORE_32LE(audio->frameEvent.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextFrame);
|
||||
|
||||
flags = GBSerializedAudioFlagsSetCh1Volume(flags, audio->ch1.envelope.currentVolume);
|
||||
|
@ -987,6 +1003,7 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt
|
|||
|
||||
LOAD_32LE(flags, 0, flagsIn);
|
||||
audio->frame = GBSerializedAudioFlagsGetFrame(flags);
|
||||
audio->skipFrame = GBSerializedAudioFlagsGetSkipFrame(flags);
|
||||
|
||||
LOAD_32LE(ch1Flags, 0, &state->ch1.envelope);
|
||||
audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags);
|
||||
|
|
|
@ -80,7 +80,8 @@ void GBTimerDivReset(struct GBTimer* timer) {
|
|||
mTimingSchedule(&timer->p->timing, &timer->irq, 7 - (timer->p->cpu->executionState & 3));
|
||||
}
|
||||
}
|
||||
if (timer->internalDiv & 0x200) {
|
||||
unsigned timingFactor = 0x400 >> !timer->p->doubleSpeed;
|
||||
if (timer->internalDiv & timingFactor) {
|
||||
GBAudioUpdateFrame(&timer->p->audio, &timer->p->timing);
|
||||
}
|
||||
timer->p->memory.io[REG_DIV] = 0;
|
||||
|
|
Loading…
Reference in New Issue