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

View File

@ -225,8 +225,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
* 0x00324 - 0x00327: Interruptable BIOS stall cycles * 0x00324 - 0x00327: Interruptable BIOS stall cycles
* 0x00328 - 0x00367: Matrix memory mapping table * 0x00328 - 0x00367: Matrix memory mapping table
* 0x00368 - 0x0036F: Reserved (leave zero) * 0x00368 - 0x0036F: Reserved (leave zero)
* 0x00370 - 0x00377: Audio FIFO A samples * 0x00370 - 0x0037F: Audio FIFO A samples
* 0x00378 - 0x0037F: Audio FIFO B samples * 0x00380 - 0x0038F: Audio FIFO B samples
* 0x00380 - 0x003FF: Reserved (leave zero) * 0x00380 - 0x003FF: Reserved (leave zero)
* 0x00400 - 0x007FF: I/O memory * 0x00400 - 0x007FF: I/O memory
* 0x00800 - 0x00BFF: Palette * 0x00800 - 0x00BFF: Palette
@ -387,11 +387,11 @@ struct GBASerializedState {
uint32_t reservedMatrix[2]; uint32_t reservedMatrix[2];
struct { struct {
int8_t chA[8]; int8_t chA[16];
int8_t chB[8]; int8_t chB[16];
} samples; } samples;
uint32_t reserved[32]; uint32_t reserved[28];
uint16_t io[SIZE_IO >> 1]; uint16_t io[SIZE_IO >> 1];
uint16_t pram[SIZE_PALETTE_RAM >> 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 <<= audio->ch4.frequency;
cycles *= 8 * audio->timingFactor; cycles *= 8 * audio->timingFactor;
int32_t last = 0;
int32_t diff = timestamp - audio->ch4.lastEvent; int32_t diff = timestamp - audio->ch4.lastEvent;
int samples = 0; if (diff >= cycles) {
int positiveSamples = 0; int32_t last;
int lsb; int samples = 0;
int coeff = 0x60; int positiveSamples = 0;
if (!audio->ch4.power) { int lsb;
coeff <<= 8; int coeff = 0x60;
} if (!audio->ch4.power) {
for (; last + cycles <= diff; last += cycles) { coeff <<= 8;
lsb = audio->ch4.lfsr & 1; }
audio->ch4.lfsr >>= 1; for (last = 0; last + cycles <= diff; last += cycles) {
audio->ch4.lfsr ^= lsb * coeff; lsb = audio->ch4.lfsr & 1;
++samples; audio->ch4.lfsr >>= 1;
positiveSamples += lsb; audio->ch4.lfsr ^= lsb * coeff;
} ++samples;
if (samples) { positiveSamples += lsb;
}
audio->ch4.sample = lsb * audio->ch4.envelope.currentVolume; audio->ch4.sample = lsb * audio->ch4.envelope.currentVolume;
audio->ch4.nSamples += samples; audio->ch4.nSamples += samples;
audio->ch4.samples += positiveSamples * audio->ch4.envelope.currentVolume; 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 unsigned GBA_AUDIO_SAMPLES = 2048;
const int GBA_AUDIO_VOLUME_MAX = 0x100; 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 const int CLOCKS_PER_FRAME = 0x800;
static int _applyBias(struct GBAAudio* audio, int sample); 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; 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 += 1 << (9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias));
until >>= 9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias); until >>= 9 - GBARegisterSOUNDBIASGetResolution(audio->soundbias);
int i; int i;
for (i = bits - until; i < bits; ++i) { for (i = bits - until; i < bits; ++i) {
if (i < 0 || i >= bits) {
abort();
}
channel->samples[i] = channel->internalSample; channel->samples[i] = channel->internalSample;
} }
if (channel->internalRemaining) { 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) { static void _sample(struct mTiming* timing, void* user, uint32_t cyclesLate) {
struct GBAAudio* audio = user; struct GBAAudio* audio = user;
int16_t samplesLeft[8]; int16_t samplesLeft[GBA_MAX_SAMPLES];
int16_t samplesRight[8]; int16_t samplesRight[GBA_MAX_SAMPLES];
int32_t timestamp = mTimingCurrentTime(&audio->p->timing) - cyclesLate - SAMPLE_INTERVAL; int32_t timestamp = mTimingCurrentTime(&audio->p->timing) - cyclesLate - SAMPLE_INTERVAL;
int sample; int sample;
for (sample = 0; sample * audio->sampleInterval < (int32_t) SAMPLE_INTERVAL; ++sample) { for (sample = 0; sample * audio->sampleInterval < (int32_t) SAMPLE_INTERVAL; ++sample) {