GBA Audio: Claw back some performance

This commit is contained in:
Vicki Pfau 2022-06-03 22:36:19 -07:00
parent f4217a7a77
commit 9f5267e24e
4 changed files with 28 additions and 31 deletions

View File

@ -16,6 +16,7 @@ CXX_GUARD_START
#include <mgba-util/circle-buffer.h>
#define GBA_AUDIO_FIFO_SIZE 8
#define GBA_MAX_SAMPLES 16
#define MP2K_MAGIC 0x68736D53
#define MP2K_MAX_SOUND_CHANNELS 12
@ -34,7 +35,7 @@ struct GBAAudioFIFO {
uint32_t internalSample;
int internalRemaining;
int dmaSource;
int8_t samples[8];
int8_t samples[GBA_MAX_SAMPLES];
};
DECL_BITFIELD(GBARegisterSOUNDCNT_HI, uint16_t);

View File

@ -225,8 +225,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
* 0x00324 - 0x00327: Interruptable BIOS stall cycles
* 0x00328 - 0x00367: Matrix memory mapping table
* 0x00368 - 0x0036F: Reserved (leave zero)
* 0x00370 - 0x00377: Audio FIFO A samples
* 0x00378 - 0x0037F: Audio FIFO B samples
* 0x00370 - 0x0037F: Audio FIFO A samples
* 0x00380 - 0x0038F: Audio FIFO B samples
* 0x00380 - 0x003FF: Reserved (leave zero)
* 0x00400 - 0x007FF: I/O memory
* 0x00800 - 0x00BFF: Palette
@ -387,11 +387,11 @@ struct GBASerializedState {
uint32_t reservedMatrix[2];
struct {
int8_t chA[8];
int8_t chB[8];
int8_t chA[16];
int8_t chB[16];
} samples;
uint32_t reserved[32];
uint32_t reserved[28];
uint16_t io[SIZE_IO >> 1];
uint16_t pram[SIZE_PALETTE_RAM >> 1];

View File

@ -566,29 +566,28 @@ void GBAudioRun(struct GBAudio* audio, int32_t timestamp, int channels) {
cycles <<= audio->ch4.frequency;
cycles *= 8 * audio->timingFactor;
int32_t last = 0;
int32_t diff = timestamp - audio->ch4.lastEvent;
int samples = 0;
int positiveSamples = 0;
int lsb;
int coeff = 0x60;
if (!audio->ch4.power) {
coeff <<= 8;
}
for (; last + cycles <= diff; last += cycles) {
lsb = audio->ch4.lfsr & 1;
audio->ch4.lfsr >>= 1;
audio->ch4.lfsr ^= lsb * coeff;
++samples;
positiveSamples += lsb;
}
if (samples) {
if (diff >= cycles) {
int32_t last;
int samples = 0;
int positiveSamples = 0;
int lsb;
int coeff = 0x60;
if (!audio->ch4.power) {
coeff <<= 8;
}
for (last = 0; last + cycles <= diff; last += cycles) {
lsb = audio->ch4.lfsr & 1;
audio->ch4.lfsr >>= 1;
audio->ch4.lfsr ^= lsb * coeff;
++samples;
positiveSamples += lsb;
}
audio->ch4.sample = lsb * audio->ch4.envelope.currentVolume;
audio->ch4.nSamples += samples;
audio->ch4.samples += positiveSamples * audio->ch4.envelope.currentVolume;
audio->ch4.lastEvent += last;
}
audio->ch4.lastEvent += last;
}
}

View File

@ -25,7 +25,7 @@ mLOG_DEFINE_CATEGORY(GBA_AUDIO, "GBA Audio", "gba.audio");
const unsigned GBA_AUDIO_SAMPLES = 2048;
const int GBA_AUDIO_VOLUME_MAX = 0x100;
static const int SAMPLE_INTERVAL = GBA_ARM7TDMI_FREQUENCY / 0x8000;
static const int SAMPLE_INTERVAL = GBA_ARM7TDMI_FREQUENCY / 0x4000;
static const int CLOCKS_PER_FRAME = 0x800;
static int _applyBias(struct GBAAudio* audio, int sample);
@ -305,14 +305,11 @@ void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles) {
}
}
int32_t until = mTimingUntil(&audio->p->timing, &audio->sampleEvent) - 1;
int bits = 1 << GBARegisterSOUNDBIASGetResolution(audio->soundbias);
int bits = 2 << GBARegisterSOUNDBIASGetResolution(audio->soundbias);
until += 1 << (9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias));
until >>= 9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias);
int i;
for (i = bits - until; i < bits; ++i) {
if (i < 0 || i >= bits) {
abort();
}
channel->samples[i] = channel->internalSample;
}
if (channel->internalRemaining) {
@ -333,8 +330,8 @@ static int _applyBias(struct GBAAudio* audio, int sample) {
static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) {
struct GBAAudio* audio = user;
int16_t samplesLeft[8];
int16_t samplesRight[8];
int16_t samplesLeft[GBA_MAX_SAMPLES];
int16_t samplesRight[GBA_MAX_SAMPLES];
int32_t timestamp = mTimingCurrentTime(&audio->p->timing) - cyclesLate - SAMPLE_INTERVAL;
int sample;
for (sample = 0; sample * audio->sampleInterval < (int32_t) SAMPLE_INTERVAL; ++sample) {