audio_device/wasapi/
buffer_mut.rs

1use crate::wasapi::Error;
2use std::marker;
3use std::ops;
4use std::slice;
5use windows_sys::Windows::Win32::CoreAudio as core;
6
7/// A typed mutable data buffer.
8pub struct BufferMut<'a, T> {
9    pub(super) tag: ste::Tag,
10    pub(super) render_client: &'a mut core::IAudioRenderClient,
11    pub(super) data: *mut T,
12    pub(super) frames: u32,
13    pub(super) len: usize,
14    pub(super) in_use: bool,
15    pub(super) _marker: marker::PhantomData<&'a mut [T]>,
16}
17
18impl<'a, T> BufferMut<'a, T> {
19    /// Release the buffer allowing the audio device to consume it.
20    pub fn release(mut self) -> Result<(), Error> {
21        self.tag.ensure_on_thread();
22
23        if std::mem::take(&mut self.in_use) {
24            unsafe {
25                self.render_client.ReleaseBuffer(self.frames, 0).ok()?;
26            }
27        }
28
29        Ok(())
30    }
31}
32
33impl<'a, T> Drop for BufferMut<'a, T> {
34    fn drop(&mut self) {
35        self.tag.ensure_on_thread();
36
37        if std::mem::take(&mut self.in_use) {
38            unsafe {
39                self.render_client
40                    .ReleaseBuffer(self.frames, 0)
41                    .ok()
42                    .unwrap();
43            }
44        }
45    }
46}
47
48impl<'a, T> ops::Deref for BufferMut<'a, T> {
49    type Target = [T];
50
51    fn deref(&self) -> &Self::Target {
52        self.tag.ensure_on_thread();
53        debug_assert!(self.in_use);
54        unsafe { slice::from_raw_parts(self.data, self.len) }
55    }
56}
57
58impl<'a, T> ops::DerefMut for BufferMut<'a, T> {
59    fn deref_mut(&mut self) -> &mut Self::Target {
60        self.tag.ensure_on_thread();
61        debug_assert!(self.in_use);
62        unsafe { slice::from_raw_parts_mut(self.data, self.len) }
63    }
64}
65
66// Safety: thread safety is ensured through tagging with ste::Tag.
67unsafe impl<T> Send for BufferMut<'_, T> {}