Ungoing refactoring
This commit is contained in:
@@ -15,15 +15,14 @@ use soft_ratatui::embedded_graphics_unicodefonts::{
|
||||
};
|
||||
use soft_ratatui::{EmbeddedGraphics, SoftBackend};
|
||||
|
||||
use cagire::app::App;
|
||||
use cagire::init::{init, InitArgs};
|
||||
use cagire::engine::{
|
||||
build_stream, spawn_sequencer, AnalysisHandle, AudioStreamConfig, LinkState, MidiCommand,
|
||||
ScopeBuffer, SequencerConfig, SequencerHandle, SpectrumBuffer,
|
||||
build_stream, AnalysisHandle, AudioStreamConfig, LinkState, MidiCommand, ScopeBuffer,
|
||||
SequencerHandle, SpectrumBuffer,
|
||||
};
|
||||
use cagire::input::{handle_key, InputContext, InputResult};
|
||||
use cagire::input_egui::convert_egui_events;
|
||||
use cagire::settings::Settings;
|
||||
use cagire::state::audio::RefreshRate;
|
||||
use cagire::views;
|
||||
use crossbeam_channel::Receiver;
|
||||
|
||||
@@ -129,7 +128,7 @@ fn create_terminal(font: FontChoice) -> TerminalType {
|
||||
}
|
||||
|
||||
struct CagireDesktop {
|
||||
app: App,
|
||||
app: cagire::app::App,
|
||||
terminal: TerminalType,
|
||||
link: Arc<LinkState>,
|
||||
sequencer: Option<SequencerHandle>,
|
||||
@@ -153,139 +152,39 @@ struct CagireDesktop {
|
||||
|
||||
impl CagireDesktop {
|
||||
fn new(cc: &eframe::CreationContext<'_>, args: Args) -> Self {
|
||||
let settings = Settings::load();
|
||||
let b = init(InitArgs {
|
||||
samples: args.samples,
|
||||
output: args.output,
|
||||
input: args.input,
|
||||
channels: args.channels,
|
||||
buffer: args.buffer,
|
||||
});
|
||||
|
||||
let link = Arc::new(LinkState::new(settings.link.tempo, settings.link.quantum));
|
||||
if settings.link.enabled {
|
||||
link.enable();
|
||||
}
|
||||
|
||||
let playing = Arc::new(AtomicBool::new(true));
|
||||
let nudge_us = Arc::new(AtomicI64::new(0));
|
||||
|
||||
let mut app = App::new();
|
||||
|
||||
app.playback
|
||||
.queued_changes
|
||||
.push(cagire::state::StagedChange {
|
||||
change: cagire::engine::PatternChange::Start {
|
||||
bank: 0,
|
||||
pattern: 0,
|
||||
},
|
||||
quantization: cagire::model::LaunchQuantization::Immediate,
|
||||
sync_mode: cagire::model::SyncMode::Reset,
|
||||
});
|
||||
|
||||
app.audio.config.output_device = args.output.or(settings.audio.output_device);
|
||||
app.audio.config.input_device = args.input.or(settings.audio.input_device);
|
||||
app.audio.config.channels = args.channels.unwrap_or(settings.audio.channels);
|
||||
app.audio.config.buffer_size = args.buffer.unwrap_or(settings.audio.buffer_size);
|
||||
app.audio.config.max_voices = settings.audio.max_voices;
|
||||
app.audio.config.lookahead_ms = settings.audio.lookahead_ms;
|
||||
app.audio.config.sample_paths = args.samples;
|
||||
app.audio.config.refresh_rate = RefreshRate::from_fps(settings.display.fps);
|
||||
app.ui.runtime_highlight = settings.display.runtime_highlight;
|
||||
app.audio.config.show_scope = settings.display.show_scope;
|
||||
app.audio.config.show_spectrum = settings.display.show_spectrum;
|
||||
app.ui.show_completion = settings.display.show_completion;
|
||||
|
||||
let metrics = Arc::new(EngineMetrics::default());
|
||||
let scope_buffer = Arc::new(ScopeBuffer::new());
|
||||
let spectrum_buffer = Arc::new(SpectrumBuffer::new());
|
||||
|
||||
let audio_sample_pos = Arc::new(AtomicU64::new(0));
|
||||
let sample_rate_shared = Arc::new(AtomicU32::new(44100));
|
||||
let lookahead_ms = Arc::new(AtomicU32::new(settings.audio.lookahead_ms));
|
||||
|
||||
let mut initial_samples = Vec::new();
|
||||
for path in &app.audio.config.sample_paths {
|
||||
let index = doux::sampling::scan_samples_dir(path);
|
||||
app.audio.config.sample_count += index.len();
|
||||
initial_samples.extend(index);
|
||||
}
|
||||
|
||||
let mouse_x = Arc::new(AtomicU32::new(0.5_f32.to_bits()));
|
||||
let mouse_y = Arc::new(AtomicU32::new(0.5_f32.to_bits()));
|
||||
let mouse_down = Arc::new(AtomicU32::new(0.0_f32.to_bits()));
|
||||
|
||||
let seq_config = SequencerConfig {
|
||||
audio_sample_pos: Arc::clone(&audio_sample_pos),
|
||||
sample_rate: Arc::clone(&sample_rate_shared),
|
||||
lookahead_ms: Arc::clone(&lookahead_ms),
|
||||
cc_access: Some(
|
||||
Arc::new(app.midi.cc_memory.clone()) as Arc<dyn cagire::model::CcAccess>
|
||||
),
|
||||
mouse_x: Arc::clone(&mouse_x),
|
||||
mouse_y: Arc::clone(&mouse_y),
|
||||
mouse_down: Arc::clone(&mouse_down),
|
||||
};
|
||||
|
||||
let (sequencer, initial_audio_rx, midi_rx) = spawn_sequencer(
|
||||
Arc::clone(&link),
|
||||
Arc::clone(&playing),
|
||||
Arc::clone(&app.variables),
|
||||
Arc::clone(&app.dict),
|
||||
Arc::clone(&app.rng),
|
||||
settings.link.quantum,
|
||||
Arc::clone(&app.live_keys),
|
||||
Arc::clone(&nudge_us),
|
||||
seq_config,
|
||||
);
|
||||
|
||||
let stream_config = AudioStreamConfig {
|
||||
output_device: app.audio.config.output_device.clone(),
|
||||
channels: app.audio.config.channels,
|
||||
buffer_size: app.audio.config.buffer_size,
|
||||
max_voices: app.audio.config.max_voices,
|
||||
};
|
||||
|
||||
let (stream, analysis_handle) = match build_stream(
|
||||
&stream_config,
|
||||
initial_audio_rx,
|
||||
Arc::clone(&scope_buffer),
|
||||
Arc::clone(&spectrum_buffer),
|
||||
Arc::clone(&metrics),
|
||||
initial_samples,
|
||||
Arc::clone(&audio_sample_pos),
|
||||
) {
|
||||
Ok((s, info, analysis)) => {
|
||||
app.audio.config.sample_rate = info.sample_rate;
|
||||
sample_rate_shared.store(info.sample_rate as u32, Ordering::Relaxed);
|
||||
(Some(s), Some(analysis))
|
||||
}
|
||||
Err(e) => {
|
||||
app.ui.set_status(format!("Audio failed: {e}"));
|
||||
app.audio.error = Some(e);
|
||||
(None, None)
|
||||
}
|
||||
};
|
||||
app.mark_all_patterns_dirty();
|
||||
|
||||
let current_font = FontChoice::from_setting(&settings.display.font);
|
||||
let current_font = FontChoice::from_setting(&b.settings.display.font);
|
||||
let terminal = create_terminal(current_font);
|
||||
|
||||
cc.egui_ctx.set_visuals(egui::Visuals::dark());
|
||||
|
||||
Self {
|
||||
app,
|
||||
app: b.app,
|
||||
terminal,
|
||||
link,
|
||||
sequencer: Some(sequencer),
|
||||
playing,
|
||||
nudge_us,
|
||||
lookahead_ms,
|
||||
metrics,
|
||||
scope_buffer,
|
||||
spectrum_buffer,
|
||||
audio_sample_pos,
|
||||
sample_rate_shared,
|
||||
_stream: stream,
|
||||
_analysis_handle: analysis_handle,
|
||||
midi_rx,
|
||||
link: b.link,
|
||||
sequencer: Some(b.sequencer),
|
||||
playing: b.playing,
|
||||
nudge_us: b.nudge_us,
|
||||
lookahead_ms: b.lookahead_ms,
|
||||
metrics: b.metrics,
|
||||
scope_buffer: b.scope_buffer,
|
||||
spectrum_buffer: b.spectrum_buffer,
|
||||
audio_sample_pos: b.audio_sample_pos,
|
||||
sample_rate_shared: b.sample_rate_shared,
|
||||
_stream: b.stream,
|
||||
_analysis_handle: b.analysis_handle,
|
||||
midi_rx: b.midi_rx,
|
||||
current_font,
|
||||
mouse_x,
|
||||
mouse_y,
|
||||
mouse_down,
|
||||
mouse_x: b.mouse_x,
|
||||
mouse_y: b.mouse_y,
|
||||
mouse_down: b.mouse_down,
|
||||
last_frame: std::time::Instant::now(),
|
||||
}
|
||||
}
|
||||
@@ -334,6 +233,8 @@ impl CagireDesktop {
|
||||
self._stream = Some(new_stream);
|
||||
self._analysis_handle = Some(new_analysis);
|
||||
self.app.audio.config.sample_rate = info.sample_rate;
|
||||
self.app.audio.config.host_name = info.host_name;
|
||||
self.app.audio.config.channels = info.channels;
|
||||
self.sample_rate_shared
|
||||
.store(info.sample_rate as u32, Ordering::Relaxed);
|
||||
self.app.audio.error = None;
|
||||
@@ -419,7 +320,6 @@ impl eframe::App for CagireDesktop {
|
||||
let seq_snapshot = sequencer.snapshot();
|
||||
|
||||
self.app.metrics.event_count = seq_snapshot.event_count;
|
||||
self.app.metrics.dropped_events = seq_snapshot.dropped_events;
|
||||
|
||||
self.app.flush_queued_changes(&sequencer.cmd_tx);
|
||||
self.app.flush_dirty_patterns(&sequencer.cmd_tx);
|
||||
@@ -562,7 +462,6 @@ fn load_icon() -> egui::IconData {
|
||||
}
|
||||
|
||||
fn main() -> eframe::Result<()> {
|
||||
// Lock memory BEFORE any threads are spawned to prevent page faults in RT context
|
||||
#[cfg(unix)]
|
||||
cagire::engine::realtime::lock_memory();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user