all repos — mgba @ 56e40b118cadc6ee1689b02f6a72a49de50d462e

mGBA Game Boy Advance Emulator

GB Audio: Implement capacitor charge
Vicki Pfau vi@endrift.com
Fri, 11 May 2018 17:02:58 -0700
commit

56e40b118cadc6ee1689b02f6a72a49de50d462e

parent

5da017ba0bbdfa0d60a0ade52faae828e2395157

4 files changed, 23 insertions(+), 4 deletions(-)

jump to
M CHANGESCHANGES

@@ -54,6 +54,7 @@ - 3DS: Remove deprecated CSND interface

- Qt: Options to mess around with layer placement - GBA Savedata: Remove ability to disable realistic timing - Qt: Add load alternate save option + - GB Audio: Improved audio quality 0.6.3: (2017-04-14) Bugfixes:
M include/mgba/internal/gb/audio.hinclude/mgba/internal/gb/audio.h

@@ -161,6 +161,8 @@ struct blip_t* left;

struct blip_t* right; int16_t lastLeft; int16_t lastRight; + int32_t capLeft; + int32_t capRight; int clock; int32_t clockRate;
M include/mgba/internal/gb/serialize.hinclude/mgba/internal/gb/serialize.h

@@ -103,7 +103,8 @@ * | bit 4: Is channel 1 sweep enabled?

* | bit 5: Has channel 1 sweep occurred? * | bit 6: Is channel 3's memory readable? * | bit 7: Reserved - * | 0x000A8 - 0x000AF: Rserved + * | 0x000A8 - 0x000AB: Left capacitor charge + * | 0x000AC - 0x000AF: Right capacitor charge * | 0x000B0 - 0x000B3: Next sample * 0x000B4 - 0x000153: Video state * | 0x000B4 - 0x000B5: Current x

@@ -302,7 +303,8 @@

struct { struct GBSerializedPSGState psg; GBSerializedAudioFlags flags; - int32_t reserved[2]; + int32_t capLeft; + int32_t capRight; uint32_t nextSample; } audio;
M src/gb/audio.csrc/gb/audio.c

@@ -140,6 +140,8 @@ audio->frame = 0;

audio->sampleInterval = 128; audio->lastLeft = 0; audio->lastRight = 0; + audio->capLeft = 0; + audio->capRight = 0; audio->clock = 0; audio->volumeRight = 0; audio->volumeLeft = 0;

@@ -640,11 +642,17 @@ sampleRight = (sampleRight * audio->masterVolume) >> 6;

mCoreSyncLockAudio(audio->p->sync); unsigned produced; + + int16_t degradedLeft = sampleLeft - (audio->capLeft >> 16); + int16_t degradedRight = sampleRight - (audio->capRight >> 16); + audio->capLeft = (sampleLeft << 16) - degradedLeft * 65184; + audio->capRight = (sampleRight << 16) - degradedRight * 65184; + sampleLeft = degradedLeft; + sampleRight = degradedRight; + if ((size_t) blip_samples_avail(audio->left) < audio->samples) { blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft); blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight); - audio->lastLeft = sampleLeft; - audio->lastRight = sampleRight; audio->clock += audio->sampleInterval; if (audio->clock >= CLOCKS_PER_BLIP_FRAME) { blip_end_frame(audio->left, CLOCKS_PER_BLIP_FRAME);

@@ -652,6 +660,8 @@ blip_end_frame(audio->right, CLOCKS_PER_BLIP_FRAME);

audio->clock -= CLOCKS_PER_BLIP_FRAME; } } + audio->lastLeft = sampleLeft; + audio->lastRight = sampleRight; produced = blip_samples_avail(audio->left); if (audio->p->stream && audio->p->stream->postAudioFrame) { audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);

@@ -1020,11 +1030,15 @@ }

void GBAudioSerialize(const struct GBAudio* audio, struct GBSerializedState* state) { GBAudioPSGSerialize(audio, &state->audio.psg, &state->audio.flags); + STORE_32LE(audio->capLeft, 0, &state->audio.capLeft); + STORE_32LE(audio->capRight, 0, &state->audio.capRight); STORE_32LE(audio->sampleEvent.when - mTimingCurrentTime(audio->timing), 0, &state->audio.nextSample); } void GBAudioDeserialize(struct GBAudio* audio, const struct GBSerializedState* state) { GBAudioPSGDeserialize(audio, &state->audio.psg, &state->audio.flags); + LOAD_32LE(audio->capLeft, 0, &state->audio.capLeft); + LOAD_32LE(audio->capRight, 0, &state->audio.capRight); uint32_t when; LOAD_32LE(when, 0, &state->audio.nextSample); mTimingSchedule(audio->timing, &audio->sampleEvent, when);