aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/audio/SDL/sdl_audio.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-01-12 21:48:33 +0800
committerchai <chaifix@163.com>2019-01-12 21:48:33 +0800
commit8b00d67febf133e89f6a0bfabc41feed555dc4a9 (patch)
treefe48ef17c250afa40c2588300fcdb5920dba6951 /src/libjin/audio/SDL/sdl_audio.cpp
parenta907c39756ef6b368d06643afa491c49a9044a8e (diff)
*去掉文件前缀je_
Diffstat (limited to 'src/libjin/audio/SDL/sdl_audio.cpp')
-rw-r--r--src/libjin/audio/SDL/sdl_audio.cpp146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/libjin/audio/SDL/sdl_audio.cpp b/src/libjin/audio/SDL/sdl_audio.cpp
new file mode 100644
index 0000000..4c4bcc2
--- /dev/null
+++ b/src/libjin/audio/SDL/sdl_audio.cpp
@@ -0,0 +1,146 @@
+#include "../../core/configuration.h"
+#if defined(jin_audio) && (jin_audio == jin_audio_sdl)
+
+#include <iostream>
+
+#include "../../math/math.h"
+#include "../../utils/log.h"
+
+#include "sdl_audio.h"
+#include "sdl_source.h"
+
+using namespace JinEngine::Math;
+
+namespace JinEngine
+{
+ namespace Audio
+ {
+ namespace SDL
+ {
+
+ /* עcallbackƵ̵߳ */
+ static void defaultCallback(void *userdata, Uint8 *stream, int size)
+ {
+ static SDLAudio* audio = static_cast<SDLAudio*>(userdata);
+ if (!audio->goOnProcess())
+ return;
+ audio->lock();
+ audio->processCommands();
+ audio->processSources(stream, size);
+ audio->processBuffer(stream, size);
+ audio->unlock();
+ }
+
+ /*call only once*/ bool SDLAudio::startSystem(const SettingBase* s)
+ {
+ jin_log_info("Initialize audio system.");
+
+ if (SDL_Init(SDL_INIT_AUDIO) < 0)
+ return false;
+
+ SDL_AudioSpec spec;
+ Setting* setting = (Setting*)s;
+ if (setting == nullptr)
+ return false;
+
+ unsigned int samplerate = setting->samplerate;
+ unsigned int samples = clamp<int>(setting->samples, 1, setting->samplerate);
+
+ spec.freq = samplerate; // ÿsample,õ 11025, 22050, 44100 and 48000 Hz.
+ spec.format = AUDIO_S16SYS; // signed 16-bit samples in native byte order
+ spec.channels = SDLAUDIO_CHANNELS; //
+ spec.samples = samples; // ÿβʱһã=setting->samplerateÿֻ1
+ spec.userdata = this;
+ spec.callback = defaultCallback;
+
+ audioDevice = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0);
+ if (audioDevice == 0)
+ return false;
+ /* start audio */
+ SDL_PauseAudioDevice(audioDevice, 0);
+ return true;
+ }
+
+ /*call only once*/ void SDLAudio::quitSystem()
+ {
+ jin_log_info("Quit audio system.");
+ SDL_CloseAudio();
+ }
+
+ void SDLAudio::lock()
+ {
+ SDL_LockAudioDevice(audioDevice);
+ }
+
+ void SDLAudio::unlock()
+ {
+ SDL_UnlockAudioDevice(audioDevice);
+ }
+
+ bool SDLAudio::goOnProcess()
+ {
+ if (state == SDLAudio::State::STOP)
+ {
+ SDLSourceManager::get()->removeAllSource();
+ pause();
+ return false;
+ }
+ else if (state == SDLAudio::State::PAUSE)
+ return false;
+ else
+ return true;
+ }
+
+ void SDLAudio::processCommands()
+ {
+ SDLSourceManager::get()->processCommands();
+ }
+
+ void SDLAudio::processSources(void* buffer, size_t len)
+ {
+ SDLSourceManager::get()->processSources(buffer, len);
+ }
+
+ void SDLAudio::processBuffer(void* buff, size_t len)
+ {
+ short* buffer = (short*)buff;
+ int samples = (len / SDLAUDIO_BYTEDEPTH) >> 1; // ˫
+ const char L = 0, R = 1;
+ for (int i = 0; i < samples; ++i)
+ {
+ short* clip = buffer + (i << 1);
+ clip[L] *= volume;
+ clip[R] *= volume;
+ }
+ }
+
+ void SDLAudio::play()
+ {
+ state = State::PLAY;
+ }
+
+ void SDLAudio::stop()
+ {
+ state = State::STOP;
+ }
+
+ void SDLAudio::pause()
+ {
+ state = State::PAUSE;
+ }
+
+ void SDLAudio::resume()
+ {
+ state = State::PLAY;
+ }
+
+ void SDLAudio::setVolume(float volume)
+ {
+ this->volume = clamp(volume, 0.0f, 1.0f);
+ }
+
+ } // namespace SDL
+ } // namespace Audio
+} // namespace JinEngine
+
+#endif // (jin_audio) && (jin_audio == jin_audio_sdl) \ No newline at end of file