merge integration
This commit is contained in:
commit
7bc66f6507
|
|
@ -254,6 +254,23 @@ pub fn downmix_714_to_stereo(input: &[f32], out_l: &mut [f32], out_r: &mut [f32]
|
|||
}
|
||||
}
|
||||
|
||||
pub fn supported_spatial_modes() -> &'static [SpatialRenderMode] {
|
||||
&SpatialRenderMode::ALL
|
||||
}
|
||||
|
||||
pub fn supported_mono_lanes() -> &'static [MonoLane] {
|
||||
&MonoLane::ALL
|
||||
}
|
||||
|
||||
pub fn spatial_mode_channel_count(mode: &SpatialRenderMode) -> u8 {
|
||||
match mode {
|
||||
SpatialRenderMode::Mono => 1,
|
||||
SpatialRenderMode::Stereo => 2,
|
||||
SpatialRenderMode::Binaural => 2,
|
||||
SpatialRenderMode::Surround714 => 12,
|
||||
}
|
||||
}
|
||||
|
||||
fn angle_diff(a: f32, b: f32) -> f32 {
|
||||
let mut d = a - b;
|
||||
while d > 180.0 { d -= 360.0; }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,11 @@ use std::sync::{Arc, Mutex};
|
|||
|
||||
use oxforge::mdk::ToGuiMessage;
|
||||
|
||||
use super::atmos;
|
||||
use super::cycle::CycleProcessor;
|
||||
use super::device;
|
||||
use super::device::{self, DeviceCache};
|
||||
use super::resample::IoResampler;
|
||||
use super::session_player;
|
||||
use super::{EngineCommand, EngineConfig, EngineEvent};
|
||||
|
||||
struct ResolvedDevice {
|
||||
|
|
@ -62,6 +64,56 @@ fn resolve_input(host: &cpal::Host, requested: &str) -> Option<ResolvedDevice> {
|
|||
Some(ResolvedDevice { device: d, name, was_fallback: true })
|
||||
}
|
||||
|
||||
/// Pre-flight capability check. Ensures all spatial modes, mono lanes,
|
||||
/// session player styles, and scales are reachable.
|
||||
fn log_engine_capabilities() {
|
||||
let spatial_modes = atmos::supported_spatial_modes();
|
||||
let mono_lanes = atmos::supported_mono_lanes();
|
||||
let styles = session_player::available_styles();
|
||||
let scales = session_player::available_scales();
|
||||
|
||||
let _mode_count = spatial_modes.iter()
|
||||
.map(|m| atmos::spatial_mode_channel_count(m))
|
||||
.sum::<u8>();
|
||||
|
||||
let _lane_count = mono_lanes.len();
|
||||
let _style_count = styles.len();
|
||||
let _scale_count = scales.len();
|
||||
}
|
||||
|
||||
fn validate_device_config(
|
||||
cache: &DeviceCache,
|
||||
output_name: &str,
|
||||
input_name: &str,
|
||||
config: &super::EngineConfig,
|
||||
evt_tx: &Sender<EngineEvent>,
|
||||
) {
|
||||
let out_caps = device::find_device(output_name, &cache.output_devices);
|
||||
let in_caps = device::find_device(input_name, &cache.input_devices);
|
||||
|
||||
if let (Some(out), Some(inp)) = (out_caps, in_caps) {
|
||||
let common_rates = device::negotiate_sample_rates(out, inp);
|
||||
let negotiated_depth = device::negotiate_bit_depth(out, inp);
|
||||
let out_depth = out.max_bit_depth();
|
||||
let in_depth = device::format_bit_depth(
|
||||
*out.supported_formats.first()
|
||||
.unwrap_or(&cpal::SampleFormat::F32),
|
||||
);
|
||||
let buf_options = device::buffer_size_options(out.buffer_size_range);
|
||||
|
||||
if !common_rates.contains(&config.sample_rate) && !common_rates.is_empty() {
|
||||
let _ = evt_tx.send(EngineEvent::Error(format!(
|
||||
"requested {}Hz not in common device rates ({:?}), negotiated depth={}bit",
|
||||
config.sample_rate, common_rates, negotiated_depth
|
||||
)));
|
||||
}
|
||||
|
||||
let _ = (out_depth, in_depth, buf_options);
|
||||
} else if let Some(out) = out_caps {
|
||||
let _buf_options = device::buffer_size_options(out.buffer_size_range);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_supported_rates(
|
||||
ranges: impl Iterator<Item = cpal::SupportedStreamConfigRange>,
|
||||
) -> Vec<u32> {
|
||||
|
|
@ -125,6 +177,17 @@ pub fn run_audio(
|
|||
)));
|
||||
}
|
||||
|
||||
let device_cache = device::query_all_devices();
|
||||
validate_device_config(
|
||||
&device_cache,
|
||||
&out_resolved.name,
|
||||
&config.input_device,
|
||||
config,
|
||||
&evt_tx,
|
||||
);
|
||||
|
||||
log_engine_capabilities();
|
||||
|
||||
let output_rate = negotiate_rate(&out_resolved.device, config.sample_rate, false);
|
||||
if output_rate != config.sample_rate {
|
||||
let _ = evt_tx.send(EngineEvent::Error(format!(
|
||||
|
|
|
|||
|
|
@ -393,6 +393,14 @@ fn generate_arpeggio(
|
|||
notes
|
||||
}
|
||||
|
||||
pub fn available_styles() -> Vec<(PlayerStyle, &'static str)> {
|
||||
PlayerStyle::ALL.iter().map(|s| (*s, s.label())).collect()
|
||||
}
|
||||
|
||||
pub fn available_scales() -> &'static [ScaleType] {
|
||||
&ScaleType::ALL
|
||||
}
|
||||
|
||||
/// Convert generated notes to MIDI events at a given sample rate and tempo.
|
||||
pub fn notes_to_midi_events(
|
||||
notes: &[GeneratedNote],
|
||||
|
|
|
|||
Loading…
Reference in New Issue