Struct wasapi::AudioClient

source ·
pub struct AudioClient { /* private fields */ }
Expand description

Struct wrapping an IAudioClient.

Implementations§

source§

impl AudioClient

source

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 returns Not implemented
  • is_supported just returns Not implemented even if the format and mode work
  • is_supported_exclusive_with_quirks just returns Unable to find a supported format
  • get_periods just returns Not implemented
  • calculate_aligned_period_near just returns Not implemented even for values that would later work.
  • get_bufferframecount returns huge values like 3131961357 but no error
  • get_current_padding just returns Not implemented
  • get_available_space_in_frames just returns Client has not been initialised even if it has.
  • get_audiorenderclient just returns No such interface supported
  • get_audiosessioncontrol just returns No such interface supported
  • get_audioclock just returns No such interface supported
  • get_sharemode slways returns None 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();
source

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.

source

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.

source

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.

source

pub fn get_periods(&self) -> Result<(i64, i64), Box<dyn Error>>

Get default and minimum periods in 100-nanosecond units

source

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.

source

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.

source

pub fn set_get_eventhandle(&self) -> Result<Handle, Box<dyn Error>>

Create and return an event handle for an [IAudioClient]

source

pub fn get_bufferframecount(&self) -> Result<u32, Box<dyn Error>>

Get buffer size in frames

source

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.

source

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.

source

pub fn start_stream(&self) -> Result<(), Box<dyn Error>>

Start the stream on an [IAudioClient]

source

pub fn stop_stream(&self) -> Result<(), Box<dyn Error>>

Stop the stream on an [IAudioClient]

source

pub fn reset_stream(&self) -> Result<(), Box<dyn Error>>

Reset the stream on an [IAudioClient]

source

pub fn get_audiorenderclient(&self) -> Result<AudioRenderClient, Box<dyn Error>>

Get a rendering (playback) client

source

pub fn get_audiocaptureclient( &self, ) -> Result<AudioCaptureClient, Box<dyn Error>>

Get a capture client

source

pub fn get_audiosessioncontrol( &self, ) -> Result<AudioSessionControl, Box<dyn Error>>

source

pub fn get_audioclock(&self) -> Result<AudioClock, Box<dyn Error>>

Get the AudioClock

source

pub fn get_direction(&self) -> Direction

Get the direction for this AudioClient

source

pub fn get_sharemode(&self) -> Option<ShareMode>

Get the sharemode for this AudioClient. The sharemode is decided when the client is initialized.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.