mirror of https://github.com/mgba-emu/mgba.git
GBA Audio: Claw back some performance
This commit is contained in:
parent
f4217a7a77
commit
9f5267e24e
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue