Permalink
Browse files

GB Audio: Implement capacitor charge

  • Loading branch information...
endrift committed May 12, 2018
1 parent 5da017b commit 56e40b118cadc6ee1689b02f6a72a49de50d462e
Showing with 23 additions and 4 deletions.
  1. +1 −0 CHANGES
  2. +2 −0 include/mgba/internal/gb/audio.h
  3. +4 −2 include/mgba/internal/gb/serialize.h
  4. +16 −2 src/gb/audio.c
View
@@ -54,6 +54,7 @@ Misc:
- 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:
@@ -161,6 +161,8 @@ struct GBAudio {
struct blip_t* right;
int16_t lastLeft;
int16_t lastRight;
+ int32_t capLeft;
+ int32_t capRight;
int clock;
int32_t clockRate;
@@ -103,7 +103,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
* | 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 GBSerializedState {
struct {
struct GBSerializedPSGState psg;
GBSerializedAudioFlags flags;
- int32_t reserved[2];
+ int32_t capLeft;
+ int32_t capRight;
uint32_t nextSample;
} audio;
View
@@ -140,6 +140,8 @@ void GBAudioReset(struct GBAudio* audio) {
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,18 +642,26 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) {
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);
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 GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt
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);

0 comments on commit 56e40b1

Please sign in to comment.