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