diff options
Diffstat (limited to 'src/libjin/audio/SDL/sdl_audio.cpp')
-rw-r--r-- | src/libjin/audio/SDL/sdl_audio.cpp | 146 |
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 |