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