src/gb/audio.c (view raw)
1/* Copyright (c) 2013-2016 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 "core/sync.h"
9#include "gb/gb.h"
10#include "gb/io.h"
11
12#define FRAME_CYCLES (DMG_LR35902_FREQUENCY >> 9)
13
14const uint32_t DMG_LR35902_FREQUENCY = 0x400000;
15static const int CLOCKS_PER_BLIP_FRAME = 0x1000;
16static const unsigned BLIP_BUFFER_SIZE = 0x4000;
17const int GB_AUDIO_VOLUME_MAX = 0x100;
18
19static void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value);
20static bool _writeSweep(struct GBAudioEnvelope* envelope, uint8_t value);
21static int32_t _updateSquareChannel(struct GBAudioSquareControl* envelope, int duty);
22static void _updateEnvelope(struct GBAudioEnvelope* envelope);
23static bool _updateSweep(struct GBAudioChannel1* ch, bool initial);
24static int32_t _updateChannel1(struct GBAudioChannel1* ch);
25static int32_t _updateChannel2(struct GBAudioChannel2* ch);
26static int32_t _updateChannel3(struct GBAudioChannel3* ch, enum GBAudioStyle style);
27static int32_t _updateChannel4(struct GBAudioChannel4* ch);
28static void _sample(struct GBAudio* audio, int32_t cycles);
29
30void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style) {
31 audio->samples = samples;
32 audio->left = blip_new(BLIP_BUFFER_SIZE);
33 audio->right = blip_new(BLIP_BUFFER_SIZE);
34 audio->clockRate = DMG_LR35902_FREQUENCY;
35 // Guess too large; we hang producing extra samples if we guess too low
36 blip_set_rates(audio->left, DMG_LR35902_FREQUENCY, 96000);
37 blip_set_rates(audio->right, DMG_LR35902_FREQUENCY, 96000);
38 audio->forceDisableCh[0] = false;
39 audio->forceDisableCh[1] = false;
40 audio->forceDisableCh[2] = false;
41 audio->forceDisableCh[3] = false;
42 audio->masterVolume = GB_AUDIO_VOLUME_MAX;
43 audio->nr52 = nr52;
44 audio->style = style;
45}
46
47void GBAudioDeinit(struct GBAudio* audio) {
48 blip_delete(audio->left);
49 blip_delete(audio->right);
50}
51
52void GBAudioReset(struct GBAudio* audio) {
53 audio->nextEvent = 0;
54 audio->nextCh1 = 0;
55 audio->nextCh2 = 0;
56 audio->nextCh3 = 0;
57 audio->nextCh4 = 0;
58 audio->ch1 = (struct GBAudioChannel1) { .envelope = { .dead = 2 } };
59 audio->ch2 = (struct GBAudioChannel2) { .envelope = { .dead = 2 } };
60 audio->ch3 = (struct GBAudioChannel3) { .bank = 0 };
61 audio->ch4 = (struct GBAudioChannel4) { .envelope = { .dead = 2 } };
62 audio->eventDiff = 0;
63 audio->nextFrame = 0;
64 audio->frame = 0;
65 audio->nextSample = 0;
66 audio->sampleInterval = 128;
67 audio->volumeRight = 0;
68 audio->volumeLeft = 0;
69 audio->ch1Right = false;
70 audio->ch2Right = false;
71 audio->ch3Right = false;
72 audio->ch4Right = false;
73 audio->ch1Left = false;
74 audio->ch2Left = false;
75 audio->ch3Left = false;
76 audio->ch4Left = false;
77 audio->playingCh1 = false;
78 audio->playingCh2 = false;
79 audio->playingCh3 = false;
80 audio->playingCh4 = false;
81}
82
83void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples) {
84 mCoreSyncLockAudio(audio->p->sync);
85 audio->samples = samples;
86 blip_clear(audio->left);
87 blip_clear(audio->right);
88 audio->clock = 0;
89 mCoreSyncConsumeAudio(audio->p->sync);
90}
91
92void GBAudioWriteNR10(struct GBAudio* audio, uint8_t value) {
93 audio->ch1.shift = GBAudioRegisterSquareSweepGetShift(value);
94 bool oldDirection = audio->ch1.direction;
95 audio->ch1.direction = GBAudioRegisterSquareSweepGetDirection(value);
96 if (audio->ch1.sweepOccurred && oldDirection && !audio->ch1.direction) {
97 audio->playingCh1 = false;
98 *audio->nr52 &= ~0x0001;
99 }
100 audio->ch1.sweepOccurred = false;
101 audio->ch1.time = GBAudioRegisterSquareSweepGetTime(value);
102 if (!audio->ch1.time) {
103 audio->ch1.time = 8;
104 }
105}
106
107void GBAudioWriteNR11(struct GBAudio* audio, uint8_t value) {
108 _writeDuty(&audio->ch1.envelope, value);
109 audio->ch1.control.length = 64 - audio->ch1.envelope.length;
110}
111
112void GBAudioWriteNR12(struct GBAudio* audio, uint8_t value) {
113 if (!_writeSweep(&audio->ch1.envelope, value)) {
114 audio->playingCh1 = false;
115 *audio->nr52 &= ~0x0001;
116 }
117}
118
119void GBAudioWriteNR13(struct GBAudio* audio, uint8_t value) {
120 audio->ch1.realFrequency &= 0x700;
121 audio->ch1.realFrequency |= GBAudioRegisterControlGetFrequency(value);
122}
123
124void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) {
125 audio->ch1.realFrequency &= 0xFF;
126 audio->ch1.realFrequency |= GBAudioRegisterControlGetFrequency(value << 8);
127 bool wasStop = audio->ch1.control.stop;
128 audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8);
129 if (!wasStop && audio->ch1.control.stop && audio->ch1.control.length && !(audio->frame & 1)) {
130 --audio->ch1.control.length;
131 if (audio->ch1.control.length == 0) {
132 audio->playingCh1 = false;
133 }
134 }
135 if (GBAudioRegisterControlIsRestart(value << 8)) {
136 if (audio->nextEvent == INT_MAX) {
137 audio->eventDiff = 0;
138 }
139 if (!audio->playingCh1) {
140 audio->nextCh1 = audio->eventDiff;
141 }
142 audio->playingCh1 = audio->ch1.envelope.initialVolume || audio->ch1.envelope.direction;
143 audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume;
144 if (audio->ch1.envelope.currentVolume > 0 && audio->ch1.envelope.stepTime) {
145 audio->ch1.envelope.dead = 0;
146 }
147 audio->ch1.control.frequency = audio->ch1.realFrequency;
148 audio->ch1.sweepStep = audio->ch1.time;
149 audio->ch1.sweepEnable = (audio->ch1.sweepStep != 8) || audio->ch1.shift;
150 audio->ch1.sweepOccurred = false;
151 if (audio->playingCh1 && audio->ch1.shift) {
152 audio->playingCh1 = _updateSweep(&audio->ch1, true);
153 }
154 if (!audio->ch1.control.length) {
155 audio->ch1.control.length = 64;
156 if (audio->ch1.control.stop && !(audio->frame & 1)) {
157 --audio->ch1.control.length;
158 }
159 }
160 // TODO: Don't need p
161 if (audio->p) {
162 audio->nextEvent = audio->p->cpu->cycles;
163 audio->p->cpu->nextEvent = audio->nextEvent;
164 } else {
165 audio->nextEvent = 0;
166 }
167 }
168 *audio->nr52 &= ~0x0001;
169 *audio->nr52 |= audio->playingCh1;
170}
171
172void GBAudioWriteNR21(struct GBAudio* audio, uint8_t value) {
173 _writeDuty(&audio->ch2.envelope, value);
174 audio->ch2.control.length = 64 - audio->ch2.envelope.length;
175}
176
177void GBAudioWriteNR22(struct GBAudio* audio, uint8_t value) {
178 if (!_writeSweep(&audio->ch2.envelope, value)) {
179 audio->playingCh2 = false;
180 *audio->nr52 &= ~0x0002;
181 }
182}
183
184void GBAudioWriteNR23(struct GBAudio* audio, uint8_t value) {
185 audio->ch2.control.frequency &= 0x700;
186 audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value);
187}
188
189void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) {
190 audio->ch2.control.frequency &= 0xFF;
191 audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8);
192 bool wasStop = audio->ch2.control.stop;
193 audio->ch2.control.stop = GBAudioRegisterControlGetStop(value << 8);
194 if (!wasStop && audio->ch2.control.stop && audio->ch2.control.length && !(audio->frame & 1)) {
195 --audio->ch2.control.length;
196 if (audio->ch2.control.length == 0) {
197 audio->playingCh2 = false;
198 }
199 }
200 if (GBAudioRegisterControlIsRestart(value << 8)) {
201 audio->playingCh2 = audio->ch2.envelope.initialVolume || audio->ch2.envelope.direction;
202 audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume;
203 if (audio->ch2.envelope.currentVolume > 0 && audio->ch2.envelope.stepTime) {
204 audio->ch2.envelope.dead = 0;
205 }
206 if (audio->nextEvent == INT_MAX) {
207 audio->eventDiff = 0;
208 }
209 if (!audio->playingCh2) {
210 audio->nextCh2 = audio->eventDiff;
211 }
212 if (!audio->ch2.control.length) {
213 audio->ch2.control.length = 64;
214 if (audio->ch2.control.stop && !(audio->frame & 1)) {
215 --audio->ch2.control.length;
216 }
217 }
218 // TODO: Don't need p
219 if (audio->p) {
220 audio->nextEvent = audio->p->cpu->cycles;
221 audio->p->cpu->nextEvent = audio->nextEvent;
222 } else {
223 audio->nextEvent = 0;
224 }
225 }
226 *audio->nr52 &= ~0x0002;
227 *audio->nr52 |= audio->playingCh2 << 1;
228}
229
230void GBAudioWriteNR30(struct GBAudio* audio, uint8_t value) {
231 audio->ch3.enable = GBAudioRegisterBankGetEnable(value);
232 if (!audio->ch3.enable) {
233 audio->playingCh3 = false;
234 *audio->nr52 &= ~0x0004;
235 }
236}
237
238void GBAudioWriteNR31(struct GBAudio* audio, uint8_t value) {
239 audio->ch3.length = 256 - value;
240}
241
242void GBAudioWriteNR32(struct GBAudio* audio, uint8_t value) {
243 audio->ch3.volume = GBAudioRegisterBankVolumeGetVolumeGB(value);
244}
245
246void GBAudioWriteNR33(struct GBAudio* audio, uint8_t value) {
247 audio->ch3.rate &= 0x700;
248 audio->ch3.rate |= GBAudioRegisterControlGetRate(value);
249}
250
251void GBAudioWriteNR34(struct GBAudio* audio, uint8_t value) {
252 audio->ch3.rate &= 0xFF;
253 audio->ch3.rate |= GBAudioRegisterControlGetRate(value << 8);
254 bool wasStop = audio->ch3.stop;
255 audio->ch3.stop = GBAudioRegisterControlGetStop(value << 8);
256 if (!wasStop && audio->ch3.stop && audio->ch3.length && !(audio->frame & 1)) {
257 --audio->ch3.length;
258 if (audio->ch3.length == 0) {
259 audio->playingCh3 = false;
260 }
261 }
262 bool wasEnable = audio->playingCh3;
263 if (GBAudioRegisterControlIsRestart(value << 8)) {
264 audio->playingCh3 = audio->ch3.enable;
265 if (!audio->ch3.length) {
266 audio->ch3.length = 256;
267 if (audio->ch3.stop && !(audio->frame & 1)) {
268 --audio->ch3.length;
269 }
270 }
271
272 if (audio->style == GB_AUDIO_DMG && wasEnable && audio->playingCh3 && audio->ch3.readable) {
273 if (audio->ch3.window < 8) {
274 audio->ch3.wavedata8[0] = audio->ch3.wavedata8[audio->ch3.window >> 1];
275 } else {
276 audio->ch3.wavedata8[0] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3)];
277 audio->ch3.wavedata8[1] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 1];
278 audio->ch3.wavedata8[2] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 2];
279 audio->ch3.wavedata8[3] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 3];
280 }
281 }
282 audio->ch3.window = 0;
283 }
284 if (audio->playingCh3) {
285 if (audio->nextEvent == INT_MAX) {
286 audio->eventDiff = 0;
287 }
288 // TODO: Where does this cycle delay come from?
289 audio->ch3.readable = false;
290 // TODO: Don't need p
291 if (audio->p) {
292 audio->nextCh3 = audio->eventDiff + audio->p->cpu->cycles + 4 + 2 * (2048 - audio->ch3.rate);
293 audio->nextEvent = audio->p->cpu->cycles;
294 audio->p->cpu->nextEvent = audio->nextEvent;
295 } else {
296 audio->nextCh3 = audio->eventDiff + 4 + 2 * (2048 - audio->ch3.rate);
297 audio->nextEvent = 0;
298 }
299 }
300 *audio->nr52 &= ~0x0004;
301 *audio->nr52 |= audio->playingCh3 << 2;
302}
303
304void GBAudioWriteNR41(struct GBAudio* audio, uint8_t value) {
305 _writeDuty(&audio->ch4.envelope, value);
306 audio->ch4.length = 64 - audio->ch4.envelope.length;
307}
308
309void GBAudioWriteNR42(struct GBAudio* audio, uint8_t value) {
310 if (!_writeSweep(&audio->ch4.envelope, value)) {
311 audio->playingCh4 = false;
312 *audio->nr52 &= ~0x0008;
313 }
314}
315
316void GBAudioWriteNR43(struct GBAudio* audio, uint8_t value) {
317 audio->ch4.ratio = GBAudioRegisterNoiseFeedbackGetRatio(value);
318 audio->ch4.frequency = GBAudioRegisterNoiseFeedbackGetFrequency(value);
319 audio->ch4.power = GBAudioRegisterNoiseFeedbackGetPower(value);
320}
321
322void GBAudioWriteNR44(struct GBAudio* audio, uint8_t value) {
323 bool wasStop = audio->ch4.stop;
324 audio->ch4.stop = GBAudioRegisterNoiseControlGetStop(value);
325 if (!wasStop && audio->ch4.stop && audio->ch4.length && !(audio->frame & 1)) {
326 --audio->ch4.length;
327 if (audio->ch4.length == 0) {
328 audio->playingCh4 = false;
329 }
330 }
331 if (GBAudioRegisterNoiseControlIsRestart(value)) {
332 audio->playingCh4 = audio->ch4.envelope.initialVolume || audio->ch4.envelope.direction;
333 audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume;
334 if (audio->ch4.envelope.currentVolume > 0 && audio->ch4.envelope.stepTime) {
335 audio->ch4.envelope.dead = 0;
336 }
337 if (audio->ch4.power) {
338 audio->ch4.lfsr = 0x40;
339 } else {
340 audio->ch4.lfsr = 0x4000;
341 }
342 if (audio->nextEvent == INT_MAX) {
343 audio->eventDiff = 0;
344 }
345 if (!audio->playingCh4) {
346 audio->nextCh4 = audio->eventDiff;
347 }
348 if (!audio->ch4.length) {
349 audio->ch4.length = 64;
350 if (audio->ch4.stop && !(audio->frame & 1)) {
351 --audio->ch4.length;
352 }
353 }
354 // TODO: Don't need p
355 if (audio->p) {
356 audio->nextEvent = audio->p->cpu->cycles;
357 audio->p->cpu->nextEvent = audio->nextEvent;
358 } else {
359 audio->nextEvent = 0;
360 }
361 }
362 *audio->nr52 &= ~0x0008;
363 *audio->nr52 |= audio->playingCh4 << 3;
364}
365
366void GBAudioWriteNR50(struct GBAudio* audio, uint8_t value) {
367 audio->volumeRight = GBRegisterNR50GetVolumeRight(value);
368 audio->volumeLeft = GBRegisterNR50GetVolumeLeft(value);
369}
370
371void GBAudioWriteNR51(struct GBAudio* audio, uint8_t value) {
372 audio->ch1Right = GBRegisterNR51GetCh1Right(value);
373 audio->ch2Right = GBRegisterNR51GetCh2Right(value);
374 audio->ch3Right = GBRegisterNR51GetCh3Right(value);
375 audio->ch4Right = GBRegisterNR51GetCh4Right(value);
376 audio->ch1Left = GBRegisterNR51GetCh1Left(value);
377 audio->ch2Left = GBRegisterNR51GetCh2Left(value);
378 audio->ch3Left = GBRegisterNR51GetCh3Left(value);
379 audio->ch4Left = GBRegisterNR51GetCh4Left(value);
380}
381
382void GBAudioWriteNR52(struct GBAudio* audio, uint8_t value) {
383 bool wasEnable = audio->enable;
384 audio->enable = GBAudioEnableGetEnable(value);
385 if (!audio->enable) {
386 audio->playingCh1 = 0;
387 audio->playingCh2 = 0;
388 audio->playingCh3 = 0;
389 audio->playingCh4 = 0;
390 GBAudioWriteNR10(audio, 0);
391 GBAudioWriteNR11(audio, 0);
392 GBAudioWriteNR12(audio, 0);
393 GBAudioWriteNR13(audio, 0);
394 GBAudioWriteNR14(audio, 0);
395 GBAudioWriteNR21(audio, 0);
396 GBAudioWriteNR22(audio, 0);
397 GBAudioWriteNR23(audio, 0);
398 GBAudioWriteNR24(audio, 0);
399 GBAudioWriteNR30(audio, 0);
400 GBAudioWriteNR31(audio, 0);
401 GBAudioWriteNR32(audio, 0);
402 GBAudioWriteNR33(audio, 0);
403 GBAudioWriteNR34(audio, 0);
404 // Don't write to NR41
405 GBAudioWriteNR42(audio, 0);
406 GBAudioWriteNR43(audio, 0);
407 GBAudioWriteNR44(audio, 0);
408 GBAudioWriteNR50(audio, 0);
409 GBAudioWriteNR51(audio, 0);
410 if (audio->p) {
411 audio->p->memory.io[REG_NR10] = 0;
412 audio->p->memory.io[REG_NR11] = 0;
413 audio->p->memory.io[REG_NR12] = 0;
414 audio->p->memory.io[REG_NR13] = 0;
415 audio->p->memory.io[REG_NR14] = 0;
416 audio->p->memory.io[REG_NR21] = 0;
417 audio->p->memory.io[REG_NR22] = 0;
418 audio->p->memory.io[REG_NR23] = 0;
419 audio->p->memory.io[REG_NR24] = 0;
420 audio->p->memory.io[REG_NR30] = 0;
421 audio->p->memory.io[REG_NR31] = 0;
422 audio->p->memory.io[REG_NR32] = 0;
423 audio->p->memory.io[REG_NR33] = 0;
424 audio->p->memory.io[REG_NR34] = 0;
425 audio->p->memory.io[REG_NR42] = 0;
426 audio->p->memory.io[REG_NR43] = 0;
427 audio->p->memory.io[REG_NR44] = 0;
428 audio->p->memory.io[REG_NR50] = 0;
429 audio->p->memory.io[REG_NR51] = 0;
430 }
431 *audio->nr52 &= ~0x000F;
432 } else if (!wasEnable) {
433 audio->frame = 7;
434 }
435}
436
437int32_t GBAudioProcessEvents(struct GBAudio* audio, int32_t cycles) {
438 if (audio->nextEvent == INT_MAX) {
439 return INT_MAX;
440 }
441 audio->nextEvent -= cycles;
442 audio->eventDiff += cycles;
443 while (audio->nextEvent <= 0) {
444 audio->nextEvent = INT_MAX;
445 if (audio->enable) {
446 audio->nextFrame -= audio->eventDiff;
447 int frame = -1;
448 if (audio->nextFrame <= 0) {
449 frame = (audio->frame + 1) & 7;
450 audio->frame = frame;
451 audio->nextFrame += FRAME_CYCLES;
452 if (audio->nextFrame < audio->nextEvent) {
453 audio->nextEvent = audio->nextFrame;
454 }
455 }
456
457 if (audio->playingCh1) {
458 audio->nextCh1 -= audio->eventDiff;
459 if (!audio->ch1.envelope.dead && frame == 7) {
460 --audio->ch1.envelope.nextStep;
461 if (audio->ch1.envelope.nextStep == 0) {
462 int8_t sample = audio->ch1.control.hi * 0x10 - 0x8;
463 _updateEnvelope(&audio->ch1.envelope);
464 audio->ch1.sample = sample * audio->ch1.envelope.currentVolume;
465 }
466 }
467
468 if (audio->ch1.sweepEnable && (frame & 3) == 2) {
469 --audio->ch1.sweepStep;
470 if (audio->ch1.sweepStep == 0) {
471 audio->playingCh1 = _updateSweep(&audio->ch1, false);
472 }
473 }
474
475 if (audio->ch1.envelope.dead != 2) {
476 if (audio->nextCh1 <= 0) {
477 audio->nextCh1 += _updateChannel1(&audio->ch1);
478 }
479 if (audio->nextCh1 < audio->nextEvent) {
480 audio->nextEvent = audio->nextCh1;
481 }
482 }
483 }
484
485 if (audio->ch1.control.length && audio->ch1.control.stop && !(frame & 1)) {
486 --audio->ch1.control.length;
487 if (audio->ch1.control.length == 0) {
488 audio->playingCh1 = 0;
489 }
490 }
491
492 if (audio->playingCh2) {
493 audio->nextCh2 -= audio->eventDiff;
494 if (!audio->ch2.envelope.dead && frame == 7) {
495 --audio->ch2.envelope.nextStep;
496 if (audio->ch2.envelope.nextStep == 0) {
497 int8_t sample = audio->ch2.control.hi * 0x10 - 0x8;
498 _updateEnvelope(&audio->ch2.envelope);
499 audio->ch2.sample = sample * audio->ch2.envelope.currentVolume;
500 }
501 }
502
503 if (audio->ch2.envelope.dead != 2) {
504 if (audio->nextCh2 <= 0) {
505 audio->nextCh2 += _updateChannel2(&audio->ch2);
506 }
507 if (audio->nextCh2 < audio->nextEvent) {
508 audio->nextEvent = audio->nextCh2;
509 }
510 }
511 }
512
513 if (audio->ch2.control.length && audio->ch2.control.stop && !(frame & 1)) {
514 --audio->ch2.control.length;
515 if (audio->ch2.control.length == 0) {
516 audio->playingCh2 = 0;
517 }
518 }
519
520 if (audio->playingCh3) {
521 audio->nextCh3 -= audio->eventDiff;
522 audio->fadeCh3 -= audio->eventDiff;
523 if (audio->fadeCh3 <= 0) {
524 audio->ch3.readable = false;
525 audio->fadeCh3 = INT_MAX;
526 }
527 if (audio->nextCh3 <= 0) {
528 audio->fadeCh3 = audio->nextCh3 + 2;
529 audio->nextCh3 += _updateChannel3(&audio->ch3, audio->style);
530 audio->ch3.readable = true;
531 }
532 if (audio->fadeCh3 < audio->nextEvent) {
533 audio->nextEvent = audio->fadeCh3;
534 }
535 if (audio->nextCh3 < audio->nextEvent) {
536 audio->nextEvent = audio->nextCh3;
537 }
538 }
539
540 if (audio->ch3.length && audio->ch3.stop && !(frame & 1)) {
541 --audio->ch3.length;
542 if (audio->ch3.length == 0) {
543 audio->playingCh3 = 0;
544 }
545 }
546
547 if (audio->playingCh4) {
548 audio->nextCh4 -= audio->eventDiff;
549 if (!audio->ch4.envelope.dead && frame == 7) {
550 --audio->ch4.envelope.nextStep;
551 if (audio->ch4.envelope.nextStep == 0) {
552 int8_t sample = (audio->ch4.sample >> 31) * 0x8;
553 _updateEnvelope(&audio->ch4.envelope);
554 audio->ch4.sample = sample * audio->ch4.envelope.currentVolume;
555 }
556 }
557
558 if (audio->ch4.envelope.dead != 2) {
559 if (audio->nextCh4 <= 0) {
560 int32_t timing = _updateChannel4(&audio->ch4);
561 if (audio->nextCh4 < -timing) {
562 int32_t bound = timing * 16;
563 // Perform negative modulo to cap to 16 iterations
564 audio->nextCh4 = bound - (audio->nextCh4 - 1) % bound - 1;
565 }
566 audio->nextCh4 += timing;
567 }
568 if (audio->nextCh4 < audio->nextEvent) {
569 audio->nextEvent = audio->nextCh4;
570 }
571 }
572 }
573
574 if (audio->ch4.length && audio->ch4.stop && !(frame & 1)) {
575 --audio->ch4.length;
576 if (audio->ch4.length == 0) {
577 audio->playingCh4 = 0;
578 }
579 }
580 }
581
582 *audio->nr52 &= ~0x000F;
583 *audio->nr52 |= audio->playingCh1;
584 *audio->nr52 |= audio->playingCh2 << 1;
585 *audio->nr52 |= audio->playingCh3 << 2;
586 *audio->nr52 |= audio->playingCh4 << 3;
587
588 if (audio->p) {
589 audio->nextSample -= audio->eventDiff;
590 if (audio->nextSample <= 0) {
591 _sample(audio, audio->sampleInterval);
592 audio->nextSample += audio->sampleInterval;
593 }
594
595 if (audio->nextSample < audio->nextEvent) {
596 audio->nextEvent = audio->nextSample;
597 }
598 }
599 audio->eventDiff = 0;
600 }
601 return audio->nextEvent;
602}
603
604void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) {
605 int sampleLeft = 0;
606 int sampleRight = 0;
607
608 if (audio->playingCh1 && !audio->forceDisableCh[0]) {
609 if (audio->ch1Left) {
610 sampleLeft += audio->ch1.sample;
611 }
612
613 if (audio->ch1Right) {
614 sampleRight += audio->ch1.sample;
615 }
616 }
617
618 if (audio->playingCh2 && !audio->forceDisableCh[1]) {
619 if (audio->ch2Left) {
620 sampleLeft += audio->ch2.sample;
621 }
622
623 if (audio->ch2Right) {
624 sampleRight += audio->ch2.sample;
625 }
626 }
627
628 if (audio->playingCh3 && !audio->forceDisableCh[2]) {
629 if (audio->ch3Left) {
630 sampleLeft += audio->ch3.sample;
631 }
632
633 if (audio->ch3Right) {
634 sampleRight += audio->ch3.sample;
635 }
636 }
637
638 if (audio->playingCh4 && !audio->forceDisableCh[3]) {
639 if (audio->ch4Left) {
640 sampleLeft += audio->ch4.sample;
641 }
642
643 if (audio->ch4Right) {
644 sampleRight += audio->ch4.sample;
645 }
646 }
647
648 *left = sampleLeft * (1 + audio->volumeLeft);
649 *right = sampleRight * (1 + audio->volumeRight);
650}
651
652void _sample(struct GBAudio* audio, int32_t cycles) {
653 int16_t sampleLeft = 0;
654 int16_t sampleRight = 0;
655 GBAudioSamplePSG(audio, &sampleLeft, &sampleRight);
656 sampleLeft = (sampleLeft * audio->masterVolume) >> 6;
657 sampleRight = (sampleRight * audio->masterVolume) >> 6;
658
659 mCoreSyncLockAudio(audio->p->sync);
660 unsigned produced;
661 if ((size_t) blip_samples_avail(audio->left) < audio->samples) {
662 blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft);
663 blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight);
664 audio->lastLeft = sampleLeft;
665 audio->lastRight = sampleRight;
666 audio->clock += cycles;
667 if (audio->clock >= CLOCKS_PER_BLIP_FRAME) {
668 blip_end_frame(audio->left, audio->clock);
669 blip_end_frame(audio->right, audio->clock);
670 audio->clock -= CLOCKS_PER_BLIP_FRAME;
671 }
672 }
673 produced = blip_samples_avail(audio->left);
674 bool wait = produced >= audio->samples;
675 mCoreSyncProduceAudio(audio->p->sync, wait);
676 // TODO: Put AVStream back
677}
678
679void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value) {
680 envelope->length = GBAudioRegisterDutyGetLength(value);
681 envelope->duty = GBAudioRegisterDutyGetDuty(value);
682}
683
684bool _writeSweep(struct GBAudioEnvelope* envelope, uint8_t value) {
685 envelope->stepTime = GBAudioRegisterSweepGetStepTime(value);
686 envelope->direction = GBAudioRegisterSweepGetDirection(value);
687 envelope->initialVolume = GBAudioRegisterSweepGetInitialVolume(value);
688 if (envelope->stepTime == 0) {
689 envelope->dead = envelope->currentVolume ? 1 : 2;
690 } else if (!envelope->direction && !envelope->currentVolume) {
691 envelope->dead = 2;
692 } else if (envelope->direction && envelope->currentVolume == 0xF) {
693 envelope->dead = 1;
694 } else {
695 envelope->dead = 0;
696 }
697 envelope->nextStep = envelope->stepTime;
698 return envelope->initialVolume || envelope->direction;
699}
700
701static int32_t _updateSquareChannel(struct GBAudioSquareControl* control, int duty) {
702 control->hi = !control->hi;
703 int period = 4 * (2048 - control->frequency);
704 switch (duty) {
705 case 0:
706 return control->hi ? period : period * 7;
707 case 1:
708 return control->hi ? period * 2 : period * 6;
709 case 2:
710 return period * 4;
711 case 3:
712 return control->hi ? period * 6 : period * 2;
713 default:
714 // This should never be hit
715 return period * 4;
716 }
717}
718
719static void _updateEnvelope(struct GBAudioEnvelope* envelope) {
720 if (envelope->direction) {
721 ++envelope->currentVolume;
722 } else {
723 --envelope->currentVolume;
724 }
725 if (envelope->currentVolume >= 15) {
726 envelope->currentVolume = 15;
727 envelope->dead = 1;
728 } else if (envelope->currentVolume <= 0) {
729 envelope->currentVolume = 0;
730 envelope->dead = 2;
731 } else {
732 envelope->nextStep = envelope->stepTime;
733 }
734}
735
736static bool _updateSweep(struct GBAudioChannel1* ch, bool initial) {
737 if (initial || ch->time != 8) {
738 int frequency = ch->control.frequency;
739 if (ch->direction) {
740 frequency -= frequency >> ch->shift;
741 if (!initial && frequency >= 0) {
742 ch->control.frequency = frequency;
743 ch->realFrequency = frequency;
744 }
745 } else {
746 frequency += frequency >> ch->shift;
747 if (frequency < 2048) {
748 if (!initial && ch->shift) {
749 ch->control.frequency = frequency;
750 if (!_updateSweep(ch, true)) {
751 return false;
752 }
753 ch->realFrequency = frequency;
754 }
755 } else {
756 return false;
757 }
758 }
759 ch->sweepOccurred = true;
760 }
761 ch->sweepStep = ch->time;
762 return true;
763}
764
765static int32_t _updateChannel1(struct GBAudioChannel1* ch) {
766 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
767 ch->sample = ch->control.hi * 0x10 - 0x8;
768 ch->sample *= ch->envelope.currentVolume;
769 return timing;
770}
771
772static int32_t _updateChannel2(struct GBAudioChannel2* ch) {
773 int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
774 ch->sample = ch->control.hi * 0x10 - 0x8;
775 ch->sample *= ch->envelope.currentVolume;
776 return timing;
777}
778
779static int32_t _updateChannel3(struct GBAudioChannel3* ch, enum GBAudioStyle style) {
780 int i;
781 int volume;
782 switch (ch->volume) {
783 case 0:
784 volume = 0;
785 break;
786 case 1:
787 volume = 4;
788 break;
789 case 2:
790 volume = 2;
791 break;
792 case 3:
793 volume = 1;
794 break;
795 default:
796 volume = 3;
797 break;
798 }
799 switch (style) {
800 int start;
801 int end;
802 case GB_AUDIO_DMG:
803 default:
804 ++ch->window;
805 ch->window &= 0x1F;
806 ch->sample = ch->wavedata8[ch->window >> 1];
807 if (ch->window & 1) {
808 ch->sample &= 0xF;
809 } else {
810 ch->sample >>= 4;
811 }
812 break;
813 case GB_AUDIO_GBA:
814 if (ch->size) {
815 start = 7;
816 end = 0;
817 } else if (ch->bank) {
818 start = 7;
819 end = 4;
820 } else {
821 start = 3;
822 end = 0;
823 }
824 uint32_t bitsCarry = ch->wavedata32[end] & 0x000000F0;
825 uint32_t bits;
826 for (i = start; i >= end; --i) {
827 bits = ch->wavedata32[i] & 0x000000F0;
828 ch->wavedata32[i] = ((ch->wavedata32[i] & 0x0F0F0F0F) << 4) | ((ch->wavedata32[i] & 0xF0F0F000) >> 12);
829 ch->wavedata32[i] |= bitsCarry << 20;
830 bitsCarry = bits;
831 }
832 ch->sample = bitsCarry >> 4;
833 break;
834 }
835 ch->sample -= 8;
836 ch->sample *= volume * 4;
837 return 2 * (2048 - ch->rate);
838}
839
840static int32_t _updateChannel4(struct GBAudioChannel4* ch) {
841 int lsb = ch->lfsr & 1;
842 ch->sample = lsb * 0x10 - 0x8;
843 ch->sample *= ch->envelope.currentVolume;
844 ch->lfsr >>= 1;
845 ch->lfsr ^= (lsb * 0x60) << (ch->power ? 0 : 8);
846 int timing = ch->ratio ? 2 * ch->ratio : 1;
847 timing <<= ch->frequency;
848 timing *= 8;
849 return timing;
850}