mirror of
https://github.com/libSDL2pp/libSDL2pp.git
synced 2025-08-03 10:55:57 -04:00
Add wrapper for large part of SDL2 audio functionality
This commit is contained in:
parent
bb1c4bf168
commit
2be68a9ebb
@ -5,6 +5,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
|
||||
# there are functions present on wiki, but not yet in stable SDL2 releases;
|
||||
# we hide these under following options
|
||||
OPTION(SDL2PP_NEW_2_0_4 "Enable new SDL2 functions present since SDL2 2.0.4" OFF)
|
||||
|
||||
IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
OPTION(SDL2PP_WITH_IMAGE "Enable SDL2_image support" ON)
|
||||
ELSE(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
@ -45,6 +49,9 @@ INCLUDE_DIRECTORIES(BEFORE ${PROJECT_BINARY_DIR})
|
||||
|
||||
# sources
|
||||
SET(LIBRARY_SOURCES
|
||||
SDL2pp/AudioDevice.cc
|
||||
SDL2pp/AudioLock.cc
|
||||
SDL2pp/AudioSpec.cc
|
||||
SDL2pp/Exception.cc
|
||||
SDL2pp/Point.cc
|
||||
SDL2pp/RWops.cc
|
||||
@ -57,6 +64,7 @@ SET(LIBRARY_SOURCES
|
||||
)
|
||||
|
||||
SET(LIBRARY_HEADERS
|
||||
SDL2pp/Audio.hh
|
||||
SDL2pp/Exception.hh
|
||||
SDL2pp/ExtraRWops.hh
|
||||
SDL2pp/Point.hh
|
||||
|
108
SDL2pp/Audio.hh
Normal file
108
SDL2pp/Audio.hh
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
libSDL2pp - C++ wrapper for libSDL2
|
||||
Copyright (C) 2014 Dmitry Marakasov <amdmi3@amdmi3.ru>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL2PP_AUDIO_HH
|
||||
#define SDL2PP_AUDIO_HH
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <SDL2/SDL_audio.h>
|
||||
|
||||
#include <SDL2pp/Config.hh>
|
||||
|
||||
namespace SDL2pp {
|
||||
|
||||
class AudioSpec : public SDL_AudioSpec {
|
||||
public:
|
||||
typedef std::function<void(Uint8* stream, int len)> AudioCallback;
|
||||
|
||||
private:
|
||||
AudioCallback callback_;
|
||||
|
||||
private:
|
||||
static void SDLCallback(void *userdata, Uint8* stream, int len);
|
||||
|
||||
public:
|
||||
AudioSpec(int freq, SDL_AudioFormat format, Uint8 channels, Uint16 samples, AudioCallback&& callback);
|
||||
~AudioSpec();
|
||||
|
||||
AudioSpec(AudioSpec&& other) noexcept;
|
||||
AudioSpec& operator=(AudioSpec&& other) noexcept;
|
||||
AudioSpec(const AudioSpec& other) = delete;
|
||||
AudioSpec& operator=(const AudioSpec& other) = delete;
|
||||
|
||||
void ChangeCallback(AudioCallback&& callback); // should be called with audio device using this spec locked!
|
||||
|
||||
void MergeChanges(const SDL_AudioSpec& obtained);
|
||||
const SDL_AudioSpec* Get() const;
|
||||
};
|
||||
|
||||
class AudioDevice {
|
||||
private:
|
||||
SDL_AudioDeviceID device_id_;
|
||||
|
||||
public:
|
||||
class LockHandle {
|
||||
friend class AudioDevice;
|
||||
private:
|
||||
AudioDevice* device_;
|
||||
|
||||
private:
|
||||
LockHandle(AudioDevice* device);
|
||||
|
||||
public:
|
||||
~LockHandle();
|
||||
|
||||
LockHandle(LockHandle&& other) noexcept;
|
||||
LockHandle& operator=(LockHandle&& other) noexcept;
|
||||
|
||||
LockHandle(const LockHandle& other) = delete;
|
||||
LockHandle& operator=(const LockHandle& other) = delete;
|
||||
};
|
||||
|
||||
public:
|
||||
AudioDevice(const std::string& device, bool iscapture, const AudioSpec& spec);
|
||||
AudioDevice(const std::string& device, bool iscapture, AudioSpec& spec, int allowed_changes);
|
||||
virtual ~AudioDevice();
|
||||
|
||||
AudioDevice(const AudioDevice& other) = delete;
|
||||
AudioDevice(AudioDevice&& other) noexcept;
|
||||
AudioDevice& operator=(const AudioDevice& other) = delete;
|
||||
AudioDevice& operator=(AudioDevice&& other) noexcept;
|
||||
|
||||
SDL_AudioDeviceID Get() const;
|
||||
|
||||
void Pause(bool pause_on);
|
||||
SDL_AudioStatus GetStatus() const;
|
||||
|
||||
LockHandle Lock();
|
||||
|
||||
#ifdef SDL2PP_NEW_2_0_4
|
||||
void QueueAudio(const void* data, Uint32 len);
|
||||
void ClearQueuedAudio();
|
||||
Uint32 GetQueuedAudioSize() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
94
SDL2pp/AudioDevice.cc
Normal file
94
SDL2pp/AudioDevice.cc
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
libSDL2pp - C++ wrapper for libSDL2
|
||||
Copyright (C) 2014 Dmitry Marakasov <amdmi3@amdmi3.ru>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <SDL2pp/Exception.hh>
|
||||
|
||||
#include <SDL2pp/Audio.hh>
|
||||
|
||||
namespace SDL2pp {
|
||||
|
||||
AudioDevice::AudioDevice(const std::string& device, bool iscapture, const AudioSpec& spec) {
|
||||
SDL_AudioSpec obtained;
|
||||
|
||||
if ((device_id_ = SDL_OpenAudioDevice(device.empty() ? nullptr : device.c_str(), iscapture ? 1 : 0, &spec, &obtained, 0)) == 0)
|
||||
throw Exception("SDL_OpenAudioDevice failed");
|
||||
}
|
||||
|
||||
AudioDevice::AudioDevice(const std::string& device, bool iscapture, AudioSpec& spec, int allowed_changes) {
|
||||
SDL_AudioSpec obtained;
|
||||
|
||||
if ((device_id_ = SDL_OpenAudioDevice(device.empty() ? nullptr : device.c_str(), iscapture ? 1 : 0, &spec, &obtained, allowed_changes)) == 0)
|
||||
throw Exception("SDL_OpenAudioDevice failed");
|
||||
|
||||
spec.MergeChanges(obtained);
|
||||
}
|
||||
|
||||
AudioDevice::~AudioDevice() {
|
||||
if (device_id_ != 0)
|
||||
SDL_CloseAudioDevice(device_id_);
|
||||
}
|
||||
|
||||
AudioDevice::AudioDevice(AudioDevice&& other) noexcept : device_id_(other.device_id_) {
|
||||
other.device_id_ = 0;
|
||||
}
|
||||
|
||||
AudioDevice& AudioDevice::operator=(AudioDevice&& other) noexcept {
|
||||
if (device_id_)
|
||||
SDL_CloseAudioDevice(device_id_);
|
||||
|
||||
device_id_ = other.device_id_;
|
||||
other.device_id_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
SDL_AudioDeviceID AudioDevice::Get() const {
|
||||
return device_id_;
|
||||
}
|
||||
|
||||
void AudioDevice::Pause(bool pause_on) {
|
||||
SDL_PauseAudioDevice(device_id_, pause_on ? 1 : 0);
|
||||
}
|
||||
|
||||
SDL_AudioStatus AudioDevice::GetStatus() const {
|
||||
return SDL_GetAudioDeviceStatus(device_id_);
|
||||
}
|
||||
|
||||
AudioDevice::LockHandle AudioDevice::Lock() {
|
||||
return LockHandle(this);
|
||||
}
|
||||
|
||||
#ifdef SDL2PP_NEW_2_0_4
|
||||
void AudioDevice::QueueAudio(const void* data, Uint32 len) {
|
||||
if (SDL_QueueAudio(device_id_, data, len) == 0)
|
||||
throw Exception("SDL_QueueAudio failed");
|
||||
}
|
||||
|
||||
void AudioDevice::ClearQueuedAudio() {
|
||||
SDL_ClearQueuedAudio(device_id_);
|
||||
}
|
||||
|
||||
Uint32 GetQueuedAudioSize() const {
|
||||
return SDL_GetQueuedAudioSize(device_id_);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
47
SDL2pp/AudioLock.cc
Normal file
47
SDL2pp/AudioLock.cc
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
libSDL2pp - C++ wrapper for libSDL2
|
||||
Copyright (C) 2014 Dmitry Marakasov <amdmi3@amdmi3.ru>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <SDL2pp/Audio.hh>
|
||||
|
||||
namespace SDL2pp {
|
||||
|
||||
AudioDevice::LockHandle::LockHandle(AudioDevice* device) : device_(device) {
|
||||
SDL_LockAudioDevice(device_->device_id_);
|
||||
}
|
||||
|
||||
AudioDevice::LockHandle::~LockHandle() {
|
||||
if (device_ != nullptr)
|
||||
SDL_UnlockAudioDevice(device_->device_id_);
|
||||
}
|
||||
|
||||
AudioDevice::LockHandle::LockHandle(AudioDevice::LockHandle&& other) noexcept : device_(other.device_) {
|
||||
other.device_ = nullptr;
|
||||
}
|
||||
|
||||
AudioDevice::LockHandle& AudioDevice::LockHandle::operator=(AudioDevice::LockHandle&& other) noexcept {
|
||||
device_ = other.device_;
|
||||
|
||||
other.device_ = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
65
SDL2pp/AudioSpec.cc
Normal file
65
SDL2pp/AudioSpec.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
libSDL2pp - C++ wrapper for libSDL2
|
||||
Copyright (C) 2014 Dmitry Marakasov <amdmi3@amdmi3.ru>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <SDL2pp/Audio.hh>
|
||||
|
||||
namespace SDL2pp {
|
||||
|
||||
void AudioSpec::SDLCallback(void *userdata, Uint8* stream, int len) {
|
||||
AudioSpec* audiospec = static_cast<AudioSpec*>(userdata);
|
||||
audiospec->callback_(stream, len);
|
||||
}
|
||||
|
||||
AudioSpec::AudioSpec(int freq, SDL_AudioFormat format, Uint8 channels, Uint16 samples, AudioCallback&& callback)
|
||||
: callback_(std::move(callback)) {
|
||||
std::fill((char*)this, (char*)this + sizeof(SDL_AudioSpec), 0);
|
||||
SDL_AudioSpec::freq = freq;
|
||||
SDL_AudioSpec::format = format;
|
||||
SDL_AudioSpec::channels = channels;
|
||||
SDL_AudioSpec::samples = samples;
|
||||
SDL_AudioSpec::callback = SDLCallback;
|
||||
SDL_AudioSpec::userdata = static_cast<void*>(this);
|
||||
}
|
||||
|
||||
AudioSpec::~AudioSpec() {
|
||||
}
|
||||
|
||||
AudioSpec::AudioSpec(AudioSpec&&) noexcept = default;
|
||||
AudioSpec& AudioSpec::operator=(AudioSpec&&) noexcept = default;
|
||||
|
||||
void AudioSpec::ChangeCallback(AudioCallback&& callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void AudioSpec::MergeChanges(const SDL_AudioSpec& obtained) {
|
||||
freq = obtained.freq;
|
||||
format = obtained.format;
|
||||
channels = obtained.channels;
|
||||
samples = obtained.samples;
|
||||
}
|
||||
|
||||
const SDL_AudioSpec* AudioSpec::Get() const {
|
||||
return static_cast<const SDL_AudioSpec*>(this);
|
||||
}
|
||||
|
||||
}
|
@ -23,5 +23,6 @@
|
||||
#define SDL2PP_CONFIG_HH
|
||||
|
||||
#cmakedefine SDL2PP_WITH_IMAGE
|
||||
#cmakedefine SDL2PP_NEW_2_0_4
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <SDL2pp/Config.hh>
|
||||
|
||||
#include <SDL2pp/SDL.hh>
|
||||
#include <SDL2pp/Audio.hh>
|
||||
#include <SDL2pp/Window.hh>
|
||||
#include <SDL2pp/Renderer.hh>
|
||||
#include <SDL2pp/Texture.hh>
|
||||
|
@ -2,6 +2,7 @@
|
||||
# they are compilable (e.g., includes and forward declarations are
|
||||
# complete and do not require extra includes)
|
||||
SET(HEADER_TESTS
|
||||
header_audio
|
||||
header_exception
|
||||
header_point
|
||||
header_rect
|
||||
|
5
tests/header_audio.cc
Normal file
5
tests/header_audio.cc
Normal file
@ -0,0 +1,5 @@
|
||||
#include <SDL2pp/Audio.hh>
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user