mirror of https://github.com/mgba-emu/mgba.git
Implement most of audio serialization
This commit is contained in:
parent
668c4f68b7
commit
9c2c93220b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue