ruby: preliminary SDL2 audio driver
このコミットが含まれているのは:
コミット
93937e8603
|
@ -13,6 +13,7 @@ ifeq ($(ruby),)
|
|||
# If we're in a posix shell, use pkg-config/pkg-check
|
||||
pkg_check = $(if $(shell pkg-config $1 && echo 1),$2)
|
||||
ruby += $(call pkg_check,sdl2,input.sdl)
|
||||
ruby += $(call pkg_check,sdl2,audio.sdl)
|
||||
endif
|
||||
else ifeq ($(platform),macos)
|
||||
ruby += video.cgl
|
||||
|
@ -30,6 +31,7 @@ ifeq ($(ruby),)
|
|||
ruby += input.xlib
|
||||
ruby += $(call pkg_check,libudev,input.udev)
|
||||
ruby += $(call pkg_check,sdl2,input.sdl)
|
||||
ruby += $(call pkg_check,sdl2,audio.sdl)
|
||||
else ifeq ($(platform),bsd)
|
||||
pkg_check = $(if $(shell pkg-config $1 && echo 1),$2)
|
||||
ruby += video.glx video.glx2 video.xshm
|
||||
|
@ -41,6 +43,7 @@ ifeq ($(ruby),)
|
|||
ruby += $(call pkg_check,ao,audio.ao)
|
||||
ruby += input.uhid input.xlib
|
||||
ruby += $(call pkg_check,sdl2,input.sdl)
|
||||
ruby += $(call pkg_check,sdl2,audio.sdl)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -55,6 +58,7 @@ ifeq ($(call which,pkg-config),)
|
|||
# TODO: add SDL2 cflags
|
||||
else
|
||||
ruby.flags += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --cflags))
|
||||
ruby.flags += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --cflags))
|
||||
endif
|
||||
|
||||
ruby.options :=
|
||||
|
@ -79,9 +83,11 @@ ifeq ($(platform),windows)
|
|||
# TODO: add SDL2 ldflags
|
||||
else
|
||||
ruby.options += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --libs --static))
|
||||
ruby.options += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --libs --static))
|
||||
endif
|
||||
else
|
||||
ruby.options += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --libs))
|
||||
ruby.options += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --libs))
|
||||
endif
|
||||
|
||||
ruby.options += $(if $(findstring input.udev,$(ruby)),-ludev)
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
#include <ruby/audio/xaudio2.cpp>
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_SDL)
|
||||
#include <ruby/audio/sdl.cpp>
|
||||
#endif
|
||||
|
||||
namespace ruby {
|
||||
|
||||
auto Audio::setExclusive(bool exclusive) -> bool {
|
||||
|
@ -186,6 +190,10 @@ auto Audio::create(string driver) -> bool {
|
|||
if(driver == "XAudio 2.1") self.instance = new AudioXAudio2(*this);
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_SDL)
|
||||
if(driver == "SDL") self.instance = new AudioSDL(*this);
|
||||
#endif
|
||||
|
||||
if(!self.instance) self.instance = new AudioDriver(*this);
|
||||
|
||||
return self.instance->create();
|
||||
|
@ -206,6 +214,10 @@ auto Audio::hasDrivers() -> vector<string> {
|
|||
"XAudio 2.1",
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_SDL)
|
||||
"SDL",
|
||||
#endif
|
||||
|
||||
#if defined(AUDIO_DIRECTSOUND)
|
||||
"DirectSound 7.0",
|
||||
#endif
|
||||
|
@ -248,6 +260,8 @@ auto Audio::optimalDriver() -> string {
|
|||
return "ASIO";
|
||||
#elif defined(AUDIO_XAUDIO2)
|
||||
return "XAudio 2.1";
|
||||
#elif defined(AUDIO_SDL)
|
||||
return "SDL";
|
||||
#elif defined(AUDIO_DIRECTSOUND)
|
||||
return "DirectSound 7.0";
|
||||
#elif defined(AUDIO_WAVEOUT)
|
||||
|
@ -278,6 +292,8 @@ auto Audio::safestDriver() -> string {
|
|||
return "WASAPI";
|
||||
#elif defined(AUDIO_XAUDIO2)
|
||||
return "XAudio 2.1";
|
||||
#elif defined(AUDIO_SDL)
|
||||
return "SDL";
|
||||
#elif defined(AUDIO_ALSA)
|
||||
return "ALSA";
|
||||
#elif defined(AUDIO_OSS)
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
#include <SDL2/SDL.h>
|
||||
|
||||
struct AudioSDL : AudioDriver {
|
||||
AudioSDL& self = *this;
|
||||
AudioSDL(Audio& super) : AudioDriver(super) {}
|
||||
~AudioSDL() { terminate(); }
|
||||
|
||||
auto create() -> bool override {
|
||||
super.setChannels(2);
|
||||
super.setFrequency(48000);
|
||||
super.setLatency(0);
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto driver() -> string override { return "SDL"; }
|
||||
auto ready() -> bool override { return _ready; }
|
||||
|
||||
auto hasBlocking() -> bool override { return true; }
|
||||
auto hasDynamic() -> bool override { return true; }
|
||||
|
||||
auto hasFrequencies() -> vector<u32> override {
|
||||
return {44100, 48000, 96000};
|
||||
}
|
||||
|
||||
auto setFrequency(u32 frequency) -> bool override { return initialize(); }
|
||||
auto setLatency(u32 latency) -> bool override { return initialize(); }
|
||||
auto setBlocking(bool blocking) -> bool override { clear(); return true; }
|
||||
|
||||
auto clear() -> void override {
|
||||
if(!ready()) return;
|
||||
SDL_ClearQueuedAudio(_device);
|
||||
}
|
||||
|
||||
auto output(const f64 samples[]) -> void override {
|
||||
if(!ready()) return;
|
||||
|
||||
if(self.blocking) {
|
||||
while(SDL_GetQueuedAudioSize(_device) > _bufferSize) {
|
||||
//wait for audio to drain
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<f32[]> output = std::make_unique<f32[]>(channels);
|
||||
for(auto n : range(channels)) output[n] = samples[n];
|
||||
SDL_QueueAudio(_device, &output[0], channels * sizeof(f32));
|
||||
}
|
||||
|
||||
auto level() -> f64 override {
|
||||
return SDL_GetQueuedAudioSize(_device) / ((f64)_bufferSize);
|
||||
}
|
||||
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
|
||||
SDL_AudioSpec want{}, have{};
|
||||
want.freq = frequency;
|
||||
want.format = AUDIO_F32SYS;
|
||||
want.channels = 2;
|
||||
want.samples = 4096;
|
||||
|
||||
_device = SDL_OpenAudioDevice(NULL,0,&want,&have,0);
|
||||
frequency = have.freq;
|
||||
channels = have.channels;
|
||||
_bufferSize = have.size;
|
||||
SDL_PauseAudioDevice(_device, 0);
|
||||
|
||||
_ready = true;
|
||||
clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto terminate() -> void {
|
||||
_ready = false;
|
||||
SDL_CloseAudioDevice(_device);
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
}
|
||||
|
||||
bool _ready = false;
|
||||
|
||||
SDL_AudioDeviceID _device = 0;
|
||||
u32 _bufferSize = 0;
|
||||
};
|
読み込み中…
新しいイシューから参照