Struct wasapi::AudioClient
source · pub struct AudioClient { /* private fields */ }
Expand description
Struct wrapping an IAudioClient.
Implementations§
source§impl AudioClient
impl AudioClient
sourcepub fn new_application_loopback_client(
process_id: u32,
include_tree: bool,
) -> Result<Self, Box<dyn Error>>
pub fn new_application_loopback_client( process_id: u32, include_tree: bool, ) -> Result<Self, Box<dyn Error>>
Creates a loopback capture AudioClient for a specific process.
include_tree
is equivalent to PROCESS_LOOPBACK_MODE.
If true, the loopback capture client will capture audio from the target process and all its child processes, if false only audio from the target process is captured.
On versions of Windows prior to Windows 10, the thread calling this function must called in a COM Single-Threaded Apartment (STA).
Additionally when calling AudioClient::initialize_client on the client returned by this method, the caller must use Direction::Capture, and ShareMode::Shared. Finally calls to AudioClient::get_periods do not work, however the period passed by the caller to AudioClient::initialize_client is irrelevant.
§Non-functional methods:
get_mixformat
just returnsNot implemented
is_supported
just returnsNot implemented
even if the format and mode workis_supported_exclusive_with_quirks
just returnsUnable to find a supported format
get_periods
just returnsNot implemented
calculate_aligned_period_near
just returnsNot implemented
even for values that would later work.get_bufferframecount
returns huge values like 3131961357 but no errorget_current_padding
just returns Notimplemented
get_available_space_in_frames
just returnsClient has not been initialised
even if it has.get_audiorenderclient
just returnsNo such interface supported
get_audiosessioncontrol
just returnsNo such interface supported
get_audioclock
just returnsNo such interface supported
get_sharemode
slways returnsNone
when it should returns Shared after initialisation
§Example
use wasapi::{WaveFormat, SampleType, ProcessAudioClient, initialize_mta};
let desired_format = WaveFormat::new(32, 32, &SampleType::Float, 44100, 2, None);
let hnsbufferduration = 200_000; // 20ms in hundreds of nanoseconds
let autoconvert = true;
let include_tree = false;
let process_id = std::process::id();
initialize_mta().ok().unwrap(); // Don't do this on a UI thread
let mut audio_client = ProcessAudioClient::new(process_id, include_tree).unwrap();
audio_client.initialize_client(&desired_format, hnsbufferduration, autoconvert).unwrap();
sourcepub fn get_mixformat(&self) -> Result<WaveFormat, Box<dyn Error>>
pub fn get_mixformat(&self) -> Result<WaveFormat, Box<dyn Error>>
Get MixFormat of the device. This is the format the device uses in shared mode and should always be accepted.
sourcepub fn is_supported(
&self,
wave_fmt: &WaveFormat,
sharemode: &ShareMode,
) -> Result<Option<WaveFormat>, Box<dyn Error>>
pub fn is_supported( &self, wave_fmt: &WaveFormat, sharemode: &ShareMode, ) -> Result<Option<WaveFormat>, Box<dyn Error>>
Check if a format is supported. If it’s directly supported, this returns Ok(None). If not, but a similar format is, then the nearest matching supported format is returned as Ok(Some(WaveFormat)).
NOTE: For exclusive mode, this function may not always give the right result for 1- and 2-channel formats. From the Microsoft documentation:
For exclusive-mode formats, the method queries the device driver. Some device drivers will report that they support a 1-channel or 2-channel PCM format if the format is specified by a stand-alone WAVEFORMATEX structure, but will reject the same format if it is specified by a WAVEFORMATEXTENSIBLE structure. To obtain reliable results from these drivers, exclusive-mode applications should call IsFormatSupported twice for each 1-channel or 2-channel PCM format. One call should use a stand-alone WAVEFORMATEX structure to specify the format, and the other call should use a WAVEFORMATEXTENSIBLE structure to specify the same format.
If the first call fails, use WaveFormat::to_waveformatex to get a copy of the WaveFormat in the simpler WAVEFORMATEX representation. Then call this function again with the new WafeFormat structure. If the driver then reports that the format is supported, use the original WaveFormat structure when calling AudioClient::initialize_client.
See also the helper function is_supported_exclusive_with_quirks.
sourcepub fn is_supported_exclusive_with_quirks(
&self,
wave_fmt: &WaveFormat,
) -> Result<WaveFormat, Box<dyn Error>>
pub fn is_supported_exclusive_with_quirks( &self, wave_fmt: &WaveFormat, ) -> Result<WaveFormat, Box<dyn Error>>
A helper function for checking if a format is supported.
It calls is_supported
several times with different options
in order to find a format that the device accepts.
The alternatives it tries are:
- The format as given.
- If one or two channels, try with the format as WAVEFORMATEX.
- Try with different channel masks:
- If channels <= 8: Recommended mask(s) from ksmedia.h.
- If channels <= 18: Simple mask.
- Zero mask.
If an accepted format is found, this is returned. An error means no accepted format was found.
sourcepub fn get_periods(&self) -> Result<(i64, i64), Box<dyn Error>>
pub fn get_periods(&self) -> Result<(i64, i64), Box<dyn Error>>
Get default and minimum periods in 100-nanosecond units
sourcepub fn calculate_aligned_period_near(
&self,
desired_period: i64,
align_bytes: Option<u32>,
wave_fmt: &WaveFormat,
) -> Result<i64, Box<dyn Error>>
pub fn calculate_aligned_period_near( &self, desired_period: i64, align_bytes: Option<u32>, wave_fmt: &WaveFormat, ) -> Result<i64, Box<dyn Error>>
Helper function for calculating a period size in 100-nanosecond units that is near a desired value, and always larger than the minimum value supported by the device. The returned value leads to a device buffer size that is aligned both to the frame size of the format, and the optional align_bytes value. This parameter is used for devices that require the buffer size to be a multiple of a certain number of bytes. Give None, Some(0) or Some(1) if the device has no special requirements for the alignment. For example, all devices following the Intel High Definition Audio specification require buffer sizes in multiples of 128 bytes.
See also the playnoise_exclusive
example.
sourcepub fn initialize_client(
&mut self,
wavefmt: &WaveFormat,
period: i64,
direction: &Direction,
sharemode: &ShareMode,
convert: bool,
) -> Result<(), Box<dyn Error>>
pub fn initialize_client( &mut self, wavefmt: &WaveFormat, period: i64, direction: &Direction, sharemode: &ShareMode, convert: bool, ) -> Result<(), Box<dyn Error>>
Initialize an [IAudioClient] for the given direction, sharemode and format.
Setting convert
to true enables automatic samplerate and format conversion, meaning that almost any format will be accepted.
sourcepub fn set_get_eventhandle(&self) -> Result<Handle, Box<dyn Error>>
pub fn set_get_eventhandle(&self) -> Result<Handle, Box<dyn Error>>
Create and return an event handle for an [IAudioClient]
sourcepub fn get_current_padding(&self) -> Result<u32, Box<dyn Error>>
pub fn get_current_padding(&self) -> Result<u32, Box<dyn Error>>
Get current padding in frames. This represents the number of frames currently in the buffer, for both capture and render devices.
sourcepub fn get_available_space_in_frames(&self) -> Result<u32, Box<dyn Error>>
pub fn get_available_space_in_frames(&self) -> Result<u32, Box<dyn Error>>
Get buffer size minus padding in frames. Use this to find out how much free space is available in the buffer.
sourcepub fn get_audiorenderclient(&self) -> Result<AudioRenderClient, Box<dyn Error>>
pub fn get_audiorenderclient(&self) -> Result<AudioRenderClient, Box<dyn Error>>
Get a rendering (playback) client
sourcepub fn get_audiocaptureclient(
&self,
) -> Result<AudioCaptureClient, Box<dyn Error>>
pub fn get_audiocaptureclient( &self, ) -> Result<AudioCaptureClient, Box<dyn Error>>
Get a capture client
sourcepub fn get_audiosessioncontrol(
&self,
) -> Result<AudioSessionControl, Box<dyn Error>>
pub fn get_audiosessioncontrol( &self, ) -> Result<AudioSessionControl, Box<dyn Error>>
Get the AudioSessionControl
sourcepub fn get_audioclock(&self) -> Result<AudioClock, Box<dyn Error>>
pub fn get_audioclock(&self) -> Result<AudioClock, Box<dyn Error>>
Get the AudioClock
sourcepub fn get_direction(&self) -> Direction
pub fn get_direction(&self) -> Direction
Get the direction for this AudioClient
Get the sharemode for this AudioClient. The sharemode is decided when the client is initialized.