GB Audio: Implement capacitor charge

This commit is contained in:
Vicki Pfau 2018-05-11 17:02:58 -07:00
parent 5da017ba0b
commit 56e40b118c
4 changed files with 23 additions and 4 deletions

View File

@ -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:

View File

@ -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;

View File

@ -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 File

@ -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,11 +642,17 @@ 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);
@ -652,6 +660,8 @@ static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) {
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);