mirror of https://github.com/mgba-emu/mgba.git
GBA Audio: Bitfield-ize audio and use LOAD_32
This commit is contained in:
parent
576ba689f1
commit
2b655a1461
|
@ -848,18 +848,20 @@ static void _sample(struct GBAAudio* audio) {
|
|||
}
|
||||
|
||||
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 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
|
|||
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 @@ void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState*
|
|||
}
|
||||
|
||||
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 @@ void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState
|
|||
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) {
|
||||
|
|
|
@ -128,7 +128,7 @@ struct GBAAudioChannel4 {
|
|||
int32_t endTime;
|
||||
} control;
|
||||
|
||||
unsigned lfsr;
|
||||
uint32_t lfsr;
|
||||
int8_t sample;
|
||||
};
|
||||
|
||||
|
|
|
@ -184,6 +184,16 @@ extern const uint32_t GBA_SAVESTATE_MAGIC;
|
|||
* 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 @@ struct GBASerializedState {
|
|||
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 {
|
||||
|
|
Loading…
Reference in New Issue