diff --git a/Cargo.lock b/Cargo.lock index 4e1f5a1..01cf3a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2051,6 +2051,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.4.2" @@ -2062,6 +2071,15 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -2455,6 +2473,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primal-check" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08" +dependencies = [ + "num-integer", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2587,6 +2614,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" +[[package]] +name = "realfft" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953d9f7e5cdd80963547b456251296efc2626ed4e3cbf36c869d9564e0220571" +dependencies = [ + "rustfft", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -2752,12 +2788,39 @@ dependencies = [ "xmlparser", ] +[[package]] +name = "rubato" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5d18b486e7d29a408ef3f825bc1327d8f87af091c987ca2f5b734625940e234" +dependencies = [ + "num-complex", + "num-integer", + "num-traits", + "realfft", +] + [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustfft" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43806561bc506d0c5d160643ad742e3161049ac01027b5e6d7524091fd401d86" +dependencies = [ + "num-complex", + "num-integer", + "num-traits", + "primal-check", + "strength_reduce", + "transpose", + "version_check", +] + [[package]] name = "rustix" version = "0.37.27" @@ -3017,6 +3080,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "soundfont" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88f3c4ee9be1386dc5d4f33fb1df6f813eb2f49510cb24e8bfd30784f4853fce" +dependencies = [ + "riff", +] + [[package]] name = "spin" version = "0.9.8" @@ -3041,6 +3113,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strength_reduce" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" + [[package]] name = "strict-num" version = "0.1.1" @@ -3437,6 +3515,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "transpose" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" +dependencies = [ + "num-integer", + "strength_reduce", +] + [[package]] name = "ttf-parser" version = "0.20.0" @@ -4277,7 +4365,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "xsynth-core" version = "0.1.0" -source = "git+https://github.com/arduano/xsynth.git?rev=e300f1d#e300f1d859023da07f15462712bdc81a89693429" +source = "git+https://github.com/arduano/xsynth.git?rev=3385cd0#3385cd0d4dcd56cbd3c9f77743258a0e72993fb7" dependencies = [ "atomic_refcell", "biquad", @@ -4297,7 +4385,7 @@ dependencies = [ [[package]] name = "xsynth-realtime" version = "0.1.0" -source = "git+https://github.com/arduano/xsynth.git?rev=e300f1d#e300f1d859023da07f15462712bdc81a89693429" +source = "git+https://github.com/arduano/xsynth.git?rev=3385cd0#3385cd0d4dcd56cbd3c9f77743258a0e72993fb7" dependencies = [ "atomic_refcell", "bytemuck", @@ -4315,13 +4403,15 @@ dependencies = [ [[package]] name = "xsynth-soundfonts" version = "0.1.0" -source = "git+https://github.com/arduano/xsynth.git?rev=e300f1d#e300f1d859023da07f15462712bdc81a89693429" +source = "git+https://github.com/arduano/xsynth.git?rev=3385cd0#3385cd0d4dcd56cbd3c9f77743258a0e72993fb7" dependencies = [ "encoding_rs", "encoding_rs_io", "lazy-regex", "regex-bnf", + "rubato", "simdeez", + "soundfont", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 4dd7654..e805101 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,8 +18,8 @@ egui = "0.21.0" winit = "0.28.3" rayon = "1.7.0" midi-toolkit-rs = { git = "https://github.com/arduano/midi-toolkit-rs.git", rev = "a54f198" } -xsynth-core = { git = "https://github.com/arduano/xsynth.git", rev = "e300f1d" } -xsynth-realtime = { git = "https://github.com/arduano/xsynth.git", rev = "e300f1d" } +xsynth-core = { git = "https://github.com/arduano/xsynth.git", rev = "3385cd0" } +xsynth-realtime = { git = "https://github.com/arduano/xsynth.git", rev = "3385cd0" } gen-iter = { git = "https://github.com/arduano/gen-iter.git", rev = "64e28bc" } enum_dispatch = "0.3.11" palette = "0.7.1" diff --git a/src/audio_playback/mod.rs b/src/audio_playback/mod.rs index d62a038..dceb4c5 100644 --- a/src/audio_playback/mod.rs +++ b/src/audio_playback/mod.rs @@ -7,6 +7,7 @@ pub mod xsynth; pub enum AudioPlayerType { XSynth { buffer: f64, + use_threadpool: bool, ignore_range: RangeInclusive, options: ChannelInitOptions, }, @@ -24,10 +25,12 @@ impl SimpleTemporaryPlayer { let (xsynth, kdmapi) = match player_type.clone() { AudioPlayerType::XSynth { buffer, + use_threadpool, ignore_range, options, } => { - let xsynth = xsynth::XSynthPlayer::new(buffer, ignore_range, options); + let xsynth = + xsynth::XSynthPlayer::new(buffer, use_threadpool, ignore_range, options); (Some(xsynth), None) } AudioPlayerType::Kdmapi => { diff --git a/src/audio_playback/xsynth.rs b/src/audio_playback/xsynth.rs index e79d2d8..d8852bc 100644 --- a/src/audio_playback/xsynth.rs +++ b/src/audio_playback/xsynth.rs @@ -43,10 +43,15 @@ pub struct XSynthPlayer { } impl XSynthPlayer { - pub fn new(buffer: f64, ignore_range: RangeInclusive, options: ChannelInitOptions) -> Self { + pub fn new( + buffer: f64, + use_threadpool: bool, + ignore_range: RangeInclusive, + options: ChannelInitOptions, + ) -> Self { let config = XSynthRealtimeConfig { render_window_ms: buffer, - use_threadpool: false, + use_threadpool, channel_init_options: options, ignore_range, ..Default::default() diff --git a/src/gui/window.rs b/src/gui/window.rs index ac8d248..fa6f0f9 100644 --- a/src/gui/window.rs +++ b/src/gui/window.rs @@ -47,6 +47,7 @@ impl GuiWasabiWindow { let synth = Arc::new(RwLock::new(SimpleTemporaryPlayer::new( AudioPlayerType::XSynth { buffer: settings.synth.buffer_ms, + use_threadpool: settings.synth.use_threadpool, ignore_range: settings.synth.vel_ignore.clone(), options: convert_to_channel_init(settings), }, diff --git a/src/gui/window/settings_window.rs b/src/gui/window/settings_window.rs index 493f910..f345483 100644 --- a/src/gui/window/settings_window.rs +++ b/src/gui/window/settings_window.rs @@ -59,6 +59,7 @@ pub fn draw_settings( .unwrap() .switch_player(AudioPlayerType::XSynth { buffer: settings.synth.buffer_ms, + use_threadpool: settings.synth.use_threadpool, ignore_range: settings.synth.vel_ignore.clone(), options: convert_to_channel_init(settings), }); diff --git a/src/gui/window/xsynth_settings.rs b/src/gui/window/xsynth_settings.rs index 87533bc..b5afe33 100644 --- a/src/gui/window/xsynth_settings.rs +++ b/src/gui/window/xsynth_settings.rs @@ -51,7 +51,7 @@ pub fn draw_xsynth_settings( if ui.button("Browse...").clicked() { // If windows, just use the native dialog let sfz_path = rfd::FileDialog::new() - .add_filter("sfz", &["sfz"]) + .add_filter("sfz/sf2", &["sfz", "sf2"]) .pick_file(); if let Some(sfz_path) = sfz_path { @@ -141,6 +141,10 @@ pub fn draw_xsynth_settings( ui.label("Use Effects*: "); ui.checkbox(&mut settings.synth.use_effects, ""); ui.end_row(); + + ui.label("Use Threadpool*: "); + ui.checkbox(&mut settings.synth.use_threadpool, ""); + ui.end_row(); }); ui.separator(); @@ -152,6 +156,7 @@ pub fn draw_xsynth_settings( .unwrap() .switch_player(AudioPlayerType::XSynth { buffer: settings.synth.buffer_ms, + use_threadpool: settings.synth.use_threadpool, ignore_range: settings.synth.vel_ignore.clone(), options: convert_to_channel_init(settings), }); diff --git a/src/settings/migrations.rs b/src/settings/migrations.rs index faf3e4e..249f596 100644 --- a/src/settings/migrations.rs +++ b/src/settings/migrations.rs @@ -16,6 +16,7 @@ pub struct WasabiConfigFileV0 { last_key: u8, midi_loading: usize, buffer_ms: f64, + use_threadpool: bool, limit_layers: bool, layer_count: usize, fade_out_kill: bool, @@ -39,6 +40,7 @@ impl WasabiConfigFileV0 { synth: SynthSettings { synth: Synth::from(cfg.synth), buffer_ms: cfg.buffer_ms, + use_threadpool: cfg.use_threadpool, limit_layers: cfg.limit_layers, layer_count: cfg.layer_count, fade_out_kill: cfg.fade_out_kill, diff --git a/src/settings/mod.rs b/src/settings/mod.rs index 3652179..eaee8a0 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -290,6 +290,7 @@ impl Default for MidiSettings { pub struct SynthSettings { pub synth: Synth, pub buffer_ms: f64, + pub use_threadpool: bool, pub sfz_path: String, pub limit_layers: bool, pub layer_count: usize, @@ -305,6 +306,7 @@ impl Default for SynthSettings { SynthSettings { synth: Synth::XSynth, buffer_ms: XSynthRealtimeConfig::default().render_window_ms, + use_threadpool: false, sfz_path: String::new(), limit_layers: true, layer_count: 4,