mirror of https://github.com/mgba-emu/mgba.git
Partially implement SOUNDBIAS
This commit is contained in:
parent
683e90fa06
commit
8f241e2cfb
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue