all repos — mgba @ 9c2c93220b22887991cc7141a8c8669f2150d6fa

mGBA Game Boy Advance Emulator

Implement most of audio serialization
Jeffrey Pfau jeffrey@endrift.com
Sat, 25 Jan 2014 18:01:31 -0800
commit

9c2c93220b22887991cc7141a8c8669f2150d6fa

parent

668c4f68b76a5d9d4ac5345201ef162078d56601

4 files changed, 141 insertions(+), 45 deletions(-)

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

@@ -2,6 +2,7 @@ #include "gba-audio.h"

#include "gba.h" #include "gba-io.h" +#include "gba-serialize.h" #include "gba-thread.h" #include <limits.h>

@@ -606,3 +607,71 @@ CircleBufferWrite32(&audio->right, sampleRight << 5);

unsigned produced = CircleBufferSize(&audio->left); GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3); } + +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.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.ch2.envelopeNextStep = audio->ch2.envelope.nextStep; + state->audio.ch2.waveNextStep = audio->ch2.control.nextStep; + state->audio.ch2.endTime = audio->ch2.control.endTime; + state->audio.ch2.nextEvent = audio->nextCh2; + + 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.ch4.envelopeNextStep = audio->ch4.envelope.nextStep; + state->audio.ch4.lfsr = audio->ch4.lfsr; + state->audio.ch4.endTime = audio->ch4.control.endTime; + state->audio.ch4.nextEvent = audio->nextCh4; + + state->audio.nextEvent = audio->nextEvent; + state->audio.eventDiff = audio->eventDiff; + 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; + + 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; + + 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; + + 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->nextEvent = state->audio.nextEvent; + audio->eventDiff = state->audio.eventDiff; + audio->nextSample = state->audio.nextSample; +}
M src/gba/gba-audio.hsrc/gba/gba-audio.h

@@ -230,4 +230,8 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles);

unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples); +struct GBASerializedState; +void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state); +void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state); + #endif
M src/gba/gba-serialize.csrc/gba/gba-serialize.c

@@ -1,5 +1,6 @@

#include "gba-serialize.h" +#include "gba-audio.h" #include "gba-io.h" #include "memory.h"

@@ -28,6 +29,7 @@

GBAMemorySerialize(&gba->memory, state); GBAIOSerialize(gba, state); GBAVideoSerialize(&gba->video, state); + GBAAudioSerialize(&gba->audio, state); } void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {

@@ -57,6 +59,7 @@

GBAMemoryDeserialize(&gba->memory, state); GBAIODeserialize(gba, state); GBAVideoDeserialize(&gba->video, state); + GBAAudioDeserialize(&gba->audio, state); } static int _getStateFd(struct GBA* gba, int slot) {
M src/gba/gba-serialize.hsrc/gba/gba-serialize.h

@@ -19,37 +19,48 @@ * | 0x00068 - 0x0006B: Cycles since last event

* | 0x0006C - 0x0006F: Cycles until next event * | 0x00070 - 0x00117: Banked registers * | 0x00118 - 0x0012F: Banked SPSRs - * 0x00130 - 0x00147: Audio channel 1 state - * | 0x00130 - 0x00130: Current volume - * | 0x00131 - 0x00131: Is channel dead? - * | 0x00132 - 0x00132: Is channel high? - * | 0x00133 - 0x00133: Reserved - * | 0x00134 - 0x00137: Next envelope step - * | 0x00137 - 0x0013B: Next square wave step - * | 0x0013C - 0x0013G: Next sweep step - * | 0x00140 - 0x00143: Channel end cycle - * | 0x00144 - 0x00147: Next event - * 0x00148 - 0x0015F: Audio channel 2/4 state - * | 0x00148 - 0x00148: Current volume - * | 0x00149 - 0x00149: Is channel dead? - * | 0x0014A - 0x0014A: Is channel high? - * | 0x0014B - 0x0014B: Reserved - * | 0x0014C - 0x0014F: Next envelope step - * | 0x00150 - 0x00153: Next square wave step - * | 0x00154 - 0x00157: Audio channel 4 LFSR - * | 0x00158 - 0x0015B: Channel end cycle - * | 0x0015C - 0x0015F: Next Event - * 0x00160 - 0x0017F: Audio channel 3 wave banks - * 0x00180 - 0x0019F: Audio FIFO 1 - * 0x001A0 - 0x001BF: Audio FIFO 2 - * 0x001C0 - 0x001DF: Audio miscellaneous state - * | 0x001C0 - 0x001C3: Next event - * | 0x001C4 - 0x001C7: Event diff - * | 0x001C8 - 0x001CB: Next channel 3 event - * | 0x001CC - 0x001CF: Next channel 4 event - * | 0x001D0 - 0x001D3: Next sample - * | 0x001D4 - 0x001D7: FIFO size - * | 0x001D8 - 0x001DF: Reserved + * 0x00130 - 0x00143: Audio channel 1 state + * | 0x00130 - 0x00133: Next envelope step + * | 0x00134 - 0x00137: Next square wave step + * | 0x00138 - 0x0013B: Next sweep step + * | 0x0013C - 0x0013F: Channel end cycle + * | 0x00140 - 0x00143: Next event + * 0x00144 - 0x00153: Audio channel 2 state + * | 0x00144 - 0x00147: Next envelope step + * | 0x00148 - 0x0014B: Next square wave step + * | 0x0014C - 0x0014F: Channel end cycle + * | 0x00150 - 0x00153: Next event + * 0x00154 - 0x0017B: Audio channel 3 state + * | 0x00154 - 0x00173: Wave banks + * | 0x00174 - 0x00177: Channel end cycle + * | 0x00178 - 0x0017B: Next event + * 0x0017C - 0x0018B: Audio channel 4 state + * | 0x0017C - 0x0017F: Linear feedback shift register state + * | 0x00180 - 0x00183: Next enveleope step + * | 0x00184 - 0x00187: Channel end cycle + * | 0x00188 - 0x0018B: Next event + * 0x0018C - 0x001AB: Audio FIFO 1 + * 0x001AC - 0x001CB: Audio FIFO 2 + * 0x001CC - 0x001DF: Audio miscellaneous state + * | 0x001CC - 0x001CF: Next event + * | 0x001D0 - 0x001D3: Event diff + * | 0x001D4 - 0x001D7: Next sample + * | 0x001D8 - 0x001DB: FIFO size + * | 0x001DC - 0x001DC: Channel 1 envelope state + * | bits 0 - 3: Current volume + * | bit 4: Is dead? + * | bit 5: Is high? + * | bits 6 - 7: Reserved + * | 0x001DD - 0x001DD: Channel 2 envelope state + * | bits 0 - 3: Current volume + * | bit 4: Is dead? + * | bit 5: Is high? + * | bits 6 - 7: Reserved + * | 0x001DE - 0x001DE: Channel 4 envelope state + * | bits 0 - 3: Current volume + * | bit 4: Is dead? + * | bits 5 - 7: Reserved + * | 0x001DF - 0x001DF: Reserved * 0x001E0 - 0x001FF: Video miscellaneous state * | 0x001E0 - 0x001E3: Next event * | 0x001E4 - 0x001E7: Event diff

@@ -139,10 +150,6 @@ } cpu;

struct { struct { - int8_t volume; - int8_t dead; - int8_t hi; - int8_t : 8; int32_t envelopeNextStep; int32_t waveNextStep; int32_t sweepNextStep;

@@ -150,27 +157,40 @@ int32_t endTime;

int32_t nextEvent; } ch1; struct { - int8_t volume; - int8_t dead; - int8_t hi; - int8_t : 8; int32_t envelopeNextStep; int32_t waveNextStep; - int32_t ch4Lfsr; int32_t endTime; int32_t nextEvent; } ch2; - uint32_t ch3[8]; + struct { + uint32_t wavebanks[8]; + int32_t endTime; + int32_t nextEvent; + } ch3; + struct { + int32_t lfsr; + int32_t envelopeNextStep; + int32_t endTime; + int32_t nextEvent; + } ch4; uint32_t fifoA[8]; uint32_t fifoB[8]; int32_t nextEvent; int32_t eventDiff; - int32_t nextCh3; - int32_t nextCh4; int32_t nextSample; int32_t fifoSize; - int32_t : 32; - int32_t : 32; + 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; } audio; struct {