Implement new `Host` API for WASAPI backend

This commit is contained in:
mitchmindtree 2019-06-24 22:21:19 +02:00
parent e8a05379c2
commit 69cd058d28
4 changed files with 130 additions and 13 deletions

View File

@ -7,4 +7,4 @@ mod coreaudio;
mod emscripten; mod emscripten;
mod null; mod null;
#[cfg(windows)] #[cfg(windows)]
mod wasapi; pub(crate) mod wasapi;

View File

@ -1,6 +1,19 @@
extern crate winapi; extern crate winapi;
use BackendSpecificError; use BackendSpecificError;
use BuildStreamError;
use DefaultFormatError;
use Device as DeviceTrait;
use DeviceNameError;
use DevicesError;
use EventLoop as EventLoopTrait;
use Format;
use Host as HostTrait;
use PlayStreamError;
use PauseStreamError;
use StreamDataResult;
use StreamId as StreamIdTrait;
use SupportedFormatsError;
use self::winapi::um::winnt::HRESULT; use self::winapi::um::winnt::HRESULT;
use std::io::Error as IoError; use std::io::Error as IoError;
pub use self::device::{Device, Devices, SupportedInputFormats, SupportedOutputFormats, default_input_device, default_output_device}; pub use self::device::{Device, Devices, SupportedInputFormats, SupportedOutputFormats, default_input_device, default_output_device};
@ -10,6 +23,110 @@ mod com;
mod device; mod device;
mod stream; mod stream;
/// The WASAPI host, the default windows host type.
#[derive(Debug)]
pub struct Host;
impl Host {
pub fn new() -> Result<Self, crate::HostUnavailable> {
Ok(Host)
}
}
impl HostTrait for Host {
type Devices = Devices;
type Device = Device;
type EventLoop = EventLoop;
fn is_available() -> bool {
// Assume WASAPI is always available on windows.
true
}
fn devices(&self) -> Result<Self::Devices, DevicesError> {
Devices::new()
}
fn default_input_device(&self) -> Option<Self::Device> {
default_input_device()
}
fn default_output_device(&self) -> Option<Self::Device> {
default_output_device()
}
fn event_loop(&self) -> Self::EventLoop {
EventLoop::new()
}
}
impl DeviceTrait for Device {
type SupportedInputFormats = SupportedInputFormats;
type SupportedOutputFormats = SupportedOutputFormats;
fn name(&self) -> Result<String, DeviceNameError> {
Device::name(self)
}
fn supported_input_formats(&self) -> Result<Self::SupportedInputFormats, SupportedFormatsError> {
Device::supported_input_formats(self)
}
fn supported_output_formats(&self) -> Result<Self::SupportedOutputFormats, SupportedFormatsError> {
Device::supported_output_formats(self)
}
fn default_input_format(&self) -> Result<Format, DefaultFormatError> {
Device::default_input_format(self)
}
fn default_output_format(&self) -> Result<Format, DefaultFormatError> {
Device::default_output_format(self)
}
}
impl EventLoopTrait for EventLoop {
type Device = Device;
type StreamId = StreamId;
fn build_input_stream(
&self,
device: &Self::Device,
format: &Format,
) -> Result<Self::StreamId, BuildStreamError> {
EventLoop::build_input_stream(self, device, format)
}
fn build_output_stream(
&self,
device: &Self::Device,
format: &Format,
) -> Result<Self::StreamId, BuildStreamError> {
EventLoop::build_output_stream(self, device, format)
}
fn play_stream(&self, stream: Self::StreamId) -> Result<(), PlayStreamError> {
EventLoop::play_stream(self, stream)
}
fn pause_stream(&self, stream: Self::StreamId) -> Result<(), PauseStreamError> {
EventLoop::pause_stream(self, stream)
}
fn destroy_stream(&self, stream: Self::StreamId) {
EventLoop::destroy_stream(self, stream)
}
fn run<F>(&self, callback: F) -> !
where
F: FnMut(Self::StreamId, StreamDataResult) + Send,
{
EventLoop::run(self, callback)
}
}
impl StreamIdTrait for StreamId {}
#[inline] #[inline]
fn check_result(result: HRESULT) -> Result<(), IoError> { fn check_result(result: HRESULT) -> Result<(), IoError> {
if result < 0 { if result < 0 {

View File

@ -115,7 +115,7 @@ impl EventLoop {
} }
} }
pub fn build_input_stream( pub(crate) fn build_input_stream(
&self, &self,
device: &Device, device: &Device,
format: &Format, format: &Format,
@ -276,7 +276,7 @@ impl EventLoop {
} }
} }
pub fn build_output_stream( pub(crate) fn build_output_stream(
&self, &self,
device: &Device, device: &Device,
format: &Format, format: &Format,
@ -439,12 +439,12 @@ impl EventLoop {
} }
#[inline] #[inline]
pub fn destroy_stream(&self, stream_id: StreamId) { pub(crate) fn destroy_stream(&self, stream_id: StreamId) {
self.push_command(Command::DestroyStream(stream_id)); self.push_command(Command::DestroyStream(stream_id));
} }
#[inline] #[inline]
pub fn run<F>(&self, mut callback: F) -> ! pub(crate) fn run<F>(&self, mut callback: F) -> !
where F: FnMut(StreamId, StreamDataResult) where F: FnMut(StreamId, StreamDataResult)
{ {
self.run_inner(&mut callback); self.run_inner(&mut callback);
@ -617,13 +617,13 @@ impl EventLoop {
} }
#[inline] #[inline]
pub fn play_stream(&self, stream: StreamId) -> Result<(), PlayStreamError> { pub(crate) fn play_stream(&self, stream: StreamId) -> Result<(), PlayStreamError> {
self.push_command(Command::PlayStream(stream)); self.push_command(Command::PlayStream(stream));
Ok(()) Ok(())
} }
#[inline] #[inline]
pub fn pause_stream(&self, stream: StreamId) -> Result<(), PauseStreamError> { pub(crate) fn pause_stream(&self, stream: StreamId) -> Result<(), PauseStreamError> {
self.push_command(Command::PauseStream(stream)); self.push_command(Command::PauseStream(stream));
Ok(()) Ok(())
} }

View File

@ -288,8 +288,8 @@ macro_rules! impl_platform_host {
fn play_stream(&self, stream: Self::StreamId) -> Result<(), crate::PlayStreamError> { fn play_stream(&self, stream: Self::StreamId) -> Result<(), crate::PlayStreamError> {
match (&self.0, stream.0) { match (&self.0, stream.0) {
$( $(
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(s)) => { (&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
e.play_stream(s) e.play_stream(s.clone())
} }
)* )*
} }
@ -298,8 +298,8 @@ macro_rules! impl_platform_host {
fn pause_stream(&self, stream: Self::StreamId) -> Result<(), crate::PauseStreamError> { fn pause_stream(&self, stream: Self::StreamId) -> Result<(), crate::PauseStreamError> {
match (&self.0, stream.0) { match (&self.0, stream.0) {
$( $(
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(s)) => { (&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
e.pause_stream(s) e.pause_stream(s.clone())
} }
)* )*
} }
@ -308,8 +308,8 @@ macro_rules! impl_platform_host {
fn destroy_stream(&self, stream: Self::StreamId) { fn destroy_stream(&self, stream: Self::StreamId) {
match (&self.0, stream.0) { match (&self.0, stream.0) {
$( $(
(&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(s)) => { (&EventLoopInner::$HostVariant(ref e), StreamIdInner::$HostVariant(ref s)) => {
e.destroy_stream(s) e.destroy_stream(s.clone())
} }
)* )*
} }