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 GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
491 struct GBAAudioFIFO* channel;
492 if (fifoId == 0) {
493 channel = &audio->chA;
494 } else if (fifoId == 1) {
495 channel = &audio->chB;
496 } else {
497 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
498 return;
499 }
500 if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) {
501 struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
502 if (GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_CUSTOM) {
503 dma->nextCount = 4;
504 dma->nextEvent = 0;
505 dma->reg = GBADMARegisterSetWidth(dma->reg, 1);
506 GBAMemoryUpdateDMAs(audio->p, -cycles);
507 } else {
508 channel->dmaSource = 0;
509 }
510 }
511 CircleBufferRead8(&channel->fifo, &channel->sample);
512}
513
514#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
515unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples) {
516 GBASyncLockAudio(audio->p->sync);
517 unsigned read = 0;
518 if (left) {
519 unsigned readL = CircleBufferRead(&audio->left, left, nSamples * sizeof(int16_t)) >> 1;
520 if (readL < nSamples) {
521 memset((int16_t*) left + readL, 0, nSamples - readL);
522 }
523 read = readL;
524 }
525 if (right) {
526 unsigned readR = CircleBufferRead(&audio->right, right, nSamples * sizeof(int16_t)) >> 1;
527 if (readR < nSamples) {
528 memset((int16_t*) right + readR, 0, nSamples - readR);
529 }
530 read = read >= readR ? read : readR;
531 }
532 GBASyncConsumeAudio(audio->p->sync);
533 return read;
534}
535
536unsigned GBAAudioResampleNN(struct GBAAudio* audio, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples) {
537 int16_t left[GBA_AUDIO_SAMPLES];
538 int16_t right[GBA_AUDIO_SAMPLES];
539
540 // toRead is in GBA samples
541 // TODO: Do this with fixed-point math
542 unsigned toRead = ceilf(nSamples / ratio);
543 unsigned totalRead = 0;
544 while (nSamples) {
545 unsigned currentRead = GBA_AUDIO_SAMPLES;
546 if (currentRead > toRead) {
547 currentRead = toRead;
548 }
549 unsigned read = GBAAudioCopy(audio, left, right, currentRead);
550 toRead -= read;
551 unsigned i;
552 for (i = 0; i < read; ++i) {
553 *drift += ratio;
554 while (*drift >= 1.f) {
555 output->left = left[i];
556 output->right = right[i];
557 ++output;
558 ++totalRead;
559 --nSamples;
560 *drift -= 1.f;
561 if (!nSamples) {
562 return totalRead;
563 }
564 }
565 }
566 if (read < currentRead) {
567 memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
568 break;
569 }
570 }
571 return totalRead;
572}
573#endif
574
575bool _writeEnvelope(struct GBAAudioEnvelope* envelope, uint16_t value) {
576 envelope->length = GBAAudioRegisterEnvelopeGetLength(value);
577 envelope->duty = GBAAudioRegisterEnvelopeGetDuty(value);
578 envelope->stepTime = GBAAudioRegisterEnvelopeGetStepTime(value);
579 envelope->direction = GBAAudioRegisterEnvelopeGetDirection(value);
580 envelope->initialVolume = GBAAudioRegisterEnvelopeGetInitialVolume(value);
581 envelope->dead = 0;
582 if (envelope->stepTime) {
583 envelope->nextStep = 0;
584 } else {
585 envelope->nextStep = INT_MAX;
586 if (envelope->initialVolume == 0) {
587 envelope->dead = 1;
588 return false;
589 }
590 }
591 return true;
592}
593
594static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
595 control->hi = !control->hi;
596 int period = 16 * (2048 - control->frequency);
597 switch (duty) {
598 case 0:
599 return control->hi ? period : period * 7;
600 case 1:
601 return control->hi ? period * 2 : period * 6;
602 case 2:
603 return period * 4;
604 case 3:
605 return control->hi ? period * 6 : period * 2;
606 default:
607 // This should never be hit
608 return period * 4;
609 }
610}
611
612static void _updateEnvelope(struct GBAAudioEnvelope* envelope) {
613 if (envelope->direction) {
614 ++envelope->currentVolume;
615 } else {
616 --envelope->currentVolume;
617 }
618 if (envelope->currentVolume >= 15) {
619 envelope->currentVolume = 15;
620 envelope->nextStep = INT_MAX;
621 } else if (envelope->currentVolume <= 0) {
622 envelope->currentVolume = 0;
623 envelope->dead = 1;
624 envelope->nextStep = INT_MAX;
625 } else {
626 envelope->nextStep += envelope->stepTime * (GBA_ARM7TDMI_FREQUENCY >> 6);
627 }
628}
629
630static bool _updateSweep(struct GBAAudioChannel1* ch) {
631 if (ch->sweep.direction) {
632 int frequency = ch->control.frequency;
633 frequency -= frequency >> ch->sweep.shift;
634 if (frequency >= 0) {
635 ch->control.frequency = frequency;
636 }
637 } else {
638 int frequency = ch->control.frequency;
639 frequency += frequency >> ch->sweep.shift;
640 if (frequency < 2048) {
641 ch->control.frequency = frequency;
642 } else {
643 return false;
644 }
645 }
646 ch->nextSweep += ch->sweep.time * SWEEP_CYCLES;
647 return true;
648}
649
650static int32_t _updateChannel1(struct GBAAudioChannel1* ch) {
651 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
652 ch->sample = ch->control.hi * 0x10 - 0x8;
653 ch->sample *= ch->envelope.currentVolume;
654 return timing;
655}
656
657static int32_t _updateChannel2(struct GBAAudioChannel2* ch) {
658 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
659 ch->sample = ch->control.hi * 0x10 - 0x8;
660 ch->sample *= ch->envelope.currentVolume;
661 return timing;
662}
663
664static int32_t _updateChannel3(struct GBAAudioChannel3* ch) {
665 int i;
666 int start;
667 int end;
668 int volume;
669 switch (ch->wave.volume) {
670 case 0:
671 volume = 0;
672 break;
673 case 1:
674 volume = 4;
675 break;
676 case 2:
677 volume = 2;
678 break;
679 case 3:
680 volume = 1;
681 break;
682 default:
683 volume = 3;
684 break;
685 }
686 if (ch->bank.size) {
687 start = 7;
688 end = 0;
689 } else if (ch->bank.bank) {
690 start = 7;
691 end = 4;
692 } else {
693 start = 3;
694 end = 0;
695 }
696 uint32_t bitsCarry = ch->wavedata[end] & 0x0F000000;
697 uint32_t bits;
698 for (i = start; i >= end; --i) {
699 bits = ch->wavedata[i] & 0x0F000000;
700 ch->wavedata[i] = ((ch->wavedata[i] & 0xF0F0F0F0) >> 4) | ((ch->wavedata[i] & 0x000F0F0F) << 12);
701 ch->wavedata[i] |= bitsCarry >> 20;
702 bitsCarry = bits;
703 }
704 ch->sample = bitsCarry >> 24;
705 ch->sample -= 8;
706 ch->sample *= volume * 4;
707 return 8 * (2048 - ch->control.rate);
708}
709
710static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
711 int lsb = ch->lfsr & 1;
712 ch->sample = lsb * 0x10 - 0x8;
713 ch->sample *= ch->envelope.currentVolume;
714 ch->lfsr >>= 1;
715 ch->lfsr ^= (lsb * 0x60) << (ch->control.power ? 0 : 8);
716 int timing = ch->control.ratio ? 2 * ch->control.ratio : 1;
717 timing <<= ch->control.frequency;
718 timing *= 32;
719 return timing;
720}
721
722static int _applyBias(struct GBAAudio* audio, int sample) {
723 sample += GBARegisterSOUNDBIASGetBias(audio->soundbias);
724 if (sample >= 0x400) {
725 sample = 0x3FF;
726 } else if (sample < 0) {
727 sample = 0;
728 }
729 return (sample - GBARegisterSOUNDBIASGetBias(audio->soundbias)) << 5;
730}
731
732static void _sample(struct GBAAudio* audio) {
733 int16_t sampleLeft = 0;
734 int16_t sampleRight = 0;
735 int psgShift = 5 - audio->volume;
736
737 if (audio->playingCh1 && !audio->forceDisableCh[0]) {
738 if (audio->ch1Left) {
739 sampleLeft += audio->ch1.sample;
740 }
741
742 if (audio->ch1Right) {
743 sampleRight += audio->ch1.sample;
744 }
745 }
746
747 if (audio->playingCh2 && !audio->forceDisableCh[1]) {
748 if (audio->ch2Left) {
749 sampleLeft += audio->ch2.sample;
750 }
751
752 if (audio->ch2Right) {
753 sampleRight += audio->ch2.sample;
754 }
755 }
756
757 if (audio->playingCh3 && !audio->forceDisableCh[2]) {
758 if (audio->ch3Left) {
759 sampleLeft += audio->ch3.sample;
760 }
761
762 if (audio->ch3Right) {
763 sampleRight += audio->ch3.sample;
764 }
765 }
766
767 if (audio->playingCh4 && !audio->forceDisableCh[3]) {
768 if (audio->ch4Left) {
769 sampleLeft += audio->ch4.sample;
770 }
771
772 if (audio->ch4Right) {
773 sampleRight += audio->ch4.sample;
774 }
775 }
776
777 sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift;
778 sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift;
779
780 if (!audio->forceDisableChA) {
781 if (audio->chALeft) {
782 sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
783 }
784
785 if (audio->chARight) {
786 sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
787 }
788 }
789
790 if (!audio->forceDisableChB) {
791 if (audio->chBLeft) {
792 sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
793 }
794
795 if (audio->chBRight) {
796 sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
797 }
798 }
799
800 sampleLeft = _applyBias(audio, sampleLeft);
801 sampleRight = _applyBias(audio, sampleRight);
802
803 GBASyncLockAudio(audio->p->sync);
804 unsigned produced;
805#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
806 CircleBufferWrite16(&audio->left, sampleLeft);
807 CircleBufferWrite16(&audio->right, sampleRight);
808 produced = CircleBufferSize(&audio->left) / 2;
809#else
810 if ((size_t) blip_samples_avail(audio->left) < audio->samples) {
811 blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft);
812 blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight);
813 audio->lastLeft = sampleLeft;
814 audio->lastRight = sampleRight;
815 audio->clock += audio->sampleInterval;
816 int clockNeeded = blip_clocks_needed(audio->left, audio->samples / 32);
817 if (audio->clock >= clockNeeded) {
818 blip_end_frame(audio->left, audio->clock);
819 blip_end_frame(audio->right, audio->clock);
820 audio->clock -= clockNeeded;
821 }
822 }
823 produced = blip_samples_avail(audio->left);
824#endif
825 if (audio->p->stream && audio->p->stream->postAudioFrame) {
826 audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
827 }
828 bool wait = produced >= audio->samples;
829 GBASyncProduceAudio(audio->p->sync, wait);
830
831 if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
832 audio->p->stream->postAudioBuffer(audio->p->stream, audio);
833 }
834}
835
836void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
837 state->audio.ch1Volume = audio->ch1.envelope.currentVolume;
838 state->audio.ch1Dead = audio->ch1.envelope.dead;
839 state->audio.ch1Hi = audio->ch1.control.hi;
840 state->audio.ch1.envelopeNextStep = audio->ch1.envelope.nextStep;
841 state->audio.ch1.waveNextStep = audio->ch1.control.nextStep;
842 state->audio.ch1.sweepNextStep = audio->ch1.nextSweep;
843 state->audio.ch1.endTime = audio->ch1.control.endTime;
844 state->audio.ch1.nextEvent = audio->nextCh1;
845
846 state->audio.ch2Volume = audio->ch2.envelope.currentVolume;
847 state->audio.ch2Dead = audio->ch2.envelope.dead;
848 state->audio.ch2Hi = audio->ch2.control.hi;
849 state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep;
850 state->audio.ch2.waveNextStep = audio->ch2.control.nextStep;
851 state->audio.ch2.endTime = audio->ch2.control.endTime;
852 state->audio.ch2.nextEvent = audio->nextCh2;
853
854 memcpy(state->audio.ch3.wavebanks, audio->ch3.wavedata, sizeof(state->audio.ch3.wavebanks));
855 state->audio.ch3.endTime = audio->ch3.control.endTime;
856 state->audio.ch3.nextEvent = audio->nextCh3;
857
858 state->audio.ch4Volume = audio->ch4.envelope.currentVolume;
859 state->audio.ch4Dead = audio->ch4.envelope.dead;
860 state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep;
861 state->audio.ch4.lfsr = audio->ch4.lfsr;
862 state->audio.ch4.endTime = audio->ch4.control.endTime;
863 state->audio.ch4.nextEvent = audio->nextCh4;
864
865 CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
866 CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
867 state->audio.fifoSize = CircleBufferSize(&audio->chA.fifo);
868
869 state->audio.nextEvent = audio->nextEvent;
870 state->audio.eventDiff = audio->eventDiff;
871 state->audio.nextSample = audio->nextSample;
872}
873
874void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
875 audio->ch1.envelope.currentVolume = state->audio.ch1Volume;
876 audio->ch1.envelope.dead = state->audio.ch1Dead;
877 audio->ch1.control.hi = state->audio.ch1Hi;
878 audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep;
879 audio->ch1.control.nextStep = state->audio.ch1.waveNextStep;
880 audio->ch1.nextSweep = state->audio.ch1.sweepNextStep;
881 audio->ch1.control.endTime = state->audio.ch1.endTime;
882 audio->nextCh1 = state->audio.ch1.nextEvent;
883
884 audio->ch2.envelope.currentVolume = state->audio.ch2Volume;
885 audio->ch2.envelope.dead = state->audio.ch2Dead;
886 audio->ch2.control.hi = state->audio.ch2Hi;
887 audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep;
888 audio->ch2.control.nextStep = state->audio.ch2.waveNextStep;
889 audio->ch2.control.endTime = state->audio.ch2.endTime;
890 audio->nextCh2 = state->audio.ch2.nextEvent;
891
892 memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata));
893 audio->ch3.control.endTime = state->audio.ch3.endTime;
894 audio->nextCh3 = state->audio.ch3.nextEvent;
895
896 audio->ch4.envelope.currentVolume = state->audio.ch4Volume;
897 audio->ch4.envelope.dead = state->audio.ch4Dead;
898 audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep;
899 audio->ch4.lfsr = state->audio.ch4.lfsr;
900 audio->ch4.control.endTime = state->audio.ch4.endTime;
901 audio->nextCh4 = state->audio.ch4.nextEvent;
902
903 CircleBufferClear(&audio->chA.fifo);
904 CircleBufferClear(&audio->chB.fifo);
905 int i;
906 for (i = 0; i < state->audio.fifoSize; ++i) {
907 CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);
908 CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
909 }
910
911 audio->nextEvent = state->audio.nextEvent;
912 audio->eventDiff = state->audio.eventDiff;
913 audio->nextSample = state->audio.nextSample;
914}
915
916float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
917 return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate);
918}