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

Panic when running enumerate.rs example #538

Closed
downfall85 opened this issue Feb 3, 2021 · 2 comments · Fixed by #597
Closed

Panic when running enumerate.rs example #538

downfall85 opened this issue Feb 3, 2021 · 2 comments · Fixed by #597

Comments

@downfall85
Copy link

Hello,

I get the following error when I run the enumerate.rs example:

Supported hosts:
[Asio, Wasapi]
Available hosts:
[Asio, Wasapi]
ASIO
Default Input Device:
Some("ASIO TonePort UX2")
Default Output Device:
Some("ASIO TonePort UX2")
Devices:

  1. "ASIO TonePort UX2"
    Default input stream config:
    SupportedStreamConfig { channels: 4, sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    All supported input stream configs:
    1.1. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.2. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.3. SupportedStreamConfigRange { channels: 3, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.4. SupportedStreamConfigRange { channels: 4, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.5. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.6. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.7. SupportedStreamConfigRange { channels: 3, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.8. SupportedStreamConfigRange { channels: 4, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.9. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.10. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.11. SupportedStreamConfigRange { channels: 3, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.12. SupportedStreamConfigRange { channels: 4, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.13. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.14. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.15. SupportedStreamConfigRange { channels: 3, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.16. SupportedStreamConfigRange { channels: 4, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    Default output stream config:
    SupportedStreamConfig { channels: 2, sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    All supported output stream configs:
    1.1. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.2. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(44100), max_sample_rate: SampleRate(44100), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.3. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.4. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(48000), max_sample_rate: SampleRate(48000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.5. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.6. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(88200), max_sample_rate: SampleRate(88200), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.7. SupportedStreamConfigRange { channels: 1, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    1.8. SupportedStreamConfigRange { channels: 2, min_sample_rate: SampleRate(96000), max_sample_rate: SampleRate(96000), buffer_size: Range { min: 128, max: 4096 }, sample_format: I16 }
    WASAPI
    thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: -2147417850, kind: Other, message: "Impossible de modifier le mode thread une fois qu’il a été fixé." }', C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\com.rs:13:77
    stack backtrace:
    0: std::panicking::begin_panic_handler
    at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library\std\src\panicking.rs:495
    1: core::panicking::panic_fmt
    at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library\core\src\panicking.rs:92
    2: core::option::expect_none_failed
    at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library\core\src\option.rs:1268
    3: core::result::Result<tuple<>, std::io::error::Error>::unwrap<tuple<>,std::io::error::Error>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\result.rs:973
    4: cpal::host::wasapi::com::COM_INITIALIZED::__init
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\com.rs:13
    5: core::ops::function::FnOnce::call_once<fn() -> cpal::host::wasapi::com::ComInitialized,tuple<>>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
    6: std::thread::local::lazy::LazyKeyInnercpal::host::wasapi::com::ComInitialized::initialize<cpal::host::wasapi::com::ComInitialized,fn() -> cpal::host::wasapi::com::ComInitialized>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:304
    7: std::thread::local::fast::Keycpal::host::wasapi::com::ComInitialized::try_initialize<cpal::host::wasapi::com::ComInitialized,fn() -> cpal::host::wasapi::com::ComInitialized>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:473
    8: std::thread::local::fast::Keycpal::host::wasapi::com::ComInitialized::get<cpal::host::wasapi::com::ComInitialized,fn() -> cpal::host::wasapi::com::ComInitialized>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:456
    9: cpal::host::wasapi::com::COM_INITIALIZED::__getit
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:183
    10: std::thread::local::LocalKeycpal::host::wasapi::com::ComInitialized::try_with<cpal::host::wasapi::com::ComInitialized,closure-0,tuple<>>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:271
    11: std::thread::local::LocalKeycpal::host::wasapi::com::ComInitialized::with<cpal::host::wasapi::com::ComInitialized,closure-0,tuple<>>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:248
    12: cpal::host::wasapi::com::com_initialized
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\com.rs:34
    13: core::ops::function::FnOnce::call_once<fn() -> cpal::host::wasapi::device::Enumerator,tuple<>>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
    14: lazy_static::lazy::{{impl}}::get::{{closure}}<cpal::host::wasapi::device::Enumerator,fn() -> cpal::host::wasapi::device::Enumerator>
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\lazy_static-1.4.0\src\inline_lazy.rs:31
    15: std::sync::once::{{impl}}::call_once::{{closure}}
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sync\once.rs:261
    16: std::sync::once::Once::call_inner
    at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library\std\src\sync\once.rs:419
    17: std::sync::once::Once::call_once
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sync\once.rs:261
    18: lazy_static::lazy::Lazycpal::host::wasapi::device::Enumerator::get
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\lazy_static-1.4.0\src\inline_lazy.rs:30
    19: cpal::host::wasapi::device::{{impl}}::deref::__stability
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\lazy_static-1.4.0\src\lib.rs:142
    20: cpal::host::wasapi::device::{{impl}}::deref
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\lazy_static-1.4.0\src\lib.rs:144
    21: cpal::host::wasapi::device::default_device
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\device.rs:1182
    22: cpal::host::wasapi::device::default_input_device
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\device.rs:1191
    23: cpal::host::wasapi::{{impl}}::default_input_device
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\host\wasapi\mod.rs:46
    24: cpal::platform::platform_impl::{{impl}}::default_input_device
    at C:\Users\downfall85.cargo\registry\src\github.com-1ecc6299db9ec823\cpal-0.13.1\src\platform\mod.rs:333
    25: pitch_shifter_rt::main
    at .\src\main.rs:15
    26: core::ops::function::FnOnce::call_once<fn() -> core::result::Result<tuple<>, anyhow::Error>,tuple<>>
    at C:\Users\downfall85.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
    note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.
    error: process didn't exit successfully: target\debug\pitch_shifter_rt.exe (exit code: 101)

From the file src\host\wasapi\com.rs:13:77; it seems hat there is already a COM library initialized in single-threaded mode and it's certainly by the ASIO code

thread_local!(static COM_INITIALIZED: ComInitialized = {
unsafe {
// this call can fail if another library initialized COM in single-threaded mode
// handling this situation properly would make the API more annoying, so we just don't care
check_result(CoInitializeEx(ptr::null_mut(), COINIT_MULTITHREADED)).unwrap(); <- line 13
ComInitialized(ptr::null_mut())
}
});

Os : Windows 10 64bits
Cpal version : 0.13.1 (build with asio)

@downfall85
Copy link
Author

As a side note, the PR described here #504 fixes the issue.

@HEnquist
Copy link
Contributor

There is an alternative solution in this PR: #441

Or an ugly hack, just change the enumerate example so that it enumerates Asio after Wasapi.

ishitatsuyuki added a commit to ishitatsuyuki/cpal that referenced this issue Aug 6, 2021
COM can prevent undefined behavior in either concurrency model by
performing marshaling when necessary. As a result, CoInitializeEx can be
called with either concurrency model, and in this case STA provides better
compatibility with other code requiring STA, e.g. ASIO backend or winit
drag-and-drop.

To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is
registered with "both" threading model, which means that COM objects are
created with whatever the thread's concurrency model is set to. This raises
the concern that when STA is used, marshaling might make audio buffer
operations block on the main thread, breaking continuous audio processing.
However, the implementation actually uses free-threaded marshaller for
interfaces dealing with buffer operations, which effectively bypasses COM's
compatibility marshaling behavior and perform any API calls on the caller's
thread instead. Therefore, the interfaces would operate just fine on either
concurrency model.

For more details on COM's threading model, see [1].

[1] https://thrysoee.dk/InsideCOM+/ch04d.htm

Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com>

Close RustAudio#348
Close RustAudio#504
Close RustAudio#538
ishitatsuyuki added a commit to ishitatsuyuki/cpal that referenced this issue Aug 6, 2021
COM can prevent undefined behavior in either concurrency model by
performing marshaling when necessary. As a result, CoInitializeEx can be
called with either concurrency model, and in this case STA provides better
compatibility with other code requiring STA, e.g. ASIO backend or winit
drag-and-drop.

To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is
registered with "both" threading model, which means that COM objects are
created with whatever the thread's concurrency model is set to. This raises
the concern that when STA is used, marshaling might make audio buffer
operations block on the main thread, breaking continuous audio processing.
However, the implementation actually uses free-threaded marshaller for
interfaces dealing with buffer operations, which effectively bypasses COM's
compatibility marshaling behavior and perform any API calls on the caller's
thread instead. Therefore, the interfaces would operate just fine on either
concurrency model.

For more details on COM's threading model, see [1].

[1] https://thrysoee.dk/InsideCOM+/ch04d.htm

Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com>

Close RustAudio#348
Close RustAudio#504
Close RustAudio#538
ishitatsuyuki added a commit to ishitatsuyuki/cpal that referenced this issue Aug 6, 2021
COM can prevent undefined behavior in either concurrency model by
performing marshaling when necessary. As a result, CoInitializeEx can be
called with either concurrency model, and in this case STA provides better
compatibility with other code requiring STA, e.g. ASIO backend or winit
drag-and-drop.

To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is
registered with "both" threading model, which means that COM objects are
created with whatever the thread's concurrency model is set to. This raises
the concern that when STA is used, marshaling might make audio buffer
operations block on the main thread, breaking continuous audio processing.
However, the implementation actually uses free-threaded marshaller for
interfaces dealing with buffer operations, which effectively bypasses COM's
compatibility marshaling behavior and perform any API calls on the caller's
thread instead. Therefore, the interfaces would operate just fine on either
concurrency model.

For more details on COM's threading model, see [1].

[1] https://thrysoee.dk/InsideCOM+/ch04d.htm

Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com>

Close RustAudio#348
Close RustAudio#504
Close RustAudio#538
ishitatsuyuki added a commit to ishitatsuyuki/cpal that referenced this issue Aug 8, 2021
COM can prevent undefined behavior in either concurrency model by
performing marshaling when necessary. As a result, CoInitializeEx can be
called with either concurrency model, and in this case STA provides better
compatibility with other code requiring STA, e.g. ASIO backend or winit
drag-and-drop.

To dive into the detail, the entry point of WASAPI, MMDeviceEnumerator, is
registered with "both" threading model, which means that COM objects are
created with whatever the thread's concurrency model is set to. This raises
the concern that when STA is used, marshaling might make audio buffer
operations block on the main thread, breaking continuous audio processing.
However, the implementation actually uses free-threaded marshaller for
interfaces dealing with buffer operations, which effectively bypasses COM's
compatibility marshaling behavior and perform any API calls on the caller's
thread instead. Therefore, the interfaces would operate just fine on either
concurrency model.

For more details on COM's threading model, see [1].

[1] https://thrysoee.dk/InsideCOM+/ch04d.htm

Co-Authored-By: Henrik Rydgård <hrydgard@gmail.com>

Close RustAudio#59
Close RustAudio#348
Close RustAudio#504
Close RustAudio#530
Close RustAudio#538
Close RustAudio#572
@est31 est31 closed this as completed in #597 Aug 8, 2021
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 a pull request may close this issue.

2 participants