Skip to content

Commit 375aef1

Browse files
committed
Enumerate Configs + Cleanup
1 parent cc15966 commit 375aef1

File tree

6 files changed

+69
-49
lines changed

6 files changed

+69
-49
lines changed

Cargo.toml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ edition = "2021"
55
rust-version = "1.80"
66
license = "MIT"
77

8-
[features]
9-
default = ["asio"]
10-
asio = ["asio-sys", "num-traits"]
11-
128
[dependencies]
139
duplicate = "2.0.0"
1410
fixed-resample = "0.8.0"
@@ -31,6 +27,7 @@ cfg_aliases = "0.2.1"
3127

3228
[features]
3329
pipewire = ["dep:pipewire", "dep:libspa", "dep:libspa-sys", "dep:zerocopy"]
30+
asio = ["asio-sys", "num-traits"]
3431

3532
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd"))'.dependencies]
3633
alsa = "0.9.1"
@@ -55,7 +52,7 @@ windows = { version = "0.61.1", features = [
5552
"Win32_Media_Multimedia",
5653
"Win32_UI_Shell_PropertiesSystem"
5754
]}
58-
asio-sys ={ version = "0.2.2", optional = true }
55+
asio-sys = { version = "0.2.2", optional = true }
5956
num-traits = {version = "0.2.19", optional = true }
6057

6158
[[example]]
@@ -69,13 +66,13 @@ path = "examples/enumerate_coreaudio.rs"
6966
[[example]]
7067
name = "enumerate_wasapi"
7168
path = "examples/enumerate_wasapi.rs"
72-
required-features = ["pipewire"]
7369

7470
[[example]]
7571
name = "enumerate_pipewire"
7672
path = "examples/enumerate_pipewire.rs"
73+
required-features = ["pipewire"]
7774

