From 5298bdefd7f7875ae8b7cb6c9201e3321af62011 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 30 May 2018 08:22:30 +0800 Subject: =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=9B=9E=E8=B0=83=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libjin/audio/sdl/source.cpp | 76 +++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 40 deletions(-) (limited to 'src/libjin/audio/sdl/source.cpp') diff --git a/src/libjin/audio/sdl/source.cpp b/src/libjin/audio/sdl/source.cpp index e8490f5..3686a92 100644 --- a/src/libjin/audio/sdl/source.cpp +++ b/src/libjin/audio/sdl/source.cpp @@ -38,6 +38,12 @@ namespace audio SDLSource* source; }; + typedef enum CHANNEL + { + MONO = 1, // µ¥ÉùµÀ + STEREO = 2, // Á¢ÌåÉù + }; + typedef MASK enum STATUS { PLAYING = 1, @@ -122,7 +128,7 @@ namespace audio raw.rate = wav.samplerate; raw.bitdepth = wav.bitdepth; raw.samples = raw.size / (wav.bitdepth / 8.f); - raw.channel = wav.channels; + raw.channel = clamp(wav.channels, CHANNEL::MONO, CHANNEL::STEREO); raw.silence = 0; } else @@ -132,6 +138,7 @@ namespace audio void SDLSource::loadOGG(void* mem, int size) { raw.samples = stb_vorbis_decode_memory((unsigned char*)mem, size, (int*)&raw.channel, &raw.rate, (short**)&raw.data) << 1; + raw.channel = clamp(raw.channel, CHANNEL::MONO, CHANNEL::STEREO); raw.size = raw.samples << 1; // 2 bytes each sample raw.bitdepth = 16; raw.end = (char*)raw.data + raw.size; @@ -275,56 +282,45 @@ Manager::get()->pushCommand(cmd); \ } } - shared void Manager::processSources(Uint8* buffer, int len) + /* AUDIO_S16SYS[size>>1] buffer */ + shared void Manager::processSources(void* buf, size_t size) { - memset(buffer, 0, len); - int16_t* buf16 = (int16_t*)buffer; - int samples = len >> 1; + Sint16* buffer = (Sint16*)buf; + unsigned int samples = size >> 1; + memset(buffer, 0, size); + SDLSource* src = nullptr; std::vector::iterator it = sources.begin(); - SDLSource* source = nullptr; for (; it != sources.end();) { - source = *it; - int16_t* data16 = (int16_t*)source->raw.data; - if (source->is(STOPPED)) - removeSource(source); - else if (source->is(PAUSED)) - continue; - else if (source->is(PLAYING)) + src = *it; + if (src == nullptr) + goto next; + src->status.pos; + Sint16* source = (Sint16*)((char*)src->raw.data + src->status.pos); + unsigned int remain = src->raw.samples - (src->status.pos >> 1); + for (int i = 0; i < min(remain, samples); ++i) { - int16_t* src16 = (int16_t*)((char*)source->raw.data + source->status.pos); - int remainsample = (source->raw.size - source->status.pos) >> 1; - int bound = min(samples, remainsample); - for (int i = 0; i < bound; ++i) - { - buf16[i] += src16[i]; // mix sources - } - source->status.pos += (bound << 1); - if (remainsample < samples) + buffer[i] += (src->raw.channel == CHANNEL::STEREO ? source[i] : source[(i % 2) * 2]); + } + if (remain < samples) + { + if (!src->status.loop) { - if (source->status.loop) - { - int j = 0; - for (int i = bound; i < samples; ++i) - { - int val = data16[j]; - buf16[i] += val; - ++j; - } - source->status.pos = (j << 1); - break; - } - else - { - it = sources.erase(it); - continue; - } + it = sources.erase(it); + continue; } + int j = 0; + for (int i = samples - remain; i < samples; ++i, ++j) + buffer[i] += (src->raw.channel == CHANNEL::STEREO ? source[j] : source[j % 2 * 2]); + src->status.pos = (j << 1); + continue; } + src->status.pos += (samples << 1); + next: ++it; } } - + shared void Manager::removeSource(SDLSource* source) { std::vector::iterator it = sources.begin(); -- cgit v1.1-26-g67d0