all repos — mgba @ 2b655a14611b4e7c1c102f54ed36b94be46e919c

mGBA Game Boy Advance Emulator

GBA Audio: Bitfield-ize audio and use LOAD_32
Jeffrey Pfau jeffrey@endrift.com
Wed, 14 Oct 2015 23:18:48 -0700
commit

2b655a14611b4e7c1c102f54ed36b94be46e919c

parent

576ba689f1be107fc0cd52948ea5d9d3ce18c440

3 files changed, 53 insertions(+), 48 deletions(-)

jump to
M src/gba/audio.csrc/gba/audio.c

@@ -848,18 +848,20 @@ }

} void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) { - state->audio.ch1Volume = audio->ch1.envelope.currentVolume; - state->audio.ch1Dead = audio->ch1.envelope.dead; - state->audio.ch1Hi = audio->ch1.control.hi; + state->audio.flags = 0; + + state->audio.flags = GBASerializedAudioFlagsSetCh1Volume(state->audio.flags, audio->ch1.envelope.currentVolume); + state->audio.flags = GBASerializedAudioFlagsSetCh1Dead(state->audio.flags, audio->ch1.envelope.dead); + state->audio.flags = GBASerializedAudioFlagsSetCh1Hi(state->audio.flags, audio->ch1.control.hi); state->audio.ch1.envelopeNextStep = audio->ch1.envelope.nextStep; state->audio.ch1.waveNextStep = audio->ch1.control.nextStep; state->audio.ch1.sweepNextStep = audio->ch1.nextSweep; state->audio.ch1.endTime = audio->ch1.control.endTime; state->audio.ch1.nextEvent = audio->nextCh1; - state->audio.ch2Volume = audio->ch2.envelope.currentVolume; - state->audio.ch2Dead = audio->ch2.envelope.dead; - state->audio.ch2Hi = audio->ch2.control.hi; + state->audio.flags = GBASerializedAudioFlagsSetCh2Volume(state->audio.flags, audio->ch2.envelope.currentVolume); + state->audio.flags = GBASerializedAudioFlagsSetCh2Dead(state->audio.flags, audio->ch2.envelope.dead); + state->audio.flags = GBASerializedAudioFlagsSetCh2Hi(state->audio.flags, audio->ch2.control.hi); state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep; state->audio.ch2.waveNextStep = audio->ch2.control.nextStep; state->audio.ch2.endTime = audio->ch2.control.endTime;

@@ -869,8 +871,8 @@ memcpy(state->audio.ch3.wavebanks, audio->ch3.wavedata, sizeof(state->audio.ch3.wavebanks));

state->audio.ch3.endTime = audio->ch3.control.endTime; state->audio.ch3.nextEvent = audio->nextCh3; - state->audio.ch4Volume = audio->ch4.envelope.currentVolume; - state->audio.ch4Dead = audio->ch4.envelope.dead; + state->audio.flags = GBASerializedAudioFlagsSetCh4Volume(state->audio.flags, audio->ch4.envelope.currentVolume); + state->audio.flags = GBASerializedAudioFlagsSetCh4Dead(state->audio.flags, audio->ch4.envelope.dead); state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep; state->audio.ch4.lfsr = audio->ch4.lfsr; state->audio.ch4.endTime = audio->ch4.control.endTime;

@@ -886,37 +888,41 @@ state->audio.nextSample = audio->nextSample;

} void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) { - audio->ch1.envelope.currentVolume = state->audio.ch1Volume; - audio->ch1.envelope.dead = state->audio.ch1Dead; - audio->ch1.control.hi = state->audio.ch1Hi; - audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep; - audio->ch1.control.nextStep = state->audio.ch1.waveNextStep; - audio->ch1.nextSweep = state->audio.ch1.sweepNextStep; - audio->ch1.control.endTime = state->audio.ch1.endTime; - audio->nextCh1 = state->audio.ch1.nextEvent; + uint32_t flags; + LOAD_32(flags, 0, &state->audio.flags); + audio->ch1.envelope.currentVolume = GBASerializedAudioFlagsGetCh1Volume(flags); + audio->ch1.envelope.dead = GBASerializedAudioFlagsGetCh1Dead(flags); + audio->ch1.control.hi = GBASerializedAudioFlagsGetCh1Hi(flags); + LOAD_32(audio->ch1.envelope.nextStep, 0, &state->audio.ch1.envelopeNextStep); + LOAD_32(audio->ch1.control.nextStep, 0, &state->audio.ch1.waveNextStep); + LOAD_32(audio->ch1.nextSweep, 0, &state->audio.ch1.sweepNextStep); + LOAD_32(audio->ch1.control.endTime, 0, &state->audio.ch1.endTime); + LOAD_32(audio->nextCh1, 0, &state->audio.ch1.nextEvent); - audio->ch2.envelope.currentVolume = state->audio.ch2Volume; - audio->ch2.envelope.dead = state->audio.ch2Dead; - audio->ch2.control.hi = state->audio.ch2Hi; - audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep; - audio->ch2.control.nextStep = state->audio.ch2.waveNextStep; - audio->ch2.control.endTime = state->audio.ch2.endTime; - audio->nextCh2 = state->audio.ch2.nextEvent; + audio->ch2.envelope.currentVolume = GBASerializedAudioFlagsGetCh2Volume(flags); + audio->ch2.envelope.dead = GBASerializedAudioFlagsGetCh2Dead(flags); + audio->ch2.control.hi = GBASerializedAudioFlagsGetCh2Hi(flags); + LOAD_32(audio->ch2.envelope.nextStep, 0, &state->audio.ch2.envelopeNextStep); + LOAD_32(audio->ch2.control.nextStep, 0, &state->audio.ch2.waveNextStep); + LOAD_32(audio->ch2.control.endTime, 0, &state->audio.ch2.endTime); + LOAD_32(audio->nextCh2, 0, &state->audio.ch2.nextEvent); + // TODO: Big endian? memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata)); - audio->ch3.control.endTime = state->audio.ch3.endTime; - audio->nextCh3 = state->audio.ch3.nextEvent; + LOAD_32(audio->ch3.control.endTime, 0, &state->audio.ch3.endTime); + LOAD_32(audio->nextCh3, 0, &state->audio.ch3.nextEvent); - audio->ch4.envelope.currentVolume = state->audio.ch4Volume; - audio->ch4.envelope.dead = state->audio.ch4Dead; - audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep; - audio->ch4.lfsr = state->audio.ch4.lfsr; - audio->ch4.control.endTime = state->audio.ch4.endTime; - audio->nextCh4 = state->audio.ch4.nextEvent; + audio->ch4.envelope.currentVolume = GBASerializedAudioFlagsGetCh4Volume(flags); + audio->ch4.envelope.dead = GBASerializedAudioFlagsGetCh4Dead(flags); + LOAD_32(audio->ch4.envelope.nextStep, 0, &state->audio.ch4.envelopeNextStep); + LOAD_32(audio->ch4.lfsr, 0, &state->audio.ch4.lfsr); + LOAD_32(audio->ch4.control.endTime, 0, &state->audio.ch4.endTime); + LOAD_32(audio->nextCh4, 0, &state->audio.ch4.nextEvent); CircleBufferClear(&audio->chA.fifo); CircleBufferClear(&audio->chB.fifo); - size_t fifoSize = state->audio.fifoSize; + uint32_t fifoSize; + LOAD_32(fifoSize, 0, &state->audio.fifoSize); if (state->audio.fifoSize > CircleBufferCapacity(&audio->chA.fifo)) { fifoSize = CircleBufferCapacity(&audio->chA.fifo); }

@@ -926,9 +932,9 @@ CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);

CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]); } - audio->nextEvent = state->audio.nextEvent; - audio->eventDiff = state->audio.eventDiff; - audio->nextSample = state->audio.nextSample; + LOAD_32(audio->nextEvent, 0, &state->audio.nextEvent); + LOAD_32(audio->eventDiff, 0, &state->audio.eventDiff); + LOAD_32(audio->nextSample, 0, &state->audio.nextSample); } float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
M src/gba/audio.hsrc/gba/audio.h

@@ -128,7 +128,7 @@ bool stop;

int32_t endTime; } control; - unsigned lfsr; + uint32_t lfsr; int8_t sample; };
M src/gba/serialize.hsrc/gba/serialize.h

@@ -184,6 +184,16 @@ * 0x21000 - 0x60FFF: WRAM

* Total size: 0x61000 (397,312) bytes */ +DECL_BITFIELD(GBASerializedAudioFlags, uint32_t); +DECL_BITS(GBASerializedAudioFlags, Ch1Volume, 0, 4); +DECL_BIT(GBASerializedAudioFlags, Ch1Dead, 4); +DECL_BIT(GBASerializedAudioFlags, Ch1Hi, 5); +DECL_BITS(GBASerializedAudioFlags, Ch2Volume, 8, 4); +DECL_BIT(GBASerializedAudioFlags, Ch2Dead, 12); +DECL_BIT(GBASerializedAudioFlags, Ch2Hi, 13); +DECL_BITS(GBASerializedAudioFlags, Ch4Volume, 16, 4); +DECL_BIT(GBASerializedAudioFlags, Ch4Dead, 20); + struct GBASerializedState { uint32_t versionMagic; uint32_t biosChecksum;

@@ -236,18 +246,7 @@ int32_t nextEvent;

int32_t eventDiff; int32_t nextSample; uint32_t fifoSize; - unsigned ch1Volume : 4; - unsigned ch1Dead : 1; - unsigned ch1Hi : 1; - unsigned : 2; - unsigned ch2Volume : 4; - unsigned ch2Dead : 1; - unsigned ch2Hi : 1; - unsigned : 2; - unsigned ch4Volume : 4; - unsigned ch4Dead : 1; - unsigned : 3; - unsigned : 8; + GBASerializedAudioFlags flags; } audio; struct {