all repos — mgba @ d2adc2449a78351aed3a5fa90ed59084a714b117

mGBA Game Boy Advance Emulator

src/gba/gba-audio.c (view raw)

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