all repos — mgba @ eb0b9dca0f3b7b46ad82efac3155fb86d2ae26a4

mGBA Game Boy Advance Emulator

src/gba/audio.c (view raw)

  1/* Copyright (c) 2013-2015 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 "gba/gba.h"
  9#include "gba/io.h"
 10#include "gba/serialize.h"
 11#include "gba/supervisor/thread.h"
 12#include "gba/video.h"
 13
 14const unsigned GBA_AUDIO_SAMPLES = 2048;
 15const unsigned BLIP_BUFFER_SIZE = 0x4000;
 16const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
 17#define SWEEP_CYCLES (GBA_ARM7TDMI_FREQUENCY / 128)
 18
 19static bool _writeEnvelope(struct GBAAudioEnvelope* envelope, uint16_t value);
 20static int32_t _updateSquareChannel(struct GBAAudioSquareControl* envelope, int duty);
 21static void _updateEnvelope(struct GBAAudioEnvelope* envelope);
 22static bool _updateSweep(struct GBAAudioChannel1* ch);
 23static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
 24static int32_t _updateChannel2(struct GBAAudioChannel2* ch);
 25static int32_t _updateChannel3(struct GBAAudioChannel3* ch);
 26static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
 27static int _applyBias(struct GBAAudio* audio, int sample);
 28static void _sample(struct GBAAudio* audio);
 29
 30void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
 31	audio->samples = samples;
 32#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
 33	CircleBufferInit(&audio->left, samples * sizeof(int16_t));
 34	CircleBufferInit(&audio->right, samples * sizeof(int16_t));
 35#else
 36	audio->left = blip_new(BLIP_BUFFER_SIZE);
 37	audio->right = blip_new(BLIP_BUFFER_SIZE);
 38	// Guess too large; we hang producing extra samples if we guess too low
 39	blip_set_rates(audio->left,  GBA_ARM7TDMI_FREQUENCY, 96000);
 40	blip_set_rates(audio->right, GBA_ARM7TDMI_FREQUENCY, 96000);
 41#endif
 42	CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
 43	CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
 44
 45	audio->forceDisableCh[0] = false;
 46	audio->forceDisableCh[1] = false;
 47	audio->forceDisableCh[2] = false;
 48	audio->forceDisableCh[3] = false;
 49	audio->forceDisableChA = false;
 50	audio->forceDisableChB = false;
 51}
 52
 53void GBAAudioReset(struct GBAAudio* audio) {
 54	audio->nextEvent = 0;
 55	audio->nextCh1 = 0;
 56	audio->nextCh2 = 0;
 57	audio->nextCh3 = 0;
 58	audio->nextCh4 = 0;
 59	audio->ch1 = (struct GBAAudioChannel1) { .envelope = { .nextStep = INT_MAX }, .nextSweep = INT_MAX };
 60	audio->ch2 = (struct GBAAudioChannel2) { .envelope = { .nextStep = INT_MAX } };
 61	audio->ch3 = (struct GBAAudioChannel3) { .bank = { .bank = 0 } };
 62	audio->ch4 = (struct GBAAudioChannel4) { .envelope = { .nextStep = INT_MAX } };
 63	audio->chA.dmaSource = 1;
 64	audio->chB.dmaSource = 2;
 65	audio->chA.sample = 0;
 66	audio->chB.sample = 0;
 67	audio->eventDiff = 0;
 68	audio->nextSample = 0;
 69	audio->sampleRate = 0x8000;
 70	audio->soundbias = 0x200;
 71	audio->volumeRight = 0;
 72	audio->volumeLeft = 0;
 73	audio->ch1Right = false;
 74	audio->ch2Right = false;
 75	audio->ch3Right = false;
 76	audio->ch4Right = false;
 77	audio->ch1Left = false;
 78	audio->ch2Left = false;
 79	audio->ch3Left = false;
 80	audio->ch4Left = false;
 81	audio->volume = 0;
 82	audio->volumeChA = false;
 83	audio->volumeChB = false;
 84	audio->chARight = false;
 85	audio->chALeft = false;
 86	audio->chATimer = false;
 87	audio->chBRight = false;
 88	audio->chBLeft = false;
 89	audio->chBTimer = false;
 90	audio->playingCh1 = false;
 91	audio->playingCh2 = false;
 92	audio->playingCh3 = false;
 93	audio->playingCh4 = false;
 94	audio->enable = false;
 95	audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
 96
 97#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
 98	CircleBufferClear(&audio->left);
 99	CircleBufferClear(&audio->right);
100#else
101	blip_clear(audio->left);
102	blip_clear(audio->right);
103	audio->clock = 0;
104#endif
105	CircleBufferClear(&audio->chA.fifo);
106	CircleBufferClear(&audio->chB.fifo);
107}
108
109void GBAAudioDeinit(struct GBAAudio* audio) {
110#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
111	CircleBufferDeinit(&audio->left);
112	CircleBufferDeinit(&audio->right);
113#else
114	blip_delete(audio->left);
115	blip_delete(audio->right);
116#endif
117	CircleBufferDeinit(&audio->chA.fifo);
118	CircleBufferDeinit(&audio->chB.fifo);
119}
120
121void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) {
122	GBASyncLockAudio(audio->p->sync);
123	audio->samples = samples;
124#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
125	size_t oldCapacity = audio->left.capacity;
126	int16_t* buffer = malloc(oldCapacity);
127	int16_t dummy;
128	size_t read;
129	size_t i;
130
131	read = CircleBufferDump(&audio->left, buffer, oldCapacity);
132	CircleBufferDeinit(&audio->left);
133	CircleBufferInit(&audio->left, samples * sizeof(int16_t));
134	for (i = 0; i * sizeof(int16_t) < read; ++i) {
135		if (!CircleBufferWrite16(&audio->left, buffer[i])) {
136			CircleBufferRead16(&audio->left, &dummy);
137			CircleBufferWrite16(&audio->left, buffer[i]);
138		}
139	}
140
141	read = CircleBufferDump(&audio->right, buffer, oldCapacity);
142	CircleBufferDeinit(&audio->right);
143	CircleBufferInit(&audio->right, samples * sizeof(int16_t));
144	for (i = 0; i * sizeof(int16_t) < read; ++i) {
145		if (!CircleBufferWrite16(&audio->right, buffer[i])) {
146			CircleBufferRead16(&audio->right, &dummy);
147			CircleBufferWrite16(&audio->right, buffer[i]);
148		}
149	}
150
151	free(buffer);
152#else
153	blip_clear(audio->left);
154	blip_clear(audio->right);
155	audio->clock = 0;
156#endif
157
158	GBASyncConsumeAudio(audio->p->sync);
159}
160
161int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
162	audio->nextEvent -= cycles;
163	audio->eventDiff += cycles;
164	if (audio->nextEvent <= 0) {
165		audio->nextEvent = INT_MAX;
166		if (audio->enable) {
167			if (audio->playingCh1 && !audio->ch1.envelope.dead) {
168				audio->nextCh1 -= audio->eventDiff;
169				if (audio->ch1.envelope.nextStep != INT_MAX) {
170					audio->ch1.envelope.nextStep -= audio->eventDiff;
171					if (audio->ch1.envelope.nextStep <= 0) {
172						int8_t sample = audio->ch1.control.hi * 0x10 - 0x8;
173						_updateEnvelope(&audio->ch1.envelope);
174						if (audio->ch1.envelope.nextStep < audio->nextEvent) {
175							audio->nextEvent = audio->ch1.envelope.nextStep;
176						}
177						audio->ch1.sample = sample * audio->ch1.envelope.currentVolume;
178					}
179				}
180
181				if (audio->ch1.nextSweep != INT_MAX) {
182					audio->ch1.nextSweep -= audio->eventDiff;
183					if (audio->ch1.nextSweep <= 0) {
184						audio->playingCh1 = _updateSweep(&audio->ch1);
185						if (audio->ch1.nextSweep < audio->nextEvent) {
186							audio->nextEvent = audio->ch1.nextSweep;
187						}
188					}
189				}
190
191				if (audio->nextCh1 <= 0) {
192					audio->nextCh1 += _updateChannel1(&audio->ch1);
193					if (audio->nextCh1 < audio->nextEvent) {
194						audio->nextEvent = audio->nextCh1;
195					}
196				}
197
198				if (audio->ch1.control.stop) {
199					audio->ch1.control.endTime -= audio->eventDiff;
200					if (audio->ch1.control.endTime <= 0) {
201						audio->playingCh1 = 0;
202					}
203				}
204			}
205
206			if (audio->playingCh2 && !audio->ch2.envelope.dead) {
207				audio->nextCh2 -= audio->eventDiff;
208				if (audio->ch2.envelope.nextStep != INT_MAX) {
209					audio->ch2.envelope.nextStep -= audio->eventDiff;
210					if (audio->ch2.envelope.nextStep <= 0) {
211						int8_t sample = audio->ch2.control.hi * 0x10 - 0x8;
212						_updateEnvelope(&audio->ch2.envelope);
213						if (audio->ch2.envelope.nextStep < audio->nextEvent) {
214							audio->nextEvent = audio->ch2.envelope.nextStep;
215						}
216						audio->ch2.sample = sample * audio->ch2.envelope.currentVolume;
217					}
218				}
219
220				if (audio->nextCh2 <= 0) {
221					audio->nextCh2 += _updateChannel2(&audio->ch2);
222					if (audio->nextCh2 < audio->nextEvent) {
223						audio->nextEvent = audio->nextCh2;
224					}
225				}
226
227				if (audio->ch2.control.stop) {
228					audio->ch2.control.endTime -= audio->eventDiff;
229					if (audio->ch2.control.endTime <= 0) {
230						audio->playingCh2 = 0;
231					}
232				}
233			}
234
235			if (audio->playingCh3) {
236				audio->nextCh3 -= audio->eventDiff;
237				if (audio->nextCh3 <= 0) {
238					audio->nextCh3 += _updateChannel3(&audio->ch3);
239					if (audio->nextCh3 < audio->nextEvent) {
240						audio->nextEvent = audio->nextCh3;
241					}
242				}
243
244				if (audio->ch3.control.stop) {
245					audio->ch3.control.endTime -= audio->eventDiff;
246					if (audio->ch3.control.endTime <= 0) {
247						audio->playingCh3 = 0;
248					}
249				}
250			}
251
252			if (audio->playingCh4 && !audio->ch4.envelope.dead) {
253				audio->nextCh4 -= audio->eventDiff;
254				if (audio->ch4.envelope.nextStep != INT_MAX) {
255					audio->ch4.envelope.nextStep -= audio->eventDiff;
256					if (audio->ch4.envelope.nextStep <= 0) {
257						int8_t sample = (audio->ch4.sample >> 31) * 0x8;
258						_updateEnvelope(&audio->ch4.envelope);
259						if (audio->ch4.envelope.nextStep < audio->nextEvent) {
260							audio->nextEvent = audio->ch4.envelope.nextStep;
261						}
262						audio->ch4.sample = sample * audio->ch4.envelope.currentVolume;
263					}
264				}
265
266				if (audio->nextCh4 <= 0) {
267					audio->nextCh4 += _updateChannel4(&audio->ch4);
268					if (audio->nextCh4 < audio->nextEvent) {
269						audio->nextEvent = audio->nextCh4;
270					}
271				}
272
273				if (audio->ch4.control.stop) {
274					audio->ch4.control.endTime -= audio->eventDiff;
275					if (audio->ch4.control.endTime <= 0) {
276						audio->playingCh4 = 0;
277					}
278				}
279			}
280		}
281
282		audio->nextSample -= audio->eventDiff;
283		if (audio->nextSample <= 0) {
284			_sample(audio);
285			audio->nextSample += audio->sampleInterval;
286		}
287
288		if (audio->nextSample < audio->nextEvent) {
289			audio->nextEvent = audio->nextSample;
290		}
291		audio->eventDiff = 0;
292	}
293	return audio->nextEvent;
294}
295
296void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
297	switch (info->dest) {
298	case BASE_IO | REG_FIFO_A_LO:
299		audio->chA.dmaSource = number;
300		break;
301	case BASE_IO | REG_FIFO_B_LO:
302		audio->chB.dmaSource = number;
303		break;
304	default:
305		GBALog(audio->p, GBA_LOG_GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
306		return;
307	}
308	info->reg = GBADMARegisterSetDestControl(info->reg, DMA_FIXED);
309}
310
311void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
312	audio->ch1.sweep.shift = GBAAudioRegisterSquareSweepGetShift(value);
313	audio->ch1.sweep.direction = GBAAudioRegisterSquareSweepGetDirection(value);
314	audio->ch1.sweep.time = GBAAudioRegisterSquareSweepGetTime(value);
315	if (audio->ch1.sweep.time) {
316		audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
317	} else {
318		audio->ch1.nextSweep = INT_MAX;
319	}
320}
321
322void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
323	if (!_writeEnvelope(&audio->ch1.envelope, value)) {
324		audio->ch1.sample = 0;
325	}
326}
327
328void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
329	audio->ch1.control.frequency = GBAAudioRegisterControlGetFrequency(value);
330	audio->ch1.control.stop = GBAAudioRegisterControlGetStop(value);
331	audio->ch1.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch1.envelope.length)) >> 8;
332	if (GBAAudioRegisterControlIsRestart(value)) {
333		if (audio->ch1.sweep.time) {
334			audio->ch1.nextSweep = audio->ch1.sweep.time * SWEEP_CYCLES;
335		} else {
336			audio->ch1.nextSweep = INT_MAX;
337		}
338		if (!audio->playingCh1) {
339			audio->nextCh1 = 0;
340		}
341		audio->playingCh1 = 1;
342		if (audio->ch1.envelope.stepTime) {
343			audio->ch1.envelope.nextStep = 0;
344		} else {
345			audio->ch1.envelope.nextStep = INT_MAX;
346		}
347		audio->ch1.envelope.currentVolume = audio->ch1.envelope.initialVolume;
348		if (audio->ch1.envelope.stepTime) {
349			audio->ch1.envelope.nextStep = 0;
350		} else {
351			audio->ch1.envelope.nextStep = INT_MAX;
352		}
353	}
354}
355
356void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
357	if (!_writeEnvelope(&audio->ch2.envelope, value)) {
358		audio->ch2.sample = 0;
359	}
360}
361
362void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
363	audio->ch2.control.frequency = GBAAudioRegisterControlGetFrequency(value);
364	audio->ch2.control.stop = GBAAudioRegisterControlGetStop(value);
365	audio->ch2.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch2.envelope.length)) >> 8;
366	if (GBAAudioRegisterControlIsRestart(value)) {
367		audio->playingCh2 = 1;
368		audio->ch2.envelope.currentVolume = audio->ch2.envelope.initialVolume;
369		if (audio->ch2.envelope.stepTime) {
370			audio->ch2.envelope.nextStep = 0;
371		} else {
372			audio->ch2.envelope.nextStep = INT_MAX;
373		}
374		audio->nextCh2 = 0;
375	}
376}
377
378void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
379	audio->ch3.bank.size = GBAAudioRegisterBankGetSize(value);
380	audio->ch3.bank.bank = GBAAudioRegisterBankGetBank(value);
381	audio->ch3.bank.enable = GBAAudioRegisterBankGetEnable(value);
382	if (audio->ch3.control.endTime >= 0) {
383		audio->playingCh3 = audio->ch3.bank.enable;
384	}
385}
386
387void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
388	audio->ch3.wave.length = GBAAudioRegisterBankWaveGetLength(value);
389	audio->ch3.wave.volume = GBAAudioRegisterBankWaveGetVolume(value);
390}
391
392void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
393	audio->ch3.control.rate = GBAAudioRegisterControlGetRate(value);
394	audio->ch3.control.stop = GBAAudioRegisterControlGetStop(value);
395	audio->ch3.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (256 - audio->ch3.wave.length)) >> 8;
396	if (GBAAudioRegisterControlIsRestart(value)) {
397		audio->playingCh3 = audio->ch3.bank.enable;
398	}
399}
400
401void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
402	if (!_writeEnvelope(&audio->ch4.envelope, value)) {
403		audio->ch4.sample = 0;
404	}
405}
406
407void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
408	audio->ch4.control.ratio = GBAAudioRegisterCh4ControlGetRatio(value);
409	audio->ch4.control.frequency = GBAAudioRegisterCh4ControlGetFrequency(value);
410	audio->ch4.control.power = GBAAudioRegisterCh4ControlGetPower(value);
411	audio->ch4.control.stop = GBAAudioRegisterCh4ControlGetStop(value);
412	audio->ch4.control.endTime = (GBA_ARM7TDMI_FREQUENCY * (64 - audio->ch4.envelope.length)) >> 8;
413	if (GBAAudioRegisterCh4ControlIsRestart(value)) {
414		audio->playingCh4 = 1;
415		audio->ch4.envelope.currentVolume = audio->ch4.envelope.initialVolume;
416		if (audio->ch4.envelope.stepTime) {
417			audio->ch4.envelope.nextStep = 0;
418		} else {
419			audio->ch4.envelope.nextStep = INT_MAX;
420		}
421		if (audio->ch4.control.power) {
422			audio->ch4.lfsr = 0x40;
423		} else {
424			audio->ch4.lfsr = 0x4000;
425		}
426		audio->nextCh4 = 0;
427	}
428}
429
430void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
431	audio->volumeRight = GBARegisterSOUNDCNT_LOGetVolumeRight(value);
432	audio->volumeLeft = GBARegisterSOUNDCNT_LOGetVolumeLeft(value);
433	audio->ch1Right = GBARegisterSOUNDCNT_LOGetCh1Right(value);
434	audio->ch2Right = GBARegisterSOUNDCNT_LOGetCh2Right(value);
435	audio->ch3Right = GBARegisterSOUNDCNT_LOGetCh3Right(value);
436	audio->ch4Right = GBARegisterSOUNDCNT_LOGetCh4Right(value);
437	audio->ch1Left = GBARegisterSOUNDCNT_LOGetCh1Left(value);
438	audio->ch2Left = GBARegisterSOUNDCNT_LOGetCh2Left(value);
439	audio->ch3Left = GBARegisterSOUNDCNT_LOGetCh3Left(value);
440	audio->ch4Left = GBARegisterSOUNDCNT_LOGetCh4Left(value);
441}
442
443void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
444	audio->volume = GBARegisterSOUNDCNT_HIGetVolume(value);
445	audio->volumeChA = GBARegisterSOUNDCNT_HIGetVolumeChA(value);
446	audio->volumeChB = GBARegisterSOUNDCNT_HIGetVolumeChB(value);
447	audio->chARight = GBARegisterSOUNDCNT_HIGetChARight(value);
448	audio->chALeft = GBARegisterSOUNDCNT_HIGetChALeft(value);
449	audio->chATimer = GBARegisterSOUNDCNT_HIGetChATimer(value);
450	audio->chBRight = GBARegisterSOUNDCNT_HIGetChBRight(value);
451	audio->chBLeft = GBARegisterSOUNDCNT_HIGetChBLeft(value);
452	audio->chBTimer = GBARegisterSOUNDCNT_HIGetChBTimer(value);
453	// TODO: Implement channel reset
454}
455
456void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
457	audio->enable = GBARegisterSOUNDCNT_XGetEnable(value);
458}
459
460void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
461	audio->soundbias = value;
462}
463
464void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
465	audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value;
466}
467
468void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
469	struct CircleBuffer* fifo;
470	switch (address) {
471	case REG_FIFO_A_LO:
472		fifo = &audio->chA.fifo;
473		break;
474	case REG_FIFO_B_LO:
475		fifo = &audio->chB.fifo;
476		break;
477	default:
478		GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", address);
479		return;
480	}
481	int i;
482	for (i = 0; i < 4; ++i) {
483		while (!CircleBufferWrite8(fifo, value >> (8 * i))) {
484			int8_t dummy;
485			CircleBufferRead8(fifo, &dummy);
486		}
487	}
488}
489
490void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
491	struct GBAAudioFIFO* channel;
492	if (fifoId == 0) {
493		channel = &audio->chA;
494	} else if (fifoId == 1) {
495		channel = &audio->chB;
496	} else {
497		GBALog(audio->p, GBA_LOG_ERROR, "Bad FIFO write to address 0x%03x", fifoId);
498		return;
499	}
500	if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) {
501		struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
502		if (GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_CUSTOM) {
503			dma->nextCount = 4;
504			dma->nextEvent = 0;
505			dma->reg = GBADMARegisterSetWidth(dma->reg, 1);
506			GBAMemoryUpdateDMAs(audio->p, -cycles);
507		} else {
508			channel->dmaSource = 0;
509		}
510	}
511	CircleBufferRead8(&channel->fifo, &channel->sample);
512}
513
514#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
515unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples) {
516	GBASyncLockAudio(audio->p->sync);
517	unsigned read = 0;
518	if (left) {
519		unsigned readL = CircleBufferRead(&audio->left, left, nSamples * sizeof(int16_t)) >> 1;
520		if (readL < nSamples) {
521			memset((int16_t*) left + readL, 0, nSamples - readL);
522		}
523		read = readL;
524	}
525	if (right) {
526		unsigned readR = CircleBufferRead(&audio->right, right, nSamples * sizeof(int16_t)) >> 1;
527		if (readR < nSamples) {
528			memset((int16_t*) right + readR, 0, nSamples - readR);
529		}
530		read = read >= readR ? read : readR;
531	}
532	GBASyncConsumeAudio(audio->p->sync);
533	return read;
534}
535
536unsigned GBAAudioResampleNN(struct GBAAudio* audio, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples) {
537	int16_t left[GBA_AUDIO_SAMPLES];
538	int16_t right[GBA_AUDIO_SAMPLES];
539
540	// toRead is in GBA samples
541	// TODO: Do this with fixed-point math
542	unsigned toRead = ceilf(nSamples / ratio);
543	unsigned totalRead = 0;
544	while (nSamples) {
545		unsigned currentRead = GBA_AUDIO_SAMPLES;
546		if (currentRead > toRead) {
547			currentRead = toRead;
548		}
549		unsigned read = GBAAudioCopy(audio, left, right, currentRead);
550		toRead -= read;
551		unsigned i;
552		for (i = 0; i < read; ++i) {
553			*drift += ratio;
554			while (*drift >= 1.f) {
555				output->left = left[i];
556				output->right = right[i];
557				++output;
558				++totalRead;
559				--nSamples;
560				*drift -= 1.f;
561				if (!nSamples) {
562					return totalRead;
563				}
564			}
565		}
566		if (read < currentRead) {
567			memset(output, 0, nSamples * sizeof(struct GBAStereoSample));
568			break;
569		}
570	}
571	return totalRead;
572}
573#endif
574
575bool _writeEnvelope(struct GBAAudioEnvelope* envelope, uint16_t value) {
576	envelope->length = GBAAudioRegisterEnvelopeGetLength(value);
577	envelope->duty = GBAAudioRegisterEnvelopeGetDuty(value);
578	envelope->stepTime = GBAAudioRegisterEnvelopeGetStepTime(value);
579	envelope->direction = GBAAudioRegisterEnvelopeGetDirection(value);
580	envelope->initialVolume = GBAAudioRegisterEnvelopeGetInitialVolume(value);
581	envelope->dead = 0;
582	if (envelope->stepTime) {
583		envelope->nextStep = 0;
584	} else {
585		envelope->nextStep = INT_MAX;
586		if (envelope->initialVolume == 0) {
587			envelope->dead = 1;
588			return false;
589		}
590	}
591	return true;
592}
593
594static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
595	control->hi = !control->hi;
596	int period = 16 * (2048 - control->frequency);
597	switch (duty) {
598	case 0:
599		return control->hi ? period : period * 7;
600	case 1:
601		return control->hi ? period * 2 : period * 6;
602	case 2:
603		return period * 4;
604	case 3:
605		return control->hi ? period * 6 : period * 2;
606	default:
607		// This should never be hit
608		return period * 4;
609	}
610}
611
612static void _updateEnvelope(struct GBAAudioEnvelope* envelope) {
613	if (envelope->direction) {
614		++envelope->currentVolume;
615	} else {
616		--envelope->currentVolume;
617	}
618	if (envelope->currentVolume >= 15) {
619		envelope->currentVolume = 15;
620		envelope->nextStep = INT_MAX;
621	} else if (envelope->currentVolume <= 0) {
622		envelope->currentVolume = 0;
623		envelope->dead = 1;
624		envelope->nextStep = INT_MAX;
625	} else {
626		envelope->nextStep += envelope->stepTime * (GBA_ARM7TDMI_FREQUENCY >> 6);
627	}
628}
629
630static bool _updateSweep(struct GBAAudioChannel1* ch) {
631	if (ch->sweep.direction) {
632		int frequency = ch->control.frequency;
633		frequency -= frequency >> ch->sweep.shift;
634		if (frequency >= 0) {
635			ch->control.frequency = frequency;
636		}
637	} else {
638		int frequency = ch->control.frequency;
639		frequency += frequency >> ch->sweep.shift;
640		if (frequency < 2048) {
641			ch->control.frequency = frequency;
642		} else {
643			return false;
644		}
645	}
646	ch->nextSweep += ch->sweep.time * SWEEP_CYCLES;
647	return true;
648}
649
650static int32_t _updateChannel1(struct GBAAudioChannel1* ch) {
651	int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
652	ch->sample = ch->control.hi * 0x10 - 0x8;
653	ch->sample *= ch->envelope.currentVolume;
654	return timing;
655}
656
657static int32_t _updateChannel2(struct GBAAudioChannel2* ch) {
658	int timing = _updateSquareChannel(&ch->control, ch->envelope.duty);
659	ch->sample = ch->control.hi * 0x10 - 0x8;
660	ch->sample *= ch->envelope.currentVolume;
661	return timing;
662}
663
664static int32_t _updateChannel3(struct GBAAudioChannel3* ch) {
665	int i;
666	int start;
667	int end;
668	int volume;
669	switch (ch->wave.volume) {
670	case 0:
671		volume = 0;
672		break;
673	case 1:
674		volume = 4;
675		break;
676	case 2:
677		volume = 2;
678		break;
679	case 3:
680		volume = 1;
681		break;
682	default:
683		volume = 3;
684		break;
685	}
686	if (ch->bank.size) {
687		start = 7;
688		end = 0;
689	} else if (ch->bank.bank) {
690		start = 7;
691		end = 4;
692	} else {
693		start = 3;
694		end = 0;
695	}
696	uint32_t bitsCarry = ch->wavedata[end] & 0x0F000000;
697	uint32_t bits;
698	for (i = start; i >= end; --i) {
699		bits = ch->wavedata[i] & 0x0F000000;
700		ch->wavedata[i] = ((ch->wavedata[i] & 0xF0F0F0F0) >> 4) | ((ch->wavedata[i] & 0x000F0F0F) << 12);
701		ch->wavedata[i] |= bitsCarry >> 20;
702		bitsCarry = bits;
703	}
704	ch->sample = bitsCarry >> 24;
705	ch->sample -= 8;
706	ch->sample *= volume * 4;
707	return 8 * (2048 - ch->control.rate);
708}
709
710static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
711	int lsb = ch->lfsr & 1;
712	ch->sample = lsb * 0x10 - 0x8;
713	ch->sample *= ch->envelope.currentVolume;
714	ch->lfsr >>= 1;
715	ch->lfsr ^= (lsb * 0x60) << (ch->control.power ? 0 : 8);
716	int timing = ch->control.ratio ? 2 * ch->control.ratio : 1;
717	timing <<= ch->control.frequency;
718	timing *= 32;
719	return timing;
720}
721
722static int _applyBias(struct GBAAudio* audio, int sample) {
723	sample += GBARegisterSOUNDBIASGetBias(audio->soundbias);
724	if (sample >= 0x400) {
725		sample = 0x3FF;
726	} else if (sample < 0) {
727		sample = 0;
728	}
729	return (sample - GBARegisterSOUNDBIASGetBias(audio->soundbias)) << 5;
730}
731
732static void _sample(struct GBAAudio* audio) {
733	int16_t sampleLeft = 0;
734	int16_t sampleRight = 0;
735	int psgShift = 5 - audio->volume;
736
737	if (audio->playingCh1 && !audio->forceDisableCh[0]) {
738		if (audio->ch1Left) {
739			sampleLeft += audio->ch1.sample;
740		}
741
742		if (audio->ch1Right) {
743			sampleRight += audio->ch1.sample;
744		}
745	}
746
747	if (audio->playingCh2 && !audio->forceDisableCh[1]) {
748		if (audio->ch2Left) {
749			sampleLeft += audio->ch2.sample;
750		}
751
752		if (audio->ch2Right) {
753			sampleRight += audio->ch2.sample;
754		}
755	}
756
757	if (audio->playingCh3 && !audio->forceDisableCh[2]) {
758		if (audio->ch3Left) {
759			sampleLeft += audio->ch3.sample;
760		}
761
762		if (audio->ch3Right) {
763			sampleRight += audio->ch3.sample;
764		}
765	}
766
767	if (audio->playingCh4 && !audio->forceDisableCh[3]) {
768		if (audio->ch4Left) {
769			sampleLeft += audio->ch4.sample;
770		}
771
772		if (audio->ch4Right) {
773			sampleRight += audio->ch4.sample;
774		}
775	}
776
777	sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift;
778	sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift;
779
780	if (!audio->forceDisableChA) {
781		if (audio->chALeft) {
782			sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
783		}
784
785		if (audio->chARight) {
786			sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
787		}
788	}
789
790	if (!audio->forceDisableChB) {
791		if (audio->chBLeft) {
792			sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
793		}
794
795		if (audio->chBRight) {
796			sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
797		}
798	}
799
800	sampleLeft = _applyBias(audio, sampleLeft);
801	sampleRight = _applyBias(audio, sampleRight);
802
803	GBASyncLockAudio(audio->p->sync);
804	unsigned produced;
805#if RESAMPLE_LIBRARY != RESAMPLE_BLIP_BUF
806	CircleBufferWrite16(&audio->left, sampleLeft);
807	CircleBufferWrite16(&audio->right, sampleRight);
808	produced = CircleBufferSize(&audio->left) / 2;
809#else
810	if ((size_t) blip_samples_avail(audio->left) < audio->samples) {
811		blip_add_delta(audio->left, audio->clock, sampleLeft - audio->lastLeft);
812		blip_add_delta(audio->right, audio->clock, sampleRight - audio->lastRight);
813		audio->lastLeft = sampleLeft;
814		audio->lastRight = sampleRight;
815		audio->clock += audio->sampleInterval;
816		int clockNeeded = blip_clocks_needed(audio->left, audio->samples / 32);
817		if (audio->clock >= clockNeeded) {
818			blip_end_frame(audio->left, audio->clock);
819			blip_end_frame(audio->right, audio->clock);
820			audio->clock -= clockNeeded;
821		}
822	}
823	produced = blip_samples_avail(audio->left);
824#endif
825	if (audio->p->stream && audio->p->stream->postAudioFrame) {
826		audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
827	}
828	bool wait = produced >= audio->samples;
829	GBASyncProduceAudio(audio->p->sync, wait);
830
831	if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
832		audio->p->stream->postAudioBuffer(audio->p->stream, audio);
833	}
834}
835
836void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
837	state->audio.ch1Volume = audio->ch1.envelope.currentVolume;
838	state->audio.ch1Dead = audio->ch1.envelope.dead;
839	state->audio.ch1Hi = audio->ch1.control.hi;
840	state->audio.ch1.envelopeNextStep = audio->ch1.envelope.nextStep;
841	state->audio.ch1.waveNextStep = audio->ch1.control.nextStep;
842	state->audio.ch1.sweepNextStep = audio->ch1.nextSweep;
843	state->audio.ch1.endTime = audio->ch1.control.endTime;
844	state->audio.ch1.nextEvent = audio->nextCh1;
845
846	state->audio.ch2Volume = audio->ch2.envelope.currentVolume;
847	state->audio.ch2Dead = audio->ch2.envelope.dead;
848	state->audio.ch2Hi = audio->ch2.control.hi;
849	state->audio.ch2.envelopeNextStep = audio->ch2.envelope.nextStep;
850	state->audio.ch2.waveNextStep = audio->ch2.control.nextStep;
851	state->audio.ch2.endTime = audio->ch2.control.endTime;
852	state->audio.ch2.nextEvent = audio->nextCh2;
853
854	memcpy(state->audio.ch3.wavebanks, audio->ch3.wavedata, sizeof(state->audio.ch3.wavebanks));
855	state->audio.ch3.endTime = audio->ch3.control.endTime;
856	state->audio.ch3.nextEvent = audio->nextCh3;
857
858	state->audio.ch4Volume = audio->ch4.envelope.currentVolume;
859	state->audio.ch4Dead = audio->ch4.envelope.dead;
860	state->audio.ch4.envelopeNextStep = audio->ch4.envelope.nextStep;
861	state->audio.ch4.lfsr = audio->ch4.lfsr;
862	state->audio.ch4.endTime = audio->ch4.control.endTime;
863	state->audio.ch4.nextEvent = audio->nextCh4;
864
865	CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
866	CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
867	state->audio.fifoSize = CircleBufferSize(&audio->chA.fifo);
868
869	state->audio.nextEvent = audio->nextEvent;
870	state->audio.eventDiff = audio->eventDiff;
871	state->audio.nextSample = audio->nextSample;
872}
873
874void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
875	audio->ch1.envelope.currentVolume = state->audio.ch1Volume;
876	audio->ch1.envelope.dead = state->audio.ch1Dead;
877	audio->ch1.control.hi = state->audio.ch1Hi;
878	audio->ch1.envelope.nextStep = state->audio.ch1.envelopeNextStep;
879	audio->ch1.control.nextStep = state->audio.ch1.waveNextStep;
880	audio->ch1.nextSweep = state->audio.ch1.sweepNextStep;
881	audio->ch1.control.endTime = state->audio.ch1.endTime;
882	audio->nextCh1 = state->audio.ch1.nextEvent;
883
884	audio->ch2.envelope.currentVolume = state->audio.ch2Volume;
885	audio->ch2.envelope.dead = state->audio.ch2Dead;
886	audio->ch2.control.hi = state->audio.ch2Hi;
887	audio->ch2.envelope.nextStep = state->audio.ch2.envelopeNextStep;
888	audio->ch2.control.nextStep = state->audio.ch2.waveNextStep;
889	audio->ch2.control.endTime = state->audio.ch2.endTime;
890	audio->nextCh2 = state->audio.ch2.nextEvent;
891
892	memcpy(audio->ch3.wavedata, state->audio.ch3.wavebanks, sizeof(audio->ch3.wavedata));
893	audio->ch3.control.endTime = state->audio.ch3.endTime;
894	audio->nextCh3 = state->audio.ch3.nextEvent;
895
896	audio->ch4.envelope.currentVolume = state->audio.ch4Volume;
897	audio->ch4.envelope.dead = state->audio.ch4Dead;
898	audio->ch4.envelope.nextStep = state->audio.ch4.envelopeNextStep;
899	audio->ch4.lfsr = state->audio.ch4.lfsr;
900	audio->ch4.control.endTime = state->audio.ch4.endTime;
901	audio->nextCh4 = state->audio.ch4.nextEvent;
902
903	CircleBufferClear(&audio->chA.fifo);
904	CircleBufferClear(&audio->chB.fifo);
905	int i;
906	for (i = 0; i < state->audio.fifoSize; ++i) {
907		CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);
908		CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
909	}
910
911	audio->nextEvent = state->audio.nextEvent;
912	audio->eventDiff = state->audio.eventDiff;
913	audio->nextSample = state->audio.nextSample;
914}
915
916float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
917	return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate);
918}