Partially implement SOUNDBIAS

This commit is contained in:
Jeffrey Pfau 2014-02-03 05:22:29 -08:00
parent 683e90fa06
commit 8f241e2cfb
3 changed files with 36 additions and 3 deletions

View File

@ -19,6 +19,7 @@ static int32_t _updateChannel1(struct GBAAudioChannel1* ch);
static int32_t _updateChannel2(struct GBAAudioChannel2* ch); static int32_t _updateChannel2(struct GBAAudioChannel2* ch);
static int32_t _updateChannel3(struct GBAAudioChannel3* ch); static int32_t _updateChannel3(struct GBAAudioChannel3* ch);
static int32_t _updateChannel4(struct GBAAudioChannel4* ch); static int32_t _updateChannel4(struct GBAAudioChannel4* ch);
static int _applyBias(struct GBAAudio* audio, int sample);
static void _sample(struct GBAAudio* audio); static void _sample(struct GBAAudio* audio);
void GBAAudioInit(struct GBAAudio* audio) { void GBAAudioInit(struct GBAAudio* audio) {
@ -45,6 +46,7 @@ void GBAAudioInit(struct GBAAudio* audio) {
audio->eventDiff = 0; audio->eventDiff = 0;
audio->nextSample = 0; audio->nextSample = 0;
audio->sampleRate = 0x8000; audio->sampleRate = 0x8000;
audio->soundbias = 0x200;
audio->soundcntLo = 0; audio->soundcntLo = 0;
audio->soundcntHi = 0; audio->soundcntHi = 0;
audio->soundcntX = 0; audio->soundcntX = 0;
@ -357,6 +359,10 @@ void GBAAudioWriteSOUNDCNT_X(struct GBAAudio* audio, uint16_t value) {
audio->soundcntX = (value & 0x80) | (audio->soundcntX & 0x0F); 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) { void GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value) {
audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value; audio->ch3.wavedata[address | (!audio->ch3.bank.bank * 4)] = value;
} }
@ -584,6 +590,16 @@ static int32_t _updateChannel4(struct GBAAudioChannel4* ch) {
return timing; 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) { static void _sample(struct GBAAudio* audio) {
int32_t sampleLeft = 0; int32_t sampleLeft = 0;
int32_t sampleRight = 0; int32_t sampleRight = 0;
@ -640,9 +656,12 @@ static void _sample(struct GBAAudio* audio) {
sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB;
} }
sampleLeft = _applyBias(audio, sampleLeft);
sampleRight = _applyBias(audio, sampleRight);
GBASyncLockAudio(audio->p->sync); GBASyncLockAudio(audio->p->sync);
CircleBufferWrite32(&audio->left, sampleLeft << 5); CircleBufferWrite32(&audio->left, sampleLeft);
CircleBufferWrite32(&audio->right, sampleRight << 5); CircleBufferWrite32(&audio->right, sampleRight);
unsigned produced = CircleBufferSize(&audio->left); unsigned produced = CircleBufferSize(&audio->left);
GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3); GBASyncProduceAudio(audio->p->sync, produced >= GBA_AUDIO_SAMPLES * 3);
} }

View File

@ -193,6 +193,15 @@ struct GBAAudio {
unsigned sampleRate; unsigned sampleRate;
union {
struct {
unsigned bias : 10;
unsigned : 4;
unsigned resolution : 2;
};
uint16_t soundbias;
};
int32_t nextEvent; int32_t nextEvent;
int32_t eventDiff; int32_t eventDiff;
int32_t nextCh1; 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_LO(struct GBAAudio* audio, uint16_t value);
void GBAAudioWriteSOUNDCNT_HI(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 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 GBAAudioWriteWaveRAM(struct GBAAudio* audio, int address, uint32_t value);
void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value); void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);

View File

@ -17,7 +17,7 @@ static const int _isValidRegister[REG_MAX >> 1] = {
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, 0, 1, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 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 // DMA
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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_DISPCNT >> 1] = 0x0080;
gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL; gba->memory.io[REG_RCNT >> 1] = RCNT_INITIAL;
gba->memory.io[REG_KEYINPUT >> 1] = 0x3FF; 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) { void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
@ -153,6 +154,9 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
case REG_SOUNDCNT_X: case REG_SOUNDCNT_X:
GBAAudioWriteSOUNDCNT_X(&gba->audio, value); GBAAudioWriteSOUNDCNT_X(&gba->audio, value);
break; break;
case REG_SOUNDBIAS:
GBAAudioWriteSOUNDBIAS(&gba->audio, value);
break;
case REG_WAVE_RAM0_LO: case REG_WAVE_RAM0_LO:
case REG_WAVE_RAM1_LO: case REG_WAVE_RAM1_LO: