Partially implement SOUNDBIAS
Jeffrey Pfau jeffrey@endrift.com
Mon, 03 Feb 2014 05:22:29 -0800
3 files changed,
36 insertions(+),
3 deletions(-)
M
src/gba/gba-audio.c
→
src/gba/gba-audio.c
@@ -19,6 +19,7 @@ static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
static int32_t _updateChannel2(struct GBAAudioChannel2* ch); static int32_t _updateChannel3(struct GBAAudioChannel3* ch); static int32_t _updateChannel4(struct GBAAudioChannel4* ch); +static int _applyBias(struct GBAAudio* audio, int sample); static void _sample(struct GBAAudio* audio); void GBAAudioInit(struct GBAAudio* audio) {@@ -45,6 +46,7 @@ audio->ch4.envelope.nextStep = INT_MAX;
audio->eventDiff = 0; audio->nextSample = 0; audio->sampleRate = 0x8000; + audio->soundbias = 0x200; audio->soundcntLo = 0; audio->soundcntHi = 0; audio->soundcntX = 0;@@ -357,6 +359,10 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
audio->soundcntX = (value & 0x80) | (audio->soundcntX & 0x0F); } +void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value) { + audio->soundbias = value; +} + void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) { audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value; }@@ -584,6 +590,16 @@ timing *= 32;
return timing; } +static int _applyBias(struct GBAAudio* audio, int sample) { + sample += audio->bias; + if (sample >= 0x400) { + sample = 0x3FF; + } else if (sample < 0) { + sample = 0; + } + return (sample - audio->bias) << 6; +} + static void _sample(struct GBAAudio* audio) { int32_t sampleLeft = 0; int32_t sampleRight = 0;@@ -640,9 +656,12 @@ if (audio->chBRight) {
sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; } + sampleLeft = _applyBias(audio, sampleLeft); + sampleRight = _applyBias(audio, sampleRight); + GBASyncLockAudio(audio->p->sync); - CircleBufferWrite32(&audio->left, sampleLeft << 5); - CircleBufferWrite32(&audio->right, sampleRight << 5); + CircleBufferWrite32(&audio->left, sampleLeft); + CircleBufferWrite32(&audio->right, sampleRight); unsigned produced = CircleBufferSize(&audio->left); GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3); }
M
src/gba/gba-audio.h
→
src/gba/gba-audio.h
@@ -193,6 +193,15 @@ };
unsigned sampleRate; + union { + struct { + unsigned bias : 10; + unsigned : 4; + unsigned resolution : 2; + }; + uint16_t soundbias; + }; + int32_t nextEvent; int32_t eventDiff; int32_t nextCh1;@@ -228,6 +237,7 @@ void GBAAudioWriteSOUND4CNT_HI(struct GBAAudio* audio, uint16_t value);
void GBAAudioWriteSOUNDCNT_LO(struct GBAAudio* audio, uint16_t value); void GBAAudioWriteSOUNDCNT_HI(struct GBAAudio* audio, uint16_t value); void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value); +void GBAAudioWriteSOUNDBIAS(struct GBAAudio* audio, uint16_t value); void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value); void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);
M
src/gba/gba-io.c
→
src/gba/gba-io.c
@@ -17,7 +17,7 @@ 1, 1, 1, 0, 1, 0, 1, 0,
1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 0, 0, 0, // DMA 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,@@ -92,6 +92,7 @@ void GBAIOInit(struct GBA* gba) {
gba->memory.io[REG_DISPCNT >> 1] = 0x0080; gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL; gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF; + gba->memory.io[REG_SOUNDBIAS >> 1] = 0x200; } void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {@@ -152,6 +153,9 @@ GBAAudioWriteSOUNDCNT_HI(&gba->audio, value);
break; case REG_SOUNDCNT_X: GBAAudioWriteSOUNDCNT_X(&gba->audio, value); + break; + case REG_SOUNDBIAS: + GBAAudioWriteSOUNDBIAS(&gba->audio, value); break; case REG_WAVE_RAM0_LO: