src/gba/gba-audio.c (view raw)
1#include "gba-audio.h"
2
3#include "gba.h"
4#include "gba-io.h"
5#include "gba-thread.h"
6
7#include <limits.h>
8
9const unsigned GBA_AUDIO_SAMPLES = 512;
10const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
11#define SWEEP_CYCLES (GBA_ARM7TDMI_FREQUENCY / 128)
12
13static int32_t _updateSquareChannel(struct GBAAudioSquareControl* envelope, int duty);
14static void _updateEnvelope(struct GBAAudioEnvelope* envelope);
15static int _updateSweep(struct GBAAudioChannel1* ch);
16static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
17static int32_t _updateChannel2(struct GBAAudioChannel2* ch);
18static int32_t _updateChannel3(struct GBAAudioChannel3* ch);
19static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
20static void _sample(struct GBAAudio* audio);
21
22void GBAAudioInit(struct GBAAudio* audio) {
23 audio->nextEvent = 0;
24 audio->nextCh1 = 0;
25 audio->nextCh2 = 0;
26 audio->nextCh3 = 0;
27 audio->nextCh4 = 0;
28 audio->ch1.envelope.nextStep = INT_MAX;
29 audio->ch1.control.nextStep = 0;
30 audio->ch1.nextSweep = INT_MAX;
31 audio->ch1.sample = 0;
32 audio->ch2.envelope.nextStep = INT_MAX;
33 audio->ch2.control.nextStep = 0;
34 audio->ch2.sample = 0;
35 audio->ch3.bank.packed = 0;
36 audio->ch3.sample = 0;
37 audio->ch4.sample = 0;
38 audio->ch4.envelope.nextStep = INT_MAX;
39 audio->eventDiff = 0;
40 audio->nextSample = 0;
41 audio->sampleRate = 0x8000;
42 audio->soundcntLo = 0;
43 audio->soundcntHi = 0;
44 audio->soundcntX = 0;
45 audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
46
47 CircleBufferInit(&audio->left, GBA_AUDIO_SAMPLES * sizeof(int32_t));
48 CircleBufferInit(&audio->right, GBA_AUDIO_SAMPLES * sizeof(int32_t));
49 CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
50 CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
51
52 pthread_mutex_init(&audio->bufferMutex, 0);
53}
54
55void GBAAudioDeinit(struct GBAAudio* audio) {
56 CircleBufferDeinit(&audio->left);
57 CircleBufferDeinit(&audio->right);
58 CircleBufferDeinit(&audio->chA.fifo);
59 CircleBufferDeinit(&audio->chB.fifo);
60
61 pthread_mutex_lock(&audio->bufferMutex);
62 pthread_mutex_destroy(&audio->bufferMutex);
63}
64
65int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
66 audio->nextEvent -= cycles;
67 audio->eventDiff += cycles;
68 while (audio->nextEvent <= 0) {
69 audio->nextEvent = INT_MAX;
70 if (audio->enable) {
71 audio->nextCh1 -= audio->eventDiff;
72 audio->nextCh2 -= audio->eventDiff;
73 audio->nextCh3 -= audio->eventDiff;
74 audio->nextCh4 -= audio->eventDiff;
75
76 if (audio->playingCh1) {
77 audio->ch1.envelope.nextStep -= audio->eventDiff;
78 if (audio->ch1.envelope.nextStep <= 0) {
79 _updateEnvelope(&audio->ch1.envelope);
80 if (audio->ch1.envelope.nextStep < audio->nextEvent) {
81 audio->nextEvent = audio->ch1.envelope.nextStep;
82 }
83 }
84
85 if (audio->ch1.nextSweep != INT_MAX) {
86 audio->ch1.nextSweep -= audio->eventDiff;
87 if (audio->ch1.nextSweep <= 0) {
88 audio->playingCh1 = _updateSweep(&audio->ch1);
89 if (audio->ch1.nextSweep < audio->nextEvent) {
90 audio->nextEvent = audio->ch1.nextSweep;
91 }
92 }
93 }
94
95 if (audio->nextCh1 <= 0) {
96 audio->nextCh1 += _updateChannel1(&audio->ch1);
97 if (audio->nextCh1 < audio->nextEvent) {
98 audio->nextEvent = audio->nextCh1;
99 }
100 }
101
102 if (audio->ch1.control.stop) {
103 audio->ch1.control.endTime -= audio->eventDiff;
104 if (audio->ch1.control.endTime <= 0) {
105 audio->playingCh1 = 0;
106 }
107 }
108 }
109
110 if (audio->playingCh2) {
111 audio->ch2.envelope.nextStep -= audio->eventDiff;
112 if (audio->ch2.envelope.nextStep <= 0) {
113 _updateEnvelope(&audio->ch2.envelope);
114 if (audio->ch2.envelope.nextStep < audio->nextEvent) {
115 audio->nextEvent = audio->ch2.envelope.nextStep;
116 }
117 }
118
119 if (audio->nextCh2 <= 0) {
120 audio->nextCh2 += _updateChannel2(&audio->ch2);
121 if (audio->nextCh2 < audio->nextEvent) {
122 audio->nextEvent = audio->nextCh2;
123 }
124 }
125
126 if (audio->ch2.control.stop) {
127 audio->ch2.control.endTime -= audio->eventDiff;
128 if (audio->ch2.control.endTime <= 0) {
129 audio->playingCh2 = 0;
130 }
131 }
132 }
133
134 if (audio->playingCh3) {
135 if (audio->nextCh3 <= 0) {
136 audio->nextCh3 += _updateChannel3(&audio->ch3);
137 if (audio->nextCh3 < audio->nextEvent) {
138 audio->nextEvent = audio->nextCh3;
139 }
140 }
141
142 if (audio->ch3.control.stop) {
143 audio->ch3.control.endTime -= audio->eventDiff;
144 if (audio->ch3.control.endTime <= 0) {
145 audio->playingCh3 = 0;
146 }
147 }
148 }
149
150 if (audio->playingCh4) {
151 audio->ch4.envelope.nextStep -= audio->eventDiff;
152 if (audio->ch4.envelope.nextStep <= 0) {
153 _updateEnvelope(&audio->ch4.envelope);
154 if (audio->ch4.envelope.nextStep < audio->nextEvent) {
155 audio->nextEvent = audio->ch4.envelope.nextStep;
156 }
157 }
158
159 if (audio->nextCh4 <= 0) {
160 audio->nextCh4 += _updateChannel4(&audio->ch4);
161 if (audio->nextCh4 < audio->nextEvent) {
162 audio->nextEvent = audio->nextCh4;
163 }
164 }
165
166 if (audio->ch4.control.stop) {
167 audio->ch4.control.endTime -= audio->eventDiff;
168 if (audio->ch4.control.endTime <= 0) {
169 audio->playingCh4 = 0;
170 }
171 }
172 }
173 }
174
175 audio->nextSample -= audio->eventDiff;
176 if (audio->nextSample <= 0) {
177 _sample(audio);
178 audio->nextSample += audio->sampleInterval;
179 }
180
181 if (audio->nextSample < audio->nextEvent) {
182 audio->nextEvent = audio->nextSample;
183 }
184 audio->eventDiff = 0;
185 }
186 return audio->nextEvent;
187}
188
189void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
190 switch (info->dest) {
191 case BASE_IO | REG_FIFO_A_LO:
192 audio->chA.dmaSource = number;
193 break;
194 case BASE_IO | REG_FIFO_B_LO:
195 audio->chB.dmaSource = number;
196 break;
197 default:
198 GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
199 return;
200 }
201 info->dstControl = DMA_FIXED;
202}
203
204void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
205 audio->ch1.sweep.packed = value;
206 if (audio->ch1.sweep.time) {
207 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
208 } else {
209 audio->ch1.nextSweep = INT_MAX;
210 }
211}
212
213void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
214 audio->ch1.envelope.packed = value;
215}
216
217void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
218 audio->ch1.control.packed = value;
219 audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8;
220 if (audio->ch1.control.restart) {
221 if (audio->ch1.sweep.time) {
222 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
223 } else {
224 audio->ch1.nextSweep = INT_MAX;
225 }
226 if (!audio->playingCh1) {
227 audio->nextCh1 = 0;
228 }
229 audio->playingCh1 = 1;
230 if (audio->ch1.envelope.stepTime) {
231 audio->ch1.envelope.nextStep = 0;
232 } else {
233 audio->ch1.envelope.nextStep = INT_MAX;
234 }
235 audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume;
236 if (audio->ch1.envelope.stepTime) {
237 audio->ch1.envelope.nextStep = 0;
238 } else {
239 audio->ch1.envelope.nextStep = INT_MAX;
240 }
241 }
242}
243
244void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
245 audio->ch2.envelope.packed = value;
246 if (audio->ch2.envelope.stepTime) {
247 audio->ch2.envelope.nextStep = 0;
248 } else {
249 audio->ch2.envelope.nextStep = INT_MAX;
250 }
251}
252
253void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
254 audio->ch2.control.packed = value;
255 audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch2.envelope.length)) >> 8;
256 if (audio->ch2.control.restart) {
257 audio->playingCh2 = 1;
258 audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume;
259 if (audio->ch2.envelope.stepTime) {
260 audio->ch2.envelope.nextStep = 0;
261 } else {
262 audio->ch2.envelope.nextStep = INT_MAX;
263 }
264 audio->nextCh2 = 0;
265 }
266}
267
268void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
269 audio->ch3.bank.packed = value;
270}
271
272void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
273 audio->ch3.wave.packed = value;
274}
275
276void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
277 audio->ch3.control.packed = value;
278 audio->ch3.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (256 - audio->ch3.wave.length)) >> 8;
279 if (audio->ch3.control.restart) {
280 audio->playingCh3 = 1;
281 }
282}
283
284void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
285 audio->ch4.envelope.packed = value;
286 if (audio->ch4.envelope.stepTime) {
287 audio->ch4.envelope.nextStep = 0;
288 } else {
289 audio->ch4.envelope.nextStep = INT_MAX;
290 }
291}
292
293void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
294 audio->ch4.control.packed = value;
295 audio->ch4.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch4.envelope.length)) >> 8;
296 if (audio->ch4.control.restart) {
297 audio->playingCh4 = 1;
298 audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume;
299 if (audio->ch4.envelope.stepTime) {
300 audio->ch4.envelope.nextStep = 0;
301 } else {
302 audio->ch4.envelope.nextStep = INT_MAX;
303 }
304 if (audio->ch4.control.power) {
305 audio->ch4.lfsr = 0x40;
306 } else {
307 audio->ch4.lfsr = 0x4000;
308 }
309 audio->nextCh4 = 0;
310 }
311}
312
313void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
314 audio->soundcntLo = value;
315}
316
317void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
318 audio->soundcntHi = value;
319}
320
321void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
322 audio->soundcntX = (value & 0x80) | (audio->soundcntX & 0x0F);
323}
324
325void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
326 audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value;
327}
328
329void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
330 struct CircleBuffer* fifo;
331 switch (address) {
332 case REG_FIFO_A_LO:
333 fifo = &audio->chA.fifo;
334 break;
335 case REG_FIFO_B_LO:
336 fifo = &audio->chB.fifo;
337 break;
338 default:
339 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
340 return;
341 }
342 while (!CircleBufferWrite32(fifo, value)) {
343 int32_t dummy;
344 CircleBufferRead32(fifo, &dummy);
345 }
346}
347
348void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId) {
349 struct GBAAudioFIFO* channel;
350 if (fifoId == 0) {
351 channel = &audio->chA;
352 } else if (fifoId == 1) {
353 channel = &audio->chB;
354 } else {
355 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
356 return;
357 }
358 if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t)) {
359 struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
360 dma->nextCount = 4;
361 GBAMemoryServiceDMA(&audio->p->memory, channel->dmaSource, dma);
362 }
363 CircleBufferRead8(&channel->fifo, &channel->sample);
364}
365
366static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
367 control->hi = !control->hi;
368 int period = 16 * (2048 - control->frequency);
369 switch (duty) {
370 case 0:
371 return control->hi ? period : period * 7;
372 case 1:
373 return control->hi ? period * 2 : period * 6;
374 case 2:
375 return period * 4;
376 case 3:
377 return control->hi ? period * 6 : period * 2;
378 default:
379 // This should never be hit
380 return period * 4;
381 }
382}
383
384static void _updateEnvelope(struct GBAAudioEnvelope* envelope) {
385 if (envelope->direction) {
386 ++envelope->currentVolume;
387 } else {
388 --envelope->currentVolume;
389 }
390 if (envelope->currentVolume >= 15) {
391 envelope->currentVolume = 15;
392 envelope->nextStep = INT_MAX;
393 } else if (envelope->currentVolume <= 0) {
394 envelope->currentVolume = 0;
395 envelope->nextStep = INT_MAX;
396 } else {
397 envelope->nextStep += envelope->stepTime * (GBA_ARM7TDMI_FREQUENCY >> 6);
398 }
399}
400
401static int _updateSweep(struct GBAAudioChannel1* ch) {
402 if (ch->sweep.direction) {
403 int frequency = ch->control.frequency;
404 frequency -= frequency >> ch->sweep.shift;
405 if (frequency >= 0) {
406 ch->control.frequency = frequency;
407 }
408 } else {
409 int frequency = ch->control.frequency;
410 frequency += frequency >> ch->sweep.shift;
411 if (frequency < 2048) {
412 ch->control.frequency = frequency;
413 } else {
414 return 0;
415 }
416 }
417 ch->nextSweep += ch->sweep.time * SWEEP_CYCLES;
418 return 1;
419}
420
421static int32_t _updateChannel1(struct GBAAudioChannel1* ch) {
422 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
423 ch->sample = ch->control.hi * 0x10 - 0x8;
424 ch->sample *= ch->envelope.currentVolume;
425 return timing;
426}
427
428static int32_t _updateChannel2(struct GBAAudioChannel2* ch) {
429 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
430 ch->sample = ch->control.hi * 0x10 - 0x8;
431 ch->sample *= ch->envelope.currentVolume;
432 return timing;
433}
434
435static int32_t _updateChannel3(struct GBAAudioChannel3* ch) {
436 int i;
437 int start;
438 int end;
439 int volume;
440 switch (ch->wave.volume) {
441 case 0:
442 volume = 0;
443 break;
444 case 1:
445 volume = 4;
446 break;
447 case 2:
448 volume = 2;
449 break;
450 case 3:
451 volume = 1;
452 break;
453 default:
454 volume = 3;
455 break;
456 }
457 if (ch->bank.size) {
458 start = 7;
459 end = 0;
460 } else if (ch->bank.bank) {
461 start = 7;
462 end = 4;
463 } else {
464 start = 3;
465 end = 0;
466 }
467 uint32_t bitsCarry = ch->wavedata[end] & 0xF0000000;
468 uint32_t bits;
469 for (i = start; i >= end; --i) {
470 bits = ch->wavedata[i] & 0xF0000000;
471 ch->wavedata[i] <<= 4;
472 ch->wavedata[i] |= bitsCarry >> 28;
473 bitsCarry = bits;
474 }
475 ch->sample = ((bitsCarry >> 26) - 0x20) * volume;
476 return 8 * (2048 - ch->control.rate);
477}
478
479static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
480 int lsb = ch->lfsr & 1;
481 ch->sample = lsb * 0x10 - 0x8;
482 ch->sample *= ch->envelope.currentVolume;
483 ch->lfsr >>= 1;
484 ch->lfsr ^= (lsb * 0x60) << (ch->control.power ? 0 : 8);
485 int timing = ch->control.ratio ? 2 * ch->control.ratio : 1;
486 timing <<= ch->control.frequency;
487 timing *= 32;
488 return timing;
489}
490
491static void _sample(struct GBAAudio* audio) {
492 int32_t sampleLeft = 0;
493 int32_t sampleRight = 0;
494 int psgShift = 1 + audio->volume;
495
496 if (audio->ch1Left) {
497 sampleLeft += audio->ch1.sample;
498 }
499
500 if (audio->ch1Right) {
501 sampleRight += audio->ch1.sample;
502 }
503
504 if (audio->ch2Left) {
505 sampleLeft += audio->ch2.sample;
506 }
507
508 if (audio->ch2Right) {
509 sampleRight += audio->ch2.sample;
510 }
511
512 if (audio->ch3Left) {
513 sampleLeft += audio->ch3.sample;
514 }
515
516 if (audio->ch3Right) {
517 sampleRight += audio->ch3.sample;
518 }
519
520 if (audio->ch4Left) {
521 sampleLeft += audio->ch4.sample;
522 }
523
524 if (audio->ch4Right) {
525 sampleRight += audio->ch4.sample;
526 }
527
528 sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift;
529 sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift;
530
531 if (audio->chALeft) {
532 sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
533 }
534
535 if (audio->chARight) {
536 sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
537 }
538
539 if (audio->chBLeft) {
540 sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
541 }
542
543 if (audio->chBRight) {
544 sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
545 }
546
547 pthread_mutex_lock(&audio->bufferMutex);
548 while (CircleBufferSize(&audio->left) + (GBA_AUDIO_SAMPLES * 2 / 5) >= audio->left.capacity) {
549 if (!audio->p->sync->audioWait) {
550 break;
551 }
552 GBASyncProduceAudio(audio->p->sync, &audio->bufferMutex);
553 }
554 CircleBufferWrite32(&audio->left, sampleLeft);
555 CircleBufferWrite32(&audio->right, sampleRight);
556 pthread_mutex_unlock(&audio->bufferMutex);
557}