From d2be6f6acb847754807ef1d5f512a834615fd70d Mon Sep 17 00:00:00 2001 From: Woyten Date: Sat, 20 Aug 2022 13:46:35 +0200 Subject: [PATCH] Cleanups --- magnetron/src/automation.rs | 4 +- magnetron/src/waveform.rs | 4 +- microwave/README.md | 7 ++- microwave/src/main.rs | 92 +++++++++++++++++-------------------- microwave/src/piano.rs | 2 +- src/midi.rs | 2 +- 6 files changed, 55 insertions(+), 56 deletions(-) diff --git a/magnetron/src/automation.rs b/magnetron/src/automation.rs index 1b5ecc30..73e9fc3c 100644 --- a/magnetron/src/automation.rs +++ b/magnetron/src/automation.rs @@ -2,8 +2,10 @@ use std::marker::PhantomData; use crate::{spec::Spec, waveform::WaveformState}; +type AutomationFn = Box) -> f64 + Send>; + pub struct Automation { - pub(crate) automation_fn: Box) -> f64 + Send>, + pub(crate) automation_fn: AutomationFn, } pub struct AutomationContext<'a, S> { diff --git a/magnetron/src/waveform.rs b/magnetron/src/waveform.rs index 1bd40680..c11205f9 100644 --- a/magnetron/src/waveform.rs +++ b/magnetron/src/waveform.rs @@ -49,8 +49,10 @@ impl Envelope { } } +type StageFn = Box) + Send>; + pub struct Stage { - pub(crate) stage_fn: Box) + Send>, + pub(crate) stage_fn: StageFn, } impl Stage { diff --git a/microwave/README.md b/microwave/README.md index d0273591..a6c5671a 100644 --- a/microwave/README.md +++ b/microwave/README.md @@ -10,7 +10,7 @@ Make xenharmonic music and explore musical tunings. `microwave` is a microtonal modular waveform synthesizer with soundfont rendering capabilities based on: - [tune](https://github.com/Woyten/tune) – a microtonal library -- [magnetron](https://github.com/Woyten/tune) – a modular synthesizer architecture +- [magnetron](https://github.com/Woyten/tune/tree/master/magnetron) – a modular synthesizer architecture - [fluid-xenth](https://github.com/Woyten/tune/tree/master/fluid-xenth) – a microtonal soundfont renderer - [Nannou](https://nannou.cc/) – a UI framework @@ -41,6 +41,9 @@ Option C: Use Cargo to build a fresh binary from scratch for your own target arc # On the CI environment (Ubuntu 20.04) we only need to add one library: sudo apt install libasound2-dev +# Make sure pkg-config is installed +sudo apt install pkg-config + cargo install -f microwave ``` @@ -231,4 +234,4 @@ microwave help # License -`microwave` statically links against [OxiSynth](https://crates.io/crates/oxisynth) for soundfont rendering capabilities. This makes the *binary executable* of `microwave` a derivative work of OxiSynth. OxiSynth is licensed under the *GNU Lesser General Public License, version 2.1*. +`microwave` statically links against [OxiSynth](https://crates.io/crates/oxisynth) for soundfont rendering capabilities. This makes the *binary executable* of `microwave` a derivative work of OxiSynth. OxiSynth is licensed under the *GNU Lesser General Public License, version 2.1*. \ No newline at end of file diff --git a/microwave/src/main.rs b/microwave/src/main.rs index 0f3ff1c8..54151eb6 100644 --- a/microwave/src/main.rs +++ b/microwave/src/main.rs @@ -13,14 +13,17 @@ mod task; mod tunable; mod view; -use std::{env, io, path::PathBuf, process, sync::mpsc}; +use std::{cell::RefCell, env, io, path::PathBuf, sync::mpsc}; use crate::magnetron::effects::{DelayOptions, ReverbOptions, RotaryOptions}; use audio::{AudioModel, AudioOptions}; use clap::Parser; use keyboard::KeyboardLayout; use model::{Model, SourceId}; -use nannou::{app::App, wgpu::Backends}; +use nannou::{ + app::{self, App}, + wgpu::Backends, +}; use piano::{Backend, NoAudio, PianoEngine}; use synth::ControlChangeNumbers; use tune::{ @@ -36,7 +39,7 @@ use tune_cli::{ midi::{MidiInArgs, MidiOutArgs, TuningMethod}, KbmOptions, SclCommand, }, - CliError, CliResult, + CliResult, }; use view::DynViewModel; @@ -351,67 +354,41 @@ fn parse_keyboard_colors(src: &str) -> Result { } fn main() { - let model_fn = match env::args().collect::>().as_slice() { - [_] => { - println!( - "[WARNING] Use a subcommand, e.g. `microwave run` to start microwave properly" - ); - create_app_from_empty_args - } - [_, arg, ..] if arg == "bench" => { - create_model_from_main_options(MainOptions::parse()).unwrap(); - return; - } - [..] => create_app_from_given_args, + let options = if env::args().len() < 2 { + println!("[WARNING] Use a subcommand, e.g. `microwave run` to start microwave properly"); + MainOptions::parse_from(["microwave", "run"]) + } else { + MainOptions::parse() }; - nannou::app(model_fn) - .backends(Backends::PRIMARY | Backends::GL) - .update(model::update) - .run(); -} - -fn create_app_from_empty_args(app: &App) -> Model { - create_app_from_main_options(app, MainOptions::parse_from(["xx", "run"])) -} - -fn create_app_from_given_args(app: &App) -> Model { - create_app_from_main_options(app, MainOptions::parse()) -} - -fn create_app_from_main_options(app: &App, options: MainOptions) -> Model { match create_model_from_main_options(options) { - Ok(model) => { - create_window(app); - model - } + Ok(None) => {} + Ok(Some(model)) => run_app(model), Err(err) => { eprintln!("[FAIL] {:?}", err); - process::exit(1); } } } -fn create_model_from_main_options(options: MainOptions) -> CliResult { +fn create_model_from_main_options(options: MainOptions) -> CliResult> { match options { - MainOptions::Run(options) => Kbm::builder(NoteLetter::D.in_octave(4)) - .build() - .map_err(CliError::from) - .and_then(|kbm| create_model_from_run_options(kbm, options)), - MainOptions::WithRefNote { kbm, options } => kbm - .to_kbm() - .map_err(CliError::from) - .and_then(|kbm| create_model_from_run_options(kbm, options)), + MainOptions::Run(options) => create_model_from_run_options( + Kbm::builder(NoteLetter::D.in_octave(4)).build()?, + options, + ) + .map(Some), + MainOptions::WithRefNote { kbm, options } => { + create_model_from_run_options(kbm.to_kbm()?, options).map(Some) + } MainOptions::UseKbmFile { kbm_file_location, options, - } => shared::import_kbm_file(&kbm_file_location) - .map_err(CliError::from) - .and_then(|kbm| create_model_from_run_options(kbm, options)), + } => create_model_from_run_options(shared::import_kbm_file(&kbm_file_location)?, options) + .map(Some), MainOptions::Devices => { let stdout = io::stdout(); - shared::midi::print_midi_devices(stdout.lock(), "microwave").unwrap(); - process::exit(0); + shared::midi::print_midi_devices(stdout.lock(), "microwave")?; + Ok(None) } MainOptions::Bench { analyze } => { if analyze { @@ -419,7 +396,7 @@ fn create_model_from_main_options(options: MainOptions) -> CliResult { } else { bench::run_benchmark()?; } - process::exit(0); + Ok(None) } } } @@ -556,6 +533,21 @@ fn create_keyboard(scl: &Scl, config: &RunOptions) -> Keyboard { keyboard.with_steps(primary_step, secondary_step) } +fn run_app(model: Model) { + // Since ModelFn is not a closure we need this workaround to pass the calculated model + thread_local!(static MODEL: RefCell> = Default::default()); + + MODEL.with(|m| m.borrow_mut().replace(model)); + + app::Builder::new(|app| { + create_window(app); + MODEL.with(|m| m.borrow_mut().take().unwrap()) + }) + .backends(Backends::PRIMARY | Backends::GL) + .update(model::update) + .run(); +} + fn create_window(app: &App) { app.new_window() .maximized(true) diff --git a/microwave/src/piano.rs b/microwave/src/piano.rs index 27406c31..3135ef72 100644 --- a/microwave/src/piano.rs +++ b/microwave/src/piano.rs @@ -334,7 +334,7 @@ pub trait Backend: Send { impl PianoEngineModel { pub fn backend_mut(&mut self) -> &mut dyn Backend { let curr_backend = self.curr_backend; - &mut *self.backends[curr_backend] + self.backends[curr_backend].as_mut() } } diff --git a/src/midi.rs b/src/midi.rs index 2688f9f4..00de4b06 100644 --- a/src/midi.rs +++ b/src/midi.rs @@ -48,7 +48,7 @@ impl ChannelMessage { /// assert_eq!(ChannelMessage::from_raw_message(&invalid_message), None); /// ``` pub fn from_raw_message(message: &[u8]) -> Option { - let status_byte = *message.get(0)?; + let status_byte = *message.first()?; let channel = status_byte & 0b0000_1111; let action = status_byte >> 4; let message_type = match action {