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