mirror of
https://github.com/exoticorn/microw8.git
synced 2026-01-20 11:16:42 +01:00
add support for sound devices that only accept 16bit audio
This commit is contained in:
@@ -328,23 +328,26 @@ fn init_sound(
|
|||||||
let mut configs: Vec<_> = device
|
let mut configs: Vec<_> = device
|
||||||
.supported_output_configs()?
|
.supported_output_configs()?
|
||||||
.filter(|config| {
|
.filter(|config| {
|
||||||
config.channels() == 2 && config.sample_format() == cpal::SampleFormat::F32
|
config.channels() == 2
|
||||||
|
&& (config.sample_format() == cpal::SampleFormat::F32
|
||||||
|
|| config.sample_format() == cpal::SampleFormat::I16)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
configs.sort_by_key(|config| {
|
configs.sort_by_key(|config| {
|
||||||
let rate = 44100
|
let rate = 44100
|
||||||
.max(config.min_sample_rate().0)
|
.max(config.min_sample_rate().0)
|
||||||
.min(config.max_sample_rate().0);
|
.min(config.max_sample_rate().0);
|
||||||
if rate >= 44100 {
|
let prio = if rate >= 44100 {
|
||||||
rate - 44100
|
rate - 44100
|
||||||
} else {
|
} else {
|
||||||
(44100 - rate) * 1000
|
(44100 - rate) * 1000
|
||||||
}
|
};
|
||||||
|
prio + (config.sample_format() == cpal::SampleFormat::I16) as u32
|
||||||
});
|
});
|
||||||
let config = configs
|
let config = configs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| anyhow!("Could not find float output config"))?;
|
.ok_or_else(|| anyhow!("Could not find float or 16bit signed output config"))?;
|
||||||
let sample_rate = cpal::SampleRate(44100)
|
let sample_rate = cpal::SampleRate(44100)
|
||||||
.max(config.min_sample_rate())
|
.max(config.min_sample_rate())
|
||||||
.min(config.max_sample_rate());
|
.min(config.max_sample_rate());
|
||||||
@@ -355,6 +358,7 @@ fn init_sound(
|
|||||||
cpal::BufferSize::Fixed(256.max(min).min(max))
|
cpal::BufferSize::Fixed(256.max(min).min(max))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let sample_format = config.sample_format();
|
||||||
let config = cpal::StreamConfig {
|
let config = cpal::StreamConfig {
|
||||||
buffer_size,
|
buffer_size,
|
||||||
..config.config()
|
..config.config()
|
||||||
@@ -384,12 +388,13 @@ fn init_sound(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dbg!(sample_format);
|
||||||
|
|
||||||
let mut sample_index = 0;
|
let mut sample_index = 0;
|
||||||
let mut pending_updates: Vec<RegisterUpdate> = Vec::with_capacity(30);
|
let mut pending_updates: Vec<RegisterUpdate> = Vec::with_capacity(30);
|
||||||
let mut current_time = 0;
|
let mut current_time = 0;
|
||||||
let stream = device.build_output_stream(
|
|
||||||
&config,
|
let mut callback = move |mut outer_buffer: &mut [f32], _: &_| {
|
||||||
move |mut outer_buffer: &mut [f32], _| {
|
|
||||||
let mut first_update = true;
|
let mut first_update = true;
|
||||||
while let Ok(update) = rx.try_recv() {
|
while let Ok(update) = rx.try_recv() {
|
||||||
if first_update {
|
if first_update {
|
||||||
@@ -462,8 +467,7 @@ fn init_sound(
|
|||||||
resampler.output_index = 0;
|
resampler.output_index = 0;
|
||||||
} else {
|
} else {
|
||||||
for i in 0..copy_size {
|
for i in 0..copy_size {
|
||||||
buffer[i * 2] =
|
buffer[i * 2] = resampler.output_buffers[0][resampler.output_index + i];
|
||||||
resampler.output_buffers[0][resampler.output_index + i];
|
|
||||||
buffer[i * 2 + 1] =
|
buffer[i * 2 + 1] =
|
||||||
resampler.output_buffers[1][resampler.output_index + i];
|
resampler.output_buffers[1][resampler.output_index + i];
|
||||||
}
|
}
|
||||||
@@ -479,15 +483,40 @@ fn init_sound(
|
|||||||
}
|
}
|
||||||
|
|
||||||
outer_buffer = &mut outer_buffer[step_size..];
|
outer_buffer = &mut outer_buffer[step_size..];
|
||||||
current_time =
|
current_time = current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32);
|
||||||
current_time.wrapping_add((step_size * 500 / sample_rate).max(1) as i32);
|
}
|
||||||
|
};
|
||||||
|
let stream = if sample_format == cpal::SampleFormat::F32 {
|
||||||
|
device.build_output_stream(
|
||||||
|
&config,
|
||||||
|
callback,
|
||||||
|
move |err| {
|
||||||
|
dbg!(err);
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
device.build_output_stream(
|
||||||
|
&config,
|
||||||
|
move |mut buffer: &mut [i16], info| {
|
||||||
|
let mut float_buffer = [0f32; 256];
|
||||||
|
|
||||||
|
while !buffer.is_empty() {
|
||||||
|
let step_size = buffer.len().min(float_buffer.len());
|
||||||
|
let step_buffer = &mut float_buffer[..step_size];
|
||||||
|
callback(step_buffer, info);
|
||||||
|
for (dest, src) in buffer.iter_mut().take(step_size).zip(step_buffer.iter()) {
|
||||||
|
*dest = (src.max(-1.0).min(1.0) * 32767.0) as i16;
|
||||||
|
}
|
||||||
|
buffer = &mut buffer[step_size..];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move |err| {
|
move |err| {
|
||||||
dbg!(err);
|
dbg!(err);
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)?;
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Uw8Sound { stream, tx })
|
Ok(Uw8Sound { stream, tx })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user