aboutsummaryrefslogtreecommitdiff
path: root/src
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
parent0dbddeaeccfd4e34f200ad915f1028ce2140d988 (diff)
更新音频模块
Diffstat (limited to 'src')
-rw-r--r--src/libjin/audio/sdl/audio.cpp2
-rw-r--r--src/libjin/audio/sdl/source.cpp86
-rw-r--r--src/libjin/audio/sdl/source.h28
-rw-r--r--src/libjin/audio/source.h5
-rw-r--r--src/libjin/utils/unittest.cpp12
5 files changed, 75 insertions, 58 deletions
diff --git a/src/libjin/audio/sdl/audio.cpp b/src/libjin/audio/sdl/audio.cpp
index 5277a3d..b5cbc1b 100644
--- a/src/libjin/audio/sdl/audio.cpp
+++ b/src/libjin/audio/sdl/audio.cpp
@@ -24,7 +24,7 @@ namespace audio
zero(spec);
spec.freq = 44100;
spec.format = AUDIO_S16SYS;
- spec.channels = 1;
+ spec.channels = 2;
spec.samples = 2048;
spec.userdata = this;
spec.callback = defaultCallback;
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;
}
}
diff --git a/src/libjin/audio/sdl/source.h b/src/libjin/audio/sdl/source.h
index d97590e..29a3676 100644
--- a/src/libjin/audio/sdl/source.h
+++ b/src/libjin/audio/sdl/source.h
@@ -35,10 +35,10 @@ namespace audio
void pause() override;
void resume() override;
void rewind() override;
- void isStopped() const override;
- void isPaused() const override;
- void isFinished() const override;
+ bool isStopped() const override;
+ bool isPaused() const override;
void setPitch(float pitch) override;
+ // Ͻ
void setVolume(float volume) override;
bool setLoop(bool loop) override;
void setRate(float rate) override;
@@ -50,25 +50,29 @@ namespace audio
void loadWAV(void* mem, int size);
void loadOGG(void* mem, int size);
- inline bool is(int state) { return (status & state) == state; }
+ inline bool is(int state) const { return (status.state & state) == state; }
struct
{
- const void* data; // Ƶ
- int length; // dataֽڳ
- void* end; // dataβ = (unsigned char*)data + length
+ const void* data; // Ƶ
+ int size; // dataֽڳ
+ const void* end; // dataβ = (unsigned char*)data + size
int rate; // Ƶ
unsigned char bitdepth; // ÿsampleıس
- int samples; // sample = length / (bitdepth / 8)
+ int samples; // sample = size / (bitdepth / 8)
unsigned char channel; // channel12
char silence; // 0
} raw;
/* Procedure controller variable */
- int pos; // ǰŵλ
- int pitch; // pitch
- int status; // ǰ״̬
- bool loop; // loop or not
+ struct
+ {
+ int pos; // ǰŵλ
+ int pitch; // pitch
+ int state; // ǰ״̬
+ bool loop; // loop or not
+ int volume; //
+ } status;
};
diff --git a/src/libjin/audio/source.h b/src/libjin/audio/source.h
index b625758..2933fe9 100644
--- a/src/libjin/audio/source.h
+++ b/src/libjin/audio/source.h
@@ -18,9 +18,8 @@ namespace audio
virtual void pause() = 0;
virtual void resume() = 0;
virtual void rewind() = 0;
- virtual void isStopped() const = 0;
- virtual void isPaused() const = 0;
- virtual void isFinished() const = 0;
+ virtual bool isStopped() const = 0;
+ virtual bool isPaused() const = 0;
virtual void setPitch(float pitch) = 0;
virtual void setVolume(float volume) = 0;
virtual bool setLoop(bool loop) = 0;
diff --git a/src/libjin/utils/unittest.cpp b/src/libjin/utils/unittest.cpp
index df1a2b6..2c2985b 100644
--- a/src/libjin/utils/unittest.cpp
+++ b/src/libjin/utils/unittest.cpp
@@ -16,14 +16,20 @@ int main(int argc, char* argv[])
Audio* audio = SDLAudio::get();
audio->init(0);
ifstream fs;
- fs.open("a.wav", ios::binary);
+ fs.open("a.ogg", ios::binary);
fs.read(buf, length);
- SDLSource source(SDLSource::WAV, buf, length);
+ SDLSource source(SDLSource::OGG, buf, length);
source.play();
source.setLoop(true);
+ int i = 0;
while (true)
{
- SDL_Delay(100);
+ i += 1;
+ if (i == 10)
+ {
+ source.resume();
+ }
+ SDL_Delay(1000);
}
audio->quit();
return 0;