Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update windows-rs dependency #726

Merged
merged 1 commit into from
Nov 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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