diff options
author | chai <chaifix@163.com> | 2018-05-28 17:01:54 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2018-05-28 17:01:54 +0800 |
commit | aa9393254a8a9deec3db5b17539a9be273965b07 (patch) | |
tree | 347e2f6d4151f6209bc96cf093dde0b9f77498b6 /src/libjin/audio/sdl/source.cpp | |
parent | 0dbddeaeccfd4e34f200ad915f1028ce2140d988 (diff) |
更新音频模块
Diffstat (limited to 'src/libjin/audio/sdl/source.cpp')
-rw-r--r-- | src/libjin/audio/sdl/source.cpp | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/src/libjin/audio/sdl/source.cpp b/src/libjin/audio/sdl/source.cpp index fc0a2fe..1537d2f 100644 --- a/src/libjin/audio/sdl/source.cpp +++ b/src/libjin/audio/sdl/source.cpp @@ -55,11 +55,8 @@ namespace audio shared Manager* Manager::manager = nullptr; SDLSource::SDLSource(Type format, void* mem, int size) - : pos(0) - , pitch(0) - , status(0) - , loop(false) { + memset(&status, 0, sizeof(status)); memset(&raw, 0, sizeof(raw)); try { @@ -85,12 +82,12 @@ namespace audio if (wav_read(&wav, mem, size) == 0) { raw.data = wav.data; - raw.length = wav.length; - raw.end = (char*)raw.data + raw.length; - raw.rate = wav.samplerate; - raw.bitdepth = wav.bitdepth; - raw.samples = wav.length / (wav.bitdepth / 8.f); - raw.channel = wav.channels; + raw.size = wav.length * wav.bitdepth / 8; + raw.end = (char*)raw.data + raw.size; + raw.rate = wav.samplerate; + raw.bitdepth = wav.bitdepth; + raw.samples = raw.size / (wav.bitdepth / 8.f); + raw.channel = wav.channels; raw.silence = 0; } else @@ -99,7 +96,12 @@ 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); + raw.samples = stb_vorbis_decode_memory((unsigned char*)mem, size, (int*)&raw.channel, &raw.rate, (short**)&raw.data) << 1; + raw.size = raw.samples << 1; // 2 bytes each sample + raw.bitdepth = 16; + raw.end = (char*)raw.data + raw.size; + raw.silence = 0; + if (raw.samples < 0) { throw SourceException(); @@ -159,14 +161,15 @@ Manager::get()->pushCommand(cmd); \ ActionNone(Rewind); } - void SDLSource::isStopped() const + inline bool SDLSource::isStopped() const { - + return is(STOPPED); } - void SDLSource::isPaused() const {} - - void SDLSource::isFinished() const {} + bool SDLSource::isPaused() const + { + return is(PAUSED); + } void SDLSource::setPitch(float pitch) { @@ -208,28 +211,32 @@ Manager::get()->pushCommand(cmd); \ case Command::Action::Play: removeSource(source); pushSource(source); - source->status = PLAYING; - source->pos = 0; // rewind + source->status.state = PLAYING; + source->status.pos = 0; // rewind break; case Command::Action::Stop: manager->removeSource(source); - source->status = STOPPED; - source->pos = 0; // rewind + source->status.state = STOPPED; + source->status.pos = 0; // rewind break; case Command::Action::Pause: - source->status = PAUSED; + manager->removeSource(source); + source->status.state = PAUSED; break; case Command::Action::Resume: - source->status = PLAYING; + manager->removeSource(source); + manager->pushSource(source); + source->status.state = PLAYING; break; case Command::Action::Rewind: - source->status = PLAYING; - source->pos = 0; + source->status.state = PLAYING; + source->status.pos = 0; break; case Command::Action::SetVolume: + //float cmd->parameter._float; break; case Command::Action::SetLoop: - source->loop = cmd->parameter._boolean; + source->status.loop = cmd->parameter._boolean; break; /*case Command::Action::SetRate: */ @@ -246,7 +253,7 @@ Manager::get()->pushCommand(cmd); \ int samples = len >> 1; std::vector<SDLSource*>::iterator it = sources.begin(); SDLSource* source = nullptr; - for (; it != sources.end(); ++it) + for (; it != sources.end();) { source = *it; int16_t* data16 = (int16_t*)source->raw.data; @@ -256,49 +263,50 @@ Manager::get()->pushCommand(cmd); \ continue; else if (source->is(PLAYING)) { - int16_t* src16 = (int16_t*)((char*)source->raw.data + source->pos); - int remainsample = (source->raw.length - source->pos) >> 1; + 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 < samples; ++i) + for (int i = 0; i < bound; ++i) { buf16[i] += src16[i]; // mix sources } - source->pos += (samples << 1); + source->status.pos += (bound << 1); if (remainsample < samples) { - if (source->loop) + if (source->status.loop) { - /* int j = 0; + int j = 0; for (int i = bound; i < samples; ++i) { int val = data16[j]; buf16[i] += val; ++j; - }*/ - //sources.erase(it); - //source->pos = (j << 1); - source->pos = 0; + } + source->status.pos = (j << 1); break; } else { + it = sources.erase(it); + continue; } - } } + ++it; } } shared void Manager::removeSource(SDLSource* source) { std::vector<SDLSource*>::iterator it = sources.begin(); - for (it = sources.begin(); it != sources.end(); ++it) + for (it = sources.begin(); it != sources.end(); ) { if (*it == source) { - sources.erase(it); + it = sources.erase(it); return; } + ++it; } } |