-
Notifications
You must be signed in to change notification settings - Fork 465
ASIO: open control panel #1074
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
base: master
Are you sure you want to change the base?
ASIO: open control panel #1074
Changes from all commits
a259084
5d0411a
f3de53f
336b168
b728f52
330e4f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| #[cfg(all(windows, feature = "asio"))] | ||
| fn main() -> anyhow::Result<()> { | ||
| use cpal::platform::asio::AsioDeviceExt; | ||
| use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; | ||
| use cpal::HostId; | ||
|
|
||
| let host = cpal::host_from_id(HostId::Asio)?; | ||
|
|
||
| let device = host | ||
| .default_output_device() | ||
| .ok_or_else(|| anyhow::anyhow!("No ASIO device found"))?; | ||
|
|
||
| println!( | ||
| "Opening control panel for: {}", | ||
| device.description()?.name() | ||
| ); | ||
|
|
||
| let config = device.default_output_config()?; | ||
|
|
||
| let err_fn = move |err| println!("Stream Error: {:?}", err); | ||
|
|
||
| let stream = device.build_output_stream( | ||
| &config.config(), | ||
| move |_data: &mut [i32], _: &cpal::OutputCallbackInfo| { /* play silence */ }, | ||
| err_fn, | ||
| None, | ||
| )?; | ||
|
|
||
| stream.play()?; | ||
|
|
||
| // This is a blocking call on some devices, so spawn it in its own thread. | ||
| std::thread::spawn(move || { | ||
| if let Err(e) = device.asio_open_control_panel() { | ||
| eprintln!("Could not open panel: {:?}", e); | ||
| } | ||
| }); | ||
|
|
||
| // Keep the thread alive so the window doesn't close immediately | ||
| std::thread::sleep(std::time::Duration::from_secs(5)); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| #[cfg(not(all(windows, feature = "asio")))] | ||
| fn main() {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| use crate::platform::DeviceInner; | ||
| use crate::BackendSpecificError; | ||
| use crate::Device; | ||
|
|
||
| pub trait AsioDeviceExt { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like the public API to have good documentation. Proposal: /// Extension trait for ASIO-specific device functionality.
|
||
| fn asio_open_control_panel(&self) -> Result<(), BackendSpecificError>; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /// Opens the ASIO driver's control panel window.
///
/// This provides access to device-specific settings like buffer size,
/// sample rate, input/output routing, and hardware-specific features.
///
/// # Blocking Behavior
///
/// **WARNING**: This call blocks until the user closes the control panel.
/// Consider spawning a thread to avoid blocking the main thread.
///
/// # Errors
///
/// Returns an error if this device is not an ASIO device.
|
||
| } | ||
|
|
||
| impl AsioDeviceExt for Device { | ||
| fn asio_open_control_panel(&self) -> Result<(), BackendSpecificError> { | ||
| if let DeviceInner::Asio(ref asio_device) = self.as_inner() { | ||
| asio_device | ||
| .driver | ||
| .open_control_panel() | ||
| .map_err(|e| BackendSpecificError { | ||
| description: format!("Failed to open control panel: {:?}", e), | ||
| }) | ||
| } else { | ||
| Err(BackendSpecificError { | ||
| description: "Not an ASIO device".to_string(), | ||
| }) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,9 @@ pub use self::platform_impl::*; | |
| #[cfg(feature = "custom")] | ||
| pub use crate::host::custom::{Device as CustomDevice, Host as CustomHost, Stream as CustomStream}; | ||
|
|
||
| #[cfg(all(target_os = "windows", feature = "asio"))] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For cross-platform compatibility in downstream code, the configuration guard should be moved from here into #[cfg(all(target_os = "windows", feature = "asio"))]
impl AsioDeviceExt for Device {
// ...
}
#[cfg(not(all(target_os = "windows", feature = "asio")))]
impl AsioDeviceExt for Device {
fn is_asio_device(&self) -> bool {
false
}
fn asio_open_control_panel(&self) -> Result<(), BackendSpecificError> {
Err(not_available())
}
fn asio_reset_device(&self) -> Result<(), BackendSpecificError> {
Err(not_available())
}
}
fn not_available() -> BackendSpecificError {
BackendSpecificError {
description: "ASIO is not available on this platform".to_string(),
}
} |
||
| pub mod asio; | ||
|
|
||
| /// A macro to assist with implementing a platform's dynamically dispatched [`Host`] type. | ||
| /// | ||
| /// These dynamically dispatched types are necessary to allow for users to switch between hosts at | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about making this an example in
asio-sys/examplesinstead?