all repos — mgba @ 63f14876c58e81867cc01bfb1165708fa17867c4

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