audio_device/wasapi/
initialized_client.rs

1use crate::loom::sync::Arc;
2use crate::wasapi::{ClientConfig, Error, RenderClient, Sample};
3use std::marker;
4use std::mem;
5use windows::Interface as _;
6use windows_sys::Windows::Win32::CoreAudio as core;
7
8/// A client that has been initialized with the given type `T`.
9///
10/// The type must implement the [Sample] trait to make sure it's appropriate for
11/// use with WASAPI.
12pub struct InitializedClient<T, E> {
13    pub(super) tag: ste::Tag,
14    pub(super) audio_client: core::IAudioClient,
15    pub(super) config: ClientConfig,
16    pub(super) buffer_size: u32,
17    pub(super) event: Arc<E>,
18    pub(super) _marker: marker::PhantomData<T>,
19}
20
21impl<T, E> InitializedClient<T, E>
22where
23    T: Sample,
24{
25    /// Get the initialized client configuration.
26    pub fn config(&self) -> ClientConfig {
27        self.config
28    }
29
30    /// Construct a render client used for writing output into.
31    pub fn render_client(&self) -> Result<RenderClient<T, E>, Error> {
32        self.tag.ensure_on_thread();
33
34        let render_client: core::IAudioRenderClient = unsafe {
35            let mut render_client = std::ptr::null_mut();
36
37            self.audio_client
38                .GetService(&core::IAudioRenderClient::IID, &mut render_client)
39                .ok()?;
40
41            debug_assert!(!render_client.is_null());
42            mem::transmute(render_client)
43        };
44
45        Ok(RenderClient {
46            tag: self.tag,
47            audio_client: self.audio_client.clone(),
48            render_client,
49            buffer_size: self.buffer_size,
50            channels: self.config.channels as usize,
51            event: self.event.clone(),
52            _marker: marker::PhantomData,
53        })
54    }
55}
56
57// Safety: thread safety is ensured through tagging with ste::Tag.
58unsafe impl<T, E> Send for InitializedClient<T, E> {}