Merge pull request #56 from Polochon-street/update-should-delete

Update library should also delete songs
This commit is contained in:
Polochon-street 2023-02-14 21:56:07 +01:00 committed by GitHub
commit 97f563dd6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 521 additions and 225 deletions

View File

@ -26,6 +26,8 @@ jobs:
run: sudo apt-get update && sudo apt-get install build-essential yasm libavutil-dev libavcodec-dev libavformat-dev libavfilter-dev libavfilter-dev libavdevice-dev libswresample-dev libfftw3-dev ffmpeg
- name: Check format
run: cargo fmt -- --check
- name: Lint
run: cargo clippy --examples --features=serde,library -- -D warnings
- name: Build
run: cargo build --verbose
- name: Run tests
@ -38,8 +40,6 @@ jobs:
run: cargo +nightly-2022-02-16 bench --verbose --features=bench --no-run
- name: Build examples
run: cargo build --examples --verbose --features=serde,library
- name: Lint
run: cargo clippy --examples --features=serde,library -- -D warnings
build-test-lint-windows:
name: Windows - build, test and lint
@ -70,11 +70,11 @@ jobs:
toolchain: stable
override: true
components: rustfmt, clippy
- name: Build
run: cargo build --examples
- name: Test
run: cargo test --examples --features=serde
- name: Lint
run: cargo clippy --examples --features=serde -- -D warnings
- name: Check format
run: cargo fmt -- --check
- name: Build
run: cargo build --examples
- name: Test
run: cargo test --examples --features=serde

View File

@ -1,5 +1,9 @@
#Changelog
## bliss 0.6.6
* Add a `delete_everything_else` function in `library`'s update functions.
* Use Rust 2021
## bliss 0.6.5
* Fix library update performance issues.
* Pretty-print JSON in the config file.

329
Cargo.lock generated
View File

@ -30,9 +30,9 @@ dependencies = [
[[package]]
name = "aho-corasick"
version = "0.7.19"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr 2.5.0",
]
@ -48,9 +48,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.65"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
[[package]]
name = "atty"
@ -58,7 +58,7 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"hermit-abi 0.1.19",
"libc",
"winapi 0.3.9",
]
@ -83,7 +83,7 @@ dependencies = [
"peeking_take_while",
"proc-macro2",
"quote",
"regex 1.6.0",
"regex 1.7.1",
"rustc-hash",
"shlex",
]
@ -96,7 +96,7 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bliss-audio"
version = "0.6.5"
version = "0.6.6"
dependencies = [
"anyhow",
"bliss-audio-aubio-rs",
@ -175,9 +175,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bzip2"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
@ -196,9 +196,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.73"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
@ -256,16 +256,15 @@ dependencies = [
[[package]]
name = "console"
version = "0.15.2"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c"
checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60"
dependencies = [
"encode_unicode",
"lazy_static 1.4.0",
"libc",
"terminal_size",
"unicode-width",
"winapi 0.3.9",
"windows-sys",
]
[[package]]
@ -323,9 +322,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.11"
version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [
"autocfg",
"cfg-if",
@ -336,9 +335,9 @@ dependencies = [
[[package]]
name = "crossbeam-queue"
version = "0.3.6"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7"
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
dependencies = [
"cfg-if",
"crossbeam-utils",
@ -346,9 +345,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
version = "0.8.12"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [
"cfg-if",
]
@ -365,9 +364,9 @@ dependencies = [
[[package]]
name = "ctor"
version = "0.1.23"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdffe87e1d521a10f9696f833fe502293ea446d7f256c06128293a4119bdf4cb"
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
dependencies = [
"quote",
"syn",
@ -390,9 +389,9 @@ dependencies = [
[[package]]
name = "digest"
version = "0.10.5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c"
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer 0.10.3",
"crypto-common",
@ -420,9 +419,9 @@ dependencies = [
[[package]]
name = "either"
version = "1.8.0"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "encode_unicode"
@ -439,7 +438,7 @@ dependencies = [
"atty",
"humantime",
"log",
"regex 1.6.0",
"regex 1.7.1",
"termcolor",
]
@ -506,9 +505,9 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.0.24"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
dependencies = [
"crc32fast",
"miniz_oxide",
@ -549,9 +548,9 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.2.7"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
@ -560,9 +559,9 @@ dependencies = [
[[package]]
name = "glob"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
@ -606,6 +605,15 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "2.1.0"
@ -614,9 +622,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "indexmap"
version = "1.9.1"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
@ -624,12 +632,13 @@ dependencies = [
[[package]]
name = "indicatif"
version = "0.17.1"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfddc9561e8baf264e0e45e197fd7696320026eb10a8180340debc27b18f535b"
checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729"
dependencies = [
"console",
"number_prefix",
"portable-atomic",
"unicode-width",
]
@ -644,9 +653,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.3"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
name = "jobserver"
@ -687,15 +696,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.134"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "libloading"
version = "0.7.3"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi 0.3.9",
@ -746,9 +755,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.6.5"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
dependencies = [
"autocfg",
]
@ -777,9 +786,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.5.4"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
"adler",
]
@ -791,7 +800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
dependencies = [
"matrixmultiply",
"num-complex 0.4.2",
"num-complex 0.4.3",
"num-integer",
"num-traits",
"rawpointer",
@ -806,7 +815,7 @@ checksum = "f85776816e34becd8bd9540818d7dc77bf28307f3b3dcc51cc82403c6931680c"
dependencies = [
"byteorder",
"ndarray",
"num-complex 0.4.2",
"num-complex 0.4.3",
"num-traits",
"py_literal",
"zip",
@ -838,9 +847,9 @@ dependencies = [
[[package]]
name = "nom"
version = "7.1.1"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr 2.5.0",
"minimal-lexical",
@ -879,9 +888,9 @@ dependencies = [
[[package]]
name = "num-complex"
version = "0.4.2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d"
dependencies = [
"num-traits",
]
@ -918,11 +927,11 @@ dependencies = [
[[package]]
name = "num_cpus"
version = "1.13.1"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
dependencies = [
"hermit-abi",
"hermit-abi 0.2.6",
"libc",
]
@ -934,9 +943,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.15.0"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "opaque-debug"
@ -961,9 +970,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pest"
version = "2.4.0"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc7bc69c062e492337d74d59b120c274fd3d261b6bf6d3207d499b4b379c41a"
checksum = "028accff104c4e513bad663bbcd2ad7cfd5304144404c31ed0a77ac103d00660"
dependencies = [
"thiserror",
"ucd-trie",
@ -971,9 +980,9 @@ dependencies = [
[[package]]
name = "pest_derive"
version = "2.4.0"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b75706b9642ebcb34dab3bc7750f811609a0eb1dd8b88c2d15bf628c1c65b2"
checksum = "2ac3922aac69a40733080f53c1ce7f91dcf57e1a5f6c52f421fadec7fbdc4b69"
dependencies = [
"pest",
"pest_generator",
@ -981,9 +990,9 @@ dependencies = [
[[package]]
name = "pest_generator"
version = "2.4.0"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f9272122f5979a6511a749af9db9bfc810393f63119970d7085fed1c4ea0db"
checksum = "d06646e185566b5961b4058dd107e0a7f56e77c3f484549fb119867773c0f202"
dependencies = [
"pest",
"pest_meta",
@ -994,26 +1003,32 @@ dependencies = [
[[package]]
name = "pest_meta"
version = "2.4.0"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8717927f9b79515e565a64fe46c38b8cd0427e64c40680b14a7365ab09ac8d"
checksum = "e6f60b2ba541577e2a0c307c8f39d1439108120eb7903adeb6497fa880c59616"
dependencies = [
"once_cell",
"pest",
"sha1",
"sha2",
]
[[package]]
name = "pkg-config"
version = "0.3.25"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "portable-atomic"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b"
[[package]]
name = "ppv-lite86"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_assertions"
@ -1038,9 +1053,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.46"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@ -1052,7 +1067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "102df7a3d46db9d3891f178dcc826dc270a6746277a9ae6436f8d29fd490a8e1"
dependencies = [
"num-bigint",
"num-complex 0.4.2",
"num-complex 0.4.3",
"num-traits",
"pest",
"pest_derive",
@ -1060,9 +1075,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.21"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
dependencies = [
"proc-macro2",
]
@ -1133,21 +1148,19 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rayon"
version = "1.5.3"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.3"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
@ -1205,13 +1218,13 @@ dependencies = [
[[package]]
name = "regex"
version = "1.6.0"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick 0.7.19",
"aho-corasick 0.7.20",
"memchr 2.5.0",
"regex-syntax 0.6.27",
"regex-syntax 0.6.28",
]
[[package]]
@ -1222,9 +1235,9 @@ checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
[[package]]
name = "regex-syntax"
version = "0.6.27"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "remove_dir_all"
@ -1275,23 +1288,24 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustfft"
version = "5.1.1"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1869bb2a6ff77380d52ff4bc631f165637035a55855c76aa462c85474dadc42f"
checksum = "e17d4f6cbdb180c9f4b2a26bbf01c4e647f1e1dea22fe8eb9db54198b32f9434"
dependencies = [
"num-complex 0.3.1",
"num-complex 0.4.3",
"num-integer",
"num-traits",
"primal-check",
"strength_reduce",
"transpose",
"version_check",
]
[[package]]
name = "ryu"
version = "1.0.11"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
name = "scopeguard"
@ -1301,18 +1315,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.145"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.145"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
dependencies = [
"proc-macro2",
"quote",
@ -1332,9 +1346,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.85"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
dependencies = [
"itoa",
"ryu",
@ -1342,14 +1356,14 @@ dependencies = [
]
[[package]]
name = "sha1"
version = "0.10.5"
name = "sha2"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.10.5",
"digest 0.10.6",
]
[[package]]
@ -1366,9 +1380,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "strength_reduce"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3ff2f71c82567c565ba4b3009a9350a96a7269eaa4001ebedae926230bc2254"
checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82"
[[package]]
name = "strsim"
@ -1396,9 +1410,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.101"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
dependencies = [
"proc-macro2",
"quote",
@ -1417,23 +1431,13 @@ dependencies = [
[[package]]
name = "termcolor"
version = "1.1.3"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
dependencies = [
"winapi-util",
]
[[package]]
name = "terminal_size"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]]
name = "textwrap"
version = "0.11.0"
@ -1445,18 +1449,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
dependencies = [
"proc-macro2",
"quote",
@ -1484,9 +1488,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.1.44"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
@ -1495,9 +1499,9 @@ dependencies = [
[[package]]
name = "transpose"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95f9c900aa98b6ea43aee227fd680550cdec726526aab8ac801549eadb25e39f"
checksum = "e6522d49d03727ffb138ae4cbc1283d3774f0d10aa7f9bf52e6784c45daf9b23"
dependencies = [
"num-integer",
"strength_reduce",
@ -1505,9 +1509,9 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "ucd-trie"
@ -1526,15 +1530,15 @@ dependencies = [
[[package]]
name = "unicode-ident"
version = "1.0.4"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
[[package]]
name = "unicode-segmentation"
version = "1.10.0"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "unicode-width"
@ -1627,6 +1631,63 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
[[package]]
name = "windows_i686_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
[[package]]
name = "windows_i686_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
name = "yansi"
version = "0.5.1"

View File

@ -1,8 +1,8 @@
[package]
name = "bliss-audio"
version = "0.6.5"
version = "0.6.6"
authors = ["Polochon-street <polochonstreet@gmx.fr>"]
edition = "2018"
edition = "2021"
license = "GPL-3.0-only"
description = "A song analysis library for making playlists"
homepage = "https://lelele.io/bliss.html"
@ -36,7 +36,7 @@ ndarray-npy = "0.8.0"
ndarray = { version = "0.15.0", features = ["rayon"] }
num_cpus = "1.13.0"
ndarray-stats = "0.5.0"
rustfft = "5.0.1"
rustfft = "6.1.0"
lazy_static = "1.4.0"
rayon = "1.5.0"
crossbeam = "0.8.0"

View File

@ -9,9 +9,9 @@ use std::env;
fn main() {
let args: Vec<String> = env::args().skip(1).collect();
for path in &args {
match Song::from_path(&path) {
match Song::from_path(path) {
Ok(song) => println!("{}: {:?}", path, song.analysis),
Err(e) => println!("{}: {}", path, e),
Err(e) => println!("{path}: {e}"),
}
}
}

View File

@ -13,8 +13,8 @@ fn main() -> Result<(), String> {
let first_path = paths.next().ok_or("Help: ./distance <song1> <song2>")?;
let second_path = paths.next().ok_or("Help: ./distance <song1> <song2>")?;
let song1 = Song::from_path(&first_path).map_err(|x| x.to_string())?;
let song2 = Song::from_path(&second_path).map_err(|x| x.to_string())?;
let song1 = Song::from_path(first_path).map_err(|x| x.to_string())?;
let song2 = Song::from_path(second_path).map_err(|x| x.to_string())?;
println!(
"d({:?}, {:?}) = {}",

View File

@ -181,7 +181,7 @@ fn main() -> Result<()> {
} else if let Some(sub_m) = matches.subcommand_matches("update") {
let config_path = sub_m.value_of("config-path").map(PathBuf::from);
let mut library: Library<Config> = Library::from_config_path(config_path)?;
library.update_library(library.song_paths()?, true)?;
library.update_library(library.song_paths()?, true, true)?;
} else if let Some(sub_m) = matches.subcommand_matches("playlist") {
let song_path = sub_m.value_of("SONG_PATH").unwrap();
let config_path = sub_m.value_of("config-path").map(PathBuf::from);
@ -196,7 +196,7 @@ fn main() -> Result<()> {
.map(|s| s.bliss_song.path.to_string_lossy().to_string())
.collect::<Vec<String>>();
for song in song_paths {
println!("{:?}", song);
println!("{song:?}");
}
}

View File

@ -199,7 +199,7 @@ fn main() -> Result<()> {
} else if let Some(sub_m) = matches.subcommand_matches("update") {
let config_path = sub_m.value_of("config-path").map(PathBuf::from);
let mut library: Library<Config> = Library::from_config_path(config_path)?;
library.update_library_extra_info(library.song_paths_info()?, true)?;
library.update_library_extra_info(library.song_paths_info()?, true, true)?;
} else if let Some(sub_m) = matches.subcommand_matches("playlist") {
let song_path = sub_m.value_of("SONG_PATH").unwrap();
let config_path = sub_m.value_of("config-path").map(PathBuf::from);
@ -219,7 +219,7 @@ fn main() -> Result<()> {
})
.collect::<Vec<(String, String)>>();
for (path, mime_type) in playlist {
println!("{} <{}>", path, mime_type,);
println!("{path} <{mime_type}>");
}
}

View File

@ -89,7 +89,7 @@ fn main() -> Result<()> {
if let Some(m) = matches.value_of("output-playlist") {
fs::write(m, playlist)?;
} else {
println!("{}", playlist);
println!("{playlist}");
}
Ok(())
}

View File

@ -53,13 +53,7 @@ impl ChromaDesc {
*/
pub fn do_(&mut self, signal: &[f32]) -> BlissResult<()> {
let mut stft = stft(signal, ChromaDesc::WINDOW_SIZE, 2205);
let tuning = estimate_tuning(
self.sample_rate as u32,
&stft,
ChromaDesc::WINDOW_SIZE,
0.01,
12,
)?;
let tuning = estimate_tuning(self.sample_rate, &stft, ChromaDesc::WINDOW_SIZE, 0.01, 12)?;
let chroma = chroma_stft(
self.sample_rate,
&mut stft,
@ -162,7 +156,7 @@ fn chroma_filter(
let n_chroma2 = (n_chroma_float / 2.0).round() as u32;
let n_chroma2_float = f64::from(n_chroma2);
let frequencies = Array::linspace(0., f64::from(sample_rate), (n_fft + 1) as usize);
let frequencies = Array::linspace(0., f64::from(sample_rate), n_fft + 1);
let mut freq_bins = frequencies;
hz_to_octs_inplace(&mut freq_bins, tuning, n_chroma);
@ -213,12 +207,12 @@ fn chroma_filter(
}
let mut b = Array::from(uninit)
.into_shape(wts.dim())
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))?;
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {e}")))?;
b.slice_mut(s![-3.., ..]).assign(&wts.slice(s![..3, ..]));
b.slice_mut(s![..-3, ..]).assign(&wts.slice(s![3.., ..]));
wts = b;
let non_aliased = (1 + n_fft / 2) as usize;
let non_aliased = 1 + n_fft / 2;
Ok(wts.slice_move(s![.., ..non_aliased]))
}
@ -308,7 +302,7 @@ fn pitch_tuning(
}
let max_index = counts
.argmax()
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))?;
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {e}")))?;
// Return the bin with the most reoccuring frequency.
Ok((-50. + (100. * resolution * max_index as f64)) / 100.)
@ -336,7 +330,7 @@ fn estimate_tuning(
let threshold: N64 = Array::from(filtered_mag.to_vec())
.quantile_axis_mut(Axis(0), n64(0.5), &Midpoint)
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))?
.map_err(|e| BlissError::AnalysisError(format!("in chroma: {e}")))?
.into_scalar();
let mut pitch = filtered_pitch
.iter()

View File

@ -64,7 +64,6 @@
//! ```
#![cfg_attr(feature = "bench", feature(test))]
#![warn(missing_docs)]
#![warn(rustdoc::missing_doc_code_examples)]
mod chroma;
pub mod cue;
#[cfg(feature = "library")]

View File

@ -123,6 +123,7 @@ use indicatif::{ProgressBar, ProgressStyle};
use log::warn;
use noisy_float::prelude::*;
use rusqlite::params;
use rusqlite::params_from_iter;
use rusqlite::Connection;
use rusqlite::OptionalExtension;
use rusqlite::Params;
@ -346,6 +347,8 @@ pub struct LibrarySong<T: Serialize + DeserializeOwned> {
// TODO a song_from_path with custom filters
// TODO "smart" playlist
// TODO should it really use anyhow errors?
// TODO make sure that the path to string is consistent
// TODO make a function that returns a list of all analyzed songs in the db
impl<Config: AppConfigTrait> Library<Config> {
/// Create a new [Library] object from the given Config struct that
/// implements the [AppConfigTrait].
@ -531,7 +534,7 @@ impl<Config: AppConfigTrait> Library<Config> {
G: DistanceMetric + Copy,
{
let first_song: LibrarySong<T> = self.song_from_path(song_path).map_err(|_| {
BlissError::ProviderError(format!("song '{}' has not been analyzed", song_path))
BlissError::ProviderError(format!("song '{song_path}' has not been analyzed"))
})?;
let mut songs = self.songs_from_library()?;
sort_by(&first_song, &mut songs, distance, |s: &LibrarySong<T>| {
@ -586,6 +589,12 @@ impl<Config: AppConfigTrait> Library<Config> {
///
/// Use this function if you don't have any extra data to bundle with each song.
///
/// Setting `delete_everything_else` to true will delete the paths that are
/// not mentionned in `paths_extra_info` from the database. If you do not
/// use it, because you only pass the new paths that need to be analyzed to
/// this function, make sure to delete yourself from the database the songs
/// that have been deleted from storage.
///
/// If your library
/// contains CUE files, pass the CUE file path only, and not individual
/// CUE track names: passing `vec![file.cue]` will add
@ -593,22 +602,36 @@ impl<Config: AppConfigTrait> Library<Config> {
pub fn update_library<P: Into<PathBuf>>(
&mut self,
paths: Vec<P>,
delete_everything_else: bool,
show_progress_bar: bool,
) -> Result<()> {
let paths_extra_info = paths.into_iter().map(|path| (path, ())).collect::<Vec<_>>();
self.update_library_convert_extra_info(paths_extra_info, show_progress_bar, |x, _, _| x)
self.update_library_convert_extra_info(
paths_extra_info,
delete_everything_else,
show_progress_bar,
|x, _, _| x,
)
}
/// Analyze and store all songs in `paths_extra_info` that haven't already
/// been analyzed, along with some extra metadata serializable, and known
/// before song analysis.
///
/// Setting `delete_everything_else` to true will delete the paths that are
/// not mentionned in `paths_extra_info` from the database. If you do not
/// use it, because you only pass the new paths that need to be analyzed to
/// this function, make sure to delete yourself from the database the songs
/// that have been deleted from storage.
pub fn update_library_extra_info<T: Serialize + DeserializeOwned, P: Into<PathBuf>>(
&mut self,
paths_extra_info: Vec<(P, T)>,
delete_everything_else: bool,
show_progress_bar: bool,
) -> Result<()> {
self.update_library_convert_extra_info(
paths_extra_info,
delete_everything_else,
show_progress_bar,
|extra_info, _, _| extra_info,
)
@ -630,9 +653,14 @@ impl<Config: AppConfigTrait> Library<Config> {
/// CUE track names: passing `vec![file.cue]` will add
/// individual tracks with the `cue_info` field set in the database.
///
/// Setting `delete_everything_else` to true will delete the paths that are
/// not mentionned in `paths_extra_info` from the database. If you do not
/// use it, because you only pass the new paths that need to be analyzed to
/// this function, make sure to delete yourself from the database the songs
/// that have been deleted from storage.
///
/// `convert_extra_info` is a function that you should specify how
/// to convert that extra info to something serializable.
// TODO have a `delete` option
pub fn update_library_convert_extra_info<
T: Serialize + DeserializeOwned,
U,
@ -640,6 +668,7 @@ impl<Config: AppConfigTrait> Library<Config> {
>(
&mut self,
paths_extra_info: Vec<(P, U)>,
delete_everything_else: bool,
show_progress_bar: bool,
convert_extra_info: fn(U, &Song, &Self) -> T,
) -> Result<()> {
@ -665,9 +694,22 @@ impl<Config: AppConfigTrait> Library<Config> {
return_value
};
let paths_to_analyze = paths_extra_info
let paths_extra_info: Vec<_> = paths_extra_info
.into_iter()
.map(|(x, y)| (x.into(), y))
.collect();
let paths: HashSet<_> = paths_extra_info.iter().map(|(p, _)| p.to_owned()).collect();
if delete_everything_else {
let paths_to_delete = existing_paths.difference(&paths);
self.delete_paths(paths_to_delete)?;
}
// Can't use hashsets because we need the extra info here too,
// and U might not be hashable.
let paths_to_analyze = paths_extra_info
.into_iter()
.filter(|(path, _)| !existing_paths.contains(path))
.collect::<Vec<(PathBuf, U)>>();
@ -843,8 +885,7 @@ impl<Config: AppConfigTrait> Library<Config> {
pb.inc(1);
}
pb.finish_with_message(format!(
"Analyzed {} song(s) successfully. {} Failure(s).",
success_count, failure_count
"Analyzed {success_count} song(s) successfully. {failure_count} Failure(s).",
));
log::info!(
@ -1016,8 +1057,7 @@ impl<Config: AppConfigTrait> Library<Config> {
.try_into()
.map_err(|_| {
BlissError::ProviderError(format!(
"song has more or less than {} features",
NUMBER_FEATURES
"song has more or less than {NUMBER_FEATURES} features",
))
})?,
};
@ -1179,7 +1219,7 @@ impl<Config: AppConfigTrait> Library<Config> {
/// Delete a song with path `song_path` from the database.
///
/// Errors out if the song is not in the database.
pub fn delete_song<P: Into<PathBuf>>(&mut self, song_path: P) -> Result<()> {
pub fn delete_path<P: Into<PathBuf>>(&mut self, song_path: P) -> Result<()> {
let song_path = song_path.into();
let count = self
.sqlite_conn
@ -1200,6 +1240,45 @@ impl<Config: AppConfigTrait> Library<Config> {
}
Ok(())
}
/// Delete a set of songs with paths `song_paths` from the database.
///
/// Will return Ok(count) even if less songs than expected were deleted from the database.
pub fn delete_paths<P: Into<PathBuf>, I: IntoIterator<Item = P>>(
&mut self,
paths: I,
) -> Result<usize> {
let song_paths: Vec<String> = paths
.into_iter()
.map(|x| x.into().to_string_lossy().to_string())
.collect();
if song_paths.is_empty() {
return Ok(0);
};
let count = self
.sqlite_conn
.lock()
.unwrap()
.execute(
&format!(
"delete from song where path in ({})",
repeat_vars(song_paths.len()),
),
params_from_iter(song_paths),
)
.map_err(|e| BlissError::ProviderError(e.to_string()))?;
Ok(count)
}
}
// Copied from
// https://docs.rs/rusqlite/latest/rusqlite/struct.ParamsFromIter.html#realistic-use-case
fn repeat_vars(count: usize) -> String {
assert_ne!(count, 0);
let mut s = "?,".repeat(count);
// Remove trailing comma
s.pop();
s
}
#[cfg(test)]
@ -1208,6 +1287,7 @@ fn data_local_dir() -> Option<PathBuf> {
}
#[cfg(test)]
// TODO refactor (especially the helper functions)
mod test {
use super::*;
use crate::{Analysis, NUMBER_FEATURES};
@ -1663,7 +1743,7 @@ mod test {
})
},
)
.expect("Song does not exist in the db.");
.expect("Song does not exist in the database");
let mut stmt = connection
.prepare(
"
@ -2031,7 +2111,7 @@ mod test {
}
#[test]
fn test_library_delete_song_non_existing() {
fn test_library_delete_path_non_existing() {
let (mut library, _temp_dir, _) = setup_test_library();
{
let connection = library.sqlite_conn.lock().unwrap();
@ -2052,11 +2132,11 @@ mod test {
.unwrap();
assert_eq!(count, 0);
}
assert!(library.delete_song("not-existing").is_err());
assert!(library.delete_path("not-existing").is_err());
}
#[test]
fn test_library_delete_song() {
fn test_library_delete_path() {
let (mut library, _temp_dir, _) = setup_test_library();
{
let connection = library.sqlite_conn.lock().unwrap();
@ -2078,7 +2158,7 @@ mod test {
assert!(count >= 1);
}
library.delete_song("/path/to/song1001").unwrap();
library.delete_path("/path/to/song1001").unwrap();
{
let connection = library.sqlite_conn.lock().unwrap();
@ -2101,6 +2181,75 @@ mod test {
}
}
#[test]
fn test_library_delete_paths() {
let (mut library, _temp_dir, _) = setup_test_library();
{
let connection = library.sqlite_conn.lock().unwrap();
let count: u32 = connection
.query_row(
"select count(*) from feature join song on song.id = feature.song_id where song.path in (?1, ?2)",
["/path/to/song1001", "/path/to/song2001"],
|row| row.get(0),
)
.unwrap();
assert!(count >= 1);
let count: u32 = connection
.query_row(
"select count(*) from song where path in (?1, ?2)",
["/path/to/song1001", "/path/to/song2001"],
|row| row.get(0),
)
.unwrap();
assert!(count >= 1);
}
library
.delete_paths(vec!["/path/to/song1001", "/path/to/song2001"])
.unwrap();
{
let connection = library.sqlite_conn.lock().unwrap();
let count: u32 = connection
.query_row(
"select count(*) from feature join song on song.id = feature.song_id where song.path in (?1, ?2)",
["/path/to/song1001", "/path/to/song2001"],
|row| row.get(0),
)
.unwrap();
assert_eq!(0, count);
let count: u32 = connection
.query_row(
"select count(*) from song where path in (?1, ?2)",
["/path/to/song1001", "/path/to/song2001"],
|row| row.get(0),
)
.unwrap();
assert_eq!(0, count);
// Make sure we did not delete everything else
let count: u32 = connection
.query_row("select count(*) from feature", [], |row| row.get(0))
.unwrap();
assert!(count >= 1);
let count: u32 = connection
.query_row("select count(*) from song", [], |row| row.get(0))
.unwrap();
assert!(count >= 1);
}
}
#[test]
fn test_library_delete_paths_empty() {
let (mut library, _temp_dir, _) = setup_test_library();
assert_eq!(library.delete_paths::<String, _>([]).unwrap(), 0);
}
#[test]
fn test_library_delete_paths_non_existing() {
let (mut library, _temp_dir, _) = setup_test_library();
assert_eq!(library.delete_paths(["not-existing"]).unwrap(), 0);
}
#[test]
fn test_analyze_paths_cue() {
let (mut library, _temp_dir, _) = setup_test_library();
@ -2307,15 +2456,17 @@ mod test {
for input in vec![
("./data/s16_mono_22_5kHz.flac", true),
("./data/s16_mono_22_5khz.flac", false),
("./data/s16_mono_22_5kHz.flac", false),
]
.into_iter()
{
let paths = vec![input.to_owned()];
library
.update_library_convert_extra_info(paths.to_owned(), false, |b, _, _| ExtraInfo {
ignore: b,
metadata_bliss_does_not_have: String::from("coucou"),
.update_library_convert_extra_info(paths.to_owned(), true, false, |b, _, _| {
ExtraInfo {
ignore: b,
metadata_bliss_does_not_have: String::from("coucou"),
}
})
.unwrap();
let song = {
@ -2339,17 +2490,18 @@ mod test {
}
}
fn _get_song_analyzed(connection: MutexGuard<Connection>, path: String) -> bool {
let mut stmt = connection
.prepare(
"
fn _get_song_analyzed(
connection: MutexGuard<Connection>,
path: String,
) -> Result<bool, RusqliteError> {
let mut stmt = connection.prepare(
"
select
analyzed from song
where song.path = ?
",
)
.unwrap();
stmt.query_row([path], |row| row.get(0)).unwrap()
)?;
stmt.query_row([path], |row| (row.get(0)))
}
#[test]
@ -2381,7 +2533,7 @@ mod test {
}
library
.update_library(vec![path.to_owned()], false)
.update_library(vec![path.to_owned()], true, false)
.unwrap();
let connection = library.sqlite_conn.lock().unwrap();
@ -2416,7 +2568,7 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
let paths = vec![
@ -2425,8 +2577,12 @@ mod test {
"/path/to/song4001",
"non-existing",
];
library.update_library(paths.to_owned(), false).unwrap();
library.update_library(paths.to_owned(), true).unwrap();
library
.update_library(paths.to_owned(), true, false)
.unwrap();
library
.update_library(paths.to_owned(), true, true)
.unwrap();
let songs = paths[..2]
.iter()
@ -2448,7 +2604,7 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
assert_eq!(
library.config.base_config_mut().features_version,
@ -2464,7 +2620,7 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
let paths = vec![
@ -2474,7 +2630,7 @@ mod test {
("non-existing", false),
];
library
.update_library_extra_info(paths.to_owned(), false)
.update_library_extra_info(paths.to_owned(), true, false)
.unwrap();
let songs = paths[..2]
.iter()
@ -2495,7 +2651,7 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
assert_eq!(
library.config.base_config_mut().features_version,
@ -2511,7 +2667,12 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that all the starting songs are there
assert!(_get_song_analyzed(connection, "/path/to/song2001".into()).unwrap());
}
let paths = vec![
@ -2521,7 +2682,7 @@ mod test {
("non-existing", false),
];
library
.update_library_convert_extra_info(paths.to_owned(), false, |b, _, _| ExtraInfo {
.update_library_convert_extra_info(paths.to_owned(), true, false, |b, _, _| ExtraInfo {
ignore: b,
metadata_bliss_does_not_have: String::from("coucou"),
})
@ -2557,7 +2718,90 @@ mod test {
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()));
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we deleted older songs
assert_eq!(
rusqlite::Error::QueryReturnedNoRows,
_get_song_analyzed(connection, "/path/to/song2001".into()).unwrap_err(),
);
}
assert_eq!(
library.config.base_config_mut().features_version,
FEATURES_VERSION
);
}
#[test]
// TODO maybe we can merge / DRY this and the function ⬆
fn test_update_convert_extra_info_do_not_delete() {
let (mut library, _temp_dir, _) = setup_test_library();
library.config.base_config_mut().features_version = 0;
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that all the starting songs are there
assert!(_get_song_analyzed(connection, "/path/to/song2001".into()).unwrap());
}
let paths = vec![
("./data/s16_mono_22_5kHz.flac", true),
("./data/s16_stereo_22_5kHz.flac", false),
("/path/to/song4001", false),
("non-existing", false),
];
library
.update_library_convert_extra_info(paths.to_owned(), false, false, |b, _, _| {
ExtraInfo {
ignore: b,
metadata_bliss_does_not_have: String::from("coucou"),
}
})
.unwrap();
let songs = paths[..2]
.iter()
.map(|(path, _)| {
let connection = library.sqlite_conn.lock().unwrap();
_library_song_from_database(connection, path)
})
.collect::<Vec<LibrarySong<ExtraInfo>>>();
let expected_songs = paths[..2]
.iter()
.zip(
vec![
ExtraInfo {
ignore: true,
metadata_bliss_does_not_have: String::from("coucou"),
},
ExtraInfo {
ignore: false,
metadata_bliss_does_not_have: String::from("coucou"),
},
]
.into_iter(),
)
.map(|((path, _extra_info), expected_extra_info)| LibrarySong {
bliss_song: Song::from_path(path).unwrap(),
extra_info: expected_extra_info,
})
.collect::<Vec<LibrarySong<ExtraInfo>>>();
assert_eq!(songs, expected_songs);
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we tried to "update" song4001 with the new features.
assert!(!_get_song_analyzed(connection, "/path/to/song4001".into()).unwrap());
}
{
let connection = library.sqlite_conn.lock().unwrap();
// Make sure that we did not delete older songs
assert!(_get_song_analyzed(connection, "/path/to/song2001".into()).unwrap());
}
assert_eq!(
library.config.base_config_mut().features_version,

View File

@ -268,7 +268,7 @@ pub fn closest_album_to_group(group: Vec<Song>, pool: Vec<Song>) -> BlissResult<
analysis
.push_row(song.analysis.as_arr1().view())
.map_err(|e| {
BlissError::ProviderError(format!("while computing distances: {}", e))
BlissError::ProviderError(format!("while computing distances: {e}"))
})?;
} else {
let mut array = Array::zeros((1, song.analysis.as_arr1().len()));
@ -370,7 +370,7 @@ where
analysis
.push_row(song.analysis.as_arr1().view())
.map_err(|e| {
BlissError::ProviderError(format!("while computing distances: {}", e))
BlissError::ProviderError(format!("while computing distances: {e}"))
})?;
} else {
let mut array = Array::zeros((1, song.analysis.as_arr1().len()));

View File

@ -158,7 +158,7 @@ impl fmt::Debug for Analysis {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut debug_struct = f.debug_struct("Analysis");
for feature in AnalysisIndex::iter() {
debug_struct.field(&format!("{:?}", feature), &self[feature]);
debug_struct.field(&format!("{feature:?}"), &self[feature]);
}
debug_struct.finish()?;
f.write_str(&format!(" /* {:?} */", &self.as_vec()))
@ -657,8 +657,7 @@ fn resample_frame(
)
.map_err(|e| {
BlissError::DecodingError(format!(
"while trying to allocate resampling context: {:?}",
e
"while trying to allocate resampling context: {e:?}",
))
})?;
let mut resampled = ffmpeg::frame::Audio::empty();
@ -680,7 +679,7 @@ fn resample_frame(
resample_context
.run(&decoded, &mut resampled)
.map_err(|e| {
BlissError::DecodingError(format!("while trying to resample song: {:?}", e))
BlissError::DecodingError(format!("while trying to resample song: {e:?}"))
})?;
push_to_sample_array(&resampled, &mut sample_array);
}
@ -691,7 +690,7 @@ fn resample_frame(
// `resampled` again?
loop {
match resample_context.flush(&mut resampled).map_err(|e| {
BlissError::DecodingError(format!("while trying to resample song: {:?}", e))
BlissError::DecodingError(format!("while trying to resample song: {e:?}"))
})? {
Some(_) => {
push_to_sample_array(&resampled, &mut sample_array);

View File

@ -48,7 +48,7 @@ impl BPMDesc {
sample_rate,
)
.map_err(|e| {
BlissError::AnalysisError(format!("error while loading aubio tempo object: {}", e))
BlissError::AnalysisError(format!("error while loading aubio tempo object: {e}"))
})?,
bpms: Vec::new(),
})
@ -56,7 +56,7 @@ impl BPMDesc {
pub fn do_(&mut self, chunk: &[f32]) -> BlissResult<()> {
let result = self.aubio_obj.do_result(chunk).map_err(|e| {
BlissError::AnalysisError(format!("aubio error while computing tempo {}", e))
BlissError::AnalysisError(format!("aubio error while computing tempo {e}"))
})?;
if result > 0. {

View File

@ -125,23 +125,20 @@ impl SpectralDesc {
centroid_aubio_desc: SpecDesc::new(SpecShape::Centroid, SpectralDesc::WINDOW_SIZE)
.map_err(|e| {
BlissError::AnalysisError(format!(
"error while loading aubio centroid object: {}",
e
"error while loading aubio centroid object: {e}",
))
})?,
rolloff_aubio_desc: SpecDesc::new(SpecShape::Rolloff, SpectralDesc::WINDOW_SIZE)
.map_err(|e| {
BlissError::AnalysisError(format!(
"error while loading aubio rolloff object: {}",
e
"error while loading aubio rolloff object: {e}",
))
})?,
phase_vocoder: PVoc::new(SpectralDesc::WINDOW_SIZE, SpectralDesc::HOP_SIZE).map_err(
|e| {
BlissError::AnalysisError(format!(
"error while loading aubio pvoc object: {}",
e
))
BlissError::AnalysisError(
format!("error while loading aubio pvoc object: {e}",),
)
},
)?,
values_centroid: Vec::new(),
@ -163,7 +160,7 @@ impl SpectralDesc {
self.phase_vocoder
.do_(chunk, fftgrain.as_mut_slice())
.map_err(|e| {
BlissError::AnalysisError(format!("error while processing aubio pv object: {}", e))
BlissError::AnalysisError(format!("error while processing aubio pv object: {e}"))
})?;
let bin = self
@ -171,8 +168,7 @@ impl SpectralDesc {
.do_result(fftgrain.as_slice())
.map_err(|e| {
BlissError::AnalysisError(format!(
"error while processing aubio centroid object: {}",
e
"error while processing aubio centroid object: {e}",
))
})?;

View File

@ -63,7 +63,7 @@ pub(crate) fn stft(signal: &[f32], window_length: usize, hop_length: usize) -> A
}
pub(crate) fn mean<T: Clone + Into<f32>>(input: &[T]) -> f32 {
input.iter().map(|x| x.clone().into() as f32).sum::<f32>() / input.len() as f32
input.iter().map(|x| x.clone().into()).sum::<f32>() / input.len() as f32
}
pub(crate) trait Normalize {
@ -112,8 +112,7 @@ pub(crate) fn geometric_mean(input: &[f32]) -> f32 {
}
let n = input.len() as u32;
((((mantissas as f32).log2() + exponents as f32) as f32) / n as f32 - (1023. + 500.) / 8.)
.exp2()
(((mantissas as f32).log2() + exponents as f32) / n as f32 - (1023. + 500.) / 8.).exp2()
}
pub(crate) fn hz_to_octs_inplace(
@ -121,7 +120,7 @@ pub(crate) fn hz_to_octs_inplace(
tuning: f64,
bins_per_octave: u32,
) -> &mut Array1<f64> {
let a440 = 440.0 * (2_f64.powf(tuning / f64::from(bins_per_octave)) as f64);
let a440 = 440.0 * 2_f64.powf(tuning / f64::from(bins_per_octave));
*frequencies /= a440 / 16.;
frequencies.mapv_inplace(f64::log2);