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-serialize.h"
6#include "gba-thread.h"
7
8#include <limits.h>
9#include <math.h>
10
11const unsigned GBA_AUDIO_SAMPLES = 512;
12const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
13#define SWEEP_CYCLES (GBA_ARM7TDMI_FREQUENCY / 128)
14
15static int32_t _updateSquareChannel(struct GBAAudioSquareControl* envelope, int duty);
16static void _updateEnvelope(struct GBAAudioEnvelope* envelope);
17static int _updateSweep(struct GBAAudioChannel1* ch);
18static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
19static int32_t _updateChannel2(struct GBAAudioChannel2* ch);
20static int32_t _updateChannel3(struct GBAAudioChannel3* ch);
21static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
22static int _applyBias(struct GBAAudio* audio, int sample);
23static void _sample(struct GBAAudio* audio);
24
25void GBAAudioInit(struct GBAAudio* audio) {
26 audio->nextEvent = 0;
27 audio->nextCh1 = 0;
28 audio->nextCh2 = 0;
29 audio->nextCh3 = 0;
30 audio->nextCh4 = 0;
31 audio->ch1.sweep.time = 0;
32 audio->ch1.envelope.nextStep = INT_MAX;
33 audio->ch1.control.nextStep = 0;
34 audio->ch1.control.endTime = 0;
35 audio->ch1.nextSweep = INT_MAX;
36 audio->ch1.sample = 0;
37 audio->ch2.envelope.nextStep = INT_MAX;
38 audio->ch2.control.nextStep = 0;
39 audio->ch2.control.endTime = 0;
40 audio->ch2.sample = 0;
41 audio->ch3.bank.packed = 0;
42 audio->ch3.control.endTime = 0;
43 audio->ch3.sample = 0;
44 audio->ch4.sample = 0;
45 audio->ch4.envelope.nextStep = INT_MAX;
46 audio->eventDiff = 0;
47 audio->nextSample = 0;
48 audio->sampleRate = 0x8000;
49 audio->soundbias = 0x200;
50 audio->soundcntLo = 0;
51 audio->soundcntHi = 0;
52 audio->soundcntX = 0;
53 audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
54
55 CircleBufferInit(&audio->left, GBA_AUDIO_SAMPLES * sizeof(int32_t));
56 CircleBufferInit(&audio->right, GBA_AUDIO_SAMPLES * sizeof(int32_t));
57 CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
58 CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
59}
60
61void GBAAudioDeinit(struct GBAAudio* audio) {
62 CircleBufferDeinit(&audio->left);
63 CircleBufferDeinit(&audio->right);
64 CircleBufferDeinit(&audio->chA.fifo);
65 CircleBufferDeinit(&audio->chB.fifo);
66}
67
68int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
69 audio->nextEvent -= cycles;
70 audio->eventDiff += cycles;
71 while (audio->nextEvent <= 0) {
72 audio->nextEvent = INT_MAX;
73 if (audio->enable) {
74 if (audio->playingCh1 && !audio->ch1.envelope.dead) {
75 audio->nextCh1 -= audio->eventDiff;
76 if (audio->ch1.envelope.nextStep != INT_MAX) {
77 audio->ch1.envelope.nextStep -= audio->eventDiff;
78 if (audio->ch1.envelope.nextStep <= 0) {
79 int8_t sample = audio->ch1.control.hi * 0x10 - 0x8;
80 _updateEnvelope(&audio->ch1.envelope);
81 if (audio->ch1.envelope.nextStep < audio->nextEvent) {
82 audio->nextEvent = audio->ch1.envelope.nextStep;
83 }
84 audio->ch1.sample = sample * audio->ch1.envelope.currentVolume;
85 }
86 }
87
88 if (audio->ch1.nextSweep != INT_MAX) {
89 audio->ch1.nextSweep -= audio->eventDiff;
90 if (audio->ch1.nextSweep <= 0) {
91 audio->playingCh1 = _updateSweep(&audio->ch1);
92 if (audio->ch1.nextSweep < audio->nextEvent) {
93 audio->nextEvent = audio->ch1.nextSweep;
94 }
95 }
96 }
97
98 if (audio->nextCh1 <= 0) {
99 audio->nextCh1 += _updateChannel1(&audio->ch1);
100 if (audio->nextCh1 < audio->nextEvent) {
101 audio->nextEvent = audio->nextCh1;
102 }
103 }
104
105 if (audio->ch1.control.stop) {
106 audio->ch1.control.endTime -= audio->eventDiff;
107 if (audio->ch1.control.endTime <= 0) {
108 audio->playingCh1 = 0;
109 }
110 }
111 }
112
113 if (audio->playingCh2 && !audio->ch2.envelope.dead) {
114 audio->nextCh2 -= audio->eventDiff;
115 if (audio->ch2.envelope.nextStep != INT_MAX) {
116 audio->ch2.envelope.nextStep -= audio->eventDiff;
117 if (audio->ch2.envelope.nextStep <= 0) {
118 int8_t sample = audio->ch2.control.hi * 0x10 - 0x8;
119 _updateEnvelope(&audio->ch2.envelope);
120 if (audio->ch2.envelope.nextStep < audio->nextEvent) {
121 audio->nextEvent = audio->ch2.envelope.nextStep;
122 }
123 audio->ch2.sample = sample * audio->ch2.envelope.currentVolume;
124 }
125 }
126
127 if (audio->nextCh2 <= 0) {
128 audio->nextCh2 += _updateChannel2(&audio->ch2);
129 if (audio->nextCh2 < audio->nextEvent) {
130 audio->nextEvent = audio->nextCh2;
131 }
132 }
133
134 if (audio->ch2.control.stop) {
135 audio->ch2.control.endTime -= audio->eventDiff;
136 if (audio->ch2.control.endTime <= 0) {
137 audio->playingCh2 = 0;
138 }
139 }
140 }
141
142 if (audio->playingCh3) {
143 audio->nextCh3 -= audio->eventDiff;
144 if (audio->nextCh3 <= 0) {
145 audio->nextCh3 += _updateChannel3(&audio->ch3);
146 if (audio->nextCh3 < audio->nextEvent) {
147 audio->nextEvent = audio->nextCh3;
148 }
149 }
150
151 if (audio->ch3.control.stop) {
152 audio->ch3.control.endTime -= audio->eventDiff;
153 if (audio->ch3.control.endTime <= 0) {
154 audio->playingCh3 = 0;
155 }
156 }
157 }
158
159 if (audio->playingCh4 && !audio->ch4.envelope.dead) {
160 audio->nextCh4 -= audio->eventDiff;
161 if (audio->ch4.envelope.nextStep != INT_MAX) {
162 audio->ch4.envelope.nextStep -= audio->eventDiff;
163 if (audio->ch4.envelope.nextStep <= 0) {
164 int8_t sample = (audio->ch4.sample >> 31) * 0x8;
165 _updateEnvelope(&audio->ch4.envelope);
166 if (audio->ch4.envelope.nextStep < audio->nextEvent) {
167 audio->nextEvent = audio->ch4.envelope.nextStep;
168 }
169 audio->ch4.sample = sample * audio->ch4.envelope.currentVolume;
170 }
171 }
172
173 if (audio->nextCh4 <= 0) {
174 audio->nextCh4 += _updateChannel4(&audio->ch4);
175 if (audio->nextCh4 < audio->nextEvent) {
176 audio->nextEvent = audio->nextCh4;
177 }
178 }
179
180 if (audio->ch4.control.stop) {
181 audio->ch4.control.endTime -= audio->eventDiff;
182 if (audio->ch4.control.endTime <= 0) {
183 audio->playingCh4 = 0;
184 }
185 }
186 }
187 }
188
189 audio->nextSample -= audio->eventDiff;
190 if (audio->nextSample <= 0) {
191 _sample(audio);
192 audio->nextSample += audio->sampleInterval;
193 }
194
195 if (audio->nextSample < audio->nextEvent) {
196 audio->nextEvent = audio->nextSample;
197 }
198 audio->eventDiff = 0;
199 }
200 return audio->nextEvent;
201}
202
203void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
204 switch (info->dest) {
205 case BASE_IO | REG_FIFO_A_LO:
206 audio->chA.dmaSource = number;
207 break;
208 case BASE_IO | REG_FIFO_B_LO:
209 audio->chB.dmaSource = number;
210 break;
211 default:
212 GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
213 return;
214 }
215 info->dstControl = DMA_FIXED;
216}
217
218void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
219 audio->ch1.sweep.packed = value;
220 if (audio->ch1.sweep.time) {
221 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
222 } else {
223 audio->ch1.nextSweep = INT_MAX;
224 }
225}
226
227void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
228 audio->ch1.envelope.packed = value;
229 audio->ch1.envelope.dead = 0;
230 if (audio->ch1.envelope.stepTime) {
231 audio->ch1.envelope.nextStep = 0;
232 } else {
233 audio->ch1.envelope.nextStep = INT_MAX;
234 if (audio->ch1.envelope.initialVolume == 0) {
235 audio->ch1.envelope.dead = 1;
236 audio->ch1.sample = 0;
237 }
238 }
239}
240
241void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
242 audio->ch1.control.packed = value;
243 audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8;
244 if (audio->ch1.control.restart) {
245 if (audio->ch1.sweep.time) {
246 audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
247 } else {
248 audio->ch1.nextSweep = INT_MAX;
249 }
250 if (!audio->playingCh1) {
251 audio->nextCh1 = 0;
252 }
253 audio->playingCh1 = 1;
254 if (audio->ch1.envelope.stepTime) {
255 audio->ch1.envelope.nextStep = 0;
256 } else {
257 audio->ch1.envelope.nextStep = INT_MAX;
258 }
259 audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume;
260 if (audio->ch1.envelope.stepTime) {
261 audio->ch1.envelope.nextStep = 0;
262 } else {
263 audio->ch1.envelope.nextStep = INT_MAX;
264 }
265 }
266}
267
268void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
269 audio->ch2.envelope.packed = value;
270 audio->ch2.envelope.dead = 0;
271 if (audio->ch2.envelope.stepTime) {
272 audio->ch2.envelope.nextStep = 0;
273 } else {
274 audio->ch2.envelope.nextStep = INT_MAX;
275 if (audio->ch2.envelope.initialVolume == 0) {
276 audio->ch2.envelope.dead = 1;
277 audio->ch2.sample = 0;
278 }
279 }
280}
281
282void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
283 audio->ch2.control.packed = value;
284 audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch2.envelope.length)) >> 8;
285 if (audio->ch2.control.restart) {
286 audio->playingCh2 = 1;
287 audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume;
288 if (audio->ch2.envelope.stepTime) {
289 audio->ch2.envelope.nextStep = 0;
290 } else {
291 audio->ch2.envelope.nextStep = INT_MAX;
292 }
293 audio->nextCh2 = 0;
294 }
295}
296
297void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
298 audio->ch3.bank.packed = value;
299 if (audio->ch3.control.endTime >= 0) {
300 audio->playingCh3 = audio->ch3.bank.enable;
301 }
302}
303
304void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
305 audio->ch3.wave.packed = value;
306}
307
308void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
309 audio->ch3.control.packed = value;
310 audio->ch3.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (256 - audio->ch3.wave.length)) >> 8;
311 if (audio->ch3.control.restart) {
312 audio->playingCh3 = audio->ch3.bank.enable;
313 }
314}
315
316void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
317 audio->ch4.envelope.packed = value;
318 audio->ch4.envelope.dead = 0;
319 if (audio->ch4.envelope.stepTime) {
320 audio->ch4.envelope.nextStep = 0;
321 } else {
322 audio->ch4.envelope.nextStep = INT_MAX;
323 if (audio->ch4.envelope.initialVolume == 0) {
324 audio->ch4.envelope.dead = 1;
325 audio->ch4.sample = 0;
326 }
327 }
328}
329
330void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
331 audio->ch4.control.packed = value;
332 audio->ch4.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch4.envelope.length)) >> 8;
333 if (audio->ch4.control.restart) {
334 audio->playingCh4 = 1;
335 audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume;
336 if (audio->ch4.envelope.stepTime) {
337 audio->ch4.envelope.nextStep = 0;
338 } else {
339 audio->ch4.envelope.nextStep = INT_MAX;
340 }
341 if (audio->ch4.control.power) {
342 audio->ch4.lfsr = 0x40;
343 } else {
344 audio->ch4.lfsr = 0x4000;
345 }
346 audio->nextCh4 = 0;
347 }
348}
349
350void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
351 audio->soundcntLo = value;
352}
353
354void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
355 audio->soundcntHi = value;
356}
357
358void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
359 audio->soundcntX = (value & 0x80) | (audio->soundcntX & 0x0F);
360}
361
362void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
363 audio->soundbias = value;
364}
365
366void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
367 audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value;
368}
369
370void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
371 struct CircleBuffer* fifo;
372 switch (address) {
373 case REG_FIFO_A_LO:
374 fifo = &audio->chA.fifo;
375 break;
376 case REG_FIFO_B_LO:
377 fifo = &audio->chB.fifo;
378 break;
379 default:
380 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
381 return;
382 }
383 while (!CircleBufferWrite32(fifo, value)) {
384 int32_t dummy;
385 CircleBufferRead32(fifo, &dummy);
386 }
387}
388
389void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
390 struct GBAAudioFIFO* channel;
391 if (fifoId == 0) {
392 channel = &audio->chA;
393 } else if (fifoId == 1) {
394 channel = &audio->chB;
395 } else {
396 GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
397 return;
398 }
399 if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t)) {
400 struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
401 dma->nextCount = 4;
402 dma->nextEvent = 0;
403 GBAMemoryUpdateDMAs(&audio->p->memory, -cycles);
404 }
405 CircleBufferRead8(&channel->fifo, &channel->sample);
406}
407
408unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples) {
409 GBASyncLockAudio(audio->p->sync);
410 unsigned read = 0;
411 if (left) {
412 unsigned readL = CircleBufferRead(&audio->left, left, nSamples * sizeof(int32_t)) >> 2;
413 if (readL < nSamples) {
414 memset((int32_t*) left + readL, 0, nSamples - readL);
415 }
416 read = readL;
417 }
418 if (right) {
419 unsigned readR = CircleBufferRead(&audio->right, right, nSamples * sizeof(int32_t)) >> 2;
420 if (readR < nSamples) {
421 memset((int32_t*) right + readR, 0, nSamples - readR);
422 }
423 read = read >= readR ? read : readR;
424 }
425 GBASyncConsumeAudio(audio->p->sync);
426 return read;
427}
428
429unsigned GBAAudioResampleNN(struct GBAAudio* audio, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples) {
430 int32_t left[GBA_AUDIO_SAMPLES];
431 int32_t right[GBA_AUDIO_SAMPLES];
432
433 // toRead is in GBA samples
434 // TODO: Do this with fixed-point math
435 unsigned toRead = ceilf(nSamples / ratio);
436 unsigned totalRead = 0;
437 while (nSamples) {
438 unsigned currentRead = GBA_AUDIO_SAMPLES;
439 if (currentRead > toRead) {
440 currentRead = toRead;
441 }
442 unsigned read = GBAAudioCopy(audio, left, right, currentRead);
443 toRead -= read;
444 unsigned i;
445 for (i = 0; i < read; ++i) {
446 *drift += ratio;
447 while (*drift >= 1.f) {
448 output->left = left[i];
449 output->right = right[i];
450 ++output;
451 ++totalRead;
452 --nSamples;
453 *drift -= 1.f;
454 if (!nSamples) {
455 return totalRead;
456 }
457 }
458 }
459 if (read < currentRead) {
460 memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
461 break;
462 }
463 }
464 return totalRead;
465}
466
467static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
468 control->hi = !control->hi;
469 int period = 16 * (2048 - control->frequency);
470 switch (duty) {
471 case 0:
472 return control->hi ? period : period * 7;
473 case 1:
474 return control->hi ? period * 2 : period * 6;
475 case 2:
476 return period * 4;
477 case 3:
478 return control->hi ? period * 6 : period * 2;
479 default:
480 // This should never be hit
481 return period * 4;
482 }
483}
484
485static void _updateEnvelope(struct GBAAudioEnvelope* envelope) {
486 if (envelope->direction) {
487 ++envelope->currentVolume;
488 } else {
489 --envelope->currentVolume;
490 }
491 if (envelope->currentVolume >= 15) {
492 envelope->currentVolume = 15;
493 envelope->nextStep = INT_MAX;
494 } else if (envelope->currentVolume <= 0) {
495 envelope->currentVolume = 0;
496 envelope->dead = 1;
497 envelope->nextStep = INT_MAX;
498 } else {
499 envelope->nextStep += envelope->stepTime * (GBA_ARM7TDMI_FREQUENCY >> 6);
500 }
501}
502
503static int _updateSweep(struct GBAAudioChannel1* ch) {
504 if (ch->sweep.direction) {
505 int frequency = ch->control.frequency;
506 frequency -= frequency >> ch->sweep.shift;
507 if (frequency >= 0) {
508 ch->control.frequency = frequency;
509 }
510 } else {
511 int frequency = ch->control.frequency;
512 frequency += frequency >> ch->sweep.shift;
513 if (frequency < 2048) {
514 ch->control.frequency = frequency;
515 } else {
516 return 0;
517 }
518 }
519 ch->nextSweep += ch->sweep.time * SWEEP_CYCLES;
520 return 1;
521}
522
523static int32_t _updateChannel1(struct GBAAudioChannel1* ch) {
524 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
525 ch->sample = ch->control.hi * 0x10 - 0x8;
526 ch->sample *= ch->envelope.currentVolume;
527 return timing;
528}
529
530static int32_t _updateChannel2(struct GBAAudioChannel2* ch) {
531 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
532 ch->sample = ch->control.hi * 0x10 - 0x8;
533 ch->sample *= ch->envelope.currentVolume;
534 return timing;
535}
536
537static int32_t _updateChannel3(struct GBAAudioChannel3* ch) {
538 int i;
539 int start;
540 int end;
541 int volume;
542 switch (ch->wave.volume) {
543 case 0:
544 volume = 0;
545 break;
546 case 1:
547 volume = 4;
548 break;
549 case 2:
550 volume = 2;
551 break;
552 case 3:
553 volume = 1;
554 break;
555 default:
556 volume = 3;
557 break;
558 }
559 if (ch->bank.size) {
560 start = 7;
561 end = 0;
562 } else if (ch->bank.bank) {
563 start = 7;
564 end = 4;
565 } else {
566 start = 3;
567 end = 0;
568 }
569 uint32_t bitsCarry = ch->wavedata[end] & 0xF0000000;
570 uint32_t bits;
571 for (i = start; i >= end; --i) {
572 bits = ch->wavedata[i] & 0xF0000000;
573 ch->wavedata[i] <<= 4;
574 ch->wavedata[i] |= bitsCarry >> 28;
575 bitsCarry = bits;
576 }
577 ch->sample = ((bitsCarry >> 26) - 0x20) * volume;
578 return 8 * (2048 - ch->control.rate);
579}
580
581static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
582 int lsb = ch->lfsr & 1;
583 ch->sample = lsb * 0x10 - 0x8;
584 ch->sample *= ch->envelope.currentVolume;
585 ch->lfsr >>= 1;
586 ch->lfsr ^= (lsb * 0x60) << (ch->control.power ? 0 : 8);
587 int timing = ch->control.ratio ? 2 * ch->control.ratio : 1;
588 timing <<= ch->control.frequency;
589 timing *= 32;
590 return timing;
591}
592
593static int _applyBias(struct GBAAudio* audio, int sample) {
594 sample += audio->bias;
595 if (sample >= 0x400) {
596 sample = 0x3FF;
597 } else if (sample < 0) {
598 sample = 0;
599 }
600 return (sample - audio->bias) << 6;
601}
602
603static void _sample(struct GBAAudio* audio) {
604 int32_t sampleLeft = 0;
605 int32_t sampleRight = 0;
606 int psgShift = 6 - audio->volume;
607
608 if (audio->ch1Left) {
609 sampleLeft += audio->ch1.sample;
610 }
611
612 if (audio->ch1Right) {
613 sampleRight += audio->ch1.sample;
614 }
615
616 if (audio->ch2Left) {
617 sampleLeft += audio->ch2.sample;
618 }
619
620 if (audio->ch2Right) {
621 sampleRight += audio->ch2.sample;
622 }
623
624 if (audio->ch3Left) {
625 sampleLeft += audio->ch3.sample;
626 }
627
628 if (audio->ch3Right) {
629 sampleRight += audio->ch3.sample;
630 }
631
632 if (audio->ch4Left) {
633 sampleLeft += audio->ch4.sample;
634 }
635
636 if (audio->ch4Right) {
637 sampleRight += audio->ch4.sample;
638 }
639
640 sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift;
641 sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift;
642
643 if (audio->chALeft) {
644 sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
645 }
646
647 if (audio->chARight) {
648 sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
649 }
650
651 if (audio->chBLeft) {
652 sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
653 }
654
655 if (audio->chBRight) {
656 sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
657 }
658
659 sampleLeft = _applyBias(audio, sampleLeft);
660 sampleRight = _applyBias(audio, sampleRight);
661
662 GBASyncLockAudio(audio->p->sync);
663 CircleBufferWrite32(&audio->left, sampleLeft);
664 CircleBufferWrite32(&audio->right, sampleRight);
665 unsigned produced = CircleBufferSize(&audio->left);
666 GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3);
667}
668
669void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
670 state->audio.ch1Volume = audio->ch1.envelope.currentVolume;
671 state->audio.ch1Dead = audio->ch1.envelope.dead;
672 state->audio.ch1Hi = audio->ch1.control.hi;
673 state->audio.ch1.envelopeNextStep = audio->ch1.envelope.nextStep;
674 state->audio.ch1.waveNextStep = audio->ch1.control.nextStep;
675 state->audio.ch1.sweepNextStep = audio->ch1.nextSweep;
676 state->audio.ch1.endTime = audio->ch1.control.endTime;
677 state->audio.ch1.nextEvent = audio->nextCh1;
678
679 state->audio.ch2Volume = audio->ch2.envelope.currentVolume;
680 state->audio.ch2Dead = audio->ch2.envelope.dead;
681 state->audio.ch2Hi = audio->ch2.control.hi;
682 state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep;
683 state->audio.ch2.waveNextStep = audio->ch2.control.nextStep;
684 state->audio.ch2.endTime = audio->ch2.control.endTime;
685 state->audio.ch2.nextEvent = audio->nextCh2;
686
687 memcpy(state->audio.ch3.wavebanks, audio->ch3.wavedata, sizeof(state->audio.ch3.wavebanks));
688 state->audio.ch3.endTime = audio->ch3.control.endTime;
689 state->audio.ch3.nextEvent = audio->nextCh3;
690
691 state->audio.ch4Volume = audio->ch4.envelope.currentVolume;
692 state->audio.ch4Dead = audio->ch4.envelope.dead;
693 state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep;
694 state->audio.ch4.lfsr = audio->ch4.lfsr;
695 state->audio.ch4.endTime = audio->ch4.control.endTime;
696 state->audio.ch4.nextEvent = audio->nextCh4;
697
698 state->audio.nextEvent = audio->nextEvent;
699 state->audio.eventDiff = audio->eventDiff;
700 state->audio.nextSample = audio->nextSample;
701}
702
703void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
704 audio->ch1.envelope.currentVolume = state->audio.ch1Volume;
705 audio->ch1.envelope.dead = state->audio.ch1Dead;
706 audio->ch1.control.hi = state->audio.ch1Hi;
707 audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep;
708 audio->ch1.control.nextStep = state->audio.ch1.waveNextStep;
709 audio->ch1.nextSweep = state->audio.ch1.sweepNextStep;
710 audio->ch1.control.endTime = state->audio.ch1.endTime;
711 audio->nextCh1 = state->audio.ch1.nextEvent;
712
713 audio->ch2.envelope.currentVolume = state->audio.ch2Volume;
714 audio->ch2.envelope.dead = state->audio.ch2Dead;
715 audio->ch2.control.hi = state->audio.ch2Hi;
716 audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep;
717 audio->ch2.control.nextStep = state->audio.ch2.waveNextStep;
718 audio->ch2.control.endTime = state->audio.ch2.endTime;
719 audio->nextCh2 = state->audio.ch2.nextEvent;
720
721 memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata));
722 audio->ch3.control.endTime = state->audio.ch3.endTime;
723 audio->nextCh3 = state->audio.ch3.nextEvent;
724
725 audio->ch4.envelope.currentVolume = state->audio.ch4Volume;
726 audio->ch4.envelope.dead = state->audio.ch4Dead;
727 audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep;
728 audio->ch4.lfsr = state->audio.ch4.lfsr;
729 audio->ch4.control.endTime = state->audio.ch4.endTime;
730 audio->nextCh4 = state->audio.ch4.nextEvent;
731
732 audio->nextEvent = state->audio.nextEvent;
733 audio->eventDiff = state->audio.eventDiff;
734 audio->nextSample = state->audio.nextSample;
735}