GB: More audio fixes

This commit is contained in:
Jeffrey Pfau 2016-02-09 20:18:24 -08:00
parent eefdcb6490
commit ce085623de
2 changed files with 38 additions and 21 deletions

View File

@ -87,9 +87,19 @@ void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples) {
void GBAudioWriteNR10(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR10(struct GBAudio* audio, uint8_t value) {
audio->ch1.shift = GBAudioRegisterSquareSweepGetShift(value); audio->ch1.shift = GBAudioRegisterSquareSweepGetShift(value);
bool oldDirection = audio->ch1.direction;
audio->ch1.direction = GBAudioRegisterSquareSweepGetDirection(value); audio->ch1.direction = GBAudioRegisterSquareSweepGetDirection(value);
if (audio->ch1.sweepOccurred && oldDirection && !audio->ch1.direction) {
audio->playingCh1 = false;
// TODO: Don't need p
if (audio->p) {
audio->p->memory.io[REG_NR52] &= ~0x0001;
}
}
audio->ch1.time = GBAudioRegisterSquareSweepGetTime(value); audio->ch1.time = GBAudioRegisterSquareSweepGetTime(value);
audio->ch1.sweepStep = audio->ch1.time; if (!audio->ch1.time) {
audio->ch1.time = 8;
}
} }
void GBAudioWriteNR11(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR11(struct GBAudio* audio, uint8_t value) {
@ -108,13 +118,13 @@ void GBAudioWriteNR12(struct GBAudio* audio, uint8_t value) {
} }
void GBAudioWriteNR13(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR13(struct GBAudio* audio, uint8_t value) {
audio->ch1.control.frequency &= 0x700; audio->ch1.realFrequency &= 0x700;
audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value); audio->ch1.realFrequency |= GBAudioRegisterControlGetFrequency(value);
} }
void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) { void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) {
audio->ch1.control.frequency &= 0xFF; audio->ch1.realFrequency &= 0xFF;
audio->ch1.control.frequency |= GBAudioRegisterControlGetFrequency(value << 8); audio->ch1.realFrequency |= GBAudioRegisterControlGetFrequency(value << 8);
bool wasStop = audio->ch1.control.stop; bool wasStop = audio->ch1.control.stop;
audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8); audio->ch1.control.stop = GBAudioRegisterControlGetStop(value << 8);
if (!wasStop && audio->ch1.control.stop && audio->ch1.control.length && !(audio->frame & 1)) { if (!wasStop && audio->ch1.control.stop && audio->ch1.control.length && !(audio->frame & 1)) {
@ -135,8 +145,10 @@ void GBAudioWriteNR14(struct GBAudio* audio, uint8_t value) {
if (audio->ch1.envelope.currentVolume > 0 && audio->ch1.envelope.stepTime) { if (audio->ch1.envelope.currentVolume > 0 && audio->ch1.envelope.stepTime) {
audio->ch1.envelope.dead = 0; audio->ch1.envelope.dead = 0;
} }
audio->ch1.control.frequency = audio->ch1.realFrequency;
audio->ch1.sweepStep = audio->ch1.time; audio->ch1.sweepStep = audio->ch1.time;
audio->ch1.sweepEnable = audio->ch1.sweepStep || audio->ch1.shift; audio->ch1.sweepEnable = (audio->ch1.sweepStep != 8) || audio->ch1.shift;
audio->ch1.sweepOccurred = false;
if (audio->playingCh1 && audio->ch1.shift) { if (audio->playingCh1 && audio->ch1.shift) {
audio->playingCh1 = _updateSweep(&audio->ch1, true); audio->playingCh1 = _updateSweep(&audio->ch1, true);
} }
@ -710,25 +722,28 @@ static void _updateEnvelope(struct GBAudioEnvelope* envelope) {
} }
static bool _updateSweep(struct GBAudioChannel1* ch, bool initial) { static bool _updateSweep(struct GBAudioChannel1* ch, bool initial) {
if (ch->direction) { if (initial || ch->time != 8) {
int frequency = ch->control.frequency; if (ch->direction) {
frequency -= frequency >> ch->shift; int frequency = ch->control.frequency;
if (frequency >= 0) { frequency -= frequency >> ch->shift;
ch->control.frequency = frequency; if (frequency >= 0) {
}
} else {
int frequency = ch->control.frequency;
frequency += frequency >> ch->shift;
if (frequency < 2048) {
if (!initial && ch->shift) {
ch->control.frequency = frequency; ch->control.frequency = frequency;
if (!_updateSweep(ch, true)) {
return false;
}
} }
} else { } else {
return false; int frequency = ch->control.frequency;
frequency += frequency >> ch->shift;
if (frequency < 2048) {
if (!initial && ch->shift) {
ch->control.frequency = frequency;
if (!_updateSweep(ch, true)) {
return false;
}
}
} else {
return false;
}
} }
ch->sweepOccurred = true;
} }
ch->sweepStep = ch->time; ch->sweepStep = ch->time;
return true; return true;

View File

@ -94,6 +94,8 @@ struct GBAudioChannel1 {
uint8_t sweepStep; uint8_t sweepStep;
bool direction; bool direction;
bool sweepEnable; bool sweepEnable;
bool sweepOccurred;
uint16_t realFrequency;
struct GBAudioEnvelope envelope; struct GBAudioEnvelope envelope;
struct GBAudioSquareControl control; struct GBAudioSquareControl control;