src/gba/audio.c (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#include "audio.h"
7
8#include "core/sync.h"
9#include "gba/gba.h"
10#include "gba/io.h"
11#include "gba/serialize.h"
12#include "gba/video.h"
13
14mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio");
15
16const unsigned GBA_AUDIO_SAMPLES = 2048;
17const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
18const int GBA_AUDIO_VOLUME_MAX = 0x100;
19
20static const int CLOCKS_PER_FRAME = 0x400;
21
22static int _applyBias(struct GBAAudio* audio, int sample);
23static void _sample(struct GBAAudio* audio);
24
25void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
26 audio->psg.p = NULL;
27 uint8_t* nr52 = (uint8_t*) &audio->p->memory.io[REG_SOUNDCNT_X >> 1];
28#ifdef __BIG_ENDIAN__
29 ++nr52;
30#endif
31 GBAudioInit(&audio->psg, 0, nr52, GB_AUDIO_GBA);
32 audio->samples = samples;
33 audio->psg.clockRate = GBA_ARM7TDMI_FREQUENCY;
34 // Guess too large; we hang producing extra samples if we guess too low
35 blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000);
36 blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000);
37 CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
38 CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
39
40 audio->forceDisableChA = false;
41 audio->forceDisableChB = false;
42 audio->masterVolume = GBA_AUDIO_VOLUME_MAX;
43}
44
45void GBAAudioReset(struct GBAAudio* audio) {
46 GBAudioReset(&audio->psg);
47 audio->nextEvent = 0;
48 audio->chA.dmaSource = 1;
49 audio->chB.dmaSource = 2;
50 audio->chA.sample = 0;
51 audio->chB.sample = 0;
52 audio->eventDiff = 0;
53 audio->nextSample = 0;
54 audio->sampleRate = 0x8000;
55 audio->soundbias = 0x200;
56 audio->volume = 0;
57 audio->volumeChA = false;
58 audio->volumeChB = false;
59 audio->chARight = false;
60 audio->chALeft = false;
61 audio->chATimer = false;
62 audio->chBRight = false;
63 audio->chBLeft = false;
64 audio->chBTimer = false;
65 audio->enable = false;
66 audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
67
68 blip_clear(audio->psg.left);
69 blip_clear(audio->psg.right);
70 audio->clock = 0;
71 CircleBufferClear(&audio->chA.fifo);
72 CircleBufferClear(&audio->chB.fifo);
73}
74
75void GBAAudioDeinit(struct GBAAudio* audio) {
76 GBAudioDeinit(&audio->psg);
77 CircleBufferDeinit(&audio->chA.fifo);
78 CircleBufferDeinit(&audio->chB.fifo);
79}
80
81void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) {
82 mCoreSyncLockAudio(audio->p->sync);
83 audio->samples = samples;
84 blip_clear(audio->psg.left);
85 blip_clear(audio->psg.right);
86 audio->clock = 0;
87 mCoreSyncConsumeAudio(audio->p->sync);
88}
89
90int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
91 audio->nextEvent -= cycles;
92 audio->eventDiff += cycles;
93 while (audio->nextEvent <= 0) {
94 audio->nextEvent = INT_MAX;
95 if (audio->enable) {
96 audio->nextEvent = GBAudioProcessEvents(&audio->psg, audio->eventDiff / 4);
97 if (audio->nextEvent != INT_MAX) {
98 audio->nextEvent *= 4;
99 }
100 }
101
102 audio->nextSample -= audio->eventDiff;
103 if (audio->nextSample <= 0) {
104 _sample(audio);
105 audio->nextSample += audio->sampleInterval;
106 }
107
108 if (audio->nextSample < audio->nextEvent) {
109 audio->nextEvent = audio->nextSample;
110 }
111 audio->eventDiff = 0;
112 }
113 return audio->nextEvent;
114}
115
116void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
117 switch (info->dest) {
118 case BASE_IO | REG_FIFO_A_LO:
119 audio->chA.dmaSource = number;
120 break;
121 case BASE_IO | REG_FIFO_B_LO:
122 audio->chB.dmaSource = number;
123 break;
124 default:
125 mLOG(GBA_AUDIO, GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
126 return;
127 }
128 info->reg = GBADMARegisterSetDestControl(info->reg, DMA_FIXED);
129}
130
131void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
132 GBAudioWriteNR10(&audio->psg, value);
133}
134
135void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
136 GBAudioWriteNR11(&audio->psg, value);
137 GBAudioWriteNR12(&audio->psg, value >> 8);
138}
139
140void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
141 GBAudioWriteNR13(&audio->psg, value);
142 GBAudioWriteNR14(&audio->psg, value >> 8);
143}
144
145void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
146 GBAudioWriteNR21(&audio->psg, value);
147 GBAudioWriteNR22(&audio->psg, value >> 8);
148}
149
150void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
151 GBAudioWriteNR23(&audio->psg, value);
152 GBAudioWriteNR24(&audio->psg, value >> 8);
153}
154
155void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
156 audio->psg.ch3.size = GBAudioRegisterBankGetSize(value);
157 audio->psg.ch3.bank = GBAudioRegisterBankGetBank(value);
158 GBAudioWriteNR30(&audio->psg, value);
159}
160
161void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
162 GBAudioWriteNR31(&audio->psg, value);
163 audio->psg.ch3.volume = GBAudioRegisterBankVolumeGetVolumeGBA(value >> 8);
164}
165
166void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
167 GBAudioWriteNR33(&audio->psg, value);
168 GBAudioWriteNR34(&audio->psg, value >> 8);
169}
170
171void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
172 GBAudioWriteNR41(&audio->psg, value);
173 GBAudioWriteNR42(&audio->psg, value >> 8);
174}
175
176void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
177 GBAudioWriteNR43(&audio->psg, value);
178 GBAudioWriteNR44(&audio->psg, value >> 8);
179}
180
181void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
182 GBAudioWriteNR50(&audio->psg, value);
183 GBAudioWriteNR51(&audio->psg, value >> 8);
184}
185
186void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
187 audio->volume = GBARegisterSOUNDCNT_HIGetVolume(value);
188 audio->volumeChA = GBARegisterSOUNDCNT_HIGetVolumeChA(value);
189 audio->volumeChB = GBARegisterSOUNDCNT_HIGetVolumeChB(value);
190 audio->chARight = GBARegisterSOUNDCNT_HIGetChARight(value);
191 audio->chALeft = GBARegisterSOUNDCNT_HIGetChALeft(value);
192 audio->chATimer = GBARegisterSOUNDCNT_HIGetChATimer(value);
193 audio->chBRight = GBARegisterSOUNDCNT_HIGetChBRight(value);
194 audio->chBLeft = GBARegisterSOUNDCNT_HIGetChBLeft(value);
195 audio->chBTimer = GBARegisterSOUNDCNT_HIGetChBTimer(value);
196 if (GBARegisterSOUNDCNT_HIIsChAReset(value)) {
197 CircleBufferClear(&audio->chA.fifo);
198 }
199 if (GBARegisterSOUNDCNT_HIIsChBReset(value)) {
200 CircleBufferClear(&audio->chB.fifo);
201 }
202}
203
204void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
205 audio->enable = GBAudioEnableGetEnable(value);
206 GBAudioWriteNR52(&audio->psg, value);
207}
208
209void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
210 audio->soundbias = value;
211}
212
213void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
214 audio->psg.ch3.wavedata32[address | (!audio->psg.ch3.bank * 4)] = value;
215}
216
217void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
218 struct CircleBuffer* fifo;
219 switch (address) {
220 case REG_FIFO_A_LO:
221 fifo = &audio->chA.fifo;
222 break;
223 case REG_FIFO_B_LO:
224 fifo = &audio->chB.fifo;
225 break;
226 default:
227 mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", address);
228 return;
229 }
230 int i;
231 for (i = 0; i < 4; ++i) {
232 while (!CircleBufferWrite8(fifo, value >> (8 * i))) {
233 int8_t dummy;
234 CircleBufferRead8(fifo, &dummy);
235 }
236 }
237}
238
239void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
240 struct GBAAudioFIFO* channel;
241 if (fifoId == 0) {
242 channel = &audio->chA;
243 } else if (fifoId == 1) {
244 channel = &audio->chB;
245 } else {
246 mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", fifoId);
247 return;
248 }
249 if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) {
250 struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
251 if (GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_CUSTOM) {
252 dma->nextCount = 4;
253 dma->nextEvent = 0;
254 dma->reg = GBADMARegisterSetWidth(dma->reg, 1);
255 GBAMemoryUpdateDMAs(audio->p, -cycles);
256 } else {
257 channel->dmaSource = 0;
258 }
259 }
260 CircleBufferRead8(&channel->fifo, (int8_t*) &channel->sample);
261}
262
263static int _applyBias(struct GBAAudio* audio, int sample) {
264 sample += GBARegisterSOUNDBIASGetBias(audio->soundbias);
265 if (sample >= 0x400) {
266 sample = 0x3FF;
267 } else if (sample < 0) {
268 sample = 0;
269 }
270 return ((sample - GBARegisterSOUNDBIASGetBias(audio->soundbias)) * audio->masterVolume) >> 3;
271}
272
273static void _sample(struct GBAAudio* audio) {
274 int16_t sampleLeft = 0;
275 int16_t sampleRight = 0;
276 int psgShift = 5 - audio->volume;
277 GBAudioSamplePSG(&audio->psg, &sampleLeft, &sampleRight);
278 sampleLeft >>= psgShift;
279 sampleRight >>= psgShift;
280
281 if (!audio->forceDisableChA) {
282 if (audio->chALeft) {
283 sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
284 }
285
286 if (audio->chARight) {
287 sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
288 }
289 }
290
291 if (!audio->forceDisableChB) {
292 if (audio->chBLeft) {
293 sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
294 }
295
296 if (audio->chBRight) {
297 sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
298 }
299 }
300
301 sampleLeft = _applyBias(audio, sampleLeft);
302 sampleRight = _applyBias(audio, sampleRight);
303
304 mCoreSyncLockAudio(audio->p->sync);
305 unsigned produced;
306 if ((size_t) blip_samples_avail(audio->psg.left) < audio->samples) {
307 blip_add_delta(audio->psg.left, audio->clock, sampleLeft - audio->lastLeft);
308 blip_add_delta(audio->psg.right, audio->clock, sampleRight - audio->lastRight);
309 audio->lastLeft = sampleLeft;
310 audio->lastRight = sampleRight;
311 audio->clock += audio->sampleInterval;
312 if (audio->clock >= CLOCKS_PER_FRAME) {
313 blip_end_frame(audio->psg.left, audio->clock);
314 blip_end_frame(audio->psg.right, audio->clock);
315 audio->clock -= CLOCKS_PER_FRAME;
316 }
317 }
318 produced = blip_samples_avail(audio->psg.left);
319 if (audio->p->stream && audio->p->stream->postAudioFrame) {
320 audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
321 }
322 bool wait = produced >= audio->samples;
323 mCoreSyncProduceAudio(audio->p->sync, wait);
324
325 if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
326 audio->p->stream->postAudioBuffer(audio->p->stream, audio->psg.left, audio->psg.right);
327 }
328}
329
330void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
331 uint32_t flags = 0;
332 uint32_t ch1Flags = 0;
333 uint32_t ch2Flags = 0;
334 uint32_t ch4Flags = 0;
335
336 flags = GBASerializedAudioFlagsSetFrame(flags, audio->psg.frame);
337
338 flags = GBASerializedAudioFlagsSetCh1Volume(flags, audio->psg.ch1.envelope.currentVolume);
339 flags = GBASerializedAudioFlagsSetCh1Dead(flags, audio->psg.ch1.envelope.dead);
340 flags = GBASerializedAudioFlagsSetCh1Hi(flags, audio->psg.ch1.control.hi);
341 flags = GBASerializedAudioFlagsSetCh1SweepEnabled(flags, audio->psg.ch1.sweepEnable);
342 flags = GBASerializedAudioFlagsSetCh1SweepOccurred(flags, audio->psg.ch1.sweepOccurred);
343 ch1Flags = GBASerializedAudioEnvelopeSetLength(ch1Flags, audio->psg.ch1.control.length);
344 ch1Flags = GBASerializedAudioEnvelopeSetNextStep(ch1Flags, audio->psg.ch1.envelope.nextStep);
345 ch1Flags = GBASerializedAudioEnvelopeSetFrequency(ch1Flags, audio->psg.ch1.realFrequency);
346 STORE_32(ch1Flags, 0, &state->audio.ch1.envelope);
347 STORE_32(audio->psg.nextFrame, 0, &state->audio.ch1.nextFrame);
348 STORE_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent);
349
350 flags = GBASerializedAudioFlagsSetCh2Volume(flags, audio->psg.ch2.envelope.currentVolume);
351 flags = GBASerializedAudioFlagsSetCh2Dead(flags, audio->psg.ch2.envelope.dead);
352 flags = GBASerializedAudioFlagsSetCh2Hi(flags, audio->psg.ch2.control.hi);
353 ch2Flags = GBASerializedAudioEnvelopeSetLength(ch2Flags, audio->psg.ch2.control.length);
354 ch2Flags = GBASerializedAudioEnvelopeSetNextStep(ch2Flags, audio->psg.ch2.envelope.nextStep);
355 STORE_32(ch2Flags, 0, &state->audio.ch2.envelope);
356 STORE_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent);
357
358 memcpy(state->audio.ch3.wavebanks, audio->psg.ch3.wavedata32, sizeof(state->audio.ch3.wavebanks));
359 STORE_16(audio->psg.ch3.length, 0, &state->audio.ch3.length);
360 STORE_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent);
361
362 flags = GBASerializedAudioFlagsSetCh4Volume(flags, audio->psg.ch4.envelope.currentVolume);
363 flags = GBASerializedAudioFlagsSetCh4Dead(flags, audio->psg.ch4.envelope.dead);
364 state->audio.flags = GBASerializedAudioFlagsSetCh4Volume(flags, audio->psg.ch4.envelope.currentVolume);
365 state->audio.flags = GBASerializedAudioFlagsSetCh4Dead(flags, audio->psg.ch4.envelope.dead);
366 STORE_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr);
367 ch4Flags = GBASerializedAudioEnvelopeSetLength(ch4Flags, audio->psg.ch4.length);
368 ch4Flags = GBASerializedAudioEnvelopeSetNextStep(ch4Flags, audio->psg.ch4.envelope.nextStep);
369 STORE_32(ch4Flags, 0, &state->audio.ch4.envelope);
370 STORE_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent);
371
372 STORE_32(flags, 0, &state->audio.flags);
373
374 CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
375 CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
376 uint32_t fifoSize = CircleBufferSize(&audio->chA.fifo);
377 STORE_32(fifoSize, 0, &state->audio.fifoSize);
378
379 STORE_32(audio->nextEvent, 0, &state->audio.nextEvent);
380 STORE_32(audio->eventDiff, 0, &state->audio.eventDiff);
381 STORE_32(audio->nextSample, 0, &state->audio.nextSample);
382}
383
384void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
385 uint32_t flags;
386 uint32_t ch1Flags = 0;
387 uint32_t ch2Flags = 0;
388 uint32_t ch4Flags = 0;
389
390 LOAD_32(flags, 0, &state->audio.flags);
391 LOAD_32(ch1Flags, 0, &state->audio.ch1.envelope);
392 audio->psg.ch1.envelope.currentVolume = GBASerializedAudioFlagsGetCh1Volume(flags);
393 audio->psg.ch1.envelope.dead = GBASerializedAudioFlagsGetCh1Dead(flags);
394 audio->psg.ch1.control.hi = GBASerializedAudioFlagsGetCh1Hi(flags);
395 audio->psg.ch1.sweepEnable = GBASerializedAudioFlagsGetCh1SweepEnabled(flags);
396 audio->psg.ch1.sweepOccurred = GBASerializedAudioFlagsGetCh1SweepOccurred(flags);
397 audio->psg.ch1.control.length = GBASerializedAudioEnvelopeGetLength(ch1Flags);
398 audio->psg.ch1.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch1Flags);
399 audio->psg.ch1.realFrequency = GBASerializedAudioEnvelopeGetFrequency(ch1Flags);
400 LOAD_32(audio->psg.nextFrame, 0, &state->audio.ch1.nextFrame);
401 LOAD_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent);
402
403 LOAD_32(ch2Flags, 0, &state->audio.ch1.envelope);
404 audio->psg.ch2.envelope.currentVolume = GBASerializedAudioFlagsGetCh2Volume(flags);
405 audio->psg.ch2.envelope.dead = GBASerializedAudioFlagsGetCh2Dead(flags);
406 audio->psg.ch2.control.hi = GBASerializedAudioFlagsGetCh2Hi(flags);
407 audio->psg.ch2.control.length = GBASerializedAudioEnvelopeGetLength(ch2Flags);
408 audio->psg.ch2.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch2Flags);
409 LOAD_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent);
410
411 // TODO: Big endian?
412 memcpy(audio->psg.ch3.wavedata32, state->audio.ch3.wavebanks, sizeof(audio->psg.ch3.wavedata32));
413 LOAD_16(audio->psg.ch3.length, 0, &state->audio.ch3.length);
414 LOAD_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent);
415
416 LOAD_32(ch4Flags, 0, &state->audio.ch1.envelope);
417 audio->psg.ch4.envelope.currentVolume = GBASerializedAudioFlagsGetCh4Volume(flags);
418 audio->psg.ch4.envelope.dead = GBASerializedAudioFlagsGetCh4Dead(flags);
419 audio->psg.ch4.length = GBASerializedAudioEnvelopeGetLength(ch4Flags);
420 audio->psg.ch4.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch4Flags);
421 LOAD_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr);
422 LOAD_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent);
423
424 CircleBufferClear(&audio->chA.fifo);
425 CircleBufferClear(&audio->chB.fifo);
426 uint32_t fifoSize;
427 LOAD_32(fifoSize, 0, &state->audio.fifoSize);
428 if (state->audio.fifoSize > CircleBufferCapacity(&audio->chA.fifo)) {
429 fifoSize = CircleBufferCapacity(&audio->chA.fifo);
430 }
431 size_t i;
432 for (i = 0; i < fifoSize; ++i) {
433 CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);
434 CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
435 }
436
437 LOAD_32(audio->nextEvent, 0, &state->audio.nextEvent);
438 LOAD_32(audio->eventDiff, 0, &state->audio.eventDiff);
439 LOAD_32(audio->nextSample, 0, &state->audio.nextSample);
440}
441
442float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
443 return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate);
444}