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 <mgba/internal/gb/audio.h>
7
8#include <mgba/core/blip_buf.h>
9#include <mgba/core/interface.h>
10#include <mgba/core/sync.h>
11#include <mgba/internal/gb/gb.h>
12#include <mgba/internal/gb/serialize.h>
13#include <mgba/internal/gb/io.h>
14
15#ifdef _3DS
16#define blip_add_delta blip_add_delta_fast
17#endif
18
19#define FRAME_CYCLES (DMG_SM83_FREQUENCY >> 9)
20
21const uint32_t DMG_SM83_FREQUENCY = 0x400000;
22static const int CLOCKS_PER_BLIP_FRAME = 0x1000;
23static const unsigned BLIP_BUFFER_SIZE = 0x4000;
24const int GB_AUDIO_VOLUME_MAX = 0x100;
25
26static bool _writeSweep(struct GBAudioSweep* sweep, uint8_t value);
27static void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value);
28static bool _writeEnvelope(struct GBAudioEnvelope* envelope, uint8_t value, enum GBAudioStyle style);
29
30static void _resetSweep(struct GBAudioSweep* sweep);
31static bool _resetEnvelope(struct GBAudioEnvelope* sweep);
32
33static void _updateEnvelope(struct GBAudioEnvelope* envelope);
34static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope);
35static bool _updateSweep(struct GBAudioSquareChannel* sweep, bool initial);
36
37static void _updateSquareSample(struct GBAudioSquareChannel* ch);
38static int32_t _updateSquareChannel(struct GBAudioSquareChannel* ch);
39
40static int16_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch);
41
42static void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate);
43static void _updateChannel1(struct mTiming* timing, void* user, uint32_t cyclesLate);
44static void _updateChannel2(struct mTiming* timing, void* user, uint32_t cyclesLate);
45static void _updateChannel3(struct mTiming* timing, void* user, uint32_t cyclesLate);
46static void _fadeChannel3(struct mTiming* timing, void* user, uint32_t cyclesLate);
47static void _updateChannel4(struct mTiming* timing, void* user, uint32_t cyclesLate);
48static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate);
49
50void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style) {
51 audio->samples = samples;
52 audio->left = blip_new(BLIP_BUFFER_SIZE);
53 audio->right = blip_new(BLIP_BUFFER_SIZE);
54 audio->clockRate = DMG_SM83_FREQUENCY;
55 // Guess too large; we hang producing extra samples if we guess too low
56 blip_set_rates(audio->left, DMG_SM83_FREQUENCY, 96000);
57 blip_set_rates(audio->right, DMG_SM83_FREQUENCY, 96000);
58 audio->forceDisableCh[0] = false;
59 audio->forceDisableCh[1] = false;
60 audio->forceDisableCh[2] = false;
61 audio->forceDisableCh[3] = false;
62 audio->masterVolume = GB_AUDIO_VOLUME_MAX;
63 audio->nr52 = nr52;
64 audio->style = style;
65 if (style == GB_AUDIO_GBA) {
66 audio->timingFactor = 4;
67 } else {
68 audio->timingFactor = 2;
69 }
70
71 audio->frameEvent.context = audio;
72 audio->frameEvent.name = "GB Audio Frame Sequencer";
73 audio->frameEvent.callback = _updateFrame;
74 audio->frameEvent.priority = 0x10;
75 audio->ch1Event.context = audio;
76 audio->ch1Event.name = "GB Audio Channel 1";
77 audio->ch1Event.callback = _updateChannel1;
78 audio->ch1Event.priority = 0x11;
79 audio->ch2Event.context = audio;
80 audio->ch2Event.name = "GB Audio Channel 2";
81 audio->ch2Event.callback = _updateChannel2;
82 audio->ch2Event.priority = 0x12;
83 audio->ch3Event.context = audio;
84 audio->ch3Event.name = "GB Audio Channel 3";
85 audio->ch3Event.callback = _updateChannel3;
86 audio->ch3Event.priority = 0x13;
87 audio->ch3Fade.context = audio;
88 audio->ch3Fade.name = "GB Audio Channel 3 Memory";
89 audio->ch3Fade.callback = _fadeChannel3;
90 audio->ch3Fade.priority = 0x14;
91 audio->ch4Event.context = audio;
92 audio->ch4Event.name = "GB Audio Channel 4";
93 audio->ch4Event.callback = _updateChannel4;
94 audio->ch4Event.priority = 0x15;
95 audio->sampleEvent.context = audio;
96 audio->sampleEvent.name = "GB Audio Sample";
97 audio->sampleEvent.callback = _sample;
98 audio->sampleEvent.priority = 0x18;
99}
100
101void GBAudioDeinit(struct GBAudio* audio) {
102 blip_delete(audio->left);
103 blip_delete(audio->right);
104}
105
106void GBAudioReset(struct GBAudio* audio) {
107 mTimingDeschedule(audio->timing, &audio->frameEvent);
108 mTimingDeschedule(audio->timing, &audio->ch1Event);
109 mTimingDeschedule(audio->timing, &audio->ch2Event);
110 mTimingDeschedule(audio->timing, &audio->ch3Event);
111 mTimingDeschedule(audio->timing, &audio->ch3Fade);
112 mTimingDeschedule(audio->timing, &audio->ch4Event);
113 mTimingDeschedule(audio->timing, &audio->sampleEvent);
114 if (audio->style != GB_AUDIO_GBA) {
115 mTimingSchedule(audio->timing, &audio->sampleEvent, 0);
116 }
117 if (audio->style == GB_AUDIO_GBA) {
118 mTimingSchedule(audio->timing, &audio->frameEvent, 0);
119 }
120 audio->ch1 = (struct GBAudioSquareChannel) { .sweep = { .time = 8 }, .envelope = { .dead = 2 } };
121 audio->ch2 = (struct GBAudioSquareChannel) { .envelope = { .dead = 2 } };
122 audio->ch3 = (struct GBAudioWaveChannel) { .bank = 0 };
123 audio->ch4 = (struct GBAudioNoiseChannel) { .nSamples = 0 };
124 // TODO: DMG randomness
125 audio->ch3.wavedata8[0] = 0x00;
126 audio->ch3.wavedata8[1] = 0xFF;
127 audio->ch3.wavedata8[2] = 0x00;
128 audio->ch3.wavedata8[3] = 0xFF;
129 audio->ch3.wavedata8[4] = 0x00;
130 audio->ch3.wavedata8[5] = 0xFF;
131 audio->ch3.wavedata8[6] = 0x00;
132 audio->ch3.wavedata8[7] = 0xFF;
133 audio->ch3.wavedata8[8] = 0x00;
134 audio->ch3.wavedata8[9] = 0xFF;
135 audio->ch3.wavedata8[10] = 0x00;
136 audio->ch3.wavedata8[11] = 0xFF;
137 audio->ch3.wavedata8[12] = 0x00;
138 audio->ch3.wavedata8[13] = 0xFF;
139 audio->ch3.wavedata8[14] = 0x00;
140 audio->ch3.wavedata8[15] = 0xFF;
141 audio->ch4 = (struct GBAudioNoiseChannel) { .envelope = { .dead = 2 } };
142 audio->frame = 0;
143 audio->sampleInterval = 128;
144 audio->lastLeft = 0;
145 audio->lastRight = 0;
146 audio->capLeft = 0;
147 audio->capRight = 0;
148 audio->clock = 0;
149 audio->playingCh1 = false;
150 audio->playingCh2 = false;
151 audio->playingCh3 = false;
152 audio->playingCh4 = false;
153 if (audio->p && !(audio->p->model & GB_MODEL_SGB)) {
154 audio->playingCh1 = true;
155 audio->enable = true;
156 *audio->nr52 |= 0x01;
157 }
158}
159
160void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples) {
161 mCoreSyncLockAudio(audio->p->sync);
162 audio->samples = samples;
163 blip_clear(audio->left);
164 blip_clear(audio->right);
165 audio->clock = 0;
166 mCoreSyncConsumeAudio(audio->p->sync);
167}
168
169void GBAudioWriteNR10(struct GBAudio* audio, uint8_t value) {
170 if (!_writeSweep(&audio->ch1.sweep, value)) {
171 mTimingDeschedule(audio->timing, &audio->ch1Event);
172 audio->playingCh1 = false;
173 *audio->nr52 &= ~0x0001;
174 }
175}
176
177void GBAudioWriteNR11(struct GBAudio* audio, uint8_t value) {
178 _writeDuty(&audio->ch1.envelope, value);
179 audio->ch1.control.length = 64 - audio->ch1.envelope.length;
180}
181
182void GBAudioWriteNR12(struct GBAudio* audio, uint8_t value) {
183 if (!_writeEnvelope(&audio->ch1.envelope, value, audio->style)) {
184 mTimingDeschedule(audio->timing, &audio->ch1Event);
185 audio->playingCh1 = false;
186 *audio->nr52 &= ~0x0001;
187 }
188}
189
190void GBAudioWriteNR13(struct GBAudio* audio, uint8_t value) {
191 audio->ch1.control.frequency &= 0x700;
192 audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value);
193}
194
195void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) {
196 audio->ch1.control.frequency &= 0xFF;
197 audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8);
198 bool wasStop = audio->ch1.control.stop;
199 audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8);
200 if (!wasStop && audio->ch1.control.stop && audio->ch1.control.length && !(audio->frame & 1)) {
201 --audio->ch1.control.length;
202 if (audio->ch1.control.length == 0) {
203 mTimingDeschedule(audio->timing, &audio->ch1Event);
204 audio->playingCh1 = false;
205 }
206 }
207 if (GBAudioRegisterControlIsRestart(value << 8)) {
208 audio->playingCh1 = _resetEnvelope(&audio->ch1.envelope);
209 audio->ch1.sweep.realFrequency = audio->ch1.control.frequency;
210 _resetSweep(&audio->ch1.sweep);
211 if (audio->playingCh1 && audio->ch1.sweep.shift) {
212 audio->playingCh1 = _updateSweep(&audio->ch1, true);
213 }
214 if (!audio->ch1.control.length) {
215 audio->ch1.control.length = 64;
216 if (audio->ch1.control.stop && !(audio->frame & 1)) {
217 --audio->ch1.control.length;
218 }
219 }
220 if (audio->playingCh1 && audio->ch1.envelope.dead != 2) {
221 _updateSquareChannel(&audio->ch1);
222 mTimingDeschedule(audio->timing, &audio->ch1Event);
223 mTimingSchedule(audio->timing, &audio->ch1Event, 0);
224 }
225 }
226 *audio->nr52 &= ~0x0001;
227 *audio->nr52 |= audio->playingCh1;
228}
229
230void GBAudioWriteNR21(struct GBAudio* audio, uint8_t value) {
231 _writeDuty(&audio->ch2.envelope, value);
232 audio->ch2.control.length = 64 - audio->ch2.envelope.length;
233}
234
235void GBAudioWriteNR22(struct GBAudio* audio, uint8_t value) {
236 if (!_writeEnvelope(&audio->ch2.envelope, value, audio->style)) {
237 mTimingDeschedule(audio->timing, &audio->ch2Event);
238 audio->playingCh2 = false;
239 *audio->nr52 &= ~0x0002;
240 }
241}
242
243void GBAudioWriteNR23(struct GBAudio* audio, uint8_t value) {
244 audio->ch2.control.frequency &= 0x700;
245 audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value);
246}
247
248void GBAudioWriteNR24(struct GBAudio* audio, uint8_t value) {
249 audio->ch2.control.frequency &= 0xFF;
250 audio->ch2.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8);
251 bool wasStop = audio->ch2.control.stop;
252 audio->ch2.control.stop = GBAudioRegisterControlGetStop(value << 8);
253 if (!wasStop && audio->ch2.control.stop && audio->ch2.control.length && !(audio->frame & 1)) {
254 --audio->ch2.control.length;
255 if (audio->ch2.control.length == 0) {
256 mTimingDeschedule(audio->timing, &audio->ch2Event);
257 audio->playingCh2 = false;
258 }
259 }
260 if (GBAudioRegisterControlIsRestart(value << 8)) {
261 audio->playingCh2 = _resetEnvelope(&audio->ch2.envelope);
262
263 if (!audio->ch2.control.length) {
264 audio->ch2.control.length = 64;
265 if (audio->ch2.control.stop && !(audio->frame & 1)) {
266 --audio->ch2.control.length;
267 }
268 }
269 if (audio->playingCh2 && audio->ch2.envelope.dead != 2) {
270 _updateSquareChannel(&audio->ch2);
271 mTimingDeschedule(audio->timing, &audio->ch2Event);
272 mTimingSchedule(audio->timing, &audio->ch2Event, 0);
273 }
274 }
275 *audio->nr52 &= ~0x0002;
276 *audio->nr52 |= audio->playingCh2 << 1;
277}
278
279void GBAudioWriteNR30(struct GBAudio* audio, uint8_t value) {
280 audio->ch3.enable = GBAudioRegisterBankGetEnable(value);
281 if (!audio->ch3.enable) {
282 mTimingDeschedule(audio->timing, &audio->ch3Event);
283 audio->playingCh3 = false;
284 *audio->nr52 &= ~0x0004;
285 }
286}
287
288void GBAudioWriteNR31(struct GBAudio* audio, uint8_t value) {
289 audio->ch3.length = 256 - value;
290}
291
292void GBAudioWriteNR32(struct GBAudio* audio, uint8_t value) {
293 audio->ch3.volume = GBAudioRegisterBankVolumeGetVolumeGB(value);
294}
295
296void GBAudioWriteNR33(struct GBAudio* audio, uint8_t value) {
297 audio->ch3.rate &= 0x700;
298 audio->ch3.rate |= GBAudioRegisterControlGetRate(value);
299}
300
301void GBAudioWriteNR34(struct GBAudio* audio, uint8_t value) {
302 audio->ch3.rate &= 0xFF;
303 audio->ch3.rate |= GBAudioRegisterControlGetRate(value << 8);
304 bool wasStop = audio->ch3.stop;
305 audio->ch3.stop = GBAudioRegisterControlGetStop(value << 8);
306 if (!wasStop && audio->ch3.stop && audio->ch3.length && !(audio->frame & 1)) {
307 --audio->ch3.length;
308 if (audio->ch3.length == 0) {
309 audio->playingCh3 = false;
310 }
311 }
312 bool wasEnable = audio->playingCh3;
313 if (GBAudioRegisterControlIsRestart(value << 8)) {
314 audio->playingCh3 = audio->ch3.enable;
315 if (!audio->ch3.length) {
316 audio->ch3.length = 256;
317 if (audio->ch3.stop && !(audio->frame & 1)) {
318 --audio->ch3.length;
319 }
320 }
321
322 if (audio->style == GB_AUDIO_DMG && wasEnable && audio->playingCh3 && audio->ch3.readable) {
323 if (audio->ch3.window < 8) {
324 audio->ch3.wavedata8[0] = audio->ch3.wavedata8[audio->ch3.window >> 1];
325 } else {
326 audio->ch3.wavedata8[0] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3)];
327 audio->ch3.wavedata8[1] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 1];
328 audio->ch3.wavedata8[2] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 2];
329 audio->ch3.wavedata8[3] = audio->ch3.wavedata8[((audio->ch3.window >> 1) & ~3) + 3];
330 }
331 }
332 audio->ch3.window = 0;
333 if (audio->style == GB_AUDIO_DMG) {
334 audio->ch3.sample = 0;
335 }
336 }
337 mTimingDeschedule(audio->timing, &audio->ch3Fade);
338 mTimingDeschedule(audio->timing, &audio->ch3Event);
339 if (audio->playingCh3) {
340 audio->ch3.readable = audio->style != GB_AUDIO_DMG;
341 // TODO: Where does this cycle delay come from?
342 mTimingSchedule(audio->timing, &audio->ch3Event, audio->timingFactor * (4 + 2 * (2048 - audio->ch3.rate)));
343 }
344 *audio->nr52 &= ~0x0004;
345 *audio->nr52 |= audio->playingCh3 << 2;
346}
347
348void GBAudioWriteNR41(struct GBAudio* audio, uint8_t value) {
349 _writeDuty(&audio->ch4.envelope, value);
350 audio->ch4.length = 64 - audio->ch4.envelope.length;
351}
352
353void GBAudioWriteNR42(struct GBAudio* audio, uint8_t value) {
354 if (!_writeEnvelope(&audio->ch4.envelope, value, audio->style)) {
355 mTimingDeschedule(audio->timing, &audio->ch4Event);
356 audio->playingCh4 = false;
357 *audio->nr52 &= ~0x0008;
358 }
359}
360
361void GBAudioWriteNR43(struct GBAudio* audio, uint8_t value) {
362 // TODO: Reschedule event
363 audio->ch4.ratio = GBAudioRegisterNoiseFeedbackGetRatio(value);
364 audio->ch4.frequency = GBAudioRegisterNoiseFeedbackGetFrequency(value);
365 audio->ch4.power = GBAudioRegisterNoiseFeedbackGetPower(value);
366}
367
368void GBAudioWriteNR44(struct GBAudio* audio, uint8_t value) {
369 bool wasStop = audio->ch4.stop;
370 audio->ch4.stop = GBAudioRegisterNoiseControlGetStop(value);
371 if (!wasStop && audio->ch4.stop && audio->ch4.length && !(audio->frame & 1)) {
372 --audio->ch4.length;
373 if (audio->ch4.length == 0) {
374 mTimingDeschedule(audio->timing, &audio->ch4Event);
375 audio->playingCh4 = false;
376 }
377 }
378 if (GBAudioRegisterNoiseControlIsRestart(value)) {
379 audio->playingCh4 = _resetEnvelope(&audio->ch4.envelope);
380
381 if (audio->ch4.power) {
382 audio->ch4.lfsr = 0x7F;
383 } else {
384 audio->ch4.lfsr = 0x7FFF;
385 }
386 if (!audio->ch4.length) {
387 audio->ch4.length = 64;
388 if (audio->ch4.stop && !(audio->frame & 1)) {
389 --audio->ch4.length;
390 }
391 }
392 if (audio->playingCh4 && audio->ch4.envelope.dead != 2) {
393 mTimingDeschedule(audio->timing, &audio->ch4Event);
394 mTimingSchedule(audio->timing, &audio->ch4Event, 0);
395 }
396 }
397 *audio->nr52 &= ~0x0008;
398 *audio->nr52 |= audio->playingCh4 << 3;
399}
400
401void GBAudioWriteNR50(struct GBAudio* audio, uint8_t value) {
402 audio->volumeRight = GBRegisterNR50GetVolumeRight(value);
403 audio->volumeLeft = GBRegisterNR50GetVolumeLeft(value);
404}
405
406void GBAudioWriteNR51(struct GBAudio* audio, uint8_t value) {
407 audio->ch1Right = GBRegisterNR51GetCh1Right(value);
408 audio->ch2Right = GBRegisterNR51GetCh2Right(value);
409 audio->ch3Right = GBRegisterNR51GetCh3Right(value);
410 audio->ch4Right = GBRegisterNR51GetCh4Right(value);
411 audio->ch1Left = GBRegisterNR51GetCh1Left(value);
412 audio->ch2Left = GBRegisterNR51GetCh2Left(value);
413 audio->ch3Left = GBRegisterNR51GetCh3Left(value);
414 audio->ch4Left = GBRegisterNR51GetCh4Left(value);
415}
416
417void GBAudioWriteNR52(struct GBAudio* audio, uint8_t value) {
418 bool wasEnable = audio->enable;
419 audio->enable = GBAudioEnableGetEnable(value);
420 if (!audio->enable) {
421 audio->playingCh1 = 0;
422 audio->playingCh2 = 0;
423 audio->playingCh3 = 0;
424 audio->playingCh4 = 0;
425 GBAudioWriteNR10(audio, 0);
426 GBAudioWriteNR12(audio, 0);
427 GBAudioWriteNR13(audio, 0);
428 GBAudioWriteNR14(audio, 0);
429 GBAudioWriteNR22(audio, 0);
430 GBAudioWriteNR23(audio, 0);
431 GBAudioWriteNR24(audio, 0);
432 GBAudioWriteNR30(audio, 0);
433 GBAudioWriteNR32(audio, 0);
434 GBAudioWriteNR33(audio, 0);
435 GBAudioWriteNR34(audio, 0);
436 GBAudioWriteNR42(audio, 0);
437 GBAudioWriteNR43(audio, 0);
438 GBAudioWriteNR44(audio, 0);
439 GBAudioWriteNR50(audio, 0);
440 GBAudioWriteNR51(audio, 0);
441 if (audio->style != GB_AUDIO_DMG) {
442 GBAudioWriteNR11(audio, 0);
443 GBAudioWriteNR21(audio, 0);
444 GBAudioWriteNR31(audio, 0);
445 GBAudioWriteNR41(audio, 0);
446 }
447
448 if (audio->p) {
449 audio->p->memory.io[GB_REG_NR10] = 0;
450 audio->p->memory.io[GB_REG_NR11] = 0;
451 audio->p->memory.io[GB_REG_NR12] = 0;
452 audio->p->memory.io[GB_REG_NR13] = 0;
453 audio->p->memory.io[GB_REG_NR14] = 0;
454 audio->p->memory.io[GB_REG_NR21] = 0;
455 audio->p->memory.io[GB_REG_NR22] = 0;
456 audio->p->memory.io[GB_REG_NR23] = 0;
457 audio->p->memory.io[GB_REG_NR24] = 0;
458 audio->p->memory.io[GB_REG_NR30] = 0;
459 audio->p->memory.io[GB_REG_NR31] = 0;
460 audio->p->memory.io[GB_REG_NR32] = 0;
461 audio->p->memory.io[GB_REG_NR33] = 0;
462 audio->p->memory.io[GB_REG_NR34] = 0;
463 audio->p->memory.io[GB_REG_NR42] = 0;
464 audio->p->memory.io[GB_REG_NR43] = 0;
465 audio->p->memory.io[GB_REG_NR44] = 0;
466 audio->p->memory.io[GB_REG_NR50] = 0;
467 audio->p->memory.io[GB_REG_NR51] = 0;
468 if (audio->style != GB_AUDIO_DMG) {
469 audio->p->memory.io[GB_REG_NR11] = 0;
470 audio->p->memory.io[GB_REG_NR21] = 0;
471 audio->p->memory.io[GB_REG_NR31] = 0;
472 audio->p->memory.io[GB_REG_NR41] = 0;
473 }
474 }
475 *audio->nr52 &= ~0x000F;
476 } else if (!wasEnable) {
477 audio->skipFrame = false;
478 audio->frame = 7;
479
480 if (audio->p && audio->p->timer.internalDiv & 0x400) {
481 audio->skipFrame = true;
482 }
483 }
484}
485
486void _updateFrame(struct mTiming* timing, void* user, uint32_t cyclesLate) {
487 struct GBAudio* audio = user;
488 GBAudioUpdateFrame(audio, timing);
489 if (audio->style == GB_AUDIO_GBA) {
490 mTimingSchedule(timing, &audio->frameEvent, audio->timingFactor * FRAME_CYCLES - cyclesLate);
491 }
492}
493
494void GBAudioUpdateFrame(struct GBAudio* audio, struct mTiming* timing) {
495 if (!audio->enable) {
496 return;
497 }
498 if (audio->skipFrame) {
499 audio->skipFrame = false;
500 return;
501 }
502 int frame = (audio->frame + 1) & 7;
503 audio->frame = frame;
504
505 switch (frame) {
506 case 2:
507 case 6:
508 if (audio->ch1.sweep.enable) {
509 --audio->ch1.sweep.step;
510 if (audio->ch1.sweep.step == 0) {
511 audio->playingCh1 = _updateSweep(&audio->ch1, false);
512 *audio->nr52 &= ~0x0001;
513 *audio->nr52 |= audio->playingCh1;
514 if (!audio->playingCh1) {
515 mTimingDeschedule(audio->timing, &audio->ch1Event);
516 }
517 }
518 }
519 // Fall through
520 case 0:
521 case 4:
522 if (audio->ch1.control.length && audio->ch1.control.stop) {
523 --audio->ch1.control.length;
524 if (audio->ch1.control.length == 0) {
525 mTimingDeschedule(timing, &audio->ch1Event);
526 audio->playingCh1 = 0;
527 *audio->nr52 &= ~0x0001;
528 }
529 }
530
531 if (audio->ch2.control.length && audio->ch2.control.stop) {
532 --audio->ch2.control.length;
533 if (audio->ch2.control.length == 0) {
534 mTimingDeschedule(timing, &audio->ch2Event);
535 audio->playingCh2 = 0;
536 *audio->nr52 &= ~0x0002;
537 }
538 }
539
540 if (audio->ch3.length && audio->ch3.stop) {
541 --audio->ch3.length;
542 if (audio->ch3.length == 0) {
543 mTimingDeschedule(timing, &audio->ch3Event);
544 audio->playingCh3 = 0;
545 *audio->nr52 &= ~0x0004;
546 }
547 }
548
549 if (audio->ch4.length && audio->ch4.stop) {
550 --audio->ch4.length;
551 if (audio->ch4.length == 0) {
552 mTimingDeschedule(timing, &audio->ch4Event);
553 audio->playingCh4 = 0;
554 *audio->nr52 &= ~0x0008;
555 }
556 }
557 break;
558 case 7:
559 if (audio->playingCh1 && !audio->ch1.envelope.dead) {
560 --audio->ch1.envelope.nextStep;
561 if (audio->ch1.envelope.nextStep == 0) {
562 _updateEnvelope(&audio->ch1.envelope);
563 if (audio->ch1.envelope.dead == 2) {
564 mTimingDeschedule(timing, &audio->ch1Event);
565 }
566 _updateSquareSample(&audio->ch1);
567 }
568 }
569
570 if (audio->playingCh2 && !audio->ch2.envelope.dead) {
571 --audio->ch2.envelope.nextStep;
572 if (audio->ch2.envelope.nextStep == 0) {
573 _updateEnvelope(&audio->ch2.envelope);
574 if (audio->ch2.envelope.dead == 2) {
575 mTimingDeschedule(timing, &audio->ch2Event);
576 }
577 _updateSquareSample(&audio->ch2);
578 }
579 }
580
581 if (audio->playingCh4 && !audio->ch4.envelope.dead) {
582 --audio->ch4.envelope.nextStep;
583 if (audio->ch4.envelope.nextStep == 0) {
584 int8_t sample = audio->ch4.sample > 0;
585 audio->ch4.samples -= audio->ch4.sample;
586 _updateEnvelope(&audio->ch4.envelope);
587 if (audio->ch4.envelope.dead == 2) {
588 mTimingDeschedule(timing, &audio->ch4Event);
589 }
590 audio->ch4.sample = sample * audio->ch4.envelope.currentVolume;
591 audio->ch4.samples += audio->ch4.sample;
592 }
593 }
594 break;
595 }
596}
597
598void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right) {
599 int dcOffset = audio->style == GB_AUDIO_GBA ? 0 : -0x8;
600 int sampleLeft = dcOffset;
601 int sampleRight = dcOffset;
602
603 if (!audio->forceDisableCh[0]) {
604 if (audio->ch1Left) {
605 sampleLeft += audio->ch1.sample;
606 }
607
608 if (audio->ch1Right) {
609 sampleRight += audio->ch1.sample;
610 }
611 }
612
613 if (!audio->forceDisableCh[1]) {
614 if (audio->ch2Left) {
615 sampleLeft += audio->ch2.sample;
616 }
617
618 if (audio->ch2Right) {
619 sampleRight += audio->ch2.sample;
620 }
621 }
622
623 if (!audio->forceDisableCh[2]) {
624 if (audio->ch3Left) {
625 sampleLeft += audio->ch3.sample;
626 }
627
628 if (audio->ch3Right) {
629 sampleRight += audio->ch3.sample;
630 }
631 }
632
633 sampleLeft <<= 3;
634 sampleRight <<= 3;
635
636 if (!audio->forceDisableCh[3]) {
637 int16_t sample = audio->style == GB_AUDIO_GBA ? (audio->ch4.sample << 3) : _coalesceNoiseChannel(&audio->ch4);
638 if (audio->ch4Left) {
639 sampleLeft += sample;
640 }
641
642 if (audio->ch4Right) {
643 sampleRight += sample;
644 }
645 }
646
647 *left = sampleLeft * (1 + audio->volumeLeft);
648 *right = sampleRight * (1 + audio->volumeRight);
649}
650
651static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) {
652 struct GBAudio* audio = user;
653 int16_t sampleLeft = 0;
654 int16_t sampleRight = 0;
655 GBAudioSamplePSG(audio, &sampleLeft, &sampleRight);
656 sampleLeft = (sampleLeft * audio->masterVolume * 6) >> 7;
657 sampleRight = (sampleRight * audio->masterVolume * 6) >> 7;
658
659 mCoreSyncLockAudio(audio->p->sync);
660 unsigned produced;
661
662 int16_t degradedLeft = sampleLeft - (audio->capLeft >> 16);
663 int16_t degradedRight = sampleRight - (audio->capRight >> 16);
664 audio->capLeft = (sampleLeft << 16) - degradedLeft * 65184;
665 audio->capRight = (sampleRight << 16) - degradedRight * 65184;
666 sampleLeft = degradedLeft;
667 sampleRight = degradedRight;
668
669 if ((size_t) blip_samples_avail(audio->left) < audio->samples) {
670 blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft);
671 blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight);
672 audio->lastLeft = sampleLeft;
673 audio->lastRight = sampleRight;
674 audio->clock += audio->sampleInterval;
675 if (audio->clock >= CLOCKS_PER_BLIP_FRAME) {
676 blip_end_frame(audio->left, CLOCKS_PER_BLIP_FRAME);
677 blip_end_frame(audio->right, CLOCKS_PER_BLIP_FRAME);
678 audio->clock -= CLOCKS_PER_BLIP_FRAME;
679 }
680 }
681 produced = blip_samples_avail(audio->left);
682 if (audio->p->stream && audio->p->stream->postAudioFrame) {
683 audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
684 }
685 bool wait = produced >= audio->samples;
686 if (!mCoreSyncProduceAudio(audio->p->sync, audio->left, audio->samples)) {
687 // Interrupted
688 audio->p->earlyExit = true;
689 }
690
691 if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
692 audio->p->stream->postAudioBuffer(audio->p->stream, audio->left, audio->right);
693 }
694 mTimingSchedule(timing, &audio->sampleEvent, audio->sampleInterval * audio->timingFactor - cyclesLate);
695}
696
697bool _resetEnvelope(struct GBAudioEnvelope* envelope) {
698 envelope->currentVolume = envelope->initialVolume;
699 _updateEnvelopeDead(envelope);
700 if (!envelope->dead) {
701 envelope->nextStep = envelope->stepTime;
702 }
703 return envelope->initialVolume || envelope->direction;
704}
705
706void _resetSweep(struct GBAudioSweep* sweep) {
707 sweep->step = sweep->time;
708 sweep->enable = (sweep->step != 8) || sweep->shift;
709 sweep->occurred = false;
710}
711
712bool _writeSweep(struct GBAudioSweep* sweep, uint8_t value) {
713 sweep->shift = GBAudioRegisterSquareSweepGetShift(value);
714 bool oldDirection = sweep->direction;
715 sweep->direction = GBAudioRegisterSquareSweepGetDirection(value);
716 bool on = true;
717 if (sweep->occurred && oldDirection && !sweep->direction) {
718 on = false;
719 }
720 sweep->occurred = false;
721 sweep->time = GBAudioRegisterSquareSweepGetTime(value);
722 if (!sweep->time) {
723 sweep->time = 8;
724 }
725 return on;
726}
727
728void _writeDuty(struct GBAudioEnvelope* envelope, uint8_t value) {
729 envelope->length = GBAudioRegisterDutyGetLength(value);
730 envelope->duty = GBAudioRegisterDutyGetDuty(value);
731}
732
733bool _writeEnvelope(struct GBAudioEnvelope* envelope, uint8_t value, enum GBAudioStyle style) {
734 envelope->stepTime = GBAudioRegisterSweepGetStepTime(value);
735 envelope->direction = GBAudioRegisterSweepGetDirection(value);
736 envelope->initialVolume = GBAudioRegisterSweepGetInitialVolume(value);
737 if (style == GB_AUDIO_DMG && !envelope->stepTime) {
738 // TODO: Improve "zombie" mode
739 ++envelope->currentVolume;
740 envelope->currentVolume &= 0xF;
741 }
742 _updateEnvelopeDead(envelope);
743 return (envelope->initialVolume || envelope->direction) && envelope->dead != 2;
744}
745
746static void _updateSquareSample(struct GBAudioSquareChannel* ch) {
747 ch->sample = ch->control.hi * ch->envelope.currentVolume;
748}
749
750static int32_t _updateSquareChannel(struct GBAudioSquareChannel* ch) {
751 ch->control.hi = !ch->control.hi;
752 _updateSquareSample(ch);
753 int period = 4 * (2048 - ch->control.frequency);
754 switch (ch->envelope.duty) {
755 case 0:
756 return ch->control.hi ? period : period * 7;
757 case 1:
758 return ch->control.hi ? period * 2 : period * 6;
759 case 2:
760 return period * 4;
761 case 3:
762 return ch->control.hi ? period * 6 : period * 2;
763 default:
764 // This should never be hit
765 return period * 4;
766 }
767}
768
769static int16_t _coalesceNoiseChannel(struct GBAudioNoiseChannel* ch) {
770 if (!ch->nSamples) {
771 return ch->sample << 3;
772 }
773 // TODO keep track of timing
774 int16_t sample = (ch->samples << 3) / ch->nSamples;
775 ch->nSamples = 0;
776 ch->samples = 0;
777 return sample;
778}
779
780static void _updateEnvelope(struct GBAudioEnvelope* envelope) {
781 if (envelope->direction) {
782 ++envelope->currentVolume;
783 } else {
784 --envelope->currentVolume;
785 }
786 if (envelope->currentVolume >= 15) {
787 envelope->currentVolume = 15;
788 envelope->dead = 1;
789 } else if (envelope->currentVolume <= 0) {
790 envelope->currentVolume = 0;
791 envelope->dead = 2;
792 } else {
793 envelope->nextStep = envelope->stepTime;
794 }
795}
796
797static void _updateEnvelopeDead(struct GBAudioEnvelope* envelope) {
798 if (!envelope->stepTime) {
799 envelope->dead = envelope->currentVolume ? 1 : 2;
800 } else if (!envelope->direction && !envelope->currentVolume) {
801 envelope->dead = 2;
802 } else if (envelope->direction && envelope->currentVolume == 0xF) {
803 envelope->dead = 1;
804 } else {
805 envelope->dead = 0;
806 }
807}
808
809static bool _updateSweep(struct GBAudioSquareChannel* ch, bool initial) {
810 if (initial || ch->sweep.time != 8) {
811 int frequency = ch->sweep.realFrequency;
812 if (ch->sweep.direction) {
813 frequency -= frequency >> ch->sweep.shift;
814 if (!initial && frequency >= 0) {
815 ch->control.frequency = frequency;
816 ch->sweep.realFrequency = frequency;
817 }
818 } else {
819 frequency += frequency >> ch->sweep.shift;
820 if (frequency < 2048) {
821 if (!initial && ch->sweep.shift) {
822 ch->control.frequency = frequency;
823 ch->sweep.realFrequency = frequency;
824 if (!_updateSweep(ch, true)) {
825 return false;
826 }
827 }
828 } else {
829 return false;
830 }
831 }
832 ch->sweep.occurred = true;
833 }
834 ch->sweep.step = ch->sweep.time;
835 return true;
836}
837
838static void _updateChannel1(struct mTiming* timing, void* user, uint32_t cyclesLate) {
839 struct GBAudio* audio = user;
840 struct GBAudioSquareChannel* ch = &audio->ch1;
841 int cycles = _updateSquareChannel(ch);
842 mTimingSchedule(timing, &audio->ch1Event, audio->timingFactor * cycles - cyclesLate);
843}
844
845static void _updateChannel2(struct mTiming* timing, void* user, uint32_t cyclesLate) {
846 struct GBAudio* audio = user;
847 struct GBAudioSquareChannel* ch = &audio->ch2;
848 int cycles = _updateSquareChannel(ch);
849 mTimingSchedule(timing, &audio->ch2Event, audio->timingFactor * cycles - cyclesLate);
850}
851
852static void _updateChannel3(struct mTiming* timing, void* user, uint32_t cyclesLate) {
853 struct GBAudio* audio = user;
854 struct GBAudioWaveChannel* ch = &audio->ch3;
855 int i;
856 int volume;
857 switch (ch->volume) {
858 case 0:
859 volume = 4;
860 break;
861 case 1:
862 volume = 0;
863 break;
864 case 2:
865 volume = 1;
866 break;
867 default:
868 case 3:
869 volume = 2;
870 break;
871 }
872 int start;
873 int end;
874 switch (audio->style) {
875 case GB_AUDIO_DMG:
876 default:
877 ++ch->window;
878 ch->window &= 0x1F;
879 ch->sample = ch->wavedata8[ch->window >> 1];
880 if (!(ch->window & 1)) {
881 ch->sample >>= 4;
882 }
883 ch->sample &= 0xF;
884 break;
885 case GB_AUDIO_GBA:
886 if (ch->size) {
887 start = 7;
888 end = 0;
889 } else if (ch->bank) {
890 start = 7;
891 end = 4;
892 } else {
893 start = 3;
894 end = 0;
895 }
896 uint32_t bitsCarry = ch->wavedata32[end] & 0x000000F0;
897 uint32_t bits;
898 for (i = start; i >= end; --i) {
899 bits = ch->wavedata32[i] & 0x000000F0;
900 ch->wavedata32[i] = ((ch->wavedata32[i] & 0x0F0F0F0F) << 4) | ((ch->wavedata32[i] & 0xF0F0F000) >> 12);
901 ch->wavedata32[i] |= bitsCarry << 20;
902 bitsCarry = bits;
903 }
904 ch->sample = bitsCarry >> 4;
905 break;
906 }
907 if (ch->volume > 3) {
908 ch->sample += ch->sample << 1;
909 }
910 ch->sample >>= volume;
911 audio->ch3.readable = true;
912 if (audio->style == GB_AUDIO_DMG) {
913 mTimingDeschedule(audio->timing, &audio->ch3Fade);
914 mTimingSchedule(timing, &audio->ch3Fade, 4 - cyclesLate);
915 }
916 int cycles = 2 * (2048 - ch->rate);
917 mTimingSchedule(timing, &audio->ch3Event, audio->timingFactor * cycles - cyclesLate);
918}
919static void _fadeChannel3(struct mTiming* timing, void* user, uint32_t cyclesLate) {
920 UNUSED(timing);
921 UNUSED(cyclesLate);
922 struct GBAudio* audio = user;
923 audio->ch3.readable = false;
924}
925
926static void _updateChannel4(struct mTiming* timing, void* user, uint32_t cyclesLate) {
927 struct GBAudio* audio = user;
928 struct GBAudioNoiseChannel* ch = &audio->ch4;
929
930 int32_t cycles = ch->ratio ? 2 * ch->ratio : 1;
931 cycles <<= ch->frequency;
932 cycles *= 8 * audio->timingFactor;
933
934 uint32_t last = 0;
935 uint32_t now = cycles;
936 int32_t next = cycles - cyclesLate;
937
938 if (audio->style == GB_AUDIO_GBA) {
939 last = ch->lastEvent;
940 now = mTimingCurrentTime(timing) - cyclesLate;
941 ch->lastEvent = now;
942 now -= last;
943 last = 0;
944 if (audio->sampleInterval > next) {
945 // TODO: Make batching work when descheduled
946 next = audio->sampleInterval;
947 }
948 }
949
950 for (; last < now; last += cycles) {
951 int lsb = ch->lfsr & 1;
952 ch->sample = lsb * ch->envelope.currentVolume;
953 ++ch->nSamples;
954 ch->samples += ch->sample;
955 ch->lfsr >>= 1;
956 ch->lfsr ^= (lsb * 0x60) << (ch->power ? 0 : 8);
957 }
958
959 mTimingSchedule(timing, &audio->ch4Event, next);
960}
961
962void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGState* state, uint32_t* flagsOut) {
963 uint32_t flags = 0;
964 uint32_t sweep = 0;
965 uint32_t ch1Flags = 0;
966 uint32_t ch2Flags = 0;
967 uint32_t ch4Flags = 0;
968
969 flags = GBSerializedAudioFlagsSetFrame(flags, audio->frame);
970 flags = GBSerializedAudioFlagsSetSkipFrame(flags, audio->skipFrame);
971 STORE_32LE(audio->frameEvent.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextFrame);
972
973 flags = GBSerializedAudioFlagsSetCh1Volume(flags, audio->ch1.envelope.currentVolume);
974 flags = GBSerializedAudioFlagsSetCh1Dead(flags, audio->ch1.envelope.dead);
975 flags = GBSerializedAudioFlagsSetCh1Hi(flags, audio->ch1.control.hi);
976 flags = GBSerializedAudioFlagsSetCh1SweepEnabled(flags, audio->ch1.sweep.enable);
977 flags = GBSerializedAudioFlagsSetCh1SweepOccurred(flags, audio->ch1.sweep.occurred);
978 ch1Flags = GBSerializedAudioEnvelopeSetLength(ch1Flags, audio->ch1.control.length);
979 ch1Flags = GBSerializedAudioEnvelopeSetNextStep(ch1Flags, audio->ch1.envelope.nextStep);
980 ch1Flags = GBSerializedAudioEnvelopeSetFrequency(ch1Flags, audio->ch1.sweep.realFrequency);
981 sweep = GBSerializedAudioSweepSetTime(sweep, audio->ch1.sweep.time & 7);
982 STORE_32LE(ch1Flags, 0, &state->ch1.envelope);
983 STORE_32LE(sweep, 0, &state->ch1.sweep);
984 STORE_32LE(audio->ch1Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextEvent);
985
986 flags = GBSerializedAudioFlagsSetCh2Volume(flags, audio->ch2.envelope.currentVolume);
987 flags = GBSerializedAudioFlagsSetCh2Dead(flags, audio->ch2.envelope.dead);
988 flags = GBSerializedAudioFlagsSetCh2Hi(flags, audio->ch2.control.hi);
989 ch2Flags = GBSerializedAudioEnvelopeSetLength(ch2Flags, audio->ch2.control.length);
990 ch2Flags = GBSerializedAudioEnvelopeSetNextStep(ch2Flags, audio->ch2.envelope.nextStep);
991 STORE_32LE(ch2Flags, 0, &state->ch2.envelope);
992 STORE_32LE(audio->ch2Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch2.nextEvent);
993
994 flags = GBSerializedAudioFlagsSetCh3Readable(flags, audio->ch3.readable);
995 memcpy(state->ch3.wavebanks, audio->ch3.wavedata32, sizeof(state->ch3.wavebanks));
996 STORE_16LE(audio->ch3.length, 0, &state->ch3.length);
997 STORE_32LE(audio->ch3Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch3.nextEvent);
998 STORE_32LE(audio->ch3Fade.when - mTimingCurrentTime(audio->timing), 0, &state->ch1.nextCh3Fade);
999
1000 flags = GBSerializedAudioFlagsSetCh4Volume(flags, audio->ch4.envelope.currentVolume);
1001 flags = GBSerializedAudioFlagsSetCh4Dead(flags, audio->ch4.envelope.dead);
1002 STORE_32LE(audio->ch4.lfsr, 0, &state->ch4.lfsr);
1003 ch4Flags = GBSerializedAudioEnvelopeSetLength(ch4Flags, audio->ch4.length);
1004 ch4Flags = GBSerializedAudioEnvelopeSetNextStep(ch4Flags, audio->ch4.envelope.nextStep);
1005 STORE_32LE(ch4Flags, 0, &state->ch4.envelope);
1006 STORE_32LE(audio->ch4.lastEvent, 0, &state->ch4.lastEvent);
1007 STORE_32LE(audio->ch4Event.when - mTimingCurrentTime(audio->timing), 0, &state->ch4.nextEvent);
1008
1009 STORE_32LE(flags, 0, flagsOut);
1010}
1011
1012void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGState* state, const uint32_t* flagsIn) {
1013 uint32_t flags;
1014 uint32_t sweep;
1015 uint32_t ch1Flags = 0;
1016 uint32_t ch2Flags = 0;
1017 uint32_t ch4Flags = 0;
1018 uint32_t when;
1019
1020 audio->playingCh1 = !!(*audio->nr52 & 0x0001);
1021 audio->playingCh2 = !!(*audio->nr52 & 0x0002);
1022 audio->playingCh3 = !!(*audio->nr52 & 0x0004);
1023 audio->playingCh4 = !!(*audio->nr52 & 0x0008);
1024 audio->enable = GBAudioEnableGetEnable(*audio->nr52);
1025
1026 if (audio->style == GB_AUDIO_GBA) {
1027 LOAD_32LE(when, 0, &state->ch1.nextFrame);
1028 mTimingSchedule(audio->timing, &audio->frameEvent, when);
1029 }
1030
1031 LOAD_32LE(flags, 0, flagsIn);
1032 audio->frame = GBSerializedAudioFlagsGetFrame(flags);
1033 audio->skipFrame = GBSerializedAudioFlagsGetSkipFrame(flags);
1034
1035 LOAD_32LE(ch1Flags, 0, &state->ch1.envelope);
1036 LOAD_32LE(sweep, 0, &state->ch1.sweep);
1037 audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags);
1038 audio->ch1.envelope.dead = GBSerializedAudioFlagsGetCh1Dead(flags);
1039 audio->ch1.control.hi = GBSerializedAudioFlagsGetCh1Hi(flags);
1040 audio->ch1.sweep.enable = GBSerializedAudioFlagsGetCh1SweepEnabled(flags);
1041 audio->ch1.sweep.occurred = GBSerializedAudioFlagsGetCh1SweepOccurred(flags);
1042 audio->ch1.sweep.time = GBSerializedAudioSweepGetTime(sweep);
1043 if (!audio->ch1.sweep.time) {
1044 audio->ch1.sweep.time = 8;
1045 }
1046 audio->ch1.control.length = GBSerializedAudioEnvelopeGetLength(ch1Flags);
1047 audio->ch1.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch1Flags);
1048 audio->ch1.sweep.realFrequency = GBSerializedAudioEnvelopeGetFrequency(ch1Flags);
1049 LOAD_32LE(when, 0, &state->ch1.nextEvent);
1050 if (audio->ch1.envelope.dead < 2 && audio->playingCh1) {
1051 mTimingSchedule(audio->timing, &audio->ch1Event, when);
1052 }
1053
1054 LOAD_32LE(ch2Flags, 0, &state->ch2.envelope);
1055 audio->ch2.envelope.currentVolume = GBSerializedAudioFlagsGetCh2Volume(flags);
1056 audio->ch2.envelope.dead = GBSerializedAudioFlagsGetCh2Dead(flags);
1057 audio->ch2.control.hi = GBSerializedAudioFlagsGetCh2Hi(flags);
1058 audio->ch2.control.length = GBSerializedAudioEnvelopeGetLength(ch2Flags);
1059 audio->ch2.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch2Flags);
1060 LOAD_32LE(when, 0, &state->ch2.nextEvent);
1061 if (audio->ch2.envelope.dead < 2 && audio->playingCh2) {
1062 mTimingSchedule(audio->timing, &audio->ch2Event, when);
1063 }
1064
1065 audio->ch3.readable = GBSerializedAudioFlagsGetCh3Readable(flags);
1066 // TODO: Big endian?
1067 memcpy(audio->ch3.wavedata32, state->ch3.wavebanks, sizeof(audio->ch3.wavedata32));
1068 LOAD_16LE(audio->ch3.length, 0, &state->ch3.length);
1069 LOAD_32LE(when, 0, &state->ch3.nextEvent);
1070 if (audio->playingCh3) {
1071 mTimingSchedule(audio->timing, &audio->ch3Event, when);
1072 }
1073 LOAD_32LE(when, 0, &state->ch1.nextCh3Fade);
1074 if (audio->ch3.readable && audio->style == GB_AUDIO_DMG) {
1075 mTimingSchedule(audio->timing, &audio->ch3Fade, when);
1076 }
1077
1078 LOAD_32LE(ch4Flags, 0, &state->ch4.envelope);
1079 audio->ch4.envelope.currentVolume = GBSerializedAudioFlagsGetCh4Volume(flags);
1080 audio->ch4.envelope.dead = GBSerializedAudioFlagsGetCh4Dead(flags);
1081 audio->ch4.length = GBSerializedAudioEnvelopeGetLength(ch4Flags);
1082 audio->ch4.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch4Flags);
1083 LOAD_32LE(audio->ch4.lfsr, 0, &state->ch4.lfsr);
1084 LOAD_32LE(audio->ch4.lastEvent, 0, &state->ch4.lastEvent);
1085 LOAD_32LE(when, 0, &state->ch4.nextEvent);
1086 if (audio->ch4.envelope.dead < 2 && audio->playingCh4) {
1087 if (!audio->ch4.lastEvent) {
1088 // Back-compat: fake this value
1089 uint32_t currentTime = mTimingCurrentTime(audio->timing);
1090 int32_t cycles = audio->ch4.ratio ? 2 * audio->ch4.ratio : 1;
1091 cycles <<= audio->ch4.frequency;
1092 cycles *= 8 * audio->timingFactor;
1093 audio->ch4.lastEvent = currentTime + (when & (cycles - 1)) - cycles;
1094 }
1095 mTimingSchedule(audio->timing, &audio->ch4Event, when);
1096 }
1097}
1098
1099void GBAudioSerialize(const struct GBAudio* audio, struct GBSerializedState* state) {
1100 GBAudioPSGSerialize(audio, &state->audio.psg, &state->audio.flags);
1101 STORE_32LE(audio->capLeft, 0, &state->audio.capLeft);
1102 STORE_32LE(audio->capRight, 0, &state->audio.capRight);
1103 STORE_32LE(audio->sampleEvent.when - mTimingCurrentTime(audio->timing), 0, &state->audio.nextSample);
1104}
1105
1106void GBAudioDeserialize(struct GBAudio* audio, const struct GBSerializedState* state) {
1107 GBAudioPSGDeserialize(audio, &state->audio.psg, &state->audio.flags);
1108 LOAD_32LE(audio->capLeft, 0, &state->audio.capLeft);
1109 LOAD_32LE(audio->capRight, 0, &state->audio.capRight);
1110 uint32_t when;
1111 LOAD_32LE(when, 0, &state->audio.nextSample);
1112 mTimingSchedule(audio->timing, &audio->sampleEvent, when);
1113}