Implement most of audio serialization

This commit is contained in:
Jeffrey Pfau 2014-01-25 18:01:31 -08:00
parent 668c4f68b7
commit 9c2c93220b
4 changed files with 141 additions and 45 deletions

View File

@ -2,6 +2,7 @@
#include "gba.h"
#include "gba-io.h"
#include "gba-serialize.h"
#include "gba-thread.h"
#include <limits.h>
@ -606,3 +607,71 @@ static void _sample(struct GBAAudio* audio) {
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;
}

View File

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

View File

@ -1,5 +1,6 @@
#include "gba-serialize.h"
#include "gba-audio.h"
#include "gba-io.h"
#include "memory.h"
@ -28,6 +29,7 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
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 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {
GBAMemoryDeserialize(&gba->memory, state);
GBAIODeserialize(gba, state);
GBAVideoDeserialize(&gba->video, state);
GBAAudioDeserialize(&gba->audio, state);
}
static int _getStateFd(struct GBA* gba, int slot) {

View File

@ -19,37 +19,48 @@ const uint32_t GBA_SAVESTATE_MAGIC;
* | 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 @@ struct GBASerializedState {
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 @@ struct GBASerializedState {
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 {