all repos — mgba @ d0b63162d590ce2e185f6f35b587244a9b7e5851

mGBA Game Boy Advance Emulator

src/gba/gba-audio.h (view raw)

  1#ifndef GBA_AUDIO_H
  2#define GBA_AUDIO_H
  3
  4#include "util/common.h"
  5#include "macros.h"
  6
  7#include "util/circle-buffer.h"
  8
  9struct GBADMA;
 10
 11extern const unsigned GBA_AUDIO_SAMPLES;
 12
 13DECL_BITFIELD(GBAAudioRegisterEnvelope, uint16_t);
 14DECL_BITS(GBAAudioRegisterEnvelope, Length, 0, 6);
 15DECL_BITS(GBAAudioRegisterEnvelope, Duty, 6, 2);
 16DECL_BITS(GBAAudioRegisterEnvelope, StepTime, 8, 3);
 17DECL_BIT(GBAAudioRegisterEnvelope, Direction, 11);
 18DECL_BITS(GBAAudioRegisterEnvelope, InitialVolume, 12, 4);
 19
 20DECL_BITFIELD(GBAAudioRegisterControl, uint16_t);
 21DECL_BITS(GBAAudioRegisterControl, Rate, 0, 11);
 22DECL_BITS(GBAAudioRegisterControl, Frequency, 0, 11);
 23DECL_BIT(GBAAudioRegisterControl, Stop, 14);
 24DECL_BIT(GBAAudioRegisterControl, Restart, 15);
 25
 26DECL_BITFIELD(GBAAudioRegisterSquareSweep, uint16_t);
 27DECL_BITS(GBAAudioRegisterSquareSweep, Shift, 0, 3);
 28DECL_BIT(GBAAudioRegisterSquareSweep, Direction, 3);
 29DECL_BITS(GBAAudioRegisterSquareSweep, Time, 4, 3);
 30
 31DECL_BITFIELD(GBAAudioRegisterBank, uint16_t);
 32DECL_BIT(GBAAudioRegisterBank, Size, 5);
 33DECL_BIT(GBAAudioRegisterBank, Bank, 6);
 34DECL_BIT(GBAAudioRegisterBank, Enable, 7);
 35
 36DECL_BITFIELD(GBAAudioRegisterBankWave, uint16_t);
 37DECL_BITS(GBAAudioRegisterBankWave, Length, 0, 8);
 38DECL_BITS(GBAAudioRegisterBankWave, Volume, 13, 3);
 39
 40DECL_BITFIELD(GBAAudioRegisterCh4Control, uint16_t);
 41DECL_BITS(GBAAudioRegisterCh4Control, Ratio, 0, 3);
 42DECL_BIT(GBAAudioRegisterCh4Control, Power, 3);
 43DECL_BITS(GBAAudioRegisterCh4Control, Frequency, 4, 4);
 44DECL_BIT(GBAAudioRegisterCh4Control, Stop, 14);
 45DECL_BIT(GBAAudioRegisterCh4Control, Restart, 15);
 46
 47struct GBAAudioEnvelope {
 48	uint8_t length;
 49	uint8_t duty;
 50	uint8_t stepTime;
 51	uint8_t initialVolume;
 52	bool direction;
 53	int currentVolume;
 54	int dead;
 55	int32_t nextStep;
 56};
 57
 58struct GBAAudioSquareControl {
 59	uint16_t frequency;
 60	bool stop;
 61	int hi;
 62	int32_t nextStep;
 63	int32_t endTime;
 64};
 65
 66struct GBAAudioChannel1 {
 67	struct GBAAudioSquareSweep {
 68		uint8_t shift;
 69		uint8_t time;
 70		bool direction;
 71	} sweep;
 72	int32_t nextSweep;
 73
 74	struct GBAAudioEnvelope envelope;
 75	struct GBAAudioSquareControl control;
 76	int8_t sample;
 77};
 78
 79struct GBAAudioChannel2 {
 80	struct GBAAudioEnvelope envelope;
 81	struct GBAAudioSquareControl control;
 82	int8_t sample;
 83};
 84
 85struct GBAAudioChannel3 {
 86	struct {
 87		bool size;
 88		bool bank;
 89		bool enable;
 90	} bank;
 91
 92	struct {
 93		uint8_t length;
 94		uint8_t volume;
 95	} wave;
 96
 97	struct {
 98		uint16_t rate;
 99		bool stop;
100		int32_t endTime;
101	} control;
102
103	uint32_t wavedata[8];
104	int8_t sample;
105};
106
107struct GBAAudioChannel4 {
108	struct GBAAudioEnvelope envelope;
109
110	struct {
111		uint8_t ratio;
112		uint8_t frequency;
113		bool power;
114		bool stop;
115		int32_t endTime;
116	} control;
117
118	unsigned lfsr;
119	int8_t sample;
120};
121
122struct GBAAudioFIFO {
123	struct CircleBuffer fifo;
124	int dmaSource;
125	int8_t sample;
126};
127
128DECL_BITFIELD(GBARegisterSOUNDCNT_LO, uint16_t);
129DECL_BITS(GBARegisterSOUNDCNT_LO, VolumeRight, 0, 3);
130DECL_BITS(GBARegisterSOUNDCNT_LO, VolumeLeft, 4, 3);
131DECL_BIT(GBARegisterSOUNDCNT_LO, Ch1Right, 8);
132DECL_BIT(GBARegisterSOUNDCNT_LO, Ch2Right, 9);
133DECL_BIT(GBARegisterSOUNDCNT_LO, Ch3Right, 10);
134DECL_BIT(GBARegisterSOUNDCNT_LO, Ch4Right, 11);
135DECL_BIT(GBARegisterSOUNDCNT_LO, Ch1Left, 12);
136DECL_BIT(GBARegisterSOUNDCNT_LO, Ch2Left, 13);
137DECL_BIT(GBARegisterSOUNDCNT_LO, Ch3Left, 14);
138DECL_BIT(GBARegisterSOUNDCNT_LO, Ch4Left, 15);
139
140DECL_BITFIELD(GBARegisterSOUNDCNT_HI, uint16_t);
141DECL_BITS(GBARegisterSOUNDCNT_HI, Volume, 0, 2);
142DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChA, 2);
143DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChB, 3);
144DECL_BIT(GBARegisterSOUNDCNT_HI, ChARight, 8);
145DECL_BIT(GBARegisterSOUNDCNT_HI, ChALeft, 9);
146DECL_BIT(GBARegisterSOUNDCNT_HI, ChATimer, 10);
147DECL_BIT(GBARegisterSOUNDCNT_HI, ChAReset, 11);
148DECL_BIT(GBARegisterSOUNDCNT_HI, ChBRight, 12);
149DECL_BIT(GBARegisterSOUNDCNT_HI, ChBLeft, 13);
150DECL_BIT(GBARegisterSOUNDCNT_HI, ChBTimer, 14);
151DECL_BIT(GBARegisterSOUNDCNT_HI, ChBReset, 15);
152
153DECL_BITFIELD(GBARegisterSOUNDCNT_X, uint16_t);
154DECL_BIT(GBARegisterSOUNDCNT_X, PlayingCh1, 0);
155DECL_BIT(GBARegisterSOUNDCNT_X, PlayingCh2, 1);
156DECL_BIT(GBARegisterSOUNDCNT_X, PlayingCh3, 2);
157DECL_BIT(GBARegisterSOUNDCNT_X, PlayingCh4, 3);
158DECL_BIT(GBARegisterSOUNDCNT_X, Enable, 7);
159
160struct GBAAudio {
161	struct GBA* p;
162
163	struct GBAAudioChannel1 ch1;
164	struct GBAAudioChannel2 ch2;
165	struct GBAAudioChannel3 ch3;
166	struct GBAAudioChannel4 ch4;
167
168	struct GBAAudioFIFO chA;
169	struct GBAAudioFIFO chB;
170
171	struct CircleBuffer left;
172	struct CircleBuffer right;
173
174	uint8_t volumeRight;
175	uint8_t volumeLeft;
176	bool ch1Right;
177	bool ch2Right;
178	bool ch3Right;
179	bool ch4Right;
180	bool ch1Left;
181	bool ch2Left;
182	bool ch3Left;
183	bool ch4Left;
184
185	uint8_t volume;
186	bool volumeChA;
187	bool volumeChB;
188	bool chARight;
189	bool chALeft;
190	bool chATimer;
191	bool chBRight;
192	bool chBLeft;
193	bool chBTimer;
194
195	bool playingCh1;
196	bool playingCh2;
197	bool playingCh3;
198	bool playingCh4;
199	bool enable;
200
201	unsigned sampleRate;
202
203	union {
204		struct {
205			unsigned bias : 10;
206			unsigned : 4;
207			unsigned resolution : 2;
208		};
209		uint16_t soundbias;
210	};
211
212	int32_t nextEvent;
213	int32_t eventDiff;
214	int32_t nextCh1;
215	int32_t nextCh2;
216	int32_t nextCh3;
217	int32_t nextCh4;
218	int32_t nextSample;
219
220	int32_t sampleInterval;
221};
222
223struct GBAStereoSample {
224	int16_t left;
225	int16_t right;
226};
227
228void GBAAudioInit(struct GBAAudio* audio, size_t samples);
229void GBAAudioReset(struct GBAAudio* audio);
230void GBAAudioDeinit(struct GBAAudio* audio);
231
232void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples);
233
234int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles);
235void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
236
237void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value);
238void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value);
239void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value);
240void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value);
241void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value);
242void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value);
243void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value);
244void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value);
245void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value);
246void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value);
247void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value);
248void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value);
249void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value);
250void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value);
251
252void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
253void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
254void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles);
255
256unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples);
257unsigned GBAAudioResampleNN(struct GBAAudio*, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples);
258
259struct GBASerializedState;
260void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state);
261void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state);
262
263float GBAAudioCalculateRatio(struct GBAAudio* audio, float desiredFPS, float desiredSampleRatio);
264
265#endif