aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/audio/sdl/source.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-05-28 17:01:54 +0800
committerchai <chaifix@163.com>2018-05-28 17:01:54 +0800
commitaa9393254a8a9deec3db5b17539a9be273965b07 (patch)
tree347e2f6d4151f6209bc96cf093dde0b9f77498b6 /src/libjin/audio/sdl/source.cpp
parent0dbddeaeccfd4e34f200ad915f1028ce2140d988 (diff)
更新音频模块
Diffstat (limited to 'src/libjin/audio/sdl/source.cpp')
-rw-r--r--src/libjin/audio/sdl/source.cpp86
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;
}
}