Skip to content

Commit

Permalink
Update windows-rs dependency (RustAudio#726)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-hansen authored and Hoodad committed Feb 8, 2023
1 parent 9c0940d commit 5003f43
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 70 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Unreleased
- Update `windows-rs` dependency

# Version 0.14.1 (2022-10-23)

- Support the 0.6.1 release of `alsa-rs`
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ clap = { version = "4.0", features = ["derive"] }
ndk-glue = "0.7"

[target.'cfg(target_os = "windows")'.dependencies]
windows = { version = "0.37", features = ["Win32_Media_Audio", "Win32_Foundation", "Win32_System_Com", "Win32_Devices_Properties", "Win32_Media_KernelStreaming", "Win32_System_Com_StructuredStorage", "Win32_System_Ole", "Win32_System_Threading", "Win32_Security", "Win32_System_SystemServices", "Win32_System_WindowsProgramming", "Win32_Media_Multimedia", "Win32_UI_Shell_PropertiesSystem"]}
windows = { version = "0.43.0", features = ["Win32_Media_Audio", "Win32_Foundation", "Win32_System_Com", "Win32_Devices_Properties", "Win32_Media_KernelStreaming", "Win32_System_Com_StructuredStorage", "Win32_System_Ole", "Win32_System_Threading", "Win32_Security", "Win32_System_SystemServices", "Win32_System_WindowsProgramming", "Win32_Media_Multimedia", "Win32_UI_Shell_PropertiesSystem"]}
asio-sys = { version = "0.2", path = "asio-sys", optional = true }
num-traits = { version = "0.2.6", optional = true }
parking_lot = "0.12"
Expand Down
3 changes: 1 addition & 2 deletions src/host/wasapi/com.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use super::IoError;
use std::marker::PhantomData;
use std::ptr;

use windows::Win32::Foundation::RPC_E_CHANGED_MODE;
use windows::Win32::System::Com::{CoInitializeEx, CoUninitialize, COINIT_APARTMENTTHREADED};
Expand All @@ -15,7 +14,7 @@ thread_local!(static COM_INITIALIZED: ComInitialized = {
// This call can fail with RPC_E_CHANGED_MODE if another library initialized COM with MTA.
// That's OK though since COM ensures thread-safety/compatibility through marshalling when
// necessary.
let result = CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
let result = CoInitializeEx(None, COINIT_APARTMENTTHREADED);
match result.clone().map_err(|e| e.code()) {
Ok(_) |
Err(RPC_E_CHANGED_MODE) => {
Expand Down
78 changes: 28 additions & 50 deletions src/host/wasapi/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@ use std::time::Duration;

use super::com;
use super::{windows_err_to_cpal_err, windows_err_to_cpal_err_message};
use std::ffi::c_void;
use windows::core::Interface;
use windows::core::GUID;
use windows::Win32::Devices::Properties;
use windows::Win32::Foundation;
use windows::Win32::Media::Audio::IAudioRenderClient;
use windows::Win32::Media::{Audio, KernelStreaming, Multimedia};
use windows::Win32::System::Com;
use windows::Win32::System::Com::StructuredStorage;
use windows::Win32::System::Ole;
use windows::Win32::System::Com::{StructuredStorage, STGM_READ, VT_LPWSTR};
use windows::Win32::System::Threading;

use super::stream::{AudioClientFlow, Stream, StreamInner};
Expand Down Expand Up @@ -136,7 +134,7 @@ struct WaveFormatExPtr(*mut Audio::WAVEFORMATEX);
impl Drop for WaveFormatExPtr {
fn drop(&mut self) {
unsafe {
Com::CoTaskMemFree(self.0 as *mut _);
Com::CoTaskMemFree(None);
}
}
}
Expand Down Expand Up @@ -201,11 +199,11 @@ pub unsafe fn is_format_supported(
waveformatex_ptr: *const Audio::WAVEFORMATEX,
) -> Result<bool, SupportedStreamConfigsError> {
// Check if the given format is supported.
let is_supported = |waveformatex_ptr, mut closest_waveformatex_ptr| {
let is_supported = |waveformatex_ptr, closest_waveformatex_ptr| {
let result = client.IsFormatSupported(
Audio::AUDCLNT_SHAREMODE_SHARED,
waveformatex_ptr,
&mut closest_waveformatex_ptr,
Some(closest_waveformatex_ptr),
);
// `IsFormatSupported` can return `S_FALSE` (which means that a compatible format
// has been found, but not an exact match) so we also treat this as unsupported.
Expand All @@ -226,16 +224,16 @@ pub unsafe fn is_format_supported(
match (*waveformatex_ptr).wFormatTag as u32 {
Audio::WAVE_FORMAT_PCM | Multimedia::WAVE_FORMAT_IEEE_FLOAT => {
let mut closest_waveformatex = *waveformatex_ptr;
let closest_waveformatex_ptr = &mut closest_waveformatex as *mut _;
is_supported(waveformatex_ptr, closest_waveformatex_ptr)
let mut closest_waveformatex_ptr = &mut closest_waveformatex as *mut _;
is_supported(waveformatex_ptr, &mut closest_waveformatex_ptr as *mut _)
}
KernelStreaming::WAVE_FORMAT_EXTENSIBLE => {
let waveformatextensible_ptr = waveformatex_ptr as *const Audio::WAVEFORMATEXTENSIBLE;
let mut closest_waveformatextensible = *waveformatextensible_ptr;
let closest_waveformatextensible_ptr = &mut closest_waveformatextensible as *mut _;
let closest_waveformatex_ptr =
let mut closest_waveformatex_ptr =
closest_waveformatextensible_ptr as *mut Audio::WAVEFORMATEX;
is_supported(waveformatex_ptr, closest_waveformatex_ptr)
is_supported(waveformatex_ptr, &mut closest_waveformatex_ptr as *mut _)
}
_ => Ok(false),
}
Expand Down Expand Up @@ -325,7 +323,7 @@ impl Device {
// Open the device's property store.
let property_store = self
.device
.OpenPropertyStore(StructuredStorage::STGM_READ)
.OpenPropertyStore(STGM_READ)
.expect("could not open property store");

// Get the endpoint's friendly-name property.
Expand All @@ -341,7 +339,7 @@ impl Device {
let prop_variant = &property_value.Anonymous.Anonymous;

// Read the friendly-name from the union data field, expecting a *const u16.
if prop_variant.vt != Ole::VT_LPWSTR.0 as _ {
if prop_variant.vt != VT_LPWSTR {
let description = format!(
"property store produced invalid data: {:?}",
prop_variant.vt
Expand Down Expand Up @@ -390,21 +388,9 @@ impl Device {
}

let audio_client: Audio::IAudioClient = unsafe {
let mut audio_client = ptr::null_mut();
self.device.Activate(
&Audio::IAudioClient::IID,
Com::CLSCTX_ALL,
ptr::null_mut(),
&mut audio_client,
)?;

// can fail if the device has been disconnected since we enumerated it, or if
// the device doesn't support playback for some reason
assert!(!audio_client.is_null());
// doing a transmute here is super nasty but the windows
// crate doesn't seem to have a native method for getting
// an interface struct from a pointer
mem::transmute::<_, Audio::IAudioClient>(audio_client as *mut _)
self.device.Activate(Com::CLSCTX_ALL, None)?
};

*lock = Some(IAudioClientWrapper(audio_client));
Expand Down Expand Up @@ -647,7 +633,7 @@ impl Device {
buffer_duration,
0,
&format_attempt.Format,
ptr::null(),
None,
);
match hresult {
Err(ref e) if e.code() == Audio::AUDCLNT_E_DEVICE_INVALIDATED => {
Expand All @@ -671,17 +657,13 @@ impl Device {

// Creating the event that will be signalled whenever we need to submit some samples.
let event = {
let event = Threading::CreateEventA(
ptr::null_mut(),
false,
false,
windows::core::PCSTR(ptr::null()),
)
.map_err(|e| {
let description = format!("failed to create event: {}", e);
let err = BackendSpecificError { description };
BuildStreamError::from(err)
})?;
let event =
Threading::CreateEventA(None, false, false, windows::core::PCSTR(ptr::null()))
.map_err(|e| {
let description = format!("failed to create event: {}", e);
let err = BackendSpecificError { description };
BuildStreamError::from(err)
})?;

if let Err(e) = audio_client.SetEventHandle(event) {
let description = format!("failed to call SetEventHandle: {}", e);
Expand Down Expand Up @@ -761,7 +743,7 @@ impl Device {
buffer_duration,
0,
&format_attempt.Format,
ptr::null(),
None,
)
.map_err(windows_err_to_cpal_err::<BuildStreamError>)?;

Expand All @@ -770,17 +752,13 @@ impl Device {

// Creating the event that will be signalled whenever we need to submit some samples.
let event = {
let event = Threading::CreateEventA(
ptr::null_mut(),
false,
false,
windows::core::PCSTR(ptr::null()),
)
.map_err(|e| {
let description = format!("failed to create event: {}", e);
let err = BackendSpecificError { description };
BuildStreamError::from(err)
})?;
let event =
Threading::CreateEventA(None, false, false, windows::core::PCSTR(ptr::null()))
.map_err(|e| {
let description = format!("failed to create event: {}", e);
let err = BackendSpecificError { description };
BuildStreamError::from(err)
})?;

if let Err(e) = audio_client.SetEventHandle(event) {
let description = format!("failed to call SetEventHandle: {}", e);
Expand Down Expand Up @@ -845,7 +823,7 @@ impl PartialEq for Device {
/// RAII for device IDs.
impl Drop for IdRAII {
fn drop(&mut self) {
unsafe { Com::CoTaskMemFree(self.0 .0 as *mut c_void) }
unsafe { Com::CoTaskMemFree(None) }
}
}
// GetId only fails with E_OUTOFMEMORY and if it does, we're probably dead already.
Expand Down
25 changes: 8 additions & 17 deletions src/host/wasapi/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::ptr;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread::{self, JoinHandle};
use windows::Win32::Foundation;
use windows::Win32::Foundation::WAIT_OBJECT_0;
use windows::Win32::Media::Audio;
use windows::Win32::System::SystemServices;
use windows::Win32::System::Threading;
Expand Down Expand Up @@ -89,12 +90,7 @@ impl Stream {
E: FnMut(StreamError) + Send + 'static,
{
let pending_scheduled_event = unsafe {
Threading::CreateEventA(
ptr::null_mut(),
false,
false,
windows::core::PCSTR(ptr::null()),
)
Threading::CreateEventA(None, false, false, windows::core::PCSTR(ptr::null()))
}
.expect("cpal: could not create input stream event");
let (tx, rx) = channel();
Expand Down Expand Up @@ -127,12 +123,7 @@ impl Stream {
E: FnMut(StreamError) + Send + 'static,
{
let pending_scheduled_event = unsafe {
Threading::CreateEventA(
ptr::null_mut(),
false,
false,
windows::core::PCSTR(ptr::null()),
)
Threading::CreateEventA(None, false, false, windows::core::PCSTR(ptr::null()))
}
.expect("cpal: could not create output stream event");
let (tx, rx) = channel();
Expand Down Expand Up @@ -249,14 +240,14 @@ fn wait_for_handle_signal(handles: &[Foundation::HANDLE]) -> Result<usize, Backe
false, // irrelevant parameter here
)
};
if result == Foundation::WAIT_FAILED.0 {
if result == Foundation::WAIT_FAILED {
let err = unsafe { Foundation::GetLastError() };
let description = format!("`WaitForMultipleObjectsEx failed: {}", err.0);
let err = BackendSpecificError { description };
return Err(err);
}
// Notifying the corresponding task handler.
let handle_idx = (result - Threading::WAIT_OBJECT_0) as usize;
let handle_idx = (result.0 - WAIT_OBJECT_0.0) as usize;
Ok(handle_idx)
}

Expand Down Expand Up @@ -387,8 +378,8 @@ fn process_input(
&mut buffer,
&mut frames_available,
flags.as_mut_ptr(),
ptr::null_mut(),
&mut qpc_position,
None,
Some(&mut qpc_position),
);

match result {
Expand Down Expand Up @@ -500,7 +491,7 @@ fn stream_instant(stream: &StreamInner) -> Result<crate::StreamInstant, StreamEr
unsafe {
stream
.audio_clock
.GetPosition(&mut position, &mut qpc_position)
.GetPosition(&mut position, Some(&mut qpc_position))
.map_err(windows_err_to_cpal_err::<StreamError>)?;
};
// The `qpc_position` is in 100 nanosecond units. Convert it to nanoseconds.
Expand Down

0 comments on commit 5003f43

Please sign in to comment.