src/gba/audio.c (view raw)
1/* Copyright (c) 2013-2015 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 "gba/gba.h"
9#include "gba/io.h"
10#include "gba/serialize.h"
11#include "gba/supervisor/thread.h"
12#include "gba/video.h"
13
14const unsigned GBA_AUDIO_SAMPLES = 2048;
15const unsigned BLIP_BUFFER_SIZE = 0x4000;
16const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
17#define SWEEP_CYCLES (GBA_ARM7TDMI_FREQUENCY / 128)
18
19static bool _writeEnvelope(struct GBAAudioEnvelope* envelope, uint16_t value);
20static int32_t _updateSquareChannel(struct GBAAudioSquareControl* envelope, int duty);
21static void _updateEnvelope(struct GBAAudioEnvelope* envelope);
22static bool _updateSweep(struct GBAAudioChannel1* ch);
23static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
24static int32_t _updateChannel2(struct GBAAudioChannel2* ch);
25static int32_t _updateChannel3(struct GBAAudioChannel3* ch);
26static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
27static int _applyBias(struct GBAAudio* audio, int sample);
28static void _sample(struct GBAAudio* audio);
29
30void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
31 audio->samples = samples;
32#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
33 CircleBufferInit(&audio->left, samples * sizeof(int16_t));
34 CircleBufferInit(&audio->right, samples * sizeof(int16_t));
35#else
36 audio->left = blip_new(BLIP_BUFFER_SIZE);
37 audio->right = blip_new(BLIP_BUFFER_SIZE);
38 // Guess too large; we hang producing extra samples if we guess too low
39 blip_set_rates(audio->left, GBA_ARM7TDMI_FREQUENCY, 96000);
40 blip_set_rates(audio->right, GBA_ARM7TDMI_FREQUENCY, 96000);
41#endif
42 CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
43 CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
44
45 audio->forceDisableCh[0] = false;
46 audio->forceDisableCh[1] = false;
47 audio->forceDisableCh[2] = false;
48 audio->forceDisableCh[3] = false;
49 audio->forceDisableChA = false;
50 audio->forceDisableChB = false;
51}
52
53void GBAAudioReset(struct GBAAudio* audio) {
54 audio->nextEvent = 0;
55 audio->nextCh1 = 0;
56 audio->nextCh2 = 0;
57 audio->nextCh3 = 0;
58 audio->nextCh4 = 0;
59 audio->ch1 = (struct GBAAudioChannel1) { .envelope = { .nextStep = INT_MAX }, .nextSweep = INT_MAX };
60 audio->ch2 = (struct GBAAudioChannel2) { .envelope = { .nextStep = INT_MAX } };
61 audio->ch3 = (struct GBAAudioChannel3) { .bank = { .bank = 0 } };
62 audio->ch4 = (struct GBAAudioChannel4) { .envelope = { .nextStep = INT_MAX } };
63 audio->chA.dmaSource = 1;
64 audio->chB.dmaSource = 2;
65 audio->chA.sample = 0;
66 audio->chB.sample = 0;
67 audio->eventDiff = 0;
68 audio->nextSample = 0;
69 audio->sampleRate = 0x8000;
70 audio->soundbias = 0x200;
71 audio->volumeRight = 0;
72 audio->volumeLeft = 0;
73 audio->ch1Right = false;
74 audio->ch2Right = false;
75 audio->ch3Right = false;
76 audio->ch4Right = false;
77 audio->ch1Left = false;
78 audio->ch2Left = false;
79 audio->ch3Left = false;
80 audio->ch4Left = false;
81 audio->volume = 0;
82 audio->volumeChA = false;
83 audio->volumeChB = false;
84 audio->chARight = false;
85 audio->chALeft = false;
86 audio->chATimer = false;
87 audio->chBRight = false;
88 audio->chBLeft = false;
89 audio->chBTimer = false;
90 audio->playingCh1 = false;
91 audio->playingCh2 = false;
92 audio->playingCh3 = false;
93 audio->playingCh4 = false;
94 audio->enable = false;
95 audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
96
97#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
98 CircleBufferClear(&audio->left);
99 CircleBufferClear(&audio->right);
100#else
101 blip_clear(audio->left);
102 blip_clear(audio->right);
103 audio->clock = 0;
104#endif
105 CircleBufferClear(&audio->chA.fifo);
106 CircleBufferClear(&audio->chB.fifo);
107}
108
109void GBAAudioDeinit(struct GBAAudio* audio) {
110#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
111 CircleBufferDeinit(&audio->left);
112 CircleBufferDeinit(&audio->right);
113#else
114 blip_delete(audio->left);
115 blip_delete(audio->right);
116#endif
117 CircleBufferDeinit(&audio->chA.fifo);
118 CircleBufferDeinit(&audio->chB.fifo);
119}
120
121void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) {
122 GBASyncLockAudio(audio->p->sync);
123 audio->samples = samples;
124#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
125 size_t oldCapacity = audio->left.capacity;
126 int16_t* buffer = malloc(oldCapacity);
127 int16_t dummy;
128 size_t read;
129 size_t i;
130
131 read = CircleBufferDump(&audio->left, buffer, oldCapacity);
132 CircleBufferDeinit(&audio->left);
133 CircleBufferInit(&audio->left, samples * sizeof(int16_t));
134 for (i = 0; i * sizeof(int16_t) < read; ++i) {
135 if (!CircleBufferWrite16(&audio->left, buffer[i])) {
136 CircleBufferRead16(&audio->left, &dummy);
137 CircleBufferWrite16(&audio->left, buffer[i]);
138 }
139 }
140
141 read = CircleBufferDump(&audio->right, buffer, oldCapacity);
142 CircleBufferDeinit(&audio->right);
143 CircleBufferInit(&audio->right, samples * sizeof(int16_t));
144 for (i = 0; i * sizeof(int16_t) < read; ++i) {
145 if (!CircleBufferWrite16(&audio->right, buffer[i])) {
146 CircleBufferRead16(&audio->right, &dummy);
147 CircleBufferWrite16(&audio->right, buffer[i]);
148 }
149 }
150
151 free(buffer);
152#else
153 blip_clear(audio->left);
154 blip_clear(audio->right);
155 audio->clock = 0;
156#endif
157
158 GBASyncConsumeAudio(audio->p->sync);
159}
160
161int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
162 audio->nextEvent -= cycles;
163 audio->eventDiff += cycles;
164 if (audio->nextEvent <= 0) {
165 audio->nextEvent = INT_MAX;
166 if (audio->enable) {
167 if (audio->playingCh1 && !audio->ch1.envelope.dead) {
168 audio->nextCh1 -= audio->eventDiff;
169 if (audio->ch1.envelope.nextStep != INT_MAX) {
170 audio->ch1.envelope.nextStep -= audio->eventDiff;
171 if (audio->ch1.envelope.nextStep <= 0) {
172 int8_t sample = audio->ch1.control.hi * 0x10 - 0x8;
173 _updateEnvelope(&audio->ch1.envelope);
174 if (audio->ch1.envelope.nextStep < audio->nextEvent) {
175 audio->nextEvent = audio->ch1.envelope.nextStep;
176 }
177 audio->ch1.sample = sample * audio->ch1.envelope.currentVolume;
178 }
179 }
180
181 if (audio->ch1.nextSweep != INT_MAX) {
182 audio->ch1.nextSweep -= audio->eventDiff;
183 if (audio->ch1.nextSweep <= 0) {
184 audio->playingCh1 = _updateSweep(&audio->ch1);
185 if (audio->ch1.nextSweep < audio->nextEvent) {
186 audio->nextEvent = audio->ch1.nextSweep;
187 }
188 }
189 }
190
191 if (audio->nextCh1 <= 0) {
192 audio->nextCh1 += _updateChannel1(&audio->ch1);
193 if (audio->nextCh1 < audio->nextEvent) {
194 audio->nextEvent = audio->nextCh1;
195 }
196 }
197
198 if (audio->ch1.control.stop) {
199 audio->ch1.control.endTime -= audio->eventDiff;
200 if (audio->ch1.control.endTime <= 0) {
201 audio->playingCh1 = 0;
202 }
203 }
204 }
205
206 if (audio->playingCh2 && !audio->ch2.envelope.dead) {
207 audio->nextCh2 -= audio->eventDiff;
208 if (audio->ch2.envelope.nextStep != INT_MAX) {
209 audio->ch2.envelope.nextStep -= audio->eventDiff;
210 if (audio->ch2.envelope.nextStep <= 0) {
211 int8_t sample = audio->ch2.control.hi * 0x10 - 0x8;
212 _updateEnvelope(&audio->ch2.envelope);
213 if (audio->ch2.envelope.nextStep < audio->nextEvent) {
214 audio->nextEvent = audio->ch2.envelope.nextStep;
215 }
216 audio->ch2.sample = sample * audio->ch2.envelope.currentVolume;
217 }
218 }
219
220 if (audio->nextCh2 <= 0) {
221 audio->nextCh2 += _updateChannel2(&audio->ch2);
222 if (audio->nextCh2 < audio->nextEvent) {
223 audio->nextEvent = audio->nextCh2;
224 }
225 }
226
227 if (audio->ch2.control.stop) {
228 audio->ch2.control.endTime -= audio->eventDiff;
229 if (audio->ch2.control.endTime <= 0) {
230 audio->playingCh2 = 0;
231 }
232 }
233 }
234
235 if (audio->playingCh3) {
236 audio->nextCh3 -= audio->eventDiff;
237 if (audio->nextCh3 <= 0) {
238 audio->nextCh3 += _updateChannel3(&audio->ch3);
239 if (audio->nextCh3 < audio->nextEvent) {
240 audio->nextEvent = audio->nextCh3;
241 }
242 }
243
244 if (audio->ch3.control.stop) {
245 audio->ch3.control.endTime -= audio->eventDiff;
246 if (audio->ch3.control.endTime <= 0) {
247 audio->playingCh3 = 0;
248 }
249 }
250 }
251
252 if (audio->playingCh4 && !audio->ch4.envelope.dead) {
253 audio->nextCh4 -= audio->eventDiff;
254 if (audio->ch4.envelope.nextStep != INT_MAX) {
255 audio->ch4.envelope.nextStep -= audio->eventDiff;
256 if (audio->ch4.envelope.nextStep <= 0) {
257 int8_t sample = (audio->ch4.sample >> 31) * 0x8;
258 _updateEnvelope(&audio->ch4.envelope);
259 if (audio->ch4.envelope.nextStep < audio->nextEvent) {
260 audio->nextEvent = audio->ch4.envelope.nextStep;
261 }
262 audio->ch4.sample = sample * audio->ch4.envelope.currentVolume;
263 }
264 }
265
266 if (audio->nextCh4 <= 0) {
267 audio->nextCh4 += _updateChannel4(&audio->ch4);
268 if (audio->nextCh4 < audio->nextEvent) {
269 audio->nextEvent = audio->nextCh4;
270 }
271 }
272
273 if (audio->ch4.control.stop) {
274 audio->ch4.control.endTime -= audio->eventDiff;
275 if (audio->ch4.control.endTime <= 0) {
276 audio->playingCh4 = 0;
277 }
278 }
279 }
280 }
281
282 audio->nextSample -= audio->eventDiff;
283 if (audio->nextSample <= 0) {
284 _sample(audio);
285 audio->nextSample += audio->sampleInterval;
286 }
287
288 if (audio->nextSample < audio->nextEvent) {
289 audio->nextEvent = audio->nextSample;
290 }
291 audio->eventDiff = 0;
292 }
293 return audio->nextEvent;
294}
295
296void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
297 switch (info->dest) {
298 case BASE_IO | REG_FIFO_A_LO:
299 audio->chA.dmaSource = number;
300 break;
301 case BASE_IO | REG_FIFO_B_LO:
302 audio->chB.dmaSource = number;
303 break;
304 default:
305 GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
306 return;
307 }
308 info->reg = GBADMARegisterSetDestControl(info->reg, DMA_FIXED);
309}
310
311void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
312 audio->ch1.sweep.shift = GBAAudioRegisterSquareSweepGetShift(value);
313 audio->ch1.sweep.direction = GBAAudioRegisterSquareSweepGetDirection(value);
314 audio->ch1.sweep.time = GBAAudioRegisterSquareSweepGetTime(value);
315 if (audio->ch1.sweep.time) {
316 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
317 } else {
318 audio->ch1.nextSweep = INT_MAX;
319 }
320}
321
322void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
323 if (!_writeEnvelope(&audio->ch1.envelope, value)) {
324 audio->ch1.sample = 0;
325 }
326}
327
328void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
329 audio->ch1.control.frequency = GBAAudioRegisterControlGetFrequency(value);
330 audio->ch1.control.stop = GBAAudioRegisterControlGetStop(value);
331 audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8;
332 if (GBAAudioRegisterControlIsRestart(value)) {
333 if (audio->ch1.sweep.time) {
334 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
335 } else {
336 audio->ch1.nextSweep = INT_MAX;
337 }
338 if (!audio->playingCh1) {
339 audio->nextCh1 = 0;
340 }
341 audio->playingCh1 = 1;
342 if (audio->ch1.envelope.stepTime) {
343 audio->ch1.envelope.nextStep = 0;
344 } else {
345 audio->ch1.envelope.nextStep = INT_MAX;
346 }
347 audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume;
348 if (audio->ch1.envelope.stepTime) {
349 audio->ch1.envelope.nextStep = 0;
350 } else {
351 audio->ch1.envelope.nextStep = INT_MAX;
352 }
353 }
354}
355
356void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
357 if (!_writeEnvelope(&audio->ch2.envelope, value)) {
358 audio->ch2.sample = 0;
359 }
360}
361
362void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
363 audio->ch2.control.frequency = GBAAudioRegisterControlGetFrequency(value);
364 audio->ch2.control.stop = GBAAudioRegisterControlGetStop(value);
365 audio->ch2.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch2.envelope.length)) >> 8;
366 if (GBAAudioRegisterControlIsRestart(value)) {
367 audio->playingCh2 = 1;
368 audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume;
369 if (audio->ch2.envelope.stepTime) {
370 audio->ch2.envelope.nextStep = 0;
371 } else {
372 audio->ch2.envelope.nextStep = INT_MAX;
373 }
374 audio->nextCh2 = 0;
375 }
376}
377
378void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
379 audio->ch3.bank.size = GBAAudioRegisterBankGetSize(value);
380 audio->ch3.bank.bank = GBAAudioRegisterBankGetBank(value);
381 audio->ch3.bank.enable = GBAAudioRegisterBankGetEnable(value);
382 if (audio->ch3.control.endTime >= 0) {
383 audio->playingCh3 = audio->ch3.bank.enable;
384 }
385}
386
387void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
388 audio->ch3.wave.length = GBAAudioRegisterBankWaveGetLength(value);
389 audio->ch3.wave.volume = GBAAudioRegisterBankWaveGetVolume(value);
390}
391
392void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
393 audio->ch3.control.rate = GBAAudioRegisterControlGetRate(value);
394 audio->ch3.control.stop = GBAAudioRegisterControlGetStop(value);
395 audio->ch3.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (256 - audio->ch3.wave.length)) >> 8;
396 if (GBAAudioRegisterControlIsRestart(value)) {
397 audio->playingCh3 = audio->ch3.bank.enable;
398 }
399}
400
401void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
402 if (!_writeEnvelope(&audio->ch4.envelope, value)) {
403 audio->ch4.sample = 0;
404 }
405}
406
407void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
408 audio->ch4.control.ratio = GBAAudioRegisterCh4ControlGetRatio(value);
409 audio->ch4.control.frequency = GBAAudioRegisterCh4ControlGetFrequency(value);
410 audio->ch4.control.power = GBAAudioRegisterCh4ControlGetPower(value);
411 audio->ch4.control.stop = GBAAudioRegisterCh4ControlGetStop(value);
412 audio->ch4.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch4.envelope.length)) >> 8;
413 if (GBAAudioRegisterCh4ControlIsRestart(value)) {
414 audio->playingCh4 = 1;
415 audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume;
416 if (audio->ch4.envelope.stepTime) {
417 audio->ch4.envelope.nextStep = 0;
418 } else {
419 audio->ch4.envelope.nextStep = INT_MAX;
420 }
421 if (audio->ch4.control.power) {
422 audio->ch4.lfsr = 0x40;
423 } else {
424 audio->ch4.lfsr = 0x4000;
425 }
426 audio->nextCh4 = 0;
427 }
428}
429
430void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
431 audio->volumeRight = GBARegisterSOUNDCNT_LOGetVolumeRight(value);
432 audio->volumeLeft = GBARegisterSOUNDCNT_LOGetVolumeLeft(value);
433 audio->ch1Right = GBARegisterSOUNDCNT_LOGetCh1Right(value);
434 audio->ch2Right = GBARegisterSOUNDCNT_LOGetCh2Right(value);
435 audio->ch3Right = GBARegisterSOUNDCNT_LOGetCh3Right(value);
436 audio->ch4Right = GBARegisterSOUNDCNT_LOGetCh4Right(value);
437 audio->ch1Left = GBARegisterSOUNDCNT_LOGetCh1Left(value);
438 audio->ch2Left = GBARegisterSOUNDCNT_LOGetCh2Left(value);
439 audio->ch3Left = GBARegisterSOUNDCNT_LOGetCh3Left(value);
440 audio->ch4Left = GBARegisterSOUNDCNT_LOGetCh4Left(value);
441}
442
443void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
444 audio->volume = GBARegisterSOUNDCNT_HIGetVolume(value);
445 audio->volumeChA = GBARegisterSOUNDCNT_HIGetVolumeChA(value);
446 audio->volumeChB = GBARegisterSOUNDCNT_HIGetVolumeChB(value);
447 audio->chARight = GBARegisterSOUNDCNT_HIGetChARight(value);
448 audio->chALeft = GBARegisterSOUNDCNT_HIGetChALeft(value);
449 audio->chATimer = GBARegisterSOUNDCNT_HIGetChATimer(value);
450 audio->chBRight = GBARegisterSOUNDCNT_HIGetChBRight(value);
451 audio->chBLeft = GBARegisterSOUNDCNT_HIGetChBLeft(value);
452 audio->chBTimer = GBARegisterSOUNDCNT_HIGetChBTimer(value);
453 // TODO: Implement channel reset
454}
455
456void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
457 audio->enable = GBARegisterSOUNDCNT_XGetEnable(value);
458}
459
460void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
461 audio->soundbias = value;
462}
463
464void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
465 audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value;
466}
467
468void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
469 struct CircleBuffer* fifo;
470 switch (address) {
471 case REG_FIFO_A_LO:
472 fifo = &audio->chA.fifo;
473 break;
474 case REG_FIFO_B_LO:
475 fifo = &audio->chB.fifo;
476 break;
477 default:
478 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
479 return;
480 }
481 int i;
482 for (i = 0; i < 4; ++i) {
483 while (!CircleBufferWrite8(fifo, value >> (8 * i))) {
484 int8_t dummy;
485 CircleBufferRead8(fifo, &dummy);
486 }
487 }
488}
489
490void GBAAudioWriteFIFO16(struct GBAAudio* audio, int address, uint16_t value) {
491 struct CircleBuffer* fifo;
492 switch (address) {
493 case REG_FIFO_A_LO:
494 case REG_FIFO_A_HI:
495 fifo = &audio->chA.fifo;
496 break;
497 case REG_FIFO_B_LO:
498 case REG_FIFO_B_HI:
499 fifo = &audio->chB.fifo;
500 break;
501 default:
502 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
503 return;
504 }
505 int i;
506 for (i = 0; i < 2; ++i) {
507 while (!CircleBufferWrite8(fifo, value >> (8 * i))) {
508 int8_t dummy;
509 CircleBufferRead8(fifo, &dummy);
510 }
511 }
512}
513
514void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
515 struct GBAAudioFIFO* channel;
516 if (fifoId == 0) {
517 channel = &audio->chA;
518 } else if (fifoId == 1) {
519 channel = &audio->chB;
520 } else {
521 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
522 return;
523 }
524 if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) {
525 struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
526 if (GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_CUSTOM) {
527 dma->nextCount = 4;
528 dma->nextEvent = 0;
529 GBAMemoryUpdateDMAs(audio->p, -cycles);
530 } else {
531 channel->dmaSource = 0;
532 }
533 }
534 CircleBufferRead8(&channel->fifo, &channel->sample);
535}
536
537#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
538unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples) {
539 GBASyncLockAudio(audio->p->sync);
540 unsigned read = 0;
541 if (left) {
542 unsigned readL = CircleBufferRead(&audio->left, left, nSamples * sizeof(int16_t)) >> 1;
543 if (readL < nSamples) {
544 memset((int16_t*) left + readL, 0, nSamples - readL);
545 }
546 read = readL;
547 }
548 if (right) {
549 unsigned readR = CircleBufferRead(&audio->right, right, nSamples * sizeof(int16_t)) >> 1;
550 if (readR < nSamples) {
551 memset((int16_t*) right + readR, 0, nSamples - readR);
552 }
553 read = read >= readR ? read : readR;
554 }
555 GBASyncConsumeAudio(audio->p->sync);
556 return read;
557}
558
559unsigned GBAAudioResampleNN(struct GBAAudio* audio, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples) {
560 int16_t left[GBA_AUDIO_SAMPLES];
561 int16_t right[GBA_AUDIO_SAMPLES];
562
563 // toRead is in GBA samples
564 // TODO: Do this with fixed-point math
565 unsigned toRead = ceilf(nSamples / ratio);
566 unsigned totalRead = 0;
567 while (nSamples) {
568 unsigned currentRead = GBA_AUDIO_SAMPLES;
569 if (currentRead > toRead) {
570 currentRead = toRead;
571 }
572 unsigned read = GBAAudioCopy(audio, left, right, currentRead);
573 toRead -= read;
574 unsigned i;
575 for (i = 0; i < read; ++i) {
576 *drift += ratio;
577 while (*drift >= 1.f) {
578 output->left = left[i];
579 output->right = right[i];
580 ++output;
581 ++totalRead;
582 --nSamples;
583 *drift -= 1.f;
584 if (!nSamples) {
585 return totalRead;
586 }
587 }
588 }
589 if (read < currentRead) {
590 memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
591 break;
592 }
593 }
594 return totalRead;
595}
596#endif
597
598bool _writeEnvelope(struct GBAAudioEnvelope* envelope, uint16_t value) {
599 envelope->length = GBAAudioRegisterEnvelopeGetLength(value);
600 envelope->duty = GBAAudioRegisterEnvelopeGetDuty(value);
601 envelope->stepTime = GBAAudioRegisterEnvelopeGetStepTime(value);
602 envelope->direction = GBAAudioRegisterEnvelopeGetDirection(value);
603 envelope->initialVolume = GBAAudioRegisterEnvelopeGetInitialVolume(value);
604 envelope->dead = 0;
605 if (envelope->stepTime) {
606 envelope->nextStep = 0;
607 } else {
608 envelope->nextStep = INT_MAX;
609 if (envelope->initialVolume == 0) {
610 envelope->dead = 1;
611 return false;
612 }
613 }
614 return true;
615}
616
617static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
618 control->hi = !control->hi;
619 int period = 16 * (2048 - control->frequency);
620 switch (duty) {
621 case 0:
622 return control->hi ? period : period * 7;
623 case 1:
624 return control->hi ? period * 2 : period * 6;
625 case 2:
626 return period * 4;
627 case 3:
628 return control->hi ? period * 6 : period * 2;
629 default:
630 // This should never be hit
631 return period * 4;
632 }
633}
634
635static void _updateEnvelope(struct GBAAudioEnvelope* envelope) {
636 if (envelope->direction) {
637 ++envelope->currentVolume;
638 } else {
639 --envelope->currentVolume;
640 }
641 if (envelope->currentVolume >= 15) {
642 envelope->currentVolume = 15;
643 envelope->nextStep = INT_MAX;
644 } else if (envelope->currentVolume <= 0) {
645 envelope->currentVolume = 0;
646 envelope->dead = 1;
647 envelope->nextStep = INT_MAX;
648 } else {
649 envelope->nextStep += envelope->stepTime * (GBA_ARM7TDMI_FREQUENCY >> 6);
650 }
651}
652
653static bool _updateSweep(struct GBAAudioChannel1* ch) {
654 if (ch->sweep.direction) {
655 int frequency = ch->control.frequency;
656 frequency -= frequency >> ch->sweep.shift;
657 if (frequency >= 0) {
658 ch->control.frequency = frequency;
659 }
660 } else {
661 int frequency = ch->control.frequency;
662 frequency += frequency >> ch->sweep.shift;
663 if (frequency < 2048) {
664 ch->control.frequency = frequency;
665 } else {
666 return false;
667 }
668 }
669 ch->nextSweep += ch->sweep.time * SWEEP_CYCLES;
670 return true;
671}
672
673static int32_t _updateChannel1(struct GBAAudioChannel1* ch) {
674 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
675 ch->sample = ch->control.hi * 0x10 - 0x8;
676 ch->sample *= ch->envelope.currentVolume;
677 return timing;
678}
679
680static int32_t _updateChannel2(struct GBAAudioChannel2* ch) {
681 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
682 ch->sample = ch->control.hi * 0x10 - 0x8;
683 ch->sample *= ch->envelope.currentVolume;
684 return timing;
685}
686
687static int32_t _updateChannel3(struct GBAAudioChannel3* ch) {
688 int i;
689 int start;
690 int end;
691 int volume;
692 switch (ch->wave.volume) {
693 case 0:
694 volume = 0;
695 break;
696 case 1:
697 volume = 4;
698 break;
699 case 2:
700 volume = 2;
701 break;
702 case 3:
703 volume = 1;
704 break;
705 default:
706 volume = 3;
707 break;
708 }
709 if (ch->bank.size) {
710 start = 7;
711 end = 0;
712 } else if (ch->bank.bank) {
713 start = 7;
714 end = 4;
715 } else {
716 start = 3;
717 end = 0;
718 }
719 uint32_t bitsCarry = ch->wavedata[end] & 0x0F000000;
720 uint32_t bits;
721 for (i = start; i >= end; --i) {
722 bits = ch->wavedata[i] & 0x0F000000;
723 ch->wavedata[i] = ((ch->wavedata[i] & 0xF0F0F0F0) >> 4) | ((ch->wavedata[i] & 0x000F0F0F) << 12);
724 ch->wavedata[i] |= bitsCarry >> 20;
725 bitsCarry = bits;
726 }
727 ch->sample = bitsCarry >> 24;
728 ch->sample -= 8;
729 ch->sample *= volume * 4;
730 return 8 * (2048 - ch->control.rate);
731}
732
733static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
734 int lsb = ch->lfsr & 1;
735 ch->sample = lsb * 0x10 - 0x8;
736 ch->sample *= ch->envelope.currentVolume;
737 ch->lfsr >>= 1;
738 ch->lfsr ^= (lsb * 0x60) << (ch->control.power ? 0 : 8);
739 int timing = ch->control.ratio ? 2 * ch->control.ratio : 1;
740 timing <<= ch->control.frequency;
741 timing *= 32;
742 return timing;
743}
744
745static int _applyBias(struct GBAAudio* audio, int sample) {
746 sample += GBARegisterSOUNDBIASGetBias(audio->soundbias);
747 if (sample >= 0x400) {
748 sample = 0x3FF;
749 } else if (sample < 0) {
750 sample = 0;
751 }
752 return (sample - GBARegisterSOUNDBIASGetBias(audio->soundbias)) << 5;
753}
754
755static void _sample(struct GBAAudio* audio) {
756 int16_t sampleLeft = 0;
757 int16_t sampleRight = 0;
758 int psgShift = 5 - audio->volume;
759
760 if (audio->playingCh1 && !audio->forceDisableCh[0]) {
761 if (audio->ch1Left) {
762 sampleLeft += audio->ch1.sample;
763 }
764
765 if (audio->ch1Right) {
766 sampleRight += audio->ch1.sample;
767 }
768 }
769
770 if (audio->playingCh2 && !audio->forceDisableCh[1]) {
771 if (audio->ch2Left) {
772 sampleLeft += audio->ch2.sample;
773 }
774
775 if (audio->ch2Right) {
776 sampleRight += audio->ch2.sample;
777 }
778 }
779
780 if (audio->playingCh3 && !audio->forceDisableCh[2]) {
781 if (audio->ch3Left) {
782 sampleLeft += audio->ch3.sample;
783 }
784
785 if (audio->ch3Right) {
786 sampleRight += audio->ch3.sample;
787 }
788 }
789
790 if (audio->playingCh4 && !audio->forceDisableCh[3]) {
791 if (audio->ch4Left) {
792 sampleLeft += audio->ch4.sample;
793 }
794
795 if (audio->ch4Right) {
796 sampleRight += audio->ch4.sample;
797 }
798 }
799
800 sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift;
801 sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift;
802
803 if (!audio->forceDisableChA) {
804 if (audio->chALeft) {
805 sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
806 }
807
808 if (audio->chARight) {
809 sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
810 }
811 }
812
813 if (!audio->forceDisableChB) {
814 if (audio->chBLeft) {
815 sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
816 }
817
818 if (audio->chBRight) {
819 sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
820 }
821 }
822
823 sampleLeft = _applyBias(audio, sampleLeft);
824 sampleRight = _applyBias(audio, sampleRight);
825
826 GBASyncLockAudio(audio->p->sync);
827 unsigned produced;
828#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
829 CircleBufferWrite16(&audio->left, sampleLeft);
830 CircleBufferWrite16(&audio->right, sampleRight);
831 produced = CircleBufferSize(&audio->left) / 2;
832#else
833 if ((size_t) blip_samples_avail(audio->left) < audio->samples) {
834 blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft);
835 blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight);
836 audio->lastLeft = sampleLeft;
837 audio->lastRight = sampleRight;
838 audio->clock += audio->sampleInterval;
839 int clockNeeded = blip_clocks_needed(audio->left, audio->samples / 32);
840 if (audio->clock >= clockNeeded) {
841 blip_end_frame(audio->left, audio->clock);
842 blip_end_frame(audio->right, audio->clock);
843 audio->clock -= clockNeeded;
844 }
845 }
846 produced = blip_samples_avail(audio->left);
847#endif
848 if (audio->p->stream && audio->p->stream->postAudioFrame) {
849 audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
850 }
851 bool wait = produced >= audio->samples;
852 GBASyncProduceAudio(audio->p->sync, wait);
853
854 if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
855 audio->p->stream->postAudioBuffer(audio->p->stream, audio);
856 }
857}
858
859void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
860 state->audio.ch1Volume = audio->ch1.envelope.currentVolume;
861 state->audio.ch1Dead = audio->ch1.envelope.dead;
862 state->audio.ch1Hi = audio->ch1.control.hi;
863 state->audio.ch1.envelopeNextStep = audio->ch1.envelope.nextStep;
864 state->audio.ch1.waveNextStep = audio->ch1.control.nextStep;
865 state->audio.ch1.sweepNextStep = audio->ch1.nextSweep;
866 state->audio.ch1.endTime = audio->ch1.control.endTime;
867 state->audio.ch1.nextEvent = audio->nextCh1;
868
869 state->audio.ch2Volume = audio->ch2.envelope.currentVolume;
870 state->audio.ch2Dead = audio->ch2.envelope.dead;
871 state->audio.ch2Hi = audio->ch2.control.hi;
872 state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep;
873 state->audio.ch2.waveNextStep = audio->ch2.control.nextStep;
874 state->audio.ch2.endTime = audio->ch2.control.endTime;
875 state->audio.ch2.nextEvent = audio->nextCh2;
876
877 memcpy(state->audio.ch3.wavebanks, audio->ch3.wavedata, sizeof(state->audio.ch3.wavebanks));
878 state->audio.ch3.endTime = audio->ch3.control.endTime;
879 state->audio.ch3.nextEvent = audio->nextCh3;
880
881 state->audio.ch4Volume = audio->ch4.envelope.currentVolume;
882 state->audio.ch4Dead = audio->ch4.envelope.dead;
883 state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep;
884 state->audio.ch4.lfsr = audio->ch4.lfsr;
885 state->audio.ch4.endTime = audio->ch4.control.endTime;
886 state->audio.ch4.nextEvent = audio->nextCh4;
887
888 CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
889 CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
890 state->audio.fifoSize = CircleBufferSize(&audio->chA.fifo);
891
892 state->audio.nextEvent = audio->nextEvent;
893 state->audio.eventDiff = audio->eventDiff;
894 state->audio.nextSample = audio->nextSample;
895}
896
897void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
898 audio->ch1.envelope.currentVolume = state->audio.ch1Volume;
899 audio->ch1.envelope.dead = state->audio.ch1Dead;
900 audio->ch1.control.hi = state->audio.ch1Hi;
901 audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep;
902 audio->ch1.control.nextStep = state->audio.ch1.waveNextStep;
903 audio->ch1.nextSweep = state->audio.ch1.sweepNextStep;
904 audio->ch1.control.endTime = state->audio.ch1.endTime;
905 audio->nextCh1 = state->audio.ch1.nextEvent;
906
907 audio->ch2.envelope.currentVolume = state->audio.ch2Volume;
908 audio->ch2.envelope.dead = state->audio.ch2Dead;
909 audio->ch2.control.hi = state->audio.ch2Hi;
910 audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep;
911 audio->ch2.control.nextStep = state->audio.ch2.waveNextStep;
912 audio->ch2.control.endTime = state->audio.ch2.endTime;
913 audio->nextCh2 = state->audio.ch2.nextEvent;
914
915 memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata));
916 audio->ch3.control.endTime = state->audio.ch3.endTime;
917 audio->nextCh3 = state->audio.ch3.nextEvent;
918
919 audio->ch4.envelope.currentVolume = state->audio.ch4Volume;
920 audio->ch4.envelope.dead = state->audio.ch4Dead;
921 audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep;
922 audio->ch4.lfsr = state->audio.ch4.lfsr;
923 audio->ch4.control.endTime = state->audio.ch4.endTime;
924 audio->nextCh4 = state->audio.ch4.nextEvent;
925
926 CircleBufferClear(&audio->chA.fifo);
927 CircleBufferClear(&audio->chB.fifo);
928 int i;
929 for (i = 0; i < state->audio.fifoSize; ++i) {
930 CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);
931 CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
932 }
933
934 audio->nextEvent = state->audio.nextEvent;
935 audio->eventDiff = state->audio.eventDiff;
936 audio->nextSample = state->audio.nextSample;
937}
938
939float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
940 return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate);
941}