diff options
author | chai <chaifix@163.com> | 2018-05-30 08:22:30 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-05-30 08:22:30 +0800 |
commit | 5298bdefd7f7875ae8b7cb6c9201e3321af62011 (patch) | |
tree | 7c750cef72035102ba012959f1914f4d560cd5a5 /src/libjin/audio/sdl/source.cpp | |
parent | aa42143689d539ca2e64c37433533b03c1dd2024 (diff) |
更改回调函数
Diffstat (limited to 'src/libjin/audio/sdl/source.cpp')
-rw-r--r-- | src/libjin/audio/sdl/source.cpp | 76 |
1 files changed, 36 insertions, 40 deletions
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<SDLSource*>::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<SDLSource*>::iterator it = sources.begin(); |