From 5ae99b4ada0e8be4ae60f837b622022982a4364d Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 3 Aug 2024 21:55:38 +0300 Subject: [PATCH] wip: refactor into crates --- Cargo.lock | 429 +++---------- crates/suil/src/gtk.rs | 37 ++ crates/tek/Cargo.toml | 60 +- crates/tek/README.md | 3 + crates/tek/src/app.rs | 130 ++++ crates/tek/src/app_focus.rs | 37 ++ crates/tek/src/{config.rs => app_paths.rs} | 1 + crates/tek/src/core.rs | 185 ------ crates/tek/src/core/midi.rs | 92 --- crates/tek/src/core/render.rs | 166 ----- crates/tek/src/devices.rs | 2 - crates/tek/src/devices/looper.rs | 12 - crates/tek/src/devices/mixer.rs | 190 ------ crates/tek/src/{devices => }/help.rs | 0 crates/tek/src/main.rs | 4 +- crates/tek/src/modal.rs | 5 + crates/tek/src/model.rs | 406 ------------ crates/tek/src/{devices => }/setup.rs | 0 crates/tek/src/view.rs | 44 -- crates/tek/src/view/border.rs | 161 ----- crates/tek/src/view/split.rs | 129 ---- crates/tek/src/view/theme.rs | 71 --- crates/tek_chain/Cargo.toml | 8 + crates/tek_chain/README.md | 1 + crates/tek_chain/src/bin/mod.rs | 0 crates/tek_chain/src/chain.rs | 49 ++ .../chain.rs => tek_chain/src/chain_view.rs} | 7 +- crates/tek_chain/src/lib.rs | 8 + crates/tek_core/Cargo.toml | 14 + crates/tek_core/README.md | 38 ++ crates/tek_core/src/exit.rs | 20 + .../{tek/src/core => tek_core/src}/handle.rs | 35 +- crates/tek_core/src/lib.rs | 90 +++ crates/tek_core/src/render.rs | 592 ++++++++++++++++++ crates/tek_jack/Cargo.toml | 8 + crates/tek_jack/README.md | 3 + .../{tek/src/jack => tek_jack/src}/device.rs | 1 + .../{tek/src/jack => tek_jack/src}/event.rs | 30 +- .../{tek/src/jack => tek_jack/src}/factory.rs | 19 +- .../{tek/src/jack.rs => tek_jack/src/lib.rs} | 41 +- .../{tek/src/jack => tek_jack/src}/ports.rs | 0 crates/tek_mixer/Cargo.toml | 9 + crates/tek_mixer/README.md | 7 + crates/tek_mixer/src/bin/mod.rs | 0 crates/tek_mixer/src/lib.rs | 8 + crates/tek_mixer/src/mixer.rs | 94 +++ crates/tek_mixer/src/mixer_track.rs | 91 +++ crates/tek_plugin/Cargo.toml | 13 + crates/tek_plugin/README.md | 4 + crates/tek_plugin/src/bin/mod.rs | 0 crates/tek_plugin/src/lib.rs | 18 + .../devices/plugin => tek_plugin/src}/lv2.rs | 26 +- crates/tek_plugin/src/lv2_gui.rs | 0 .../src/devices => tek_plugin/src}/plugin.rs | 18 +- crates/tek_plugin/src/vst2.rs | 13 + crates/tek_plugin/src/vst3.rs | 1 + crates/tek_sampler/Cargo.toml | 10 + crates/tek_sampler/README.md | 4 + crates/tek_sampler/src/bin/mod.rs | 0 crates/tek_sampler/src/lib.rs | 20 + .../sampler => tek_sampler/src}/sample.rs | 2 +- .../src/sample_add.rs} | 2 +- .../devices => tek_sampler/src}/sampler.rs | 12 +- .../sampler => tek_sampler/src}/voice.rs | 1 - crates/tek_sequencer/Cargo.toml | 9 + crates/tek_sequencer/README.md | 3 + .../devices => tek_sequencer/src}/arranger.rs | 74 ++- .../src/arranger_focus.rs} | 3 + .../src/arranger_phrase.rs} | 3 +- .../src/arranger_scene.rs} | 3 +- .../src/arranger_track.rs} | 3 +- .../src/arranger_view_h.rs} | 3 +- .../src/arranger_view_v.rs} | 2 +- crates/tek_sequencer/src/bin/mod.rs | 3 + crates/tek_sequencer/src/lib.rs | 53 ++ crates/tek_sequencer/src/midi.rs | 36 ++ crates/tek_sequencer/src/phrase.rs | 93 +++ .../src}/sequencer.rs | 163 +---- crates/tek_sequencer/src/sequencer_track.rs | 227 +++++++ crates/tek_timer/Cargo.toml | 9 + crates/tek_timer/README.md | 3 + crates/tek_timer/src/bin/mod.rs | 5 + crates/tek_timer/src/lib.rs | 72 +++ crates/tek_timer/src/ticks.rs | 50 ++ .../time.rs => tek_timer/src/timebase.rs} | 53 +- .../devices => tek_timer/src}/transport.rs | 124 ++-- crates/tek_timer/src/transport_focus.rs | 23 + 87 files changed, 2281 insertions(+), 2217 deletions(-) create mode 100644 crates/suil/src/gtk.rs create mode 100644 crates/tek/README.md create mode 100644 crates/tek/src/app.rs create mode 100644 crates/tek/src/app_focus.rs rename crates/tek/src/{config.rs => app_paths.rs} (99%) delete mode 100644 crates/tek/src/core.rs delete mode 100644 crates/tek/src/core/midi.rs delete mode 100644 crates/tek/src/core/render.rs delete mode 100644 crates/tek/src/devices.rs delete mode 100644 crates/tek/src/devices/looper.rs delete mode 100644 crates/tek/src/devices/mixer.rs rename crates/tek/src/{devices => }/help.rs (100%) create mode 100644 crates/tek/src/modal.rs delete mode 100644 crates/tek/src/model.rs rename crates/tek/src/{devices => }/setup.rs (100%) delete mode 100644 crates/tek/src/view.rs delete mode 100644 crates/tek/src/view/border.rs delete mode 100644 crates/tek/src/view/split.rs delete mode 100644 crates/tek/src/view/theme.rs create mode 100644 crates/tek_chain/Cargo.toml create mode 100644 crates/tek_chain/README.md create mode 100644 crates/tek_chain/src/bin/mod.rs create mode 100644 crates/tek_chain/src/chain.rs rename crates/{tek/src/devices/chain.rs => tek_chain/src/chain_view.rs} (95%) create mode 100644 crates/tek_chain/src/lib.rs create mode 100644 crates/tek_core/Cargo.toml create mode 100644 crates/tek_core/README.md create mode 100644 crates/tek_core/src/exit.rs rename crates/{tek/src/core => tek_core/src}/handle.rs (65%) create mode 100644 crates/tek_core/src/lib.rs create mode 100644 crates/tek_core/src/render.rs create mode 100644 crates/tek_jack/Cargo.toml create mode 100644 crates/tek_jack/README.md rename crates/{tek/src/jack => tek_jack/src}/device.rs (97%) rename crates/{tek/src/jack => tek_jack/src}/event.rs (57%) rename crates/{tek/src/jack => tek_jack/src}/factory.rs (85%) rename crates/{tek/src/jack.rs => tek_jack/src/lib.rs} (77%) rename crates/{tek/src/jack => tek_jack/src}/ports.rs (100%) create mode 100644 crates/tek_mixer/Cargo.toml create mode 100644 crates/tek_mixer/README.md create mode 100644 crates/tek_mixer/src/bin/mod.rs create mode 100644 crates/tek_mixer/src/lib.rs create mode 100644 crates/tek_mixer/src/mixer.rs create mode 100644 crates/tek_mixer/src/mixer_track.rs create mode 100644 crates/tek_plugin/Cargo.toml create mode 100644 crates/tek_plugin/README.md create mode 100644 crates/tek_plugin/src/bin/mod.rs create mode 100644 crates/tek_plugin/src/lib.rs rename crates/{tek/src/devices/plugin => tek_plugin/src}/lv2.rs (83%) create mode 100644 crates/tek_plugin/src/lv2_gui.rs rename crates/{tek/src/devices => tek_plugin/src}/plugin.rs (94%) create mode 100644 crates/tek_plugin/src/vst2.rs create mode 100644 crates/tek_plugin/src/vst3.rs create mode 100644 crates/tek_sampler/Cargo.toml create mode 100644 crates/tek_sampler/README.md create mode 100644 crates/tek_sampler/src/bin/mod.rs create mode 100644 crates/tek_sampler/src/lib.rs rename crates/{tek/src/devices/sampler => tek_sampler/src}/sample.rs (98%) rename crates/{tek/src/devices/sampler/add_sample.rs => tek_sampler/src/sample_add.rs} (99%) rename crates/{tek/src/devices => tek_sampler/src}/sampler.rs (95%) rename crates/{tek/src/devices/sampler => tek_sampler/src}/voice.rs (97%) create mode 100644 crates/tek_sequencer/Cargo.toml create mode 100644 crates/tek_sequencer/README.md rename crates/{tek/src/devices => tek_sequencer/src}/arranger.rs (68%) rename crates/{tek/src/devices/arranger/arr_focus.rs => tek_sequencer/src/arranger_focus.rs} (99%) rename crates/{tek/src/devices/arranger/arr_phrase.rs => tek_sequencer/src/arranger_phrase.rs} (97%) rename crates/{tek/src/devices/arranger/arr_scene.rs => tek_sequencer/src/arranger_scene.rs} (98%) rename crates/{tek/src/devices/arranger/arr_track.rs => tek_sequencer/src/arranger_track.rs} (97%) rename crates/{tek/src/devices/arranger/arr_draw_h.rs => tek_sequencer/src/arranger_view_h.rs} (99%) rename crates/{tek/src/devices/arranger/arr_draw_v.rs => tek_sequencer/src/arranger_view_v.rs} (99%) create mode 100644 crates/tek_sequencer/src/bin/mod.rs create mode 100644 crates/tek_sequencer/src/lib.rs create mode 100644 crates/tek_sequencer/src/midi.rs create mode 100644 crates/tek_sequencer/src/phrase.rs rename crates/{tek/src/devices => tek_sequencer/src}/sequencer.rs (64%) create mode 100644 crates/tek_sequencer/src/sequencer_track.rs create mode 100644 crates/tek_timer/Cargo.toml create mode 100644 crates/tek_timer/README.md create mode 100644 crates/tek_timer/src/bin/mod.rs create mode 100644 crates/tek_timer/src/lib.rs create mode 100644 crates/tek_timer/src/ticks.rs rename crates/{tek/src/core/time.rs => tek_timer/src/timebase.rs} (67%) rename crates/{tek/src/devices => tek_timer/src}/transport.rs (81%) create mode 100644 crates/tek_timer/src/transport_focus.rs diff --git a/Cargo.lock b/Cargo.lock index c51c2dab..6d030ba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,12 +211,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "better-panic" version = "0.3.0" @@ -454,24 +448,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" -[[package]] -name = "clojure-reader" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe72db90a90a91de4a9fbd79542538caa0445ebdebcd3112589cab4c1e0e10b" -dependencies = [ - "ordered-float", -] - -[[package]] -name = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - [[package]] name = "colorchoice" version = "1.0.1" @@ -522,12 +498,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "const-default" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" - [[package]] name = "core-foundation" version = "0.9.4" @@ -624,125 +594,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" -[[package]] -name = "dasp" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7381b67da416b639690ac77c73b86a7b5e64a29e31d1f75fb3b1102301ef355a" -dependencies = [ - "dasp_envelope", - "dasp_frame", - "dasp_interpolate", - "dasp_peak", - "dasp_ring_buffer", - "dasp_rms", - "dasp_sample", - "dasp_signal", - "dasp_slice", - "dasp_window", -] - -[[package]] -name = "dasp_envelope" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ec617ce7016f101a87fe85ed44180839744265fae73bb4aa43e7ece1b7668b6" -dependencies = [ - "dasp_frame", - "dasp_peak", - "dasp_ring_buffer", - "dasp_rms", - "dasp_sample", -] - -[[package]] -name = "dasp_frame" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a3937f5fe2135702897535c8d4a5553f8b116f76c1529088797f2eee7c5cd6" -dependencies = [ - "dasp_sample", -] - -[[package]] -name = "dasp_interpolate" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc975a6563bb7ca7ec0a6c784ead49983a21c24835b0bc96eea11ee407c7486" -dependencies = [ - "dasp_frame", - "dasp_ring_buffer", - "dasp_sample", -] - -[[package]] -name = "dasp_peak" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf88559d79c21f3d8523d91250c397f9a15b5fc72fbb3f87fdb0a37b79915bf" -dependencies = [ - "dasp_frame", - "dasp_sample", -] - -[[package]] -name = "dasp_ring_buffer" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d79e19b89618a543c4adec9c5a347fe378a19041699b3278e616e387511ea1" - -[[package]] -name = "dasp_rms" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6c5dcb30b7e5014486e2822537ea2beae50b19722ffe2ed7549ab03774575aa" -dependencies = [ - "dasp_frame", - "dasp_ring_buffer", - "dasp_sample", -] - -[[package]] -name = "dasp_sample" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" - -[[package]] -name = "dasp_signal" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa1ab7d01689c6ed4eae3d38fe1cea08cba761573fbd2d592528d55b421077e7" -dependencies = [ - "dasp_envelope", - "dasp_frame", - "dasp_interpolate", - "dasp_peak", - "dasp_ring_buffer", - "dasp_rms", - "dasp_sample", - "dasp_window", -] - -[[package]] -name = "dasp_slice" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1c7335d58e7baedafa516cb361360ff38d6f4d3f9d9d5ee2a2fc8e27178fa1" -dependencies = [ - "dasp_frame", - "dasp_sample", -] - -[[package]] -name = "dasp_window" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ded7b88821d2ce4e8b842c9f1c86ac911891ab89443cc1de750cae764c5076" -dependencies = [ - "dasp_sample", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -850,16 +701,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" -[[package]] -name = "fraction" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f158e3ff0a1b334408dc9fb811cd99b446986f4d8b741bb08f9df1604085ae7" -dependencies = [ - "lazy_static", - "num", -] - [[package]] name = "futures-channel" version = "0.3.30" @@ -1494,15 +1335,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "music-math" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7475e279ecd71671f462a096fcc33ab1840d0fb7e2e984df8b096831960050" -dependencies = [ - "num-traits", -] - [[package]] name = "ndk" version = "0.9.0" @@ -1543,70 +1375,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[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-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1652,7 +1420,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 2.0.0", "proc-macro2", "quote", "syn 2.0.60", @@ -1885,15 +1653,6 @@ dependencies = [ "libredox", ] -[[package]] -name = "ordered-float" -version = "4.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ff2cf528c6c03d9ed653d6c4ce1dc0582dc4af309790ad92f07c1cd551b0be" -dependencies = [ - "num-traits", -] - [[package]] name = "owned_ttf_parser" version = "0.24.0" @@ -2051,15 +1810,6 @@ dependencies = [ "syn 2.0.60", ] -[[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" @@ -2130,15 +1880,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r8brain-rs" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d8a95a5235085537051f80f1cdf704e41b1a1c749c067d381412c62da88b44" -dependencies = [ - "cmake", -] - [[package]] name = "ratatui" version = "0.26.3" @@ -2185,15 +1926,6 @@ dependencies = [ "crossbeam-utils", ] -[[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.2.16" @@ -2259,30 +1991,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rlsf" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf" -dependencies = [ - "cfg-if", - "const-default", - "libc", - "svgbobdoc", -] - -[[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-demangle" version = "0.1.24" @@ -2304,21 +2012,6 @@ dependencies = [ "semver", ] -[[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.38.34" @@ -2514,12 +2207,6 @@ 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" @@ -2564,19 +2251,6 @@ dependencies = [ "winit", ] -[[package]] -name = "svgbobdoc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50" -dependencies = [ - "base64", - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-width", -] - [[package]] name = "symphonia" version = "0.5.4" @@ -2817,32 +2491,95 @@ checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2" name = "tek" version = "0.1.0" dependencies = [ - "atomic_float", + "tek_chain", + "tek_core", + "tek_jack", + "tek_mixer", + "tek_plugin", + "tek_sampler", + "tek_sequencer", + "tek_timer", +] + +[[package]] +name = "tek_chain" +version = "0.1.0" +dependencies = [ + "tek_core", + "tek_jack", +] + +[[package]] +name = "tek_core" +version = "0.1.0" +dependencies = [ "backtrace", "better-panic", "clap", - "clojure-reader", "crossterm", - "dasp", - "fraction", - "jack", - "livi", "microxdg", "midly", - "music-math", - "once_cell", - "r8brain-rs", "ratatui", - "rlsf", - "rubato", - "suil-rs", - "symphonia", "toml", +] + +[[package]] +name = "tek_jack" +version = "0.1.0" +dependencies = [ + "jack", + "tek_core", +] + +[[package]] +name = "tek_mixer" +version = "0.1.0" +dependencies = [ + "tek_chain", + "tek_core", + "tek_jack", +] + +[[package]] +name = "tek_plugin" +version = "0.1.0" +dependencies = [ + "livi", + "suil-rs", + "tek_core", + "tek_jack", "vst", - "wavers", "winit", ] +[[package]] +name = "tek_sampler" +version = "0.1.0" +dependencies = [ + "symphonia", + "tek_core", + "tek_jack", + "wavers", +] + +[[package]] +name = "tek_sequencer" +version = "0.1.0" +dependencies = [ + "tek_core", + "tek_jack", + "tek_timer", +] + +[[package]] +name = "tek_timer" +version = "0.1.0" +dependencies = [ + "atomic_float", + "tek_core", + "tek_jack", +] + [[package]] name = "thiserror" version = "1.0.61" @@ -2960,16 +2697,6 @@ version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -[[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.24.0" diff --git a/crates/suil/src/gtk.rs b/crates/suil/src/gtk.rs new file mode 100644 index 00000000..0aac2767 --- /dev/null +++ b/crates/suil/src/gtk.rs @@ -0,0 +1,37 @@ +struct SuilX11Wrapper { + socket: GtkSocket, + plug: GtkPlug, + wrapper: SuilWrapper, + instance: SuilInstance, + idle_iface: LV2UI_Idle_Interface, + idle_id: usize, + idle_ms: usize, + idle_size_req_id: usize, + initial_width: usize, + initial_height: usize, + req_width: usize, + req_height: usize, +} + +struct SuilX11WrapperClass { + parent_class: GtkSocketClass, +} + +impl SuilX11Wrapper { + fn x_window_is_valid (&self) { + let window: GdkWindow = gtk_widget_get_window(self.plug); + let root: X11Window = Some(0); + let parent: X11Window = Some(0); + let children: [X11Window] = None; + let child_count: usize = 0; + x_query_tree(window.xdisplay, window.xid, root, parent, children, &mut childcount); + for i in 0..child_count { + if children[i] == self.instance.ui_widget { + x_free(children); + return true; + } + } + x_free(children); + return false; + } +} diff --git a/crates/tek/Cargo.toml b/crates/tek/Cargo.toml index 5ffd462c..6345dc77 100644 --- a/crates/tek/Cargo.toml +++ b/crates/tek/Cargo.toml @@ -4,36 +4,38 @@ edition = "2021" version = "0.1.0" [dependencies] -jack = "0.10" -clap = { version = "4.5.4", features = [ "derive" ] } -crossterm = "0.27" -ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] } -backtrace = "0.3.72" -microxdg = "0.1.2" -toml = "0.8.12" -better-panic = "0.3.0" -midly = "0.5" +tek_core = { path = "../tek_core" } +tek_jack = { path = "../tek_jack" } +tek_plugin = { path = "../tek_plugin" } +tek_sampler = { path = "../tek_sampler" } +tek_sequencer = { path = "../tek_sequencer" } +tek_timer = { path = "../tek_timer" } +tek_chain = { path = "../tek_chain" } +tek_mixer = { path = "../tek_mixer" } +#jack = "0.10" +#clap = { version = "4.5.4", features = [ "derive" ] } +#crossterm = "0.27" +#ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] } +#backtrace = "0.3.72" +#microxdg = "0.1.2" +#toml = "0.8.12" +#better-panic = "0.3.0" +#midly = "0.5" -vst = "0.4.0" -#vst3 = "0.1.0" -livi = "0.7.4" -#atomic_enum = "0.3.0" -wavers = "1.4.3" -music-math = "0.1.1" -atomic_float = "1.0.0" -fraction = "0.15.3" -rlsf = "0.2.1" -r8brain-rs = "0.3.5" -clojure-reader = "0.1.0" -once_cell = "1.19.0" +#vst = "0.4.0" +##vst3 = "0.1.0" +#livi = "0.7.4" +##atomic_enum = "0.3.0" +#wavers = "1.4.3" +#music-math = "0.1.1" +#fraction = "0.15.3" +#rlsf = "0.2.1" +#r8brain-rs = "0.3.5" +#clojure-reader = "0.1.0" +#once_cell = "1.19.0" -symphonia = { version = "0.5.4", features = [ "all" ] } +#symphonia = { version = "0.5.4", features = [ "all" ] } -dasp = { version = "0.11.0", features = [ "all" ] } +#dasp = { version = "0.11.0", features = [ "all" ] } -rubato = "0.15.0" - -winit = { version = "0.30.4", features = [ "x11" ] } -#winit = { path = "../winit" } - -suil-rs = { path = "../suil" } +#rubato = "0.15.0" diff --git a/crates/tek/README.md b/crates/tek/README.md new file mode 100644 index 00000000..44965638 --- /dev/null +++ b/crates/tek/README.md @@ -0,0 +1,3 @@ +# `tek` + +This crate unifies the `tek_*` subcrates into a single application. diff --git a/crates/tek/src/app.rs b/crates/tek/src/app.rs new file mode 100644 index 00000000..724923ff --- /dev/null +++ b/crates/tek/src/app.rs @@ -0,0 +1,130 @@ +use crate::*; + +/// Root of application state. +pub struct App { + /// Whether the currently focused section has input priority + pub entered: bool, + /// Currently focused section + pub section: AppFocus, + /// Transport model and view. + pub transport: TransportToolbar, + /// Arranger/sequencer + pub arranger: Arranger, + /// Main JACK client. + pub jack: Option, + /// Map of external MIDI outs in the jack graph + /// to internal MIDI ins of this app. + pub midi_in: Option>>, + /// Names of ports to connect to main MIDI IN. + pub midi_ins: Vec, + /// Display mode of chain section + pub chain_mode: bool, + /// Main audio outputs. + pub audio_outs: Vec>>, + /// Number of frames requested by process callback + chunk_size: usize, + /// Paths to user directories + _xdg: Option>, +} + +impl App { + pub fn new () -> Usually { + let xdg = Arc::new(microxdg::XdgApp::new("tek")?); + let first_run = crate::config::AppPaths::new(&xdg)?.should_create(); + let jack = JackClient::Inactive(Client::new("tek", ClientOptions::NO_START_SERVER)?.0); + *MODAL.lock().unwrap() = first_run.then(||{ + Exit::boxed(crate::devices::setup::SetupModal(Some(xdg.clone()), false)) + }); + Ok(Self { + entered: true, + section: AppFocus::default(), + transport: TransportToolbar::new(Some(jack.transport())), + arranger: Arranger::new(), + jack: Some(jack), + audio_outs: vec![], + chain_mode: false, + chunk_size: 0, + midi_in: None, + midi_ins: vec![], + _xdg: Some(xdg), + }) + } +} + +process!(App |self, _client, scope| { + let ( + reset, current_frames, chunk_size, current_usecs, next_usecs, period_usecs + ) = self.transport.update(&scope); + self.chunk_size = chunk_size; + for track in self.arranger.tracks.iter_mut() { + track.process( + self.midi_in.as_ref().map(|p|p.iter(&scope)), + &self.transport.timebase, + self.transport.playing, + self.transport.started, + self.transport.quant as usize, + reset, + &scope, + (current_frames as usize, self.chunk_size), + (current_usecs as usize, next_usecs.saturating_sub(current_usecs) as usize), + period_usecs as f64 + ); + } + Control::Continue +}); + +impl App { + pub fn client (&self) -> &Client { + self.jack.as_ref().unwrap().client() + } + pub fn audio_out (&self, index: usize) -> Option>> { + self.audio_outs.get(index).map(|x|x.clone()) + } + pub fn with_midi_ins (mut self, names: &[&str]) -> Usually { + self.midi_ins = names.iter().map(|x|x.to_string()).collect(); + Ok(self) + } + pub fn with_audio_outs (mut self, names: &[&str]) -> Usually { + let client = self.client(); + self.audio_outs = names + .iter() + .map(|name|client + .ports(Some(name), None, PortFlags::empty()) + .get(0) + .map(|name|client.port_by_name(name))) + .flatten() + .filter_map(|x|x) + .map(Arc::new) + .collect(); + Ok(self) + } + pub fn activate ( + mut self, init: Option>)->Usually<()>> + ) -> Usually>> { + let jack = self.jack.take().expect("no jack client"); + let app = Arc::new(RwLock::new(self)); + app.write().unwrap().jack = Some(jack.activate(&app.clone(), |state, client, scope|{ + state.write().unwrap().process(client, scope) + })?); + if let Some(init) = init { + init(&app)?; + } + Ok(app) + } +} + + +render!(App |self, buf, area| { + Split::down([ + &self.transport, + &self.arranger, + &If(self.arranger.selected.is_clip(), &Split::right([ + &ChainView::vertical(&self), + &self.sequencer, + ])) + ]).render(buf, area)?; + if let Some(ref modal) = *MODAL.lock().unwrap() { + modal.render(buf, area)?; + } + Ok(area) +}); diff --git a/crates/tek/src/app_focus.rs b/crates/tek/src/app_focus.rs new file mode 100644 index 00000000..7bd0a1ea --- /dev/null +++ b/crates/tek/src/app_focus.rs @@ -0,0 +1,37 @@ +use crate::*; + +/// Different sections of the UI that may be focused. +#[derive(PartialEq, Clone, Copy)] +pub enum AppFocus { + /// The transport is selected. + Transport, + /// The arranger is selected. + Arranger, + /// The sequencer is selected. + Sequencer, + /// The device chain is selected. + Chain, +} + +impl Default for AppFocus { + fn default () -> Self { Self::Arranger } +} + +impl AppFocus { + pub fn prev (&mut self) { + *self = match self { + Self::Transport => Self::Chain, + Self::Arranger => Self::Transport, + Self::Sequencer => Self::Arranger, + Self::Chain => Self::Sequencer, + } + } + pub fn next (&mut self) { + *self = match self { + Self::Transport => Self::Arranger, + Self::Arranger => Self::Sequencer, + Self::Sequencer => Self::Chain, + Self::Chain => Self::Transport, + } + } +} diff --git a/crates/tek/src/config.rs b/crates/tek/src/app_paths.rs similarity index 99% rename from crates/tek/src/config.rs rename to crates/tek/src/app_paths.rs index 4deff25c..91f8b766 100644 --- a/crates/tek/src/config.rs +++ b/crates/tek/src/app_paths.rs @@ -14,6 +14,7 @@ pub struct AppPaths { data_dir: PathBuf, project_file: PathBuf, } + impl AppPaths { pub fn new (xdg: &XdgApp) -> Usually { let config_dir = PathBuf::from(xdg.app_config()?); diff --git a/crates/tek/src/core.rs b/crates/tek/src/core.rs deleted file mode 100644 index 77fcc4ce..00000000 --- a/crates/tek/src/core.rs +++ /dev/null @@ -1,185 +0,0 @@ -//! Prelude. - -// Stdlib dependencies: -pub(crate) use std::error::Error; -pub(crate) use std::io::{stdout}; -pub(crate) use std::thread::{spawn, JoinHandle}; -pub(crate) use std::time::Duration; -pub(crate) use std::collections::BTreeMap; -pub(crate) use std::sync::atomic::{Ordering, AtomicBool}; -pub(crate) use std::sync::{Arc, Mutex, RwLock, LockResult, RwLockReadGuard, RwLockWriteGuard}; -pub(crate) use std::path::PathBuf; -pub(crate) use std::fs::read_dir; -pub(crate) use std::ffi::OsString; - -// Non-stdlib dependencies: -pub(crate) use microxdg::XdgApp; -pub(crate) use midly::{MidiMessage, live::LiveEvent, num::u7}; -pub(crate) use crossterm::{ExecutableCommand}; -pub(crate) use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers}; -use better_panic::{Settings, Verbosity}; -use crossterm::terminal::{ - EnterAlternateScreen, LeaveAlternateScreen, - enable_raw_mode, disable_raw_mode -}; - -/// Define and reexport submodules. -#[macro_export] macro_rules! submod { - ($($name:ident)*) => { $(mod $name; pub use self::$name::*;)* }; -} - -/// Define and reexport public modules. -#[macro_export] macro_rules! pubmod { - ($($name:ident)*) => { $(pub mod $name;)* }; -} - -submod!( handle midi render time ); - -/// Standard result type. -pub type Usually = Result>; - -/// A UI component. -pub trait Component: Render + Handle + Sync { - /// Perform type erasure for collecting heterogeneous components. - fn boxed (self) -> Box where Self: Sized + 'static { - Box::new(self) - } -} - -pub trait Exit: Component { - fn exited (&self) -> bool; - fn exit (&mut self); - fn boxed (self) -> Box where Self: Sized + 'static { - Box::new(self) - } -} - -#[macro_export] macro_rules! exit { - ($T:ty) => { - impl Exit for $T { - fn exited (&self) -> bool { - self.exited - } - fn exit (&mut self) { - self.exited = true - } - } - } -} - -/// Anything that implements `Render` + `Handle` can be used as a UI component. -impl Component for T {} - -/// A UI component that may be associated with a JACK client by the `Jack` factory. -pub trait Device: Render + Handle + Process + Send + Sync { - /// Perform type erasure for collecting heterogeneous devices. - fn boxed (self) -> Box where Self: Sized + 'static { - Box::new(self) - } -} - -/// All things that implement the required traits can be treated as `Device`. -impl Device for T {} - -// Reexport macros: -pub use crate::{ - submod, pubmod, render, handle, process, phrase, keymap, ports, exit -}; - -// Reexport JACK proto-lib: -pub use crate::jack::*; - -/// Run the main loop. -pub fn run (state: Arc>) -> Usually>> - where T: Render + Handle + Send + Sync + Sized + 'static -{ - let exited = Arc::new(AtomicBool::new(false)); - let _input_thread = input_thread(&exited, &state); - terminal_setup()?; - panic_hook_setup(); - let main_thread = main_thread(&exited, &state)?; - main_thread.join().expect("main thread failed"); - terminal_teardown()?; - Ok(state) -} - -/// Set up panic hook -pub fn panic_hook_setup () { - let better_panic_handler = Settings::auto().verbosity(Verbosity::Full).create_panic_handler(); - std::panic::set_hook(Box::new(move |info: &std::panic::PanicInfo|{ - stdout().execute(LeaveAlternateScreen).unwrap(); - disable_raw_mode().unwrap(); - better_panic_handler(info); - })); -} - -/// Set up terminal -pub fn terminal_setup () -> Usually<()> { - stdout().execute(EnterAlternateScreen)?; - enable_raw_mode()?; - Ok(()) -} -/// Cleanup -pub fn terminal_teardown () -> Usually<()> { - stdout().execute(LeaveAlternateScreen)?; - disable_raw_mode()?; - Ok(()) -} - -/// Main thread render loop -pub fn main_thread ( - exited: &Arc, - device: &Arc> -) -> Usually> { - let exited = exited.clone(); - let device = device.clone(); - let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?; - let sleep = Duration::from_millis(20); - Ok(spawn(move || loop { - - if let Ok(device) = device.try_read() { - terminal.draw(|frame|{ - let area = frame.size(); - let buffer = frame.buffer_mut(); - device - .render(buffer, area) - .expect("Failed to render content"); - }) - .expect("Failed to render frame"); - } - - if exited.fetch_and(true, Ordering::Relaxed) { - break - } - - std::thread::sleep(sleep); - - })) -} - -/// Spawn thread that listens for user input -pub fn input_thread ( - exited: &Arc, - device: &Arc> -) -> JoinHandle<()> { - let poll = Duration::from_millis(100); - let exited = exited.clone(); - let device = device.clone(); - spawn(move || loop { - // Exit if flag is set - if exited.fetch_and(true, Ordering::Relaxed) { - break - } - // Listen for events and send them to the main thread - if ::crossterm::event::poll(poll).is_ok() { - let event = ::crossterm::event::read().unwrap(); - if let Event::Key(KeyEvent { - code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, .. - }) = event { - exited.store(true, Ordering::Relaxed); - } else if let Err(e) = device.write().unwrap().handle(&AppEvent::Input(event)) { - panic!("{e}") - } - } - }) -} diff --git a/crates/tek/src/core/midi.rs b/crates/tek/src/core/midi.rs deleted file mode 100644 index c9db6570..00000000 --- a/crates/tek/src/core/midi.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::core::*; - -pub type MIDIMessage = - Vec; - -pub type MIDIChunk = - [Vec]; - -/// Add "all notes off" to the start of a buffer. -pub fn all_notes_off (output: &mut MIDIChunk) { - let mut buf = vec![]; - let msg = MidiMessage::Controller { controller: 123.into(), value: 0.into() }; - let evt = LiveEvent::Midi { channel: 0.into(), message: msg }; - evt.write(&mut buf).unwrap(); - output[0].push(buf); -} - -pub fn parse_midi_input (input: MidiIter) -> Box + '_> { - Box::new(input.map(|RawMidi { time, bytes }|( - time as usize, - LiveEvent::parse(bytes).unwrap(), - bytes - ))) -} - -/// Write to JACK port from output buffer (containing notes from sequence and/or monitor) -pub fn write_midi_output (writer: &mut ::jack::MidiWriter, output: &MIDIChunk, frames: usize) { - for time in 0..frames { - for event in output[time].iter() { - writer.write(&::jack::RawMidi { time: time as u32, bytes: &event }) - .expect(&format!("{event:?}")); - } - } -} - -/// (pulses, name) -pub const NOTE_DURATIONS: [(u16, &str);26] = [ - (1, "1/384"), - (2, "1/192"), - (3, "1/128"), - (4, "1/96"), - (6, "1/64"), - (8, "1/48"), - (12, "1/32"), - (16, "1/24"), - (24, "1/16"), - (32, "1/12"), - (48, "1/8"), - (64, "1/6"), - (96, "1/4"), - (128, "1/3"), - (192, "1/2"), - (256, "2/3"), - (384, "1/1"), - (512, "4/3"), - (576, "3/2"), - (768, "2/1"), - (1152, "3/1"), - (1536, "4/1"), - (2304, "6/1"), - (3072, "8/1"), - (3456, "9/1"), - (6144, "16/1"), -]; - -pub fn prev_note_length (ppq: u16) -> u16 { - for i in 1..=16 { - let length = NOTE_DURATIONS[16-i].0; - if length < ppq { - return length - } - } - ppq -} - -pub fn next_note_length (ppq: u16) -> u16 { - for (length, _) in &NOTE_DURATIONS { - if *length > ppq { - return *length - } - } - ppq -} - -pub fn ppq_to_name (ppq: u16) -> &'static str { - for (length, name) in &NOTE_DURATIONS { - if *length == ppq { - return name - } - } - "" -} diff --git a/crates/tek/src/core/render.rs b/crates/tek/src/core/render.rs deleted file mode 100644 index 6929dec0..00000000 --- a/crates/tek/src/core/render.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::core::*; -pub(crate) use ratatui::prelude::CrosstermBackend; -pub(crate) use ratatui::style::{Stylize, Style, Color, Modifier}; -pub(crate) use ratatui::layout::Rect; -pub(crate) use ratatui::buffer::{Buffer, Cell}; -use ratatui::widgets::WidgetRef; - -pub fn make_dim (buf: &mut Buffer) { - for cell in buf.content.iter_mut() { - cell.bg = ratatui::style::Color::Rgb(30,30,30); - cell.fg = ratatui::style::Color::Rgb(100,100,100); - cell.modifier = ratatui::style::Modifier::DIM; - } -} -pub fn center_box (area: Rect, w: u16, h: u16) -> Rect { - let width = w.min(area.width * 3 / 5); - let height = h.min(area.width * 3 / 5); - let x = area.x + (area.width - width) / 2; - let y = area.y + (area.height - height) / 2; - Rect { x, y, width, height } -} -pub fn buffer_update ( - buf: &mut Buffer, area: Rect, callback: &impl Fn(&mut Cell, u16, u16) -) { - for row in 0..area.height { - let y = area.y + row; - for col in 0..area.width { - let x = area.x + col; - if x < buf.area.width && y < buf.area.height { - callback(buf.get_mut(x, y), col, row); - } - } - } -} -pub fn fill_fg (buf: &mut Buffer, area: Rect, color: Color) { - buffer_update(buf, area, &|cell,_,_|{cell.set_fg(color);}) -} -pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) { - buffer_update(buf, area, &|cell,_,_|{cell.set_bg(color);}) -} -pub fn to_fill_bg (color: Color) -> impl Render { - move |buf: &mut Buffer, area: Rect|{ - fill_bg(buf, area, color); - Ok(area) - } -} -pub fn fill_char (buf: &mut Buffer, area: Rect, c: char) { - buffer_update(buf, area, &|cell,_,_|{cell.set_char(c);}) -} -pub fn half_block (lower: bool, upper: bool) -> Option { - match (lower, upper) { - (true, true) => Some('█'), - (true, false) => Some('▄'), - (false, true) => Some('▀'), - _ => None - } -} - -pub trait Blit { - // Render something to X, Y coordinates in a buffer, ignoring width/height. - fn blit (&self, buf: &mut Buffer, x: u16, y: u16, style: Option