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