Skip to content

Conversation

@melody-rs
Copy link
Contributor

This PR adds support for writing and using custom HostTrait, DeviceTrait, and StreamTrait implementations

This was already sort of possible before, but cpal::Data has no public constructor so writing a custom device implementation wasn't possible.
Actually using the custom host wasn't doable either, as crates like rodio only accept a cpal::Host/cpal::Device, which doesn't support Hosts defined outside cpal

Why

Currently, adding support for platforms that cpal doesn't support requires forking cpal.
Depending on the platform, it might not be possible/desirable to upstream support into cpal either

How

I partially modeled this PR off of wgpu's custom device support and erased-serde.

Custom hosts require everything to be 'static, which is annoying, but relaxing that requirement would've meant introducing lifetimes in a lot of places that didn't have them previously

There's also the requirement that custom devices and supported configs be Clone as well, because of these derives in platform/mod.rs:

cpal/src/platform/mod.rs

Lines 90 to 96 in 2b7dc14

#[derive(Clone)]
pub enum DeviceInner {
$(
$(#[cfg($feat)])?
$HostVariant(<$Host as crate::traits::HostTrait>::Device),
)*
}

cpal/src/platform/mod.rs

Lines 122 to 128 in 2b7dc14

#[derive(Clone)]
enum SupportedInputConfigsInner {
$(
$(#[cfg($feat)])?
$HostVariant(<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::SupportedInputConfigs),
)*
}

cpal/src/platform/mod.rs

Lines 130 to 136 in 2b7dc14

#[derive(Clone)]
enum SupportedOutputConfigsInner {
$(
$(#[cfg($feat)])?
$HostVariant(<<$Host as crate::traits::HostTrait>::Device as crate::traits::DeviceTrait>::SupportedOutputConfigs),
)*
}

Removing those derives would make the code for custom devices simpler

@roderickvd
Copy link
Member

Thanks for the PR! I'm off for a little while and will look at it later. It's an interesting feature - however curious for what kind of hosts one would want to add proprietary support instead of contributing it to cpal?

@melody-rs
Copy link
Contributor Author

melody-rs commented Oct 18, 2025

Any hosts written against proprietary code (anything console-specific for example) couldn't be upstreamed for legal reasons

There's definitely other reasons not to upstream a host aside from that, certain hosts could be very niche or be designed for very specific use-cases!

I wrote this PR after I tried to make a custom cpal backend for the 3ds using libctru and couldn't. In order to upstream it, I'd have to make the host production ready, and after it'd be upstreamed the cpal maintainers would have to maintain a host for a very niche platform

Copy link
Member

@roderickvd roderickvd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late response and thanks for your earlier explanation.
I think it's interesting to add this as an opt-in feature. Would you also add a changelog entry and an example?

@melody-rs
Copy link
Contributor Author

I tried to make the example generally show how Host impls should be written while not getting into the details too much

@roderickvd roderickvd merged commit 99aabd0 into RustAudio:master Nov 13, 2025
16 checks passed
@roderickvd
Copy link
Member

Merged. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants