all repos — mgba @ db2659962b45e242562c23c4b907eec7ce568464

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