GBA Audio: Bitfield-ize audio and use LOAD_32

This commit is contained in:
Jeffrey Pfau 2015-10-14 23:18:48 -07:00
parent 576ba689f1
commit 2b655a1461
3 changed files with 53 additions and 48 deletions

View File

@ -848,18 +848,20 @@ static void _sample(struct GBAAudio* audio) {
} }
void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) { void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
state->audio.ch1Volume = audio->ch1.envelope.currentVolume; state->audio.flags = 0;
state->audio.ch1Dead = audio->ch1.envelope.dead;
state->audio.ch1Hi = audio->ch1.control.hi; 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.envelopeNextStep = audio->ch1.envelope.nextStep;
state->audio.ch1.waveNextStep = audio->ch1.control.nextStep; state->audio.ch1.waveNextStep = audio->ch1.control.nextStep;
state->audio.ch1.sweepNextStep = audio->ch1.nextSweep; state->audio.ch1.sweepNextStep = audio->ch1.nextSweep;
state->audio.ch1.endTime = audio->ch1.control.endTime; state->audio.ch1.endTime = audio->ch1.control.endTime;
state->audio.ch1.nextEvent = audio->nextCh1; state->audio.ch1.nextEvent = audio->nextCh1;
state->audio.ch2Volume = audio->ch2.envelope.currentVolume; state->audio.flags = GBASerializedAudioFlagsSetCh2Volume(state->audio.flags, audio->ch2.envelope.currentVolume);
state->audio.ch2Dead = audio->ch2.envelope.dead; state->audio.flags = GBASerializedAudioFlagsSetCh2Dead(state->audio.flags, audio->ch2.envelope.dead);
state->audio.ch2Hi = audio->ch2.control.hi; state->audio.flags = GBASerializedAudioFlagsSetCh2Hi(state->audio.flags, audio->ch2.control.hi);
state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep; state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep;
state->audio.ch2.waveNextStep = audio->ch2.control.nextStep; state->audio.ch2.waveNextStep = audio->ch2.control.nextStep;
state->audio.ch2.endTime = audio->ch2.control.endTime; state->audio.ch2.endTime = audio->ch2.control.endTime;
@ -869,8 +871,8 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
state->audio.ch3.endTime = audio->ch3.control.endTime; state->audio.ch3.endTime = audio->ch3.control.endTime;
state->audio.ch3.nextEvent = audio->nextCh3; state->audio.ch3.nextEvent = audio->nextCh3;
state->audio.ch4Volume = audio->ch4.envelope.currentVolume; state->audio.flags = GBASerializedAudioFlagsSetCh4Volume(state->audio.flags, audio->ch4.envelope.currentVolume);
state->audio.ch4Dead = audio->ch4.envelope.dead; state->audio.flags = GBASerializedAudioFlagsSetCh4Dead(state->audio.flags, audio->ch4.envelope.dead);
state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep; state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep;
state->audio.ch4.lfsr = audio->ch4.lfsr; state->audio.ch4.lfsr = audio->ch4.lfsr;
state->audio.ch4.endTime = audio->ch4.control.endTime; state->audio.ch4.endTime = audio->ch4.control.endTime;
@ -886,37 +888,41 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
} }
void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) { void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
audio->ch1.envelope.currentVolume = state->audio.ch1Volume; uint32_t flags;
audio->ch1.envelope.dead = state->audio.ch1Dead; LOAD_32(flags, 0, &state->audio.flags);
audio->ch1.control.hi = state->audio.ch1Hi; audio->ch1.envelope.currentVolume = GBASerializedAudioFlagsGetCh1Volume(flags);
audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep; audio->ch1.envelope.dead = GBASerializedAudioFlagsGetCh1Dead(flags);
audio->ch1.control.nextStep = state->audio.ch1.waveNextStep; audio->ch1.control.hi = GBASerializedAudioFlagsGetCh1Hi(flags);
audio->ch1.nextSweep = state->audio.ch1.sweepNextStep; LOAD_32(audio->ch1.envelope.nextStep, 0, &state->audio.ch1.envelopeNextStep);
audio->ch1.control.endTime = state->audio.ch1.endTime; LOAD_32(audio->ch1.control.nextStep, 0, &state->audio.ch1.waveNextStep);
audio->nextCh1 = state->audio.ch1.nextEvent; 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.currentVolume = GBASerializedAudioFlagsGetCh2Volume(flags);
audio->ch2.envelope.dead = state->audio.ch2Dead; audio->ch2.envelope.dead = GBASerializedAudioFlagsGetCh2Dead(flags);
audio->ch2.control.hi = state->audio.ch2Hi; audio->ch2.control.hi = GBASerializedAudioFlagsGetCh2Hi(flags);
audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep; LOAD_32(audio->ch2.envelope.nextStep, 0, &state->audio.ch2.envelopeNextStep);
audio->ch2.control.nextStep = state->audio.ch2.waveNextStep; LOAD_32(audio->ch2.control.nextStep, 0, &state->audio.ch2.waveNextStep);
audio->ch2.control.endTime = state->audio.ch2.endTime; LOAD_32(audio->ch2.control.endTime, 0, &state->audio.ch2.endTime);
audio->nextCh2 = state->audio.ch2.nextEvent; LOAD_32(audio->nextCh2, 0, &state->audio.ch2.nextEvent);
// TODO: Big endian?
memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata)); memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata));
audio->ch3.control.endTime = state->audio.ch3.endTime; LOAD_32(audio->ch3.control.endTime, 0, &state->audio.ch3.endTime);
audio->nextCh3 = state->audio.ch3.nextEvent; LOAD_32(audio->nextCh3, 0, &state->audio.ch3.nextEvent);
audio->ch4.envelope.currentVolume = state->audio.ch4Volume; audio->ch4.envelope.currentVolume = GBASerializedAudioFlagsGetCh4Volume(flags);
audio->ch4.envelope.dead = state->audio.ch4Dead; audio->ch4.envelope.dead = GBASerializedAudioFlagsGetCh4Dead(flags);
audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep; LOAD_32(audio->ch4.envelope.nextStep, 0, &state->audio.ch4.envelopeNextStep);
audio->ch4.lfsr = state->audio.ch4.lfsr; LOAD_32(audio->ch4.lfsr, 0, &state->audio.ch4.lfsr);
audio->ch4.control.endTime = state->audio.ch4.endTime; LOAD_32(audio->ch4.control.endTime, 0, &state->audio.ch4.endTime);
audio->nextCh4 = state->audio.ch4.nextEvent; LOAD_32(audio->nextCh4, 0, &state->audio.ch4.nextEvent);
CircleBufferClear(&audio->chA.fifo); CircleBufferClear(&audio->chA.fifo);
CircleBufferClear(&audio->chB.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)) { if (state->audio.fifoSize > CircleBufferCapacity(&audio->chA.fifo)) {
fifoSize = CircleBufferCapacity(&audio->chA.fifo); fifoSize = CircleBufferCapacity(&audio->chA.fifo);
} }
@ -926,9 +932,9 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]); CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
} }
audio->nextEvent = state->audio.nextEvent; LOAD_32(audio->nextEvent, 0, &state->audio.nextEvent);
audio->eventDiff = state->audio.eventDiff; LOAD_32(audio->eventDiff, 0, &state->audio.eventDiff);
audio->nextSample = state->audio.nextSample; LOAD_32(audio->nextSample, 0, &state->audio.nextSample);
} }
float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) { float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {

View File

@ -128,7 +128,7 @@ struct GBAAudioChannel4 {
int32_t endTime; int32_t endTime;
} control; } control;
unsigned lfsr; uint32_t lfsr;
int8_t sample; int8_t sample;
}; };

View File

@ -184,6 +184,16 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
* Total size: 0x61000 (397,312) bytes * 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 { struct GBASerializedState {
uint32_t versionMagic; uint32_t versionMagic;
uint32_t biosChecksum; uint32_t biosChecksum;
@ -236,18 +246,7 @@ struct GBASerializedState {
int32_t eventDiff; int32_t eventDiff;
int32_t nextSample; int32_t nextSample;
uint32_t fifoSize; uint32_t fifoSize;
unsigned ch1Volume : 4; GBASerializedAudioFlags flags;
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;
} audio; } audio;
struct { struct {