include/mgba/internal/gba/audio.h (view raw)
1/* Copyright (c) 2013-2016 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#ifndef GBA_AUDIO_H
7#define GBA_AUDIO_H
8
9#include <mgba-util/common.h>
10
11CXX_GUARD_START
12
13#include <mgba/core/cpu.h>
14#include <mgba/core/log.h>
15#include <mgba/internal/gb/audio.h>
16#include <mgba-util/circle-buffer.h>
17
18#define GBA_AUDIO_FIFO_SIZE 8
19
20#define MP2K_MAGIC 0x68736D53
21#define MP2K_MAX_SOUND_CHANNELS 12
22
23mLOG_DECLARE_CATEGORY(GBA_AUDIO);
24
25struct GBADMA;
26
27extern const unsigned GBA_AUDIO_SAMPLES;
28extern const int GBA_AUDIO_VOLUME_MAX;
29
30struct GBAAudioFIFO {
31 uint32_t fifo[GBA_AUDIO_FIFO_SIZE];
32 int fifoWrite;
33 int fifoRead;
34 uint32_t internalSample;
35 int internalRemaining;
36 int dmaSource;
37 int8_t sample;
38};
39
40DECL_BITFIELD(GBARegisterSOUNDCNT_HI, uint16_t);
41DECL_BITS(GBARegisterSOUNDCNT_HI, Volume, 0, 2);
42DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChA, 2);
43DECL_BIT(GBARegisterSOUNDCNT_HI, VolumeChB, 3);
44DECL_BIT(GBARegisterSOUNDCNT_HI, ChARight, 8);
45DECL_BIT(GBARegisterSOUNDCNT_HI, ChALeft, 9);
46DECL_BIT(GBARegisterSOUNDCNT_HI, ChATimer, 10);
47DECL_BIT(GBARegisterSOUNDCNT_HI, ChAReset, 11);
48DECL_BIT(GBARegisterSOUNDCNT_HI, ChBRight, 12);
49DECL_BIT(GBARegisterSOUNDCNT_HI, ChBLeft, 13);
50DECL_BIT(GBARegisterSOUNDCNT_HI, ChBTimer, 14);
51DECL_BIT(GBARegisterSOUNDCNT_HI, ChBReset, 15);
52
53DECL_BITFIELD(GBARegisterSOUNDBIAS, uint16_t);
54DECL_BITS(GBARegisterSOUNDBIAS, Bias, 0, 10);
55DECL_BITS(GBARegisterSOUNDBIAS, Resolution, 14, 2);
56
57struct GBAAudioMixer;
58struct GBAAudio {
59 struct GBA* p;
60
61 struct GBAudio psg;
62 struct GBAAudioFIFO chA;
63 struct GBAAudioFIFO chB;
64
65 int16_t lastLeft;
66 int16_t lastRight;
67 int clock;
68
69 uint8_t volume;
70 bool volumeChA;
71 bool volumeChB;
72 bool chARight;
73 bool chALeft;
74 bool chATimer;
75 bool chBRight;
76 bool chBLeft;
77 bool chBTimer;
78 bool enable;
79
80 size_t samples;
81 unsigned sampleRate;
82
83 GBARegisterSOUNDBIAS soundbias;
84
85 struct GBAAudioMixer* mixer;
86 bool externalMixing;
87 int32_t sampleInterval;
88
89 bool forceDisableChA;
90 bool forceDisableChB;
91 int masterVolume;
92
93 struct mTimingEvent sampleEvent;
94};
95
96struct GBAStereoSample {
97 int16_t left;
98 int16_t right;
99};
100
101struct GBAMP2kADSR {
102 uint8_t attack;
103 uint8_t decay;
104 uint8_t sustain;
105 uint8_t release;
106};
107
108struct GBAMP2kSoundChannel {
109 uint8_t status;
110 uint8_t type;
111 uint8_t rightVolume;
112 uint8_t leftVolume;
113 struct GBAMP2kADSR adsr;
114 uint8_t ky;
115 uint8_t envelopeV;
116 uint8_t envelopeRight;
117 uint8_t envelopeLeft;
118 uint8_t echoVolume;
119 uint8_t echoLength;
120 uint8_t d1;
121 uint8_t d2;
122 uint8_t gt;
123 uint8_t midiKey;
124 uint8_t ve;
125 uint8_t pr;
126 uint8_t rp;
127 uint8_t d3[3];
128 uint32_t ct;
129 uint32_t fw;
130 uint32_t freq;
131 uint32_t waveData;
132 uint32_t cp;
133 uint32_t track;
134 uint32_t pp;
135 uint32_t np;
136 uint32_t d4;
137 uint16_t xpi;
138 uint16_t xpc;
139};
140
141struct GBAMP2kContext {
142 uint32_t magic;
143 uint8_t pcmDmaCounter;
144 uint8_t reverb;
145 uint8_t maxChans;
146 uint8_t masterVolume;
147 uint8_t freq;
148 uint8_t mode;
149 uint8_t c15;
150 uint8_t pcmDmaPeriod;
151 uint8_t maxLines;
152 uint8_t gap[3];
153 int32_t pcmSamplesPerVBlank;
154 int32_t pcmFreq;
155 int32_t divFreq;
156 uint32_t cgbChans;
157 uint32_t func;
158 uint32_t intp;
159 uint32_t cgbSound;
160 uint32_t cgbOscOff;
161 uint32_t midiKeyToCgbFreq;
162 uint32_t mPlayJumpTable;
163 uint32_t plynote;
164 uint32_t extVolPit;
165 uint8_t gap2[16];
166 struct GBAMP2kSoundChannel chans[MP2K_MAX_SOUND_CHANNELS];
167};
168
169struct GBAMP2kMusicPlayerInfo {
170 uint32_t songHeader;
171 uint32_t status;
172 uint8_t trackCount;
173 uint8_t priority;
174 uint8_t cmd;
175 uint8_t unk_B;
176 uint32_t clock;
177 uint8_t gap[8];
178 uint32_t memAccArea;
179 uint16_t tempoD;
180 uint16_t tempoU;
181 uint16_t tempoI;
182 uint16_t tempoC;
183 uint16_t fadeOI;
184 uint16_t fadeOC;
185 uint16_t fadeOV;
186 uint32_t tracks;
187 uint32_t tone;
188 uint32_t magic;
189 uint32_t func;
190 uint32_t intp;
191};
192
193struct GBAMP2kInstrument {
194 uint8_t type;
195 uint8_t key;
196 uint8_t length;
197 union {
198 uint8_t pan;
199 uint8_t sweep;
200 } ps;
201 union {
202 uint32_t waveData;
203 uint32_t subTable;
204 } data;
205 union {
206 struct GBAMP2kADSR adsr;
207 uint32_t map;
208 } extInfo;
209};
210
211struct GBAMP2kMusicPlayerTrack {
212 uint8_t flags;
213 uint8_t wait;
214 uint8_t patternLevel;
215 uint8_t repN;
216 uint8_t gateTime;
217 uint8_t key;
218 uint8_t velocity;
219 uint8_t runningStatus;
220 uint8_t keyM;
221 uint8_t pitM;
222 int8_t keyShift;
223 int8_t keyShiftX;
224 int8_t tune;
225 uint8_t pitX;
226 int8_t bend;
227 uint8_t bendRange;
228 uint8_t volMR;
229 uint8_t volML;
230 uint8_t vol;
231 uint8_t volX;
232 int8_t pan;
233 int8_t panX;
234 int8_t modM;
235 uint8_t mod;
236 uint8_t modT;
237 uint8_t lfoSpeed;
238 uint8_t lfoSpeedC;
239 uint8_t lfoDelay;
240 uint8_t lfoDelayC;
241 uint8_t priority;
242 uint8_t echoVolume;
243 uint8_t echoLength;
244 uint32_t chan;
245 struct GBAMP2kInstrument instrument;
246 uint8_t gap[10];
247 uint16_t unk_3A;
248 uint32_t unk_3C;
249 uint32_t cmdPtr;
250 uint32_t patternStack[3];
251};
252
253struct GBAMP2kTrack {
254 struct GBAMP2kMusicPlayerTrack track;
255 struct GBAMP2kSoundChannel* channel;
256 uint8_t lastCommand;
257 struct CircleBuffer buffer;
258 uint32_t samplePlaying;
259 float currentOffset;
260 bool waiting;
261};
262
263struct GBAAudioMixer {
264 struct mCPUComponent d;
265 struct GBAAudio* p;
266
267 uint32_t contextAddress;
268
269 bool (*engage)(struct GBAAudioMixer* mixer, uint32_t address);
270 void (*vblank)(struct GBAAudioMixer* mixer);
271 void (*step)(struct GBAAudioMixer* mixer);
272
273 struct GBAMP2kContext context;
274 struct GBAMP2kMusicPlayerInfo player;
275 struct GBAMP2kTrack activeTracks[MP2K_MAX_SOUND_CHANNELS];
276
277 double tempo;
278 double frame;
279
280 struct GBAStereoSample last;
281};
282
283void GBAAudioInit(struct GBAAudio* audio, size_t samples);
284void GBAAudioReset(struct GBAAudio* audio);
285void GBAAudioDeinit(struct GBAAudio* audio);
286
287void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples);
288
289void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info);
290
291void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value);
292void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value);
293void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value);
294void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value);
295void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value);
296void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value);
297void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value);
298void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value);
299void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value);
300void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value);
301void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value);
302void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value);
303void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value);
304void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value);
305
306void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
307uint32_t GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
308void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles);
309
310struct GBASerializedState;
311void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state);
312void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state);
313
314float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRatio);
315
316CXX_GUARD_END
317
318#endif