all repos — mgba @ a79a592c1e8edabe908e15e77190b8c1fbf8d50e

mGBA Game Boy Advance Emulator

Move audio resampling out of SDL code
Jeffrey Pfau jeffrey@endrift.com
Tue, 28 Jan 2014 23:52:28 -0800
commit

a79a592c1e8edabe908e15e77190b8c1fbf8d50e

parent

2e2ca19220c6ce39079c95e5eb923af02fcf4a69

3 files changed, 44 insertions(+), 2 deletions(-)

jump to
M src/gba/gba-audio.csrc/gba/gba-audio.c

@@ -6,6 +6,7 @@ #include "gba-serialize.h"

#include "gba-thread.h" #include <limits.h> +#include <math.h> const unsigned GBA_AUDIO_SAMPLES = 512; const unsigned GBA_AUDIO_FIFO_SIZE = 8 * sizeof(int32_t);

@@ -417,6 +418,41 @@ read = read >= readR ? read : readR;

} GBASyncConsumeAudio(audio->p->sync); return read; +} + +void GBAAudioResampleNN(struct GBAAudio* audio, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples) { + int32_t left[GBA_AUDIO_SAMPLES]; + int32_t right[GBA_AUDIO_SAMPLES]; + + // toRead is in GBA samples + // TODO: Do this with fixed-point math + unsigned toRead = ceilf(nSamples / ratio); + while (nSamples) { + unsigned currentRead = GBA_AUDIO_SAMPLES; + if (currentRead > toRead) { + currentRead = toRead; + } + unsigned read = GBAAudioCopy(audio, left, right, currentRead); + toRead -= read; + unsigned i; + for (i = 0; i < read; ++i) { + *drift += ratio; + while (*drift >= 1.f) { + output->left = left[i]; + output->right = right[i]; + ++output; + --nSamples; + *drift -= 1.f; + if (!nSamples) { + return; + } + } + } + if (read < currentRead) { + memset(output, 0, nSamples * sizeof(struct GBAStereoSample)); + return; + } + } } static int32_t _updateSquareChannel(struct GBAAudioSquareControl* control, int duty) {
M src/gba/gba-audio.hsrc/gba/gba-audio.h

@@ -7,7 +7,7 @@ #include <stdint.h>

struct GBADMA; -const unsigned GBA_AUDIO_SAMPLES; +extern const unsigned GBA_AUDIO_SAMPLES; struct GBAAudioEnvelope { union {

@@ -204,6 +204,11 @@

int32_t sampleInterval; }; +struct GBAStereoSample { + int16_t left; + int16_t right; +}; + void GBAAudioInit(struct GBAAudio* audio); void GBAAudioDeinit(struct GBAAudio* audio);

@@ -229,6 +234,7 @@ void GBAAudioWriteFIFO(struct GBAAudio* audio, int address, uint32_t value);

void GBAAudioSampleFIFO(struct GBAAudio* audio, int fifoId, int32_t cycles); unsigned GBAAudioCopy(struct GBAAudio* audio, void* left, void* right, unsigned nSamples); +void GBAAudioResampleNN(struct GBAAudio*, float ratio, float* drift, struct GBAStereoSample* output, unsigned nSamples); struct GBASerializedState; void GBAAudioSerialize(const struct GBAAudio* audio, struct GBASerializedState* state);
M src/gba/gba.hsrc/gba/gba.h

@@ -7,7 +7,7 @@ #include "gba-memory.h"

#include "gba-video.h" #include "gba-audio.h" -const uint32_t GBA_ARM7TDMI_FREQUENCY; +extern const uint32_t GBA_ARM7TDMI_FREQUENCY; enum GBAIRQ { IRQ_VBLANK = 0x0,