7875
[[example]]
7976
name = "enumerate_asio"
8077
path = "examples/enumerate_asio.rs"
81-
features = ["asio"]
78+
required-features = ["asio"]

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ fn main() {
77
os_alsa: { any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd",
88
target_os = "netbsd") },
99
os_coreaudio: { any (target_os = "macos", target_os = "ios") },
10+
os_pipewire: { any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd") },
1011
os_wasapi: { target_os = "windows" },
1112
os_asio: { all(target_os = "windows", feature = "asio") },
1213
unsupported: { not(any(os_alsa, os_coreaudio, os_wasapi))}

src/backends/asio/device.rs

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ impl AsioDevice {
8080
*streams = new_streams;
8181
bs
8282
})
83-
.map_err(|e| AsioError::BackendError(e))
83+
.map_err(AsioError::BackendError)
8484
}
8585
}
8686
}
@@ -111,7 +111,7 @@ impl AsioDevice {
111111
*streams = new_streams;
112112
bs
113113
})
114-
.map_err(|e| AsioError::BackendError(e))
114+
.map_err(AsioError::BackendError)
115115
}
116116
}
117117
}
@@ -131,7 +131,7 @@ impl AudioDevice for AsioDevice {
131131
fn is_config_supported(&self, config: &StreamConfig) -> bool {
132132
let sample_rate = config.samplerate;
133133
self.driver.can_sample_rate(sample_rate).unwrap_or(false)
134-
&& self.driver.channels().map_or(false, |channels| {
134+
&& self.driver.channels().is_ok_and(|channels| {
135135
let num_channels = config.channels as i32;
136136
match self.device_type {
137137
DeviceType::Input => channels.ins >= num_channels,
@@ -141,7 +141,7 @@ impl AudioDevice for AsioDevice {
141141
}
142142
}
143143
})
144-
&& self.driver.buffersize_range().map_or(false, |(min, max)| {
144+
&& self.driver.buffersize_range().is_ok_and(|(min, max)| {
145145
match config.buffer_size_range {
146146
(Some(min_config), Some(max_config)) => {
147147
min_config >= min as usize && max_config <= max as usize
@@ -152,7 +152,31 @@ impl AudioDevice for AsioDevice {
152152
}
153153

154154
fn enumerate_configurations(&self) -> Option<impl IntoIterator<Item = StreamConfig>> {
155-
None::<[StreamConfig; 0]>
155+
let sample_rates = [
156+
44100.0, 48000.0, 96000.0, 192000.0, 384000.0, 768000.0,
157+
];
158+
159+
let buffer_size_range = self.driver.buffersize_range().ok().map(|(min, max)| {
160+
(Some(min as usize), Some(max as usize))
161+
})?;
162+
163+
let channels = self.driver.channels().ok().map(|channels| {
164+
match self.device_type {
165+
DeviceType::Input => channels.ins as u32,
166+
DeviceType::Output => channels.outs as u32,
167+
DeviceType::Duplex => channels.ins.max(channels.outs) as u32,
168+
169+
}
170+
})?;
171+
172+
Some(sample_rates.into_iter().filter_map(move |samplerate| {
173+
self.driver.can_sample_rate(samplerate).ok().filter(|&can| can).map(|_| StreamConfig {
174+
channels,
175+
samplerate,
176+
buffer_size_range,
177+
exclusive: false,
178+
})
179+
}))
156180
}
157181
}
158182

@@ -279,7 +303,7 @@ impl AudioOutputDevice for AsioDevice {
279303
let mut buffer = vec![0.0f32; num_samples];
280304

281305
let mut streams = self.asio_streams.lock().unwrap();
282-
let output_stream = streams.output.take().ok_or(AsioError::MultipleStreams)?;
306+
let mut output_stream = streams.output.take().ok_or(AsioError::MultipleStreams)?;
283307

284308
let (tx, rx) = oneshot::channel::<oneshot::Sender<Callback>>();
285309
let mut callback = Some(callback);
@@ -306,7 +330,7 @@ impl AudioOutputDevice for AsioDevice {
306330

307331
let output = create_output(
308332
&output_data_type,
309-
&output_stream,
333+
&mut output_stream,
310334
&mut buffer,
311335
buffer_index,
312336
num_channels,
@@ -364,7 +388,7 @@ impl AudioDuplexDevice for AsioDevice {
364388
let mut output_buffer = vec![0.0f32; num_samples];
365389

366390
let mut streams = self.asio_streams.lock().unwrap();
367-
let output_stream = streams.output.take().ok_or(AsioError::MultipleStreams)?;
391+
let mut output_stream = streams.output.take().ok_or(AsioError::MultipleStreams)?;
368392
let input_stream = streams.input.take().ok_or(AsioError::MultipleStreams)?;
369393

370394
let (tx, rx) = oneshot::channel::<oneshot::Sender<Callback>>();
@@ -396,7 +420,7 @@ impl AudioDuplexDevice for AsioDevice {
396420

397421
let output = create_output(
398422
&output_data_type,
399-
&output_stream,
423+
&mut output_stream,
400424
&mut output_buffer,
401425
buffer_index,
402426
num_channels,
@@ -428,71 +452,71 @@ impl AudioDuplexDevice for AsioDevice {
428452
/// Create an `AudioOutput` from the ASIO stream and the buffer.
429453
unsafe fn create_output<'a>(
430454
output_data_type: &asio::AsioSampleType,
431-
asio_stream: &asio::AsioStream,
455+
asio_stream: &mut asio::AsioStream,
432456
buffer: &'a mut [f32],
433457
buffer_index: usize,
434458
num_channels: usize,
435459
timestamp: timestamp::Timestamp,
436460
) -> AudioOutput<'a, f32> {
437461
let audio_output_buffer = match output_data_type {
438462
asio::AsioSampleType::ASIOSTInt16MSB => create_output_buffer(
439-
&asio_stream,
463+
asio_stream,
440464
buffer,
441465
buffer_index,
442466
num_channels,
443467
to_be,
444468
f32_to_i16,
445469
),
446470
asio::AsioSampleType::ASIOSTInt16LSB => create_output_buffer(
447-
&asio_stream,
471+
asio_stream,
448472
buffer,
449473
buffer_index,
450474
num_channels,
451475
to_le,
452476
f32_to_i16,
453477
),
454478
asio::AsioSampleType::ASIOSTInt24MSB => create_output_buffer(
455-
&asio_stream,
479+
asio_stream,
456480
buffer,
457481
buffer_index,
458482
num_channels,
459483
to_be,
460484
f32_to_i24,
461485
),
462486
asio::AsioSampleType::ASIOSTInt24LSB => create_output_buffer(
463-
&asio_stream,
487+
asio_stream,
464488
buffer,
465489
buffer_index,
466490
num_channels,
467491
to_le,
468492
f32_to_i24,
469493
),
470494
asio::AsioSampleType::ASIOSTInt32MSB => create_output_buffer(
471-
&asio_stream,
495+
asio_stream,
472496
buffer,
473497
buffer_index,
474498
num_channels,
475499
to_be,
476500
f32_to_i32,
477501
),
478502
asio::AsioSampleType::ASIOSTInt32LSB => create_output_buffer(
479-
&asio_stream,
503+
asio_stream,
480504
buffer,
481505
buffer_index,
482506
num_channels,
483507
to_le,
484508
f32_to_i32,
485509
),
486510
asio::AsioSampleType::ASIOSTFloat32MSB => create_output_buffer::<u32>(
487-
&asio_stream,
511+
asio_stream,
488512
buffer,
489513
buffer_index,
490514
num_channels,
491515
to_be,
492516
f32::to_bits,
493517
),
494518
asio::AsioSampleType::ASIOSTFloat32LSB => create_output_buffer::<u32>(
495-
&asio_stream,
519+
asio_stream,
496520
buffer,
497521
buffer_index,
498522
num_channels,
@@ -521,63 +545,63 @@ unsafe fn create_input<'a>(
521545
) -> AudioInput<'a, f32> {
522546
let audio_input_buffer = match input_data_type {
523547
asio::AsioSampleType::ASIOSTInt16MSB => create_input_buffer(
524-
&asio_stream,
548+
asio_stream,
525549
buffer,
526550
buffer_index,
527551
num_channels,
528552
from_be,
529553
i16_to_f32,
530554
),
531555
asio::AsioSampleType::ASIOSTInt16LSB => create_input_buffer(
532-
&asio_stream,
556+
asio_stream,
533557
buffer,
534558
buffer_index,
535559
num_channels,
536560
from_le,
537561
i16_to_f32,
538562
),
539563
asio::AsioSampleType::ASIOSTInt24MSB => create_input_buffer(
540-
&asio_stream,
564+
asio_stream,
541565
buffer,
542566
buffer_index,
543567
num_channels,
544568
from_be,
545569
i24_to_f32,
546570
),
547571
asio::AsioSampleType::ASIOSTInt24LSB => create_input_buffer(
548-
&asio_stream,
572+
asio_stream,
549573
buffer,
550574
buffer_index,
551575
num_channels,
552576
from_le,
553577
i24_to_f32,
554578
),
555579
asio::AsioSampleType::ASIOSTInt32MSB => create_input_buffer(
556-
&asio_stream,
580+
asio_stream,
557581
buffer,
558582
buffer_index,
559583
num_channels,
560584
from_be,
561585
i32_to_f32,
562586
),
563587
asio::AsioSampleType::ASIOSTInt32LSB => create_input_buffer(
564-
&asio_stream,
588+
asio_stream,
565589
buffer,
566590
buffer_index,
567591
num_channels,
568592
from_le,
569593
i32_to_f32,
570594
),
571595
asio::AsioSampleType::ASIOSTFloat32MSB => create_input_buffer::<u32>(
572-
&asio_stream,
596+
asio_stream,
573597
buffer,
574598
buffer_index,
575599
num_channels,
576600
from_be,
577601
f32::from_bits,
578602
),
579603
asio::AsioSampleType::ASIOSTFloat32LSB => create_input_buffer::<u32>(
580-
&asio_stream,
604+
asio_stream,
581605
buffer,
582606
buffer_index,
583607
num_channels,
@@ -614,7 +638,7 @@ unsafe fn create_input_buffer<'a, SampleType: Copy>(
614638
}
615639

616640
unsafe fn create_output_buffer<'a, SampleType: Copy>(
617-
asio_stream: &asio::AsioStream,
641+
asio_stream: &mut asio::AsioStream,
618642
buffer: &'a mut [f32],
619643
buffer_index: usize,
620644
num_channels: usize,
@@ -638,18 +662,18 @@ unsafe fn asio_channel_slice<T>(
638662
) -> &[T] {
639663
let buffer_size = asio_stream.buffer_size as usize;
640664
let buff_ptr: *const T =
641-
asio_stream.buffer_infos[channel_index].buffers[buffer_index as usize] as *const _;
665+
asio_stream.buffer_infos[channel_index].buffers[buffer_index] as *const _;
642666
std::slice::from_raw_parts(buff_ptr, buffer_size)
643667
}
644668

645669
unsafe fn asio_channel_slice_mut<T>(
646-
asio_stream: &asio::AsioStream,
670+
asio_stream: &mut asio::AsioStream,
647671
buffer_index: usize,
648672
channel_index: usize,
649673
) -> &mut [T] {
650674
let buffer_size = asio_stream.buffer_size as usize;
651675
let buff_ptr: *mut T =
652-
asio_stream.buffer_infos[channel_index].buffers[buffer_index as usize] as *mut _;
676+
asio_stream.buffer_infos[channel_index].buffers[buffer_index] as *mut _;
653677
std::slice::from_raw_parts_mut(buff_ptr, buffer_size)
654678
}
655679

@@ -701,4 +725,4 @@ fn f32_to_i32(f: f32) -> i32 {
701725
/// Helper function to convert from f32 to i24.
702726
fn f32_to_i24(f: f32) -> i32 {
703727
(f * 0x7FFFFF as f32) as i32
704-
}
728+
}

src/backends/asio/driver.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,14 @@ impl AudioDriver for AsioDriver {
3434
}
3535

3636
fn default_device(&self, device_type: DeviceType) -> Result<Option<Self::Device>, Self::Error> {
37-
let iter = AsioDeviceList::new(self.asio.clone())?;
37+
let mut iter = AsioDeviceList::new(self.asio.clone())?;
3838

3939
let dd = iter
40-
.filter(|device| match (device.device_type(), device_type) {
41-
(DeviceType::Input | DeviceType::Duplex, DeviceType::Input) => true,
42-
(DeviceType::Output | DeviceType::Duplex, DeviceType::Output) => true,
43-
(a, b) => a == b,
44-
})
45-
.next();
40+
.find(|device| match (device.device_type(), device_type) {
41+
(DeviceType::Input | DeviceType::Duplex, DeviceType::Input) => true,
42+
(DeviceType::Output | DeviceType::Duplex, DeviceType::Output) => true,
43+
(a, b) => a == b,
44+
});
4645
Ok(dd)
4746
}
4847

src/backends/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,8 @@ pub fn default_output_device() -> impl AudioOutputDevice {
113113
return default_output_device_from(&alsa::AlsaDriver);
114114
#[cfg(os_coreaudio)]
115115
return default_output_device_from(&coreaudio::CoreAudioDriver);
116-
// #[cfg(os_wasapi)]
117-
// return default_output_device_from(&wasapi::WasapiDriver);
118-
#[cfg(os_asio)]
119-
return default_output_device_from(&asio::AsioDriver::new().unwrap());
116+
#[cfg(os_wasapi)]
117+
return default_output_device_from(&wasapi::WasapiDriver);
120118
}
121119

122120
/// Default duplex device from the default driver of this platform.

src/duplex.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
//!
33
//! This module includes a proxy for gathering an input audio stream, and optionally process it to resample it to the
44
//! output sample rate.
5+
use crate::audio_buffer::AudioRef;
56
use crate::channel_map::Bitset;
67
use crate::device::{AudioDevice, AudioInputDevice, AudioOutputDevice};
78
use crate::stream::{

0 commit comments

Comments
 (0)