Implement WASAPI loopback support
This works by detecting output devices in build_input_stream() and setting the AUDCLNT_STREAMFLAGS_LOOPBACK flag to enable loopback recording. closes #251
This commit is contained in:
parent
be54ffff09
commit
dcabad105b
|
@ -552,7 +552,7 @@ impl Device {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data_flow(&self) -> EDataFlow {
|
pub(crate) fn data_flow(&self) -> EDataFlow {
|
||||||
let endpoint = Endpoint::from(self.device as *const _);
|
let endpoint = Endpoint::from(self.device as *const _);
|
||||||
endpoint.data_flow()
|
endpoint.data_flow()
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ mod device;
|
||||||
mod stream;
|
mod stream;
|
||||||
|
|
||||||
/// The WASAPI host, the default windows host type.
|
/// The WASAPI host, the default windows host type.
|
||||||
|
///
|
||||||
|
/// Note: If you use a WASAPI output device as an input device it will
|
||||||
|
/// transparently enable loopback mode (see
|
||||||
|
/// https://docs.microsoft.com/en-us/windows/win32/coreaudio/loopback-recording).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Host;
|
pub struct Host;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,8 @@ use super::winapi::shared::ksmedia;
|
||||||
use super::winapi::shared::minwindef::{BYTE, DWORD, FALSE, WORD};
|
use super::winapi::shared::minwindef::{BYTE, DWORD, FALSE, WORD};
|
||||||
use super::winapi::shared::mmreg;
|
use super::winapi::shared::mmreg;
|
||||||
use super::winapi::um::audioclient::{self, AUDCLNT_E_DEVICE_INVALIDATED, AUDCLNT_S_BUFFER_EMPTY};
|
use super::winapi::um::audioclient::{self, AUDCLNT_E_DEVICE_INVALIDATED, AUDCLNT_S_BUFFER_EMPTY};
|
||||||
use super::winapi::um::audiosessiontypes::{AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK};
|
use super::winapi::um::audiosessiontypes::{AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, AUDCLNT_STREAMFLAGS_LOOPBACK};
|
||||||
|
use super::winapi::um::mmdeviceapi::eRender;
|
||||||
use super::winapi::um::handleapi;
|
use super::winapi::um::handleapi;
|
||||||
use super::winapi::um::synchapi;
|
use super::winapi::um::synchapi;
|
||||||
use super::winapi::um::winbase;
|
use super::winapi::um::winbase;
|
||||||
|
@ -151,10 +152,16 @@ impl EventLoop {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support capturing output devices.
|
||||||
|
let mut stream_flags: DWORD = AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
|
||||||
|
if device.data_flow() == eRender {
|
||||||
|
stream_flags |= AUDCLNT_STREAMFLAGS_LOOPBACK;
|
||||||
|
}
|
||||||
|
|
||||||
// finally initializing the audio client
|
// finally initializing the audio client
|
||||||
let hresult = (*audio_client).Initialize(
|
let hresult = (*audio_client).Initialize(
|
||||||
share_mode,
|
share_mode,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
stream_flags,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&format_attempt.Format,
|
&format_attempt.Format,
|
||||||
|
|
Loading…
Reference in New Issue