all repos — mgba @ 3b24e94018c2f26f503db72b058444882fff4ccf

mGBA Game Boy Advance Emulator

src/gba/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 "audio.h"
  7
  8#include "core/sync.h"
  9#include "gba/gba.h"
 10#include "gba/io.h"
 11#include "gba/serialize.h"
 12#include "gba/video.h"
 13
 14#ifdef _3DS
 15#define blip_add_delta blip_add_delta_fast
 16#endif
 17
 18mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio");
 19
 20const unsigned GBA_AUDIO_SAMPLES = 2048;
 21const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);
 22const int GBA_AUDIO_VOLUME_MAX = 0x100;
 23
 24static const int CLOCKS_PER_FRAME = 0x400;
 25
 26static int _applyBias(struct GBAAudio* audio, int sample);
 27static void _sample(struct GBAAudio* audio);
 28
 29void GBAAudioInit(struct GBAAudio* audio, size_t samples) {
 30	audio->psg.p = NULL;
 31	uint8_t* nr52 = (uint8_t*) &audio->p->memory.io[REG_SOUNDCNT_X >> 1];
 32#ifdef __BIG_ENDIAN__
 33	++nr52;
 34#endif
 35	GBAudioInit(&audio->psg, 0, nr52, GB_AUDIO_GBA);
 36	audio->samples = samples;
 37	audio->psg.clockRate = GBA_ARM7TDMI_FREQUENCY;
 38	// Guess too large; we hang producing extra samples if we guess too low
 39	blip_set_rates(audio->psg.left, GBA_ARM7TDMI_FREQUENCY, 96000);
 40	blip_set_rates(audio->psg.right, GBA_ARM7TDMI_FREQUENCY, 96000);
 41	CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE);
 42	CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE);
 43
 44	audio->forceDisableChA = false;
 45	audio->forceDisableChB = false;
 46	audio->masterVolume = GBA_AUDIO_VOLUME_MAX;
 47}
 48
 49void GBAAudioReset(struct GBAAudio* audio) {
 50	GBAudioReset(&audio->psg);
 51	audio->nextEvent = 0;
 52	audio->chA.dmaSource = 1;
 53	audio->chB.dmaSource = 2;
 54	audio->chA.sample = 0;
 55	audio->chB.sample = 0;
 56	audio->eventDiff = 0;
 57	audio->nextSample = 0;
 58	audio->sampleRate = 0x8000;
 59	audio->soundbias = 0x200;
 60	audio->volume = 0;
 61	audio->volumeChA = false;
 62	audio->volumeChB = false;
 63	audio->chARight = false;
 64	audio->chALeft = false;
 65	audio->chATimer = false;
 66	audio->chBRight = false;
 67	audio->chBLeft = false;
 68	audio->chBTimer = false;
 69	audio->enable = false;
 70	audio->sampleInterval = GBA_ARM7TDMI_FREQUENCY / audio->sampleRate;
 71
 72	blip_clear(audio->psg.left);
 73	blip_clear(audio->psg.right);
 74	audio->clock = 0;
 75	CircleBufferClear(&audio->chA.fifo);
 76	CircleBufferClear(&audio->chB.fifo);
 77}
 78
 79void GBAAudioDeinit(struct GBAAudio* audio) {
 80	GBAudioDeinit(&audio->psg);
 81	CircleBufferDeinit(&audio->chA.fifo);
 82	CircleBufferDeinit(&audio->chB.fifo);
 83}
 84
 85void GBAAudioResizeBuffer(struct GBAAudio* audio, size_t samples) {
 86	mCoreSyncLockAudio(audio->p->sync);
 87	audio->samples = samples;
 88	blip_clear(audio->psg.left);
 89	blip_clear(audio->psg.right);
 90	audio->clock = 0;
 91	mCoreSyncConsumeAudio(audio->p->sync);
 92}
 93
 94int32_t GBAAudioProcessEvents(struct GBAAudio* audio, int32_t cycles) {
 95	audio->nextEvent -= cycles;
 96	audio->eventDiff += cycles;
 97	while (audio->nextEvent <= 0) {
 98		audio->nextEvent = INT_MAX;
 99		if (audio->enable) {
100			audio->nextEvent = GBAudioProcessEvents(&audio->psg, audio->eventDiff / 4);
101			if (audio->nextEvent != INT_MAX) {
102				audio->nextEvent *= 4;
103			}
104		}
105
106		audio->nextSample -= audio->eventDiff;
107		if (audio->nextSample <= 0) {
108			_sample(audio);
109			audio->nextSample += audio->sampleInterval;
110		}
111
112		if (audio->nextSample < audio->nextEvent) {
113			audio->nextEvent = audio->nextSample;
114		}
115		audio->eventDiff = 0;
116	}
117	return audio->nextEvent;
118}
119
120void GBAAudioScheduleFifoDma(struct GBAAudio* audio, int number, struct GBADMA* info) {
121	switch (info->dest) {
122	case BASE_IO | REG_FIFO_A_LO:
123		audio->chA.dmaSource = number;
124		break;
125	case BASE_IO | REG_FIFO_B_LO:
126		audio->chB.dmaSource = number;
127		break;
128	default:
129		mLOG(GBA_AUDIO, GAME_ERROR, "Invalid FIFO destination: 0x%08X", info->dest);
130		return;
131	}
132	info->reg = GBADMARegisterSetDestControl(info->reg, DMA_FIXED);
133}
134
135void GBAAudioWriteSOUND1CNT_LO(struct GBAAudio* audio, uint16_t value) {
136	GBAudioWriteNR10(&audio->psg, value);
137}
138
139void GBAAudioWriteSOUND1CNT_HI(struct GBAAudio* audio, uint16_t value) {
140	GBAudioWriteNR11(&audio->psg, value);
141	GBAudioWriteNR12(&audio->psg, value >> 8);
142}
143
144void GBAAudioWriteSOUND1CNT_X(struct GBAAudio* audio, uint16_t value) {
145	GBAudioWriteNR13(&audio->psg, value);
146	GBAudioWriteNR14(&audio->psg, value >> 8);
147}
148
149void GBAAudioWriteSOUND2CNT_LO(struct GBAAudio* audio, uint16_t value) {
150	GBAudioWriteNR21(&audio->psg, value);
151	GBAudioWriteNR22(&audio->psg, value >> 8);
152}
153
154void GBAAudioWriteSOUND2CNT_HI(struct GBAAudio* audio, uint16_t value) {
155	GBAudioWriteNR23(&audio->psg, value);
156	GBAudioWriteNR24(&audio->psg, value >> 8);
157}
158
159void GBAAudioWriteSOUND3CNT_LO(struct GBAAudio* audio, uint16_t value) {
160	audio->psg.ch3.size = GBAudioRegisterBankGetSize(value);
161	audio->psg.ch3.bank = GBAudioRegisterBankGetBank(value);
162	GBAudioWriteNR30(&audio->psg, value);
163}
164
165void GBAAudioWriteSOUND3CNT_HI(struct GBAAudio* audio, uint16_t value) {
166	GBAudioWriteNR31(&audio->psg, value);
167	audio->psg.ch3.volume = GBAudioRegisterBankVolumeGetVolumeGBA(value >> 8);
168}
169
170void GBAAudioWriteSOUND3CNT_X(struct GBAAudio* audio, uint16_t value) {
171	GBAudioWriteNR33(&audio->psg, value);
172	GBAudioWriteNR34(&audio->psg, value >> 8);
173}
174
175void GBAAudioWriteSOUND4CNT_LO(struct GBAAudio* audio, uint16_t value) {
176	GBAudioWriteNR41(&audio->psg, value);
177	GBAudioWriteNR42(&audio->psg, value >> 8);
178}
179
180void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value) {
181	GBAudioWriteNR43(&audio->psg, value);
182	GBAudioWriteNR44(&audio->psg, value >> 8);
183}
184
185void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value) {
186	GBAudioWriteNR50(&audio->psg, value);
187	GBAudioWriteNR51(&audio->psg, value >> 8);
188}
189
190void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value) {
191	audio->volume = GBARegisterSOUNDCNT_HIGetVolume(value);
192	audio->volumeChA = GBARegisterSOUNDCNT_HIGetVolumeChA(value);
193	audio->volumeChB = GBARegisterSOUNDCNT_HIGetVolumeChB(value);
194	audio->chARight = GBARegisterSOUNDCNT_HIGetChARight(value);
195	audio->chALeft = GBARegisterSOUNDCNT_HIGetChALeft(value);
196	audio->chATimer = GBARegisterSOUNDCNT_HIGetChATimer(value);
197	audio->chBRight = GBARegisterSOUNDCNT_HIGetChBRight(value);
198	audio->chBLeft = GBARegisterSOUNDCNT_HIGetChBLeft(value);
199	audio->chBTimer = GBARegisterSOUNDCNT_HIGetChBTimer(value);
200	if (GBARegisterSOUNDCNT_HIIsChAReset(value)) {
201		CircleBufferClear(&audio->chA.fifo);
202	}
203	if (GBARegisterSOUNDCNT_HIIsChBReset(value)) {
204		CircleBufferClear(&audio->chB.fifo);
205	}
206}
207
208void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
209	audio->enable = GBAudioEnableGetEnable(value);
210	GBAudioWriteNR52(&audio->psg, value);
211}
212
213void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) {
214	audio->soundbias = value;
215}
216
217void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
218	audio->psg.ch3.wavedata32[address | (!audio->psg.ch3.bank * 4)] = value;
219}
220
221void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value) {
222	struct CircleBuffer* fifo;
223	switch (address) {
224	case REG_FIFO_A_LO:
225		fifo = &audio->chA.fifo;
226		break;
227	case REG_FIFO_B_LO:
228		fifo = &audio->chB.fifo;
229		break;
230	default:
231		mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", address);
232		return;
233	}
234	int i;
235	for (i = 0; i < 4; ++i) {
236		while (!CircleBufferWrite8(fifo, value >> (8 * i))) {
237			int8_t dummy;
238			CircleBufferRead8(fifo, &dummy);
239		}
240	}
241}
242
243void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
244	struct GBAAudioFIFO* channel;
245	if (fifoId == 0) {
246		channel = &audio->chA;
247	} else if (fifoId == 1) {
248		channel = &audio->chB;
249	} else {
250		mLOG(GBA_AUDIO, ERROR, "Bad FIFO write to address 0x%03x", fifoId);
251		return;
252	}
253	if (CircleBufferSize(&channel->fifo) <= 4 * sizeof(int32_t) && channel->dmaSource > 0) {
254		struct GBADMA* dma = &audio->p->memory.dma[channel->dmaSource];
255		if (GBADMARegisterGetTiming(dma->reg) == DMA_TIMING_CUSTOM) {
256			dma->nextCount = 4;
257			dma->nextEvent = 0;
258			dma->reg = GBADMARegisterSetWidth(dma->reg, 1);
259			GBAMemoryUpdateDMAs(audio->p, -cycles);
260		} else {
261			channel->dmaSource = 0;
262		}
263	}
264	CircleBufferRead8(&channel->fifo, (int8_t*) &channel->sample);
265}
266
267static int _applyBias(struct GBAAudio* audio, int sample) {
268	sample += GBARegisterSOUNDBIASGetBias(audio->soundbias);
269	if (sample >= 0x400) {
270		sample = 0x3FF;
271	} else if (sample < 0) {
272		sample = 0;
273	}
274	return ((sample - GBARegisterSOUNDBIASGetBias(audio->soundbias)) * audio->masterVolume) >> 3;
275}
276
277static void _sample(struct GBAAudio* audio) {
278	int16_t sampleLeft = 0;
279	int16_t sampleRight = 0;
280	int psgShift = 5 - audio->volume;
281	GBAudioSamplePSG(&audio->psg, &sampleLeft, &sampleRight);
282	sampleLeft >>= psgShift;
283	sampleRight >>= psgShift;
284
285	if (!audio->forceDisableChA) {
286		if (audio->chALeft) {
287			sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA;
288		}
289
290		if (audio->chARight) {
291			sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA;
292		}
293	}
294
295	if (!audio->forceDisableChB) {
296		if (audio->chBLeft) {
297			sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB;
298		}
299
300		if (audio->chBRight) {
301			sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
302		}
303	}
304
305	sampleLeft = _applyBias(audio, sampleLeft);
306	sampleRight = _applyBias(audio, sampleRight);
307
308	mCoreSyncLockAudio(audio->p->sync);
309	unsigned produced;
310	if ((size_t) blip_samples_avail(audio->psg.left) < audio->samples) {
311		blip_add_delta(audio->psg.left, audio->clock, sampleLeft - audio->lastLeft);
312		blip_add_delta(audio->psg.right, audio->clock, sampleRight - audio->lastRight);
313		audio->lastLeft = sampleLeft;
314		audio->lastRight = sampleRight;
315		audio->clock += audio->sampleInterval;
316		if (audio->clock >= CLOCKS_PER_FRAME) {
317			blip_end_frame(audio->psg.left, audio->clock);
318			blip_end_frame(audio->psg.right, audio->clock);
319			audio->clock -= CLOCKS_PER_FRAME;
320		}
321	}
322	produced = blip_samples_avail(audio->psg.left);
323	if (audio->p->stream && audio->p->stream->postAudioFrame) {
324		audio->p->stream->postAudioFrame(audio->p->stream, sampleLeft, sampleRight);
325	}
326	bool wait = produced >= audio->samples;
327	mCoreSyncProduceAudio(audio->p->sync, wait);
328
329	if (wait && audio->p->stream && audio->p->stream->postAudioBuffer) {
330		audio->p->stream->postAudioBuffer(audio->p->stream, audio->psg.left, audio->psg.right);
331	}
332}
333
334void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state) {
335	uint32_t flags = 0;
336	uint32_t ch1Flags = 0;
337	uint32_t ch2Flags = 0;
338	uint32_t ch4Flags = 0;
339
340	flags = GBASerializedAudioFlagsSetFrame(flags, audio->psg.frame);
341
342	flags = GBASerializedAudioFlagsSetCh1Volume(flags, audio->psg.ch1.envelope.currentVolume);
343	flags = GBASerializedAudioFlagsSetCh1Dead(flags, audio->psg.ch1.envelope.dead);
344	flags = GBASerializedAudioFlagsSetCh1Hi(flags, audio->psg.ch1.control.hi);
345	flags = GBASerializedAudioFlagsSetCh1SweepEnabled(flags, audio->psg.ch1.sweepEnable);
346	flags = GBASerializedAudioFlagsSetCh1SweepOccurred(flags, audio->psg.ch1.sweepOccurred);
347	ch1Flags = GBASerializedAudioEnvelopeSetLength(ch1Flags, audio->psg.ch1.control.length);
348	ch1Flags = GBASerializedAudioEnvelopeSetNextStep(ch1Flags, audio->psg.ch1.envelope.nextStep);
349	ch1Flags = GBASerializedAudioEnvelopeSetFrequency(ch1Flags, audio->psg.ch1.realFrequency);
350	STORE_32(ch1Flags, 0, &state->audio.ch1.envelope);
351	STORE_32(audio->psg.nextFrame, 0, &state->audio.ch1.nextFrame);
352	STORE_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent);
353
354	flags = GBASerializedAudioFlagsSetCh2Volume(flags, audio->psg.ch2.envelope.currentVolume);
355	flags = GBASerializedAudioFlagsSetCh2Dead(flags, audio->psg.ch2.envelope.dead);
356	flags = GBASerializedAudioFlagsSetCh2Hi(flags, audio->psg.ch2.control.hi);
357	ch2Flags = GBASerializedAudioEnvelopeSetLength(ch2Flags, audio->psg.ch2.control.length);
358	ch2Flags = GBASerializedAudioEnvelopeSetNextStep(ch2Flags, audio->psg.ch2.envelope.nextStep);
359	STORE_32(ch2Flags, 0, &state->audio.ch2.envelope);
360	STORE_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent);
361
362	memcpy(state->audio.ch3.wavebanks, audio->psg.ch3.wavedata32, sizeof(state->audio.ch3.wavebanks));
363	STORE_16(audio->psg.ch3.length, 0, &state->audio.ch3.length);
364	STORE_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent);
365
366	flags = GBASerializedAudioFlagsSetCh4Volume(flags, audio->psg.ch4.envelope.currentVolume);
367	flags = GBASerializedAudioFlagsSetCh4Dead(flags, audio->psg.ch4.envelope.dead);
368	state->audio.flags = GBASerializedAudioFlagsSetCh4Volume(flags, audio->psg.ch4.envelope.currentVolume);
369	state->audio.flags = GBASerializedAudioFlagsSetCh4Dead(flags, audio->psg.ch4.envelope.dead);
370	STORE_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr);
371	ch4Flags = GBASerializedAudioEnvelopeSetLength(ch4Flags, audio->psg.ch4.length);
372	ch4Flags = GBASerializedAudioEnvelopeSetNextStep(ch4Flags, audio->psg.ch4.envelope.nextStep);
373	STORE_32(ch4Flags, 0, &state->audio.ch4.envelope);
374	STORE_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent);
375
376	STORE_32(flags, 0, &state->audio.flags);
377
378	CircleBufferDump(&audio->chA.fifo, state->audio.fifoA, sizeof(state->audio.fifoA));
379	CircleBufferDump(&audio->chB.fifo, state->audio.fifoB, sizeof(state->audio.fifoB));
380	uint32_t fifoSize = CircleBufferSize(&audio->chA.fifo);
381	STORE_32(fifoSize, 0, &state->audio.fifoSize);
382
383	STORE_32(audio->nextEvent, 0, &state->audio.nextEvent);
384	STORE_32(audio->eventDiff, 0, &state->audio.eventDiff);
385	STORE_32(audio->nextSample, 0, &state->audio.nextSample);
386}
387
388void GBAAudioDeserialize(struct GBAAudio* audio, const struct GBASerializedState* state) {
389	uint32_t flags;
390	uint32_t ch1Flags = 0;
391	uint32_t ch2Flags = 0;
392	uint32_t ch4Flags = 0;
393
394	LOAD_32(flags, 0, &state->audio.flags);
395	LOAD_32(ch1Flags, 0, &state->audio.ch1.envelope);
396	audio->psg.ch1.envelope.currentVolume = GBASerializedAudioFlagsGetCh1Volume(flags);
397	audio->psg.ch1.envelope.dead = GBASerializedAudioFlagsGetCh1Dead(flags);
398	audio->psg.ch1.control.hi = GBASerializedAudioFlagsGetCh1Hi(flags);
399	audio->psg.ch1.sweepEnable = GBASerializedAudioFlagsGetCh1SweepEnabled(flags);
400	audio->psg.ch1.sweepOccurred = GBASerializedAudioFlagsGetCh1SweepOccurred(flags);
401	audio->psg.ch1.control.length = GBASerializedAudioEnvelopeGetLength(ch1Flags);
402	audio->psg.ch1.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch1Flags);
403	audio->psg.ch1.realFrequency = GBASerializedAudioEnvelopeGetFrequency(ch1Flags);
404	LOAD_32(audio->psg.nextFrame, 0, &state->audio.ch1.nextFrame);
405	LOAD_32(audio->psg.nextCh1, 0, &state->audio.ch1.nextEvent);
406
407	LOAD_32(ch2Flags, 0, &state->audio.ch1.envelope);
408	audio->psg.ch2.envelope.currentVolume = GBASerializedAudioFlagsGetCh2Volume(flags);
409	audio->psg.ch2.envelope.dead = GBASerializedAudioFlagsGetCh2Dead(flags);
410	audio->psg.ch2.control.hi = GBASerializedAudioFlagsGetCh2Hi(flags);
411	audio->psg.ch2.control.length = GBASerializedAudioEnvelopeGetLength(ch2Flags);
412	audio->psg.ch2.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch2Flags);
413	LOAD_32(audio->psg.nextCh2, 0, &state->audio.ch2.nextEvent);
414
415	// TODO: Big endian?
416	memcpy(audio->psg.ch3.wavedata32, state->audio.ch3.wavebanks, sizeof(audio->psg.ch3.wavedata32));
417	LOAD_16(audio->psg.ch3.length, 0, &state->audio.ch3.length);
418	LOAD_32(audio->psg.nextCh3, 0, &state->audio.ch3.nextEvent);
419
420	LOAD_32(ch4Flags, 0, &state->audio.ch1.envelope);
421	audio->psg.ch4.envelope.currentVolume = GBASerializedAudioFlagsGetCh4Volume(flags);
422	audio->psg.ch4.envelope.dead = GBASerializedAudioFlagsGetCh4Dead(flags);
423	audio->psg.ch4.length = GBASerializedAudioEnvelopeGetLength(ch4Flags);
424	audio->psg.ch4.envelope.nextStep = GBASerializedAudioEnvelopeGetNextStep(ch4Flags);
425	LOAD_32(audio->psg.ch4.lfsr, 0, &state->audio.ch4.lfsr);
426	LOAD_32(audio->psg.nextCh4, 0, &state->audio.ch4.nextEvent);
427
428	CircleBufferClear(&audio->chA.fifo);
429	CircleBufferClear(&audio->chB.fifo);
430	uint32_t fifoSize;
431	LOAD_32(fifoSize, 0, &state->audio.fifoSize);
432	if (state->audio.fifoSize > CircleBufferCapacity(&audio->chA.fifo)) {
433		fifoSize = CircleBufferCapacity(&audio->chA.fifo);
434	}
435	size_t i;
436	for (i = 0; i < fifoSize; ++i) {
437		CircleBufferWrite8(&audio->chA.fifo, state->audio.fifoA[i]);
438		CircleBufferWrite8(&audio->chB.fifo, state->audio.fifoB[i]);
439	}
440
441	LOAD_32(audio->nextEvent, 0, &state->audio.nextEvent);
442	LOAD_32(audio->eventDiff, 0, &state->audio.eventDiff);
443	LOAD_32(audio->nextSample, 0, &state->audio.nextSample);
444}
445
446float GBAAudioCalculateRatio(float inputSampleRate, float desiredFPS, float desiredSampleRate) {
447	return desiredSampleRate * GBA_ARM7TDMI_FREQUENCY / (VIDEO_TOTAL_LENGTH * desiredFPS * inputSampleRate);
448}