Skip to content

Commit

Permalink
Implement BufferSize::Fixed in wasapi, and migrate wasapi to official…
Browse files Browse the repository at this point in the history
…ly-supported Windows crate (RustAudio#669)

I migrated to `windows-rs` in this PR since exposing the buffer size range for hardware-offloaded audio processing requires `IAudioClient2`, which isn't exposed in the `winapi` crate, and `winapi` seems to be more or less unmaintained at this point.

* Basic type conversion

* Make everything compile!

* Fix warnings

* Implement buffer sizing for wasapi

* Convert tabs to spaces

* Run cargo fmt

* Remove winapi from Cargo.toml

* Remove unused commented code from wasapi, and fix lingering TODOs

* Fix compile error

* Update to windows 0.37.0

* Run rustfmt

* Work around rustfmt nested tuple issues

* Improve readability of guid comparison code
  • Loading branch information
Osspial authored and Hoodad committed Feb 8, 2023
1 parent ae2880e commit 3044e0e
Show file tree
Hide file tree
Showing 5 changed files with 479 additions and 650 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ clap = { version = "3.1", default-features = false, features = ["std"] }
ndk-glue = "0.6"

[target.'cfg(target_os = "windows")'.dependencies]
winapi = { version = "0.3", features = ["audiosessiontypes", "audioclient", "coml2api", "combaseapi", "debug", "devpkey", "errhandlingapi", "handleapi", "ksmedia", "mmdeviceapi", "objbase", "profileapi", "std", "synchapi", "winbase", "winuser"] }
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"]}
asio-sys = { version = "0.2", path = "asio-sys", optional = true }
num-traits = { version = "0.2.6", optional = true }
parking_lot = "0.12"
Expand Down
27 changes: 15 additions & 12 deletions src/host/wasapi/com.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ use super::IoError;
use std::marker::PhantomData;
use std::ptr;

use super::winapi::shared::winerror::{HRESULT, RPC_E_CHANGED_MODE, SUCCEEDED};
use super::winapi::um::combaseapi::{CoInitializeEx, CoUninitialize};
use super::winapi::um::objbase::COINIT_APARTMENTTHREADED;
use windows::Win32::Foundation::RPC_E_CHANGED_MODE;
use windows::Win32::System::Com::{CoInitializeEx, CoUninitialize, COINIT_APARTMENTTHREADED};

thread_local!(static COM_INITIALIZED: ComInitialized = {
unsafe {
Expand All @@ -17,14 +16,18 @@ thread_local!(static COM_INITIALIZED: ComInitialized = {
// That's OK though since COM ensures thread-safety/compatibility through marshalling when
// necessary.
let result = CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED);
if SUCCEEDED(result) || result == RPC_E_CHANGED_MODE {
ComInitialized {
result,
_ptr: PhantomData,
match result.clone().map_err(|e| e.code()) {
Ok(_) |
Err(RPC_E_CHANGED_MODE) => {
ComInitialized {
result,
_ptr: PhantomData,
}
},
Err(e) => {
// COM initialization failed in another way, something is really wrong.
panic!("Failed to initialize COM: {}", IoError::from_raw_os_error(e.0));
}
} else {
// COM initialization failed in another way, something is really wrong.
panic!("Failed to initialize COM: {}", IoError::from_raw_os_error(result));
}
}
});
Expand All @@ -34,7 +37,7 @@ thread_local!(static COM_INITIALIZED: ComInitialized = {
// We store a raw pointer because it's the only way at the moment to remove `Send`/`Sync` from the
// object.
struct ComInitialized {
result: HRESULT,
result: windows::core::Result<()>,
_ptr: PhantomData<*mut ()>,
}

Expand All @@ -43,7 +46,7 @@ impl Drop for ComInitialized {
fn drop(&mut self) {
// Need to avoid calling CoUninitialize() if CoInitializeEx failed since it may have
// returned RPC_E_MODE_CHANGED - which is OK, see above.
if SUCCEEDED(self.result) {
if self.result.is_ok() {
unsafe { CoUninitialize() };
}
}
Expand Down
Loading

0 comments on commit 3044e0e

Please sign in to comment.