all repos — mgba @ e9c1a53cfbf03252db40b5a19b830f8eb968c684

mGBA Game Boy Advance Emulator

DS Audio: Add PSG audio
Vicki Pfau vi@endrift.com
Mon, 10 Apr 2017 20:44:14 -0700
commit

e9c1a53cfbf03252db40b5a19b830f8eb968c684

parent

4ab96b42a086031a273c78fdf9ad273852e8400e

4 files changed, 42 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -1,4 +1,6 @@

medusa alpha 2: (Future) +Features: + - DS Audio: Add PSG audio Bugfixes: - DS Video: Fix VRAM mirroring in the renderer (fixes mgba.io/i/561) - DS Video: Fix extended modes 1.x screen base range (fixes mgba.io/i/568)
M README.mdREADME.md

@@ -164,7 +164,6 @@

Missing features on DS are - Audio: - - PSG audio - Master audio settings - Sound output capture - Microphone
M include/mgba/internal/ds/audio.hinclude/mgba/internal/ds/audio.h

@@ -46,6 +46,10 @@

uint32_t period; int16_t sample; + int duty; + bool high; + uint16_t lfsr; + int adpcmOffset; int16_t adpcmStartSample;
M src/ds/audio.csrc/ds/audio.c

@@ -132,6 +132,7 @@

ch->panning = DSRegisterSOUNDxCNTGetPanning(reg); ch->repeat = DSRegisterSOUNDxCNTGetRepeat(reg); ch->format = DSRegisterSOUNDxCNTGetFormat(reg); + ch->duty = DSRegisterSOUNDxCNTGetDuty(reg); if (ch->format > 2) { mLOG(DS_AUDIO, STUB, "Unimplemented audio format %i", ch->format);

@@ -141,6 +142,7 @@ if (ch->enable && !DSRegisterSOUNDxCNTIsBusy(reg)) {

mTimingDeschedule(&audio->p->ds7.timing, &ch->updateEvent); } else if (!ch->enable && DSRegisterSOUNDxCNTIsBusy(reg)) { ch->offset = 0; + ch->lfsr = 0x4000; mTimingDeschedule(&audio->p->ds7.timing, &ch->updateEvent); mTimingSchedule(&audio->p->ds7.timing, &ch->updateEvent, 0); if (ch->format == 2) {

@@ -228,6 +230,13 @@ }

ch->adpcmIndex += _adpcmIndexTable[sample & 0x7]; } +static void _updateNoiseChannel(struct DSAudioChannel* ch) { + int lsb = ch->lfsr & 1; + ch->high = lsb; + ch->lfsr >>= 1; + ch->lfsr ^= lsb * 0x6000; +} + static void _updateChannel(struct mTiming* timing, void* user, uint32_t cyclesLate) { struct DSAudioChannel* ch = user; struct ARMCore* cpu = ch->p->p->ds7.cpu;

@@ -249,8 +258,35 @@ ch->adpcmStartSample = ch->adpcmSample;

ch->adpcmStartIndex = ch->adpcmIndex; } break; + case 3: + switch (ch->index) { + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + ch->high = !ch->high; + break; + case 14: + case 15: + _updateNoiseChannel(ch); + break; + } + ch->sample = (0xFFFF * ch->high) - 0x8000; } _updateMixer(ch->p); + if (ch->format == 3 && ch->index < 14) { + int32_t period = ch->period; + if (ch->high) { + period *= ch->duty + 1; + } else { + period *= 7 - ch->duty; + } + mTimingSchedule(timing, &ch->updateEvent, period - cyclesLate); + return; + } + switch (ch->repeat) { case 1: if (ch->offset >= ch->length + ch->loopPoint) {