diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..b5e063a --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,18 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc" +rustflags = [ + "-C", "link-arg=-Bstatic", +] + +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc" +rustflags = [ + "-C", "link-arg=-Bstatic", +] + +# [target.i686-unknown-linux-gnu] +# linker = "i686-linux-gnu-gcc" +# rustflags = [ +# "-C", "link-arg=-Bstatic", +# ] + diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..edb59c5 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,152 @@ +name: CI/CD +permissions: write-all +on: [push] +env: + CRATE_NAME: smrec + GITHUB_TOKEN: ${{ github.token }} + RUST_BACKTRACE: 1 +jobs: + test: + name: ${{ matrix.platform.os_name }} with rust ${{ matrix.toolchain }} + runs-on: ${{ matrix.platform.os }} + strategy: + fail-fast: false + matrix: + platform: + # Linux Gnu + - os_name: Linux-x86_64 + os: ubuntu-latest + target: x86_64-unknown-linux-gnu + bin: smrec + name: smrec-Linux-x86_64-gnu.tar.gz + # - os_name: Linux-i686 + # os: ubuntu-latest + # target: i686-unknown-linux-gnu + # bin: smrec + # name: smrec-Linux-i686-gnu.tar.gz + + # Linux Gnu Arm + - os_name: Linux-aarch64 + os: ubuntu-latest + target: aarch64-unknown-linux-gnu + bin: smrec + name: smrec-Linux-aarch64-gnu.tar.gz + - os_name: Linux-armv7 + os: ubuntu-latest + target: armv7-unknown-linux-gnueabihf + bin: smrec + name: smrec-Linux-armv7-gnueabihf.tar.gz + + # Windows Arm + - os_name: Windows-aarch64 + os: windows-latest + target: aarch64-pc-windows-msvc + bin: smrec.exe + name: smrec-Windows-aarch64.zip + skip_tests: true + + # Windows + - os_name: Windows-i686 + os: windows-latest + target: i686-pc-windows-msvc + bin: smrec.exe + name: smrec-Windows-i686.zip + skip_tests: true + - os_name: Windows-x86_64 + os: windows-latest + target: x86_64-pc-windows-msvc + bin: smrec.exe + name: smrec-Windows-x86_64.zip + + # macOS + - os_name: macOS-x86_64 + os: macOS-latest + target: x86_64-apple-darwin + bin: smrec + name: smrec-Darwin-x86_64.tar.gz + + # macOS Arm + - os_name: macOS-aarch64 + os: macOS-latest + target: aarch64-apple-darwin + bin: smrec + name: smrec-Darwin-aarch64.tar.gz + skip_tests: true + toolchain: + - stable + steps: + - uses: actions/checkout@v4 + - name: Cache cargo & target directories + uses: Swatinem/rust-cache@v2 + with: + key: "v2" + + - name: Configure Git + run: | + git config --global user.email "alisomay@runbox.com" + git config --global user.name "Ali Somay" + + - name: Install alsa & jack libraries + run: sudo apt-get update && sudo apt-get install -y libjack-jackd2-dev libasound2-dev + if: matrix.platform.target == 'x86_64-unknown-linux-gnu' + + # --locked can be added later + - name: Build binary + uses: houseabsolute/actions-rust-cross@v0 + with: + command: "build" + target: ${{ matrix.platform.target }} + toolchain: ${{ matrix.toolchain }} + args: "--release" + strip: true + env: + # Build environment variables + GITHUB_ENV: ${{ github.workspace }}/.env + + # --locked can be added later + - name: Run tests + uses: houseabsolute/actions-rust-cross@v0 + with: + command: "test" + target: ${{ matrix.platform.target }} + toolchain: ${{ matrix.toolchain }} + args: "--release" + if: ${{ !matrix.platform.skip_tests }} + + - name: Package as archive + shell: bash + run: | + cd target/${{ matrix.platform.target }}/release + if [[ "${{ matrix.platform.os }}" == "windows-latest" ]]; then + 7z a ../../../${{ matrix.platform.name }} ${{ matrix.platform.bin }} + else + tar czvf ../../../${{ matrix.platform.name }} ${{ matrix.platform.bin }} + fi + cd - + if: | + matrix.toolchain == 'stable' && + ( startsWith( github.ref, 'refs/tags/v' ) || + github.ref == 'refs/tags/test-release' ) + + - name: Publish release artifacts + uses: actions/upload-artifact@v3 + with: + name: smrec-${{ matrix.platform.os_name }} + path: "smrec-*" + if: matrix.toolchain == 'stable' && github.ref == 'refs/tags/test-release' + + - name: Generate SHA-256 + run: shasum -a 256 ${{ matrix.platform.name }} + if: | + matrix.toolchain == 'stable' && + matrix.platform.os == 'macOS-latest' && + ( startsWith( github.ref, 'refs/tags/v' ) || + github.ref == 'refs/tags/test-release' ) + + - name: Publish GitHub release + uses: softprops/action-gh-release@v1 + with: + draft: true + files: "smrec*" + body_path: CHANGELOG.md + if: matrix.toolchain == 'stable' && startsWith( github.ref, 'refs/tags/v' ) diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ece99c5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog + +The format of this changelog is based on +[Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +smrec project adheres to +[Semantic Versioning](https://semver.org/spec/v2.0.0.html). + + + +## [0.2.1] - 2020.11.20 + +- Initial release diff --git a/Cargo.lock b/Cargo.lock index 06751a7..b513f46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,13 +105,14 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "asio-sys" version = "0.2.1" -source = "git+https://github.com/RustAudio/cpal.git#3a449538b7d263138455f5669685e7b2e50ac28d" +source = "git+https://github.com/RustAudio/cpal.git#efa0c7af6b997cbdab3b95e5d792717503ef1667" dependencies = [ - "bindgen", + "bindgen 0.69.1", "cc", - "num-derive", + "num-derive 0.4.1", "num-traits", "once_cell", + "parse_cfg", "walkdir", ] @@ -127,7 +128,27 @@ version = "0.68.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.39", +] + +[[package]] +name = "bindgen" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +dependencies = [ + "bitflags 2.4.1", "cexpr", "clang-sys", "lazy_static", @@ -140,7 +161,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.38", + "syn 2.0.39", "which", ] @@ -152,9 +173,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "bumpalo" @@ -239,9 +260,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.6" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" dependencies = [ "clap_builder", "clap_derive", @@ -249,9 +270,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" dependencies = [ "anstream", "anstyle", @@ -261,21 +282,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "colorchoice" @@ -299,16 +320,10 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ - "core-foundation-sys 0.8.4", + "core-foundation-sys", "libc", ] -[[package]] -name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -317,12 +332,12 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "coreaudio-rs" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb17e2d1795b1996419648915df94bc7103c28f7b48062d7acf4652fc371b2ff" +checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace" dependencies = [ "bitflags 1.3.2", - "core-foundation-sys 0.6.2", + "core-foundation-sys", "coreaudio-sys", ] @@ -332,7 +347,7 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8478e5bdad14dce236b9898ea002eabfa87cbe14f0aa538dbe3b6a4bec4332d" dependencies = [ - "bindgen", + "bindgen 0.68.1", ] [[package]] @@ -342,7 +357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a7847ca018a67204508b77cb9e6de670125075f7464fff5f673023378fa34f5" dependencies = [ "core-foundation", - "core-foundation-sys 0.8.4", + "core-foundation-sys", "coremidi-sys", ] @@ -352,17 +367,17 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79a6deed0c97b2d40abbab77e4c97f81d71e162600423382c277dd640019116c" dependencies = [ - "core-foundation-sys 0.8.4", + "core-foundation-sys", ] [[package]] name = "cpal" version = "0.15.2" -source = "git+https://github.com/RustAudio/cpal.git#3a449538b7d263138455f5669685e7b2e50ac28d" +source = "git+https://github.com/RustAudio/cpal.git#efa0c7af6b997cbdab3b95e5d792717503ef1667" dependencies = [ "alsa", "asio-sys", - "core-foundation-sys 0.8.4", + "core-foundation-sys", "coreaudio-rs", "dasp_sample", "jack", @@ -479,9 +494,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" dependencies = [ "libc", "windows-sys", @@ -501,9 +516,9 @@ checksum = "9985c9503b412198aa4197559e9a318524ebc4519c229bfa05a535828c950b9d" [[package]] name = "hashbrown" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" @@ -528,16 +543,16 @@ checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", - "core-foundation-sys 0.8.4", + "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core", ] [[package]] @@ -551,9 +566,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", "hashbrown", @@ -631,9 +646,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -652,9 +667,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libloading" @@ -668,15 +683,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -781,7 +796,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "libc", ] @@ -807,6 +822,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -846,7 +872,7 @@ dependencies = [ "jni 0.20.0", "ndk", "ndk-context", - "num-derive", + "num-derive 0.3.3", "num-traits", "oboe-sys", ] @@ -878,9 +904,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", @@ -889,6 +915,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "parse_cfg" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "905787a434a2c721408e7c9a252e85f3d93ca0f118a5283022636c0e05a7ea49" +dependencies = [ + "nom", +] + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -908,7 +943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" dependencies = [ "proc-macro2", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] @@ -947,18 +982,18 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.10.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -968,9 +1003,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -979,9 +1014,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rosc" @@ -1001,11 +1036,11 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.19" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -1029,29 +1064,29 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] @@ -1064,13 +1099,13 @@ checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "smallvec" -version = "1.11.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smrec" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", "camino", @@ -1109,9 +1144,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1120,41 +1155,41 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", ] [[package]] name = "toml" -version = "0.8.2" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -1172,9 +1207,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap", "serde", @@ -1207,9 +1242,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1217,24 +1252,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -1244,9 +1279,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1254,28 +1289,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -1348,6 +1383,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1458,9 +1502,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.16" +version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 02afd1b..e72720f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smrec" -version = "0.2.0" +version = "0.2.1" authors = ["alisomay "] edition = "2021" license = "MIT" @@ -17,7 +17,6 @@ exclude = [ "assets/logo_*" ] - # When https://github.com/RustAudio/cpal/issues/794 is resolved this can continue to track the stable release. [target.'cfg(target_os = "windows")'.dependencies] cpal = { git = "https://github.com/RustAudio/cpal.git", features = ["asio"] } diff --git a/Cross.toml b/Cross.toml new file mode 100644 index 0000000..f413594 --- /dev/null +++ b/Cross.toml @@ -0,0 +1,25 @@ +# Install build dependencies for the right architecture per target +# [target.i686-unknown-linux-gnu] +# runner = "qemu-user" +# pre-build = [ +# "export BUILDKIT_PROGRESS=plain", +# "dpkg --add-architecture $CROSS_DEB_ARCH", +# "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +# ] + +[target.aarch64-unknown-linux-gnu] +runner = "qemu-user" +pre-build = [ + "export BUILDKIT_PROGRESS=plain", + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +] + +[target.armv7-unknown-linux-gnueabihf] +runner = "qemu-user" +pre-build = [ + "export BUILDKIT_PROGRESS=plain", + "dpkg --add-architecture $CROSS_DEB_ARCH", + "apt-get update && apt-get --assume-yes install libasound2-dev:$CROSS_DEB_ARCH libjack-jackd2-dev:$CROSS_DEB_ARCH" +] + diff --git a/README.md b/README.md index e565169..fe16d50 100644 --- a/README.md +++ b/README.md @@ -133,9 +133,9 @@ The configuration file can configure: ```toml [channel_names] -1 = "Kick" -2 = "Snare" -3 = "Hi-Hat" +1 = "Kick.wav" +2 = "Snare.wav" +3 = "Hi-Hat.wav" ``` - More to come.. @@ -272,8 +272,8 @@ But I don't plan to heavily maintain this project, I'll just make sure that it i - `x86_64` ✅ - `aarch64` ✅ - linux: - - `x86_64` (Should work but not checked yet, will be checked though) - - `aarch64` (Should work but not checked yet, will be checked though) + - `x86_64` ✅ + - `aarch64` ✅ - windows: - `x86_64` ✅ - `aarch64` ✅ diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..db4ec23 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,77 @@ +# max_width = 100 +# hard_tabs = false +# tab_spaces = 4 +# newline_style = "Auto" +# indent_style = "Block" +# use_small_heuristics = "Default" +# fn_call_width = 60 +# attr_fn_like_width = 70 +# struct_lit_width = 18 +# struct_variant_width = 35 +# array_width = 60 +# chain_width = 60 +# single_line_if_else_max_width = 50 +# wrap_comments = false +# format_code_in_doc_comments = false +# comment_width = 80 +# normalize_comments = false +# normalize_doc_attributes = false +# license_template_path = "" +# format_strings = false +# format_macro_matchers = false +# format_macro_bodies = true +# hex_literal_case = "Preserve" +# empty_item_single_line = true +# struct_lit_single_line = true +# fn_single_line = false +# where_single_line = false +# imports_indent = "Block" +# imports_layout = "Mixed" +imports_granularity = "Crate" +group_imports = "One" +reorder_imports = true +reorder_modules = true +# reorder_impl_items = false +# type_punctuation_density = "Wide" +# space_before_colon = false +# space_after_colon = true +# spaces_around_ranges = false +# binop_separator = "Front" +# remove_nested_parens = true +# combine_control_expr = true +# overflow_delimited_expr = false +# struct_field_align_threshold = 0 +# enum_discrim_align_threshold = 0 +# match_arm_blocks = true +# match_arm_leading_pipes = "Never" +# force_multiline_blocks = false +# fn_args_layout = "Tall" +# brace_style = "SameLineWhere" +# control_brace_style = "AlwaysSameLine" +# trailing_semicolon = true +# trailing_comma = "Vertical" +# match_block_trailing_comma = false +# blank_lines_upper_bound = 1 +# blank_lines_lower_bound = 0 +edition = "2021" +# version = "One" +# inline_attribute_width = 0 +# format_generated_files = true +# merge_derives = true +# use_try_shorthand = false +# use_field_init_shorthand = false +# force_explicit_abi = true +# condense_wildcard_suffixes = false +# color = "Auto" +# required_version = "1.4.38" +# unstable_features = false +# disable_all_formatting = false +# skip_children = false +# hide_parse_errors = false +# error_on_line_overflow = false +# error_on_unformatted = false +# report_todo = "Never" +# report_fixme = "Never" +# ignore = [] +# emit_mode = "Files" +# make_backup = false diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..75ff53f --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,6 @@ +# Pre build scripts + +These are about the become obsolete. +They are here for historical reasons. +Once ` cpal`` publishes a new version, we can remove them. +For linux users, we'll see how it works but I might make a PR to `cpal`` to automate installation of jack and alsa dependencies also if it makes sense. diff --git a/pre-build-linux.sh b/scripts/pre-build-linux.sh similarity index 100% rename from pre-build-linux.sh rename to scripts/pre-build-linux.sh diff --git a/pre-build-win.ps1 b/scripts/pre-build-win.ps1 similarity index 51% rename from pre-build-win.ps1 rename to scripts/pre-build-win.ps1 index 565e85a..6ed2c1d 100644 --- a/pre-build-win.ps1 +++ b/scripts/pre-build-win.ps1 @@ -1,8 +1,54 @@ +param ( + [switch]$ci +) + Write-Output "=============================================================================" Write-Output "Pre build script for cpal asio feature." -Write-Output "Make sure that you have sourced this script instead of directly executing it." +Write-Output "Make sure that you have sourced this script instead of directly executing it or if in CI environment, pass the --ci flag." Write-Output "=============================================================================" +function Write-Env { + <# + .SYNOPSIS + Sets an environment variable either in the current process or in the GITHUB_ENV file. + + .DESCRIPTION + This function sets an environment variable. If the --ci switch is specified when + running the script, it writes the environment variable to the GITHUB_ENV file + so it is available to subsequent steps in a GitHub Actions workflow. Otherwise, + it sets the environment variable in the current process. + + .PARAMETER name + The name of the environment variable to set. + + .PARAMETER value + The value to set the environment variable to. + + .EXAMPLE + Write-Env "MY_VARIABLE" "Some Value" + + This example sets the MY_VARIABLE environment variable to "Some Value" in the current process. + + .EXAMPLE + .\pre-build-win.ps1 --ci + Write-Env "MY_VARIABLE" "Some Value" + + This example, when run within the script with the --ci switch, writes the MY_VARIABLE + environment variable to the GITHUB_ENV file with a value of "Some Value". + #> + param ( + [string]$name, + [string]$value + ) + if ($ci) { + Write-Output "$name=$value" | Out-File -FilePath $env:GITHUB_ENV -Append + } + else { + Write-Output "Setting $name=$value" + [System.Environment]::SetEnvironmentVariable($name, $value, "Process") + } +} + function Invoke-VcVars { <# .SYNOPSIS @@ -18,23 +64,56 @@ function Invoke-VcVars { Write-Output "Determining system architecture..." $arch = if ([Environment]::Is64BitOperatingSystem) { switch -Wildcard ((Get-CimInstance -ClassName Win32_Processor).Description) { - "*ARM64*"{ "arm64" } - "*ARM*"{ "arm" } + "*ARM64*" { "arm64" } + "*ARM*" { "arm" } default { "amd64" } } - } else { + } + else { "x86" } Write-Output "Architecture detected as $arch." + # Define search paths based on architecture - $paths = if ($arch -eq 'amd64') { - @('C:\Program Files (x86)\Microsoft Visual Studio\', 'C:\Program Files\Microsoft Visual Studio\') - } else { - @('C:\Program Files\Microsoft Visual Studio\') + # Will be overridden if CI flag is set + $paths = @('C:\Program Files (x86)\Microsoft Visual Studio\', 'C:\Program Files\Microsoft Visual Studio\') + + # Find Visual Studio version number (only when CI flag is set) + # TODO: This can be more robust and improve.. but later.. + if ($ci) { + Write-Output "Searching for Visual Studio version number..." + $vsVersion = Get-ChildItem 'C:\Program Files (x86)\Microsoft Visual Studio\' -Directory | + Where-Object { $_.Name -match '\d{4}' } | + Select-Object -ExpandProperty Name -First 1 + + if (-not $vsVersion) { + $vsVersion = Get-ChildItem 'C:\Program Files\Microsoft Visual Studio\' -Directory | + Where-Object { $_.Name -match '\d{4}' } | + Select-Object -ExpandProperty Name -First 1 + } + + if ($vsVersion) { + Write-Output "Visual Studio version $vsVersion detected." + $paths = + @( + "C:\Program Files (x86)\Microsoft Visual Studio\$vsVersion\Community\VC\Auxiliary\Build\", + "C:\Program Files\Microsoft Visual Studio\$vsVersion\Community\VC\Auxiliary\Build\", + "C:\Program Files (x86)\Microsoft Visual Studio\$vsVersion\Professional\VC\Auxiliary\Build\", + "C:\Program Files\Microsoft Visual Studio\$vsVersion\Professional\VC\Auxiliary\Build\", + "C:\Program Files (x86)\Microsoft Visual Studio\$vsVersion\Enterprise\VC\Auxiliary\Build\", + "C:\Program Files\Microsoft Visual Studio\$vsVersion\Enterprise\VC\Auxiliary\Build\" + ) + + } + else { + Write-Output "Visual Studio version not detected. Proceeding with original search paths." + $paths = @('C:\Program Files (x86)\Microsoft Visual Studio\', 'C:\Program Files\Microsoft Visual Studio\') + } } + # Search for vcvarsall.bat and execute the first instance found with the appropriate architecture argument Write-Output "Searching for vcvarsall.bat..." foreach ($path in $paths) { @@ -46,7 +125,7 @@ function Invoke-VcVars { if ($line -match "^(.*?)=(.*)$") { $varName = $matches[1] $varValue = $matches[2] - [System.Environment]::SetEnvironmentVariable($varName, $varValue, "Process") + Write-Env $varName $varValue } } return @@ -86,25 +165,30 @@ if ($env:OS -match "Windows") { # Move the contents of the inner directory (like asiosdk_2.3.3_2019-06-14) to $asio_dir $innerDir = Get-ChildItem -Path $out_dir -Directory | Where-Object { $_.Name -match 'asio.*' } | Select-Object -First 1 Move-Item -Path "$($innerDir.FullName)\*" -Destination $asio_dir -Force - } else { + } + else { Write-Output "ASIO SDK already exists. Skipping download." } # Set the CPAL_ASIO_DIR environment variable Write-Output "Setting CPAL_ASIO_DIR environment variable..." - $env:CPAL_ASIO_DIR = $asio_dir + Write-Env "CPAL_ASIO_DIR" $asio_dir # Check if LIBCLANG_PATH is set if (-not $env:LIBCLANG_PATH) { Write-Error "Error: LIBCLANG_PATH is not set!" Write-Output "Please ensure LLVM is installed and set the LIBCLANG_PATH environment variable." exit 1 - } else { + } + else { Write-Output "LIBCLANG_PATH is set to $env:LIBCLANG_PATH." } # Run the vcvars function Invoke-VcVars -} else { + + Write-Output "Environment is ready for build." +} +else { Write-Output "This setup script is intended for Windows only." } diff --git a/src/config.rs b/src/config.rs index bf07ca9..8157a2a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,16 +1,21 @@ -use crate::wav::spec_from_config; -use crate::WriterHandles; +use crate::{wav::spec_from_config, WriterHandles}; use anyhow::{anyhow, bail, Result}; use camino::Utf8PathBuf; use chrono::{Datelike, Timelike, Utc}; -use cpal::traits::{DeviceTrait, HostTrait}; -use cpal::SupportedStreamConfig; -use serde::de::{self, Deserializer, MapAccess, Visitor}; -use serde::Deserialize; -use std::collections::HashMap; -use std::fmt; -use std::str::FromStr; -use std::sync::{Arc, Mutex}; +use cpal::{ + traits::{DeviceTrait, HostTrait}, + SupportedStreamConfig, +}; +use serde::{ + de::{self, Deserializer, MapAccess, Visitor}, + Deserialize, +}; +use std::{ + collections::HashMap, + fmt, + str::FromStr, + sync::{Arc, Mutex}, +}; /// Chooses which channels to record. pub fn choose_channels_to_record( @@ -132,17 +137,20 @@ impl SmrecConfig { config.channels_to_record = channels_to_record; config.channels_to_record.iter().for_each(|channel| { - if !config.channel_names.contains_key(&(channel + 1)) { - config - .channel_names - .insert(*channel + 1, format!("chn_{}.wav", channel + 1)); - } else { + if config.channel_names.contains_key(&(channel + 1)) { let name = config.channel_names.get(&(channel + 1)).unwrap(); - if !name.ends_with(".wav") { + if !std::path::Path::new(name) + .extension() + .map_or(false, |ext| ext.eq_ignore_ascii_case("wav")) + { config .channel_names - .insert(*channel + 1, format!("{}.wav", name)); + .insert(*channel + 1, format!("{name}.wav")); } + } else { + config + .channel_names + .insert(*channel + 1, format!("chn_{}.wav", channel + 1)); } }); config.cpal_stream_config = Some(cpal_stream_config); @@ -272,14 +280,14 @@ mod tests { fn deserialize_external_config() { let config: &str = r#" [channel_names] - 1 = "channel_1.wav" - 2 = "channel_2.wav" - 3 = "channel_3.wav" - 4 = "channel_4.wav" - 5 = "channel_5.wav" - 6 = "channel_6.wav" - 7 = "channel_7.wav" - 8 = "channel_8.wav" + 1 = "channel_1" + 2 = "channel_2" + 3 = "channel_3" + 4 = "channel_4" + 5 = "channel_5" + 6 = "channel_6" + 7 = "channel_7" + 8 = "channel_8" "#; let config: SmrecConfig = toml::from_str(config).unwrap(); diff --git a/src/main.rs b/src/main.rs index c869ac1..9938795 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,34 @@ +// Most of the lints we deny here have a good chance to be relevant for our project. +#![deny(clippy::all)] +// We warn for all lints on the planet. Just to filter them later for customization. +// It is impossible to remember all the lints so a subtractive approach keeps us updated, in control and knowledgeable. +#![warn(clippy::pedantic, clippy::nursery, clippy::cargo)] +// Then in the end we allow ridiculous or too restrictive lints that are not relevant for our project. +// This list is dynamic and will grow in time which will define our style. +#![allow( + clippy::multiple_crate_versions, + clippy::blanket_clippy_restriction_lints, + clippy::missing_docs_in_private_items, + clippy::pub_use, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core, + clippy::implicit_return, + clippy::missing_inline_in_public_items, + clippy::similar_names, + clippy::question_mark_used, + clippy::expect_used, + clippy::missing_errors_doc, + clippy::pattern_type_mismatch, + clippy::module_name_repetitions, + clippy::empty_structs_with_brackets, + clippy::as_conversions, + clippy::self_named_module_files, + clippy::cargo_common_metadata, + clippy::exhaustive_structs, + // It is a binary crate, panicing is usually fine. + clippy::missing_panics_doc +)] + mod config; mod list; mod midi; @@ -6,22 +37,25 @@ mod stream; mod types; mod wav; +use crate::{ + config::{choose_channels_to_record, SmrecConfig}, + midi::Midi, +}; use anyhow::{bail, Result}; use clap::{Parser, Subcommand}; use config::{choose_device, choose_host}; use cpal::traits::{DeviceTrait, StreamTrait}; use hound::WavWriter; use osc::Osc; -use std::cell::RefCell; -use std::fs::File; -use std::io::BufWriter; -use std::rc::Rc; -use std::sync::{Arc, Mutex}; +use std::{ + cell::RefCell, + fs::File, + io::BufWriter, + rc::Rc, + sync::{Arc, Mutex}, +}; use types::Action; -use crate::config::{choose_channels_to_record, SmrecConfig}; -use crate::midi::Midi; - #[derive(Parser)] #[command( author, @@ -93,6 +127,7 @@ struct List { pub type WriterHandle = Arc>>>>; pub type WriterHandles = Arc>; +#[allow(clippy::too_many_lines)] fn main() -> Result<()> { let cli = Cli::parse(); diff --git a/src/midi.rs b/src/midi.rs index 0e3fc78..ccbbc6a 100644 --- a/src/midi.rs +++ b/src/midi.rs @@ -8,10 +8,12 @@ use anyhow::{bail, Result}; use midir::{ MidiInput, MidiInputConnection, MidiInputPort, MidiOutput, MidiOutputConnection, MidiOutputPort, }; -use std::collections::HashMap; -use std::ops::Deref; -use std::str::FromStr; -use std::sync::{Arc, Mutex}; +use std::{ + collections::HashMap, + ops::Deref, + str::FromStr, + sync::{Arc, Mutex}, +}; enum MessageType { NoteOff, @@ -45,7 +47,7 @@ const fn make_cc_message(channel: u8, cc_num: u8, value: u8) -> [u8; 3] { [0xB0 + channel, cc_num, value] } -/// HashMap of port name to vector of (channel_num, cc_num[start], cc_num[stop]) +/// `HashMap` of port name to vector of (`channel_num`, `cc_num`[start], `cc_num`[stop]) #[derive(Debug, Clone)] pub struct MidiConfig(HashMap>); @@ -160,9 +162,10 @@ impl Midi { }) } - pub fn listen(&mut self) -> Result<()> { - let input_ports = self - .input_config + // These are going to be addressed in a later refactor. + #[allow(clippy::type_complexity)] + fn input_ports_from_configs(&self) -> Result)>> { + self.input_config .iter() .filter_map(|(port_name, configs)| { let input_ports = self.find_input_ports(port_name).ok()?; @@ -175,7 +178,11 @@ impl Midi { }) .flatten() .map(Ok) - .collect::)>, anyhow::Error>>()?; + .collect::)>, anyhow::Error>>() + } + + fn register_midi_input_hooks(&mut self) -> Result<()> { + let input_ports = self.input_ports_from_configs()?; // Start listening for MIDI messages on all configured ports and channels. for (port_name, port, configs) in input_ports { @@ -254,46 +261,59 @@ impl Midi { ); } + Ok(()) + } + + // These are going to be addressed in a later refactor. + #[allow(clippy::type_complexity)] + fn output_connections_from_config( + &self, + ) -> Result>, Vec<(u8, u8, u8)>)>>> { if let Some(ref output_config) = self.output_config { - let output_connections = { - let output_ports = output_config - .iter() - .filter_map(|(port_name, configs)| { - let output_ports = self.find_output_ports(port_name).ok()?; - Some( - output_ports - .into_iter() - .map(move |(name, port)| (name, port, configs.clone())) - .collect::>(), - ) - }) - .flatten() - .map(Ok) - .collect::)>, anyhow::Error>>()?; - - output_ports - .iter() - .map(|(port_name, port, configs)| { - let output = MidiOutput::new("smrec")?; - Ok::< - ( - std::string::String, - Arc>, - std::vec::Vec<(u8, u8, u8)>, - ), - anyhow::Error, - >(( - port_name.clone(), - Arc::new(Mutex::new(output.connect(port, port_name).expect("Could not bind to {port_name}"))), - configs.clone(), - )) - }) - .collect::>, Vec<(u8, u8, u8)>)>, _>>( - )? - }; - - let receiver_channel = self.receiver_channel.clone(); + let output_ports = output_config + .iter() + .filter_map(|(port_name, configs)| { + let output_ports = self.find_output_ports(port_name).ok()?; + Some( + output_ports + .into_iter() + .map(move |(name, port)| (name, port, configs.clone())) + .collect::>(), + ) + }) + .flatten() + .map(Ok) + .collect::)>, anyhow::Error>>( + )?; + + return output_ports + .iter() + .map(|(port_name, port, configs)| { + let output = MidiOutput::new("smrec")?; + Ok(Some(( + port_name.clone(), + Arc::new(Mutex::new( + output + .connect(port, port_name) + .expect("Could not bind to {port_name}"), + )), + configs.clone(), + ))) + }) + .collect::>, Vec<(u8, u8, u8)>)>>, + _, + >>(); + } + Ok(None) + } + + fn spin_midi_output_thread_if_necessary(&mut self) -> Result<()> { + let output_connections = self.output_connections_from_config()?; + let receiver_channel = self.receiver_channel.clone(); + + if let Some(output_connections) = output_connections { self.output_thread = Some(std::thread::spawn(move || { loop { if let Ok(action) = receiver_channel.recv() { @@ -371,4 +391,11 @@ impl Midi { Ok(()) } + + pub fn listen(&mut self) -> Result<()> { + self.register_midi_input_hooks()?; + self.spin_midi_output_thread_if_necessary()?; + + Ok(()) + } } diff --git a/src/midi/parse.rs b/src/midi/parse.rs index ec7b79a..f1ca460 100644 --- a/src/midi/parse.rs +++ b/src/midi/parse.rs @@ -1,9 +1,7 @@ #![allow(clippy::type_complexity)] -use anyhow::anyhow; -use anyhow::Result; -use std::collections::HashMap; - +use crate::midi::MidiConfig; +use anyhow::{anyhow, Result}; use nom::{ branch::alt, bytes::complete::take_until, @@ -13,8 +11,7 @@ use nom::{ sequence::{delimited, preceded, tuple}, IResult, }; - -use crate::midi::MidiConfig; +use std::collections::HashMap; /// Parses * or a u8 ranged number fn parse_u8_or_star(input: &str) -> IResult<&str, u8> { diff --git a/src/osc.rs b/src/osc.rs index 2fcf942..9f762dd 100644 --- a/src/osc.rs +++ b/src/osc.rs @@ -1,10 +1,11 @@ use crate::types::Action; use anyhow::Result; -use rosc::encoder::encode; -use rosc::{OscMessage, OscPacket, OscType}; -use std::net::{SocketAddr, UdpSocket}; -use std::str::FromStr; -use std::sync::Arc; +use rosc::{encoder::encode, OscMessage, OscPacket, OscType}; +use std::{ + net::{SocketAddr, UdpSocket}, + str::FromStr, + sync::Arc, +}; pub struct Osc { sender_socket: Arc, diff --git a/src/stream.rs b/src/stream.rs index 7c0e185..a82a658 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -1,12 +1,8 @@ +use crate::{wav::write_input_data, WriterHandles}; use anyhow::{bail, Result}; -use cpal::traits::DeviceTrait; -use cpal::{FromSample, Sample}; - +use cpal::{traits::DeviceTrait, FromSample, Sample}; use std::sync::{Arc, Mutex}; -use crate::wav::write_input_data; -use crate::WriterHandles; - pub fn build( device: &cpal::Device, config: cpal::SupportedStreamConfig, diff --git a/src/wav.rs b/src/wav.rs index c9f0773..0ef9d34 100644 --- a/src/wav.rs +++ b/src/wav.rs @@ -1,7 +1,9 @@ use cpal::{FromSample, Sample}; -use std::fs::File; -use std::io::BufWriter; -use std::sync::{Arc, Mutex}; +use std::{ + fs::File, + io::BufWriter, + sync::{Arc, Mutex}, +}; pub fn sample_format(format: cpal::SampleFormat) -> hound::SampleFormat { if format.is_float() { @@ -32,7 +34,7 @@ pub fn write_input_data( { if let Ok(mut guard) = writer.try_lock() { if let Some(writer) = guard.as_mut() { - for &sample in input.iter() { + for &sample in input { let sample: U = U::from_sample(sample); writer.write_sample(sample).ok(); }