moving standalone mode to alsa rust direct binding crate & moving led_driver to a specific package
This commit is contained in:
Generated
+234
-424
@@ -141,7 +141,47 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.71.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.72.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -162,6 +202,12 @@ version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
@@ -184,10 +230,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -215,6 +264,17 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.3"
|
||||
@@ -222,13 +282,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
name = "colored"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
"lazy_static",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -237,46 +297,6 @@ version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "coreaudio-rs"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aae284fbaf7d27aa0e292f7677dfbe26503b0d555026f702940805a630eac17"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"objc2-audio-toolbox",
|
||||
"objc2-core-audio",
|
||||
"objc2-core-audio-types",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpal"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbd307f43cc2a697e2d1f8bc7a1d824b5269e052209e28883e5bc04d095aaa3f"
|
||||
dependencies = [
|
||||
"alsa",
|
||||
"coreaudio-rs",
|
||||
"dasp_sample",
|
||||
"jni",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"mach2",
|
||||
"ndk",
|
||||
"ndk-context",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"objc2-audio-toolbox",
|
||||
"objc2-core-audio",
|
||||
"objc2-core-audio-types",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam"
|
||||
version = "0.8.4"
|
||||
@@ -344,21 +364,21 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dasp_sample"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f"
|
||||
|
||||
[[package]]
|
||||
name = "dispatch2"
|
||||
name = "drawille"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
|
||||
checksum = "e64e461c3f1e69d99372620640b3fd5f0309eeda2e26e4af69f6760c0e1df845"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"objc2",
|
||||
"colored",
|
||||
"fnv",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.3"
|
||||
@@ -383,10 +403,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
name = "float-cmp"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
@@ -395,10 +424,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
@@ -412,7 +441,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -424,22 +453,21 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jiff"
|
||||
version = "0.2.14"
|
||||
@@ -464,28 +492,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.77"
|
||||
@@ -496,25 +502,58 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "led_driver"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen 0.72.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
|
||||
[[package]]
|
||||
name = "lightsabre_backend"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"alsa",
|
||||
"artnet_protocol",
|
||||
"cpal",
|
||||
"bindgen 0.71.1",
|
||||
"crossbeam",
|
||||
"ctrlc",
|
||||
"env_logger",
|
||||
"led_driver",
|
||||
"log",
|
||||
"nix 0.30.1",
|
||||
"rpi-mailbox",
|
||||
"rppal",
|
||||
"spectrum-analyzer",
|
||||
"textplots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -533,15 +572,6 @@ version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
@@ -557,6 +587,23 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "microfft"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2b6673eb0cc536241d6734c2ca45abfdbf90e9e7791c66a36a7ba3c315b76cf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"num-complex",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
@@ -577,35 +624,6 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk-context"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
|
||||
|
||||
[[package]]
|
||||
name = "ndk-sys"
|
||||
version = "0.6.0+11769913"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873"
|
||||
dependencies = [
|
||||
"jni-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
@@ -632,14 +650,22 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -651,100 +677,6 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a"
|
||||
dependencies = [
|
||||
"num_enum_derive",
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_enum_derive"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551"
|
||||
dependencies = [
|
||||
"objc2-encode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-audio-toolbox"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10cbe18d879e20a4aea544f8befe38bcf52255eb63d3f23eca2842f3319e4c07"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"libc",
|
||||
"objc2",
|
||||
"objc2-core-audio",
|
||||
"objc2-core-audio-types",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-audio"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca44961e888e19313b808f23497073e3f6b3c22bb485056674c8b49f3b025c82"
|
||||
dependencies = [
|
||||
"dispatch2",
|
||||
"objc2",
|
||||
"objc2-core-audio-types",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-audio-types"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0f1cc99bb07ad2ddb6527ddf83db6a15271bb036b3eb94b801cd44fdc666ee1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"dispatch2",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-encode"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
|
||||
|
||||
[[package]]
|
||||
name = "objc2-foundation"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c"
|
||||
dependencies = [
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
@@ -786,9 +718,15 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
@@ -823,12 +761,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.3.0"
|
||||
name = "prettyplease"
|
||||
version = "0.2.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
|
||||
checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -887,6 +826,15 @@ version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpi-mailbox"
|
||||
version = "0.3.0"
|
||||
@@ -922,21 +870,18 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -994,6 +939,24 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spectrum-analyzer"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f5353405212be77e7f9e95aa77934f0aafb0f80c586571680b9c20ce5bae758"
|
||||
dependencies = [
|
||||
"float-cmp",
|
||||
"libm",
|
||||
"microfft",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
@@ -1005,6 +968,16 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textplots"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f7657a0066c9f9663659db0665319adff8b0943305fc73eddf1010e5a2072b1"
|
||||
dependencies = [
|
||||
"drawille",
|
||||
"rgb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
@@ -1054,23 +1027,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
@@ -1083,16 +1039,6 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
@@ -1125,19 +1071,6 @@ dependencies = [
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.100"
|
||||
@@ -1170,45 +1103,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.54.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
|
||||
dependencies = [
|
||||
"windows-core 0.54.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.54.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
|
||||
dependencies = [
|
||||
"windows-result 0.1.2",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.61.2"
|
||||
@@ -1218,7 +1112,7 @@ dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result 0.3.4",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
@@ -1250,15 +1144,6 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
@@ -1277,22 +1162,13 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets 0.42.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1301,22 +1177,7 @@ version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.2",
|
||||
"windows_aarch64_msvc 0.42.2",
|
||||
"windows_i686_gnu 0.42.2",
|
||||
"windows_i686_msvc 0.42.2",
|
||||
"windows_x86_64_gnu 0.42.2",
|
||||
"windows_x86_64_gnullvm 0.42.2",
|
||||
"windows_x86_64_msvc 0.42.2",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1325,46 +1186,28 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
@@ -1377,59 +1220,26 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
+5
-1
@@ -1,3 +1,7 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["lightsabre_backend", "rust_sandbox"]
|
||||
members = [
|
||||
"lightsabre_backend/led_driver",
|
||||
"lightsabre_backend/system",
|
||||
"rust_sandbox",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# LightSabre
|
||||
|
||||
LightSabre is a project designed to control WS281x RGB LEDs using the Secondary Memory Interface (SMI) of a Raspberry Pi, tailored for scenographic and lighting applications.
|
||||
LightSabre is a project designed to control WS281x RGB LEDs using the Secondary Memory Interface (SMI) of a Raspberry Pi, tailored for scenography and lighting applications.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -42,8 +42,8 @@ What about Realtime ?
|
||||
`sudo raspi-config`
|
||||
|
||||
See. `nmcli`
|
||||
`nmcli c up preconfigured`
|
||||
|
||||
`nmcli c up preconfigured`
|
||||
|
||||
|
||||
#### Rust
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
fn main() {
|
||||
println!("cargo::rustc-link-search=/workspaces/LightSabre/lightsabre_backend/drivers/lib/");
|
||||
// println!("cargo:rustc-link-search=/workspaces/LightSabre/lightsabre_backend/drivers/lib");
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "led_driver"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.72.0"
|
||||
@@ -0,0 +1,26 @@
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
fn main() {
|
||||
println!("cargo::rustc-link-search=/workspaces/LightSabre/lightsabre_backend/led_driver/lib");
|
||||
|
||||
// Tell cargo to tell rustc to link the RPiLedBars_drivers and logc libraries.
|
||||
println!("cargo:rustc-link-lib=RpiLedBars_drivers_8ch");
|
||||
println!("cargo:rustc-link-lib=logc");
|
||||
|
||||
// The bindgen::Builder is the main entry point to bindgen, and lets you build up options for the resulting bindings.
|
||||
let bindings = bindgen::Builder::default()
|
||||
// The input header we would like to generate bindings for.
|
||||
.header("lib/wrapper.h")
|
||||
// Tell cargo to invalidate the built crate whenever any of the included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
dest_path=${0%/*}/lib
|
||||
source_host=${1:-raspberrypi.local}
|
||||
|
||||
|
||||
scp \
|
||||
raspberrypi.local:RpiLedBars/backend/.build/src/drivers/libRpiLedBars_drivers.a \
|
||||
${dest_path}/bin/libRpiLedBars_drivers_8ch.a
|
||||
|
||||
scp \
|
||||
raspberrypi.local:RpiLedBars/backend/.build/_deps/logc-build/liblogc.a \
|
||||
${dest_path}/bin/liblogc.a
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
#include "include/log.h"
|
||||
#include "src/leddriver/rpi_leddriver.h"
|
||||
#include "src/common.h"
|
||||
|
||||
#define CHAN_MAXLEDS 60 // Maximum number of LEDs per channel
|
||||
#define LED_NCHANS 8 // Number of LED channels (8 or 16)
|
||||
|
||||
#define TX_TEST 0 // If non-zero, use dummy Tx data
|
||||
#define LED_NBITS 24 // Number of data bits per LED
|
||||
#define LED_PREBITS 4 // Number of zero bits before LED data
|
||||
#define LED_POSTBITS 4 // Number of zero bits after LED data
|
||||
#define BIT_NPULSES 3 // Number of O/P pulses per LED bit
|
||||
|
||||
// Length of data for 1 row (1 LED on each channel)
|
||||
#define LED_DLEN (LED_NBITS * BIT_NPULSES)
|
||||
|
||||
// Transmit data type, 8 or 16 bits
|
||||
#if LED_NCHANS > 8
|
||||
typedef uint16_t TXDATA_T;
|
||||
#else
|
||||
typedef uint8_t TXDATA_T;
|
||||
#endif
|
||||
|
||||
// Ofset into Tx data buffer, given LED number in chan
|
||||
#define LED_TX_OSET(n) (LED_PREBITS + (LED_DLEN * (n)))
|
||||
|
||||
// Size of data buffers & NV memory, given number of LEDs per chan
|
||||
#define TX_BUFF_LEN(n) (LED_TX_OSET(n) + LED_POSTBITS)
|
||||
#define TX_BUFF_SIZE(n) (TX_BUFF_LEN(n) * sizeof(TXDATA_T))
|
||||
#define VC_MEM_SIZE (PAGE_SIZE + TX_BUFF_SIZE(CHAN_MAXLEDS))
|
||||
|
||||
extern TXDATA_T tx_buffer[TX_BUFF_LEN(CHAN_MAXLEDS)];
|
||||
extern TXDATA_T *txdata;
|
||||
extern MEM_MAP vc_mem;
|
||||
@@ -0,0 +1,159 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
pub struct LedDriver {
|
||||
led_per_strip_count: usize,
|
||||
strip_count: usize,
|
||||
}
|
||||
|
||||
// Offset into Tx data buffer, given LED number in chan
|
||||
macro_rules! LED_TX_OSET {
|
||||
($n:expr) => {
|
||||
LED_PREBITS + (LED_DLEN * $n)
|
||||
};
|
||||
}
|
||||
|
||||
impl LedDriver {
|
||||
const LED_NCHANS: usize = LED_NCHANS as usize; // Number of channels (strips)
|
||||
const TX_TEST: usize = TX_TEST as usize; // If non-zero, use dummy Tx data
|
||||
const LED_NBITS: usize = LED_NBITS as usize; // Number of data bits per LED
|
||||
pub const LED_PREBITS: usize = LED_PREBITS as usize; // Number of zero bits before LED data
|
||||
const LED_POSTBITS: usize = LED_POSTBITS as usize; // Number of zero bits after LED data
|
||||
const BIT_NPULSES: usize = BIT_NPULSES as usize; // Number of O/P pulses per LED bit
|
||||
|
||||
// Length of data for 1 row (1 LED on each channel)
|
||||
pub const LED_DLEN: usize = Self::LED_NBITS * Self::BIT_NPULSES;
|
||||
|
||||
pub fn new(led_per_strip_count: usize, strip_count: usize) -> LedDriver {
|
||||
unsafe { leddriver_setup() };
|
||||
LedDriver {
|
||||
led_per_strip_count,
|
||||
strip_count,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_led_per_strip_count(&self) -> usize {
|
||||
self.led_per_strip_count
|
||||
}
|
||||
|
||||
pub fn get_strip_count(&self) -> usize {
|
||||
self.strip_count
|
||||
}
|
||||
|
||||
pub fn set_color(&self, rgb: u32, index: usize) {
|
||||
unsafe { set_color(rgb, index as i32) };
|
||||
}
|
||||
|
||||
pub fn set_color_till_led(&self, color: u32, led_num: usize) {
|
||||
let led_num = led_num.min(self.get_led_per_strip_count());
|
||||
// Set color for all strips
|
||||
for led_index in 0..=led_num {
|
||||
self.direct_set_color(color, led_index);
|
||||
}
|
||||
for led in led_num + 1..self.get_led_per_strip_count() {
|
||||
self.direct_set_color(0x000000, led);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn direct_set_color(&self, rgb: u32, index: usize) {
|
||||
let mut mask = 0_u32;
|
||||
let mut offset = LED_TX_OSET!(index as u32) as usize;
|
||||
|
||||
// For each bit of the 24-bit RGB values..
|
||||
for n in 0..Self::LED_NBITS {
|
||||
let tx_data = unsafe { &mut tx_buffer[offset..offset + Self::BIT_NPULSES] };
|
||||
// Mask to convert RGB to GRB, M.S bit first
|
||||
Self::compute_mask(&mut mask, n);
|
||||
|
||||
// 1st byte or word is a high pulse on all lines
|
||||
tx_data[0] = 0xff;
|
||||
// 2nd has high or low bits from data
|
||||
tx_data[1] = if rgb & mask != 0_u32 { 0xff } else { 0x00 };
|
||||
// 3rd is a low pulse
|
||||
tx_data[2] = 0x00;
|
||||
offset += Self::BIT_NPULSES;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_led_color(&self, rgb: u32, led_index: usize, strip_index: usize) {
|
||||
let mut mask = 0_u32;
|
||||
let mut offset = LED_TX_OSET!(led_index as u32) as usize;
|
||||
let strip_mask = !(0b1_u8 << strip_index); // Mask to clear the led bit of desired strip
|
||||
|
||||
// For each bit of the 24-bit RGB values..
|
||||
for n in 0..Self::LED_NBITS {
|
||||
let tx_data = unsafe { &mut tx_buffer[offset..offset + Self::BIT_NPULSES] };
|
||||
// Mask to convert RGB to GRB, M.S bit first
|
||||
Self::compute_mask(&mut mask, n);
|
||||
|
||||
// 1st byte or word is a high pulse on all lines
|
||||
tx_data[0] = 0xff;
|
||||
// 2nd has high or low bits from data
|
||||
tx_data[1] = tx_data[1] & strip_mask
|
||||
| if rgb & mask != 0_u32 {
|
||||
0b1 << strip_index
|
||||
} else {
|
||||
0x00
|
||||
};
|
||||
// 3rd is a low pulse
|
||||
tx_data[2] = 0x00;
|
||||
offset += Self::BIT_NPULSES;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_strip_index_colors(&self, rgb: [u32; Self::LED_NCHANS], led_index: usize) {
|
||||
let mut mask = 0_u32;
|
||||
let mut offset = LED_TX_OSET!(led_index as u32) as usize;
|
||||
|
||||
// For each bit of the 24-bit RGB values..
|
||||
for n in 0..Self::LED_NBITS {
|
||||
let tx_data = unsafe { &mut tx_buffer[offset..offset + Self::BIT_NPULSES] };
|
||||
// Mask to convert RGB to GRB, M.S bit first
|
||||
Self::compute_mask(&mut mask, n);
|
||||
|
||||
// 1st byte or word is a high pulse on all lines
|
||||
tx_data[offset] = 0xff;
|
||||
tx_data[offset + 1] = 0x00; // Clear the strip bits first
|
||||
// 2nd has high or low bits from data
|
||||
for (strip_index, rgb) in rgb.iter().enumerate() {
|
||||
if rgb & mask != 0_u32 {
|
||||
// Set the bit for this strip
|
||||
tx_data[offset + 1] |= 0b1 << strip_index;
|
||||
}
|
||||
}
|
||||
// 3rd is a low pulse
|
||||
tx_data[offset + 2] = 0x00;
|
||||
offset += Self::BIT_NPULSES;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn refresh(&self) {
|
||||
unsafe { leddriver_refresh() };
|
||||
}
|
||||
|
||||
// pub fn color_hsv(&self, hue: u16, sat: u8, val: u8) -> u32 {
|
||||
// unsafe { ColorHSV(hue, sat, val) }
|
||||
// }
|
||||
|
||||
fn compute_mask(mask: &mut u32, n: usize) {
|
||||
*mask = if n == 0 {
|
||||
0x800000
|
||||
} else if n == 8 {
|
||||
0x8000
|
||||
} else if n == 16 {
|
||||
0x80
|
||||
} else {
|
||||
*mask >> 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for LedDriver {
|
||||
fn drop(&mut self) {
|
||||
unsafe { leddriver_close() };
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
use cpal::traits::{DeviceTrait, HostTrait};
|
||||
use rppal::gpio::Gpio;
|
||||
|
||||
use crate::cputasks::modes::AppModeHandler;
|
||||
use crate::devices::led_driver::LedDriver;
|
||||
|
||||
pub struct StandaloneMode {
|
||||
_i2s_mic_pin: Vec<rppal::gpio::IoPin>,
|
||||
}
|
||||
|
||||
impl StandaloneMode {
|
||||
const I2S_PINS: [u8; 3] = [20, 19, 18];
|
||||
|
||||
pub fn new() -> Self {
|
||||
let gpio = Gpio::new().expect("Failed to initialize GPIO");
|
||||
let i2s_mic_pin: Vec<rppal::gpio::IoPin> = Self::I2S_PINS
|
||||
.iter()
|
||||
.map(|&pin| {
|
||||
gpio.get(pin)
|
||||
.expect(&format!("Failed to get GPIO pin {}", pin))
|
||||
.into_io(rppal::gpio::Mode::Alt0)
|
||||
})
|
||||
.collect();
|
||||
StandaloneMode {
|
||||
_i2s_mic_pin: i2s_mic_pin,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AppModeHandler for StandaloneMode {
|
||||
fn enter(&mut self) {
|
||||
log::debug!("[Standalone] Entering Standalone Mode");
|
||||
let host = cpal::default_host();
|
||||
|
||||
// default_input_device()
|
||||
host.devices()
|
||||
.unwrap()
|
||||
.for_each(|device| log::info!("{:?}", device.name()));
|
||||
|
||||
if let Some(device) = host
|
||||
.input_devices()
|
||||
.unwrap()
|
||||
.find(|device| device.name() == Ok(String::from("snd_rpi_googlevoicehat_soundcar")))
|
||||
{
|
||||
log::info!("Found record device {:?}", device.name());
|
||||
log::info!("Default config : {:?}", device.default_input_config())
|
||||
} else {
|
||||
log::error!("Record device not found");
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&mut self, _: &mut LedDriver) {
|
||||
log::trace!("[Standalone] Running...");
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
log::debug!("[Standalone] Exiting Standalone Mode");
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#[link(name = "logc", kind = "static")]
|
||||
unsafe extern "C" {
|
||||
unsafe fn log_log(level: u32, file: *const u8, line: i32, fmt: *const u8, ...);
|
||||
}
|
||||
|
||||
#[link(name = "RpiLedBars_drivers", kind = "static")]
|
||||
unsafe extern "C" {
|
||||
|
||||
unsafe fn leddriver_setup();
|
||||
|
||||
unsafe fn leddriver_close();
|
||||
|
||||
unsafe fn set_color(rgb: u32, index: usize);
|
||||
|
||||
// unsafe fn rgb_txdata(rgbs: *mut u32, index: usize);
|
||||
|
||||
unsafe fn leddriver_refresh();
|
||||
|
||||
// unsafe fn ColorHSV(hue: u16, sat: u8, val: u8) -> u32;
|
||||
}
|
||||
|
||||
pub struct LedDriver {
|
||||
led_per_strips: usize,
|
||||
}
|
||||
|
||||
impl LedDriver {
|
||||
pub fn new(led_per_strips: usize) -> LedDriver {
|
||||
unsafe {
|
||||
log_log(
|
||||
0,
|
||||
"coucou".as_bytes().as_ptr(),
|
||||
13,
|
||||
"hello".as_bytes().as_ptr(),
|
||||
)
|
||||
};
|
||||
unsafe { leddriver_setup() };
|
||||
LedDriver { led_per_strips }
|
||||
}
|
||||
|
||||
pub fn get_led_per_strips(&self) -> usize {
|
||||
self.led_per_strips
|
||||
}
|
||||
|
||||
pub fn set_color(&self, rgb: u32, index: usize) {
|
||||
unsafe { set_color(rgb, index) };
|
||||
}
|
||||
|
||||
pub fn refresh(&self) {
|
||||
unsafe { leddriver_refresh() };
|
||||
}
|
||||
|
||||
// pub fn color_hsv(&self, hue: u16, sat: u8, val: u8) -> u32 {
|
||||
// unsafe { ColorHSV(hue, sat, val) }
|
||||
// }
|
||||
}
|
||||
|
||||
impl Drop for LedDriver {
|
||||
fn drop(&mut self) {
|
||||
unsafe { leddriver_close() };
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,8 @@ version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
alsa = "0.9.1"
|
||||
artnet_protocol = "0.4.3"
|
||||
cpal = "0.16.0"
|
||||
crossbeam = "0.8.4"
|
||||
ctrlc = { version = "3.4.7", features = ["termination"] }
|
||||
env_logger = "0.11.8"
|
||||
@@ -13,6 +13,12 @@ log = "0.4.27"
|
||||
nix = "0.30.1"
|
||||
rpi-mailbox = "0.3.0"
|
||||
rppal = "0.22.1"
|
||||
spectrum-analyzer = "1.7.0"
|
||||
textplots = "0.8.7"
|
||||
led_driver = { path = "../led_driver" }
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.71.0"
|
||||
|
||||
[features]
|
||||
default = ["rpizero2", "16channel"]
|
||||
+3
-3
@@ -14,9 +14,9 @@ use crate::channels::Message;
|
||||
use crate::devices::led_driver::LedDriver;
|
||||
|
||||
pub trait AppModeHandler {
|
||||
fn enter(&mut self);
|
||||
fn run(&mut self, led_driver: &mut LedDriver);
|
||||
fn exit(&mut self);
|
||||
fn enter(&mut self) -> Result<(), Box<dyn std::error::Error>>;
|
||||
fn run(&mut self, led_driver: &mut LedDriver) -> Result<(), Box<dyn std::error::Error>>;
|
||||
fn exit(&mut self) -> Result<(), Box<dyn std::error::Error>>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
+9
-7
@@ -20,7 +20,7 @@ impl ArtNetMode {
|
||||
}
|
||||
|
||||
impl AppModeHandler for ArtNetMode {
|
||||
fn enter(&mut self) {
|
||||
fn enter(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[ArtNet] Entering ArtNet Mode");
|
||||
|
||||
let mut attempts = 0_usize;
|
||||
@@ -41,9 +41,10 @@ impl AppModeHandler for ArtNetMode {
|
||||
socket.set_nonblocking(true).unwrap();
|
||||
self.socket = Some(socket);
|
||||
log::debug!("[ArtNet] ArtNet Mode initialized and listening on port 6454");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self, led_driver: &mut LedDriver) {
|
||||
fn run(&mut self, led_driver: &mut LedDriver) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::trace!("[ArtNet] Running...");
|
||||
let buf = &mut [0; 530];
|
||||
let mut is_first_data_frame = true;
|
||||
@@ -109,8 +110,9 @@ impl AppModeHandler for ArtNetMode {
|
||||
is_first_data_frame = false;
|
||||
}
|
||||
|
||||
let led_strip = (u16::from(output.port_address) & 0b0111_u16) as usize;
|
||||
//output.port_address
|
||||
for i in 0..led_driver.get_led_per_strips() {
|
||||
for i in 0..led_driver.get_led_per_strip_count() {
|
||||
let data_index = i * 3;
|
||||
let g = *output.data.as_ref().get(data_index).unwrap_or(&0);
|
||||
let r = *output.data.as_ref().get(data_index + 1).unwrap_or(&0);
|
||||
@@ -118,11 +120,9 @@ impl AppModeHandler for ArtNetMode {
|
||||
// let color = (r as u32) << 16 + (g as u32) << 8 + b;
|
||||
let color: u32 =
|
||||
((r as u32) << 16) | ((g as u32) << 8) | (b as u32);
|
||||
led_driver.set_color(color, i);
|
||||
led_driver.direct_set_color(color, i);
|
||||
}
|
||||
led_driver.refresh();
|
||||
// Here you would typically handle the output data, e.g., send it to the LED driver
|
||||
// For now, we just log it
|
||||
}
|
||||
ArtCommand::PollReply(_) => {
|
||||
log::trace!("[ArtNet] Received PollReply command, ignoring");
|
||||
@@ -139,14 +139,16 @@ impl AppModeHandler for ArtNetMode {
|
||||
Err(e) => panic!("encountered IO error: {e}"),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
fn exit(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[ArtNet] Exiting ArtNet Mode");
|
||||
log::info!("[ArtNet] Statistics: {}", self.statistics);
|
||||
self.socket = None;
|
||||
self.last_frame_time = None;
|
||||
self.statistics = ArtNetModeStatistics::default();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+13
-7
@@ -30,22 +30,24 @@ impl DiagnosticsMode {
|
||||
|
||||
fn init_led_iterator(led_driver: &LedDriver) -> Range<usize> {
|
||||
// Initialize the LED iterator to cover all LEDs
|
||||
0..led_driver.get_led_per_strips()
|
||||
0..led_driver.get_led_per_strip_count()
|
||||
}
|
||||
}
|
||||
|
||||
impl AppModeHandler for DiagnosticsMode {
|
||||
fn enter(&mut self) {
|
||||
fn enter(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[Diagnostics] Entering Diagnostics Mode");
|
||||
self.cycle_count = 0;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self, led_driver: &mut LedDriver) {
|
||||
fn run(&mut self, led_driver: &mut LedDriver) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if self.cycle_count % 50 == 0 {
|
||||
log::trace!("[Diagnostics] Running...");
|
||||
let (led, color) = match self.led_iterator.next() {
|
||||
Some(led) => {
|
||||
led_driver.set_color(**self.color_iterator.peek().unwrap(), led);
|
||||
// led_driver.direct_set_color(**self.color_iterator.peek().unwrap(), led);
|
||||
led_driver.set_led_color(**self.color_iterator.peek().unwrap(), led, 0);
|
||||
(led, *self.color_iterator.peek().unwrap())
|
||||
}
|
||||
None => {
|
||||
@@ -57,14 +59,16 @@ impl AppModeHandler for DiagnosticsMode {
|
||||
led,
|
||||
match self.color_iterator.peek() {
|
||||
Some(color) => {
|
||||
led_driver.set_color(**color, led);
|
||||
// led_driver.direct_set_color(**color, led);
|
||||
led_driver.set_led_color(**color, led, 0);
|
||||
*color
|
||||
}
|
||||
None => {
|
||||
// Reset the color iterator if it reaches the end
|
||||
self.color_iterator = DiagnosticsMode::color_iterator();
|
||||
let color = self.color_iterator.peek().unwrap();
|
||||
led_driver.set_color(**color, led);
|
||||
// led_driver.direct_set_color(**color, led);
|
||||
led_driver.set_led_color(**color, led, 0);
|
||||
*color
|
||||
}
|
||||
},
|
||||
@@ -75,9 +79,11 @@ impl AppModeHandler for DiagnosticsMode {
|
||||
led_driver.refresh();
|
||||
}
|
||||
self.cycle_count += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
fn exit(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[Diagnostics] Exiting Diagnostics Mode");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
+9
-3
@@ -10,15 +10,21 @@ impl ManualMode {
|
||||
}
|
||||
|
||||
impl AppModeHandler for ManualMode {
|
||||
fn enter(&mut self) {
|
||||
fn enter(&mut self) -> std::result::Result<(), Box<(dyn std::error::Error + 'static)>> {
|
||||
log::debug!("[Manual] Entering Manual Mode");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self, _: &mut LedDriver) {
|
||||
fn run(
|
||||
&mut self,
|
||||
_: &mut LedDriver,
|
||||
) -> std::result::Result<(), Box<(dyn std::error::Error + 'static)>> {
|
||||
log::trace!("[Manual] Running...");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(&mut self) {
|
||||
fn exit(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[Manual] Exiting Manual Mode");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
use core::f32;
|
||||
use crossbeam::channel;
|
||||
use spectrum_analyzer::windows::hann_window;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::thread;
|
||||
use std::time::Instant;
|
||||
|
||||
use rppal::gpio::Gpio;
|
||||
use spectrum_analyzer::scaling::divide_by_N_sqrt;
|
||||
use spectrum_analyzer::{FrequencyLimit, FrequencyValue, samples_fft_to_spectrum};
|
||||
|
||||
use crate::cputasks::modes::AppModeHandler;
|
||||
use crate::devices::led_driver::LedDriver;
|
||||
|
||||
pub struct StandaloneMode {
|
||||
_i2s_mic_pin: Vec<rppal::gpio::IoPin>,
|
||||
audio_processor: Option<AudioProcessorControl>,
|
||||
}
|
||||
|
||||
impl StandaloneMode {
|
||||
const I2S_PINS: [u8; 3] = [20, 19, 18];
|
||||
|
||||
pub fn new() -> Self {
|
||||
let gpio = Gpio::new().expect("Failed to initialize GPIO");
|
||||
let i2s_mic_pin: Vec<rppal::gpio::IoPin> = Self::I2S_PINS
|
||||
.iter()
|
||||
.map(|&pin| {
|
||||
gpio.get(pin)
|
||||
.expect(&format!("Failed to get GPIO pin {}", pin))
|
||||
.into_io(rppal::gpio::Mode::Alt0)
|
||||
})
|
||||
.collect();
|
||||
StandaloneMode {
|
||||
_i2s_mic_pin: i2s_mic_pin,
|
||||
audio_processor: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_log_spectrum(
|
||||
fft_data: &[(f32, f32)],
|
||||
strip_count: usize,
|
||||
f_min: f32,
|
||||
f_max: f32,
|
||||
) -> Vec<f32> {
|
||||
let mut bands = vec![0.0; strip_count];
|
||||
let mut counts = vec![0usize; strip_count];
|
||||
|
||||
// Precompute band edges logarithmically
|
||||
let mut edges = Vec::with_capacity(strip_count + 1);
|
||||
for i in 0..=strip_count {
|
||||
let fraction = i as f32 / strip_count as f32;
|
||||
let edge = f_min * (f_max / f_min).powf(fraction);
|
||||
edges.push(edge);
|
||||
}
|
||||
|
||||
// Assign each frequency to a band
|
||||
for &(freq, amp) in fft_data {
|
||||
if freq < f_min || freq > f_max {
|
||||
continue;
|
||||
}
|
||||
if let Some(idx) = edges.windows(2).position(|w| freq >= w[0] && freq < w[1]) {
|
||||
bands[idx] += amp;
|
||||
counts[idx] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize
|
||||
for (b, c) in bands.iter_mut().zip(counts) {
|
||||
if c > 0 {
|
||||
*b /= c as f32;
|
||||
}
|
||||
}
|
||||
|
||||
bands
|
||||
}
|
||||
}
|
||||
|
||||
impl AppModeHandler for StandaloneMode {
|
||||
fn enter(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[Standalone] Entering Standalone Mode");
|
||||
let audio_processor = AudioProcessorControl::new()?;
|
||||
self.audio_processor = Some(audio_processor);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&mut self, led_driver: &mut LedDriver) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::trace!("[Standalone] Running...");
|
||||
if let Some(audio_processor) = &self.audio_processor {
|
||||
match audio_processor.get_data() {
|
||||
Some(data) => {
|
||||
log::trace!("[Standalone] Received audio data: {:?}", data.len());
|
||||
|
||||
log::info!(
|
||||
"Frequency count: {} MAX([|{}; {}|]) -> {:?}",
|
||||
data.len(),
|
||||
data[0].0,
|
||||
data[data.len() - 1].0,
|
||||
data.iter()
|
||||
.fold((0_f32, 0_f32), |(freq_max, val_max), (freq, val)| {
|
||||
if *val >= val_max {
|
||||
(*freq, *val)
|
||||
} else {
|
||||
(freq_max, val_max)
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
let spectrum = StandaloneMode::compute_log_spectrum(
|
||||
&data,
|
||||
led_driver.get_strip_count(),
|
||||
data[0].0,
|
||||
data[data.len() - 1].0,
|
||||
);
|
||||
|
||||
log::debug!(
|
||||
"[Standalone] Computed spectrum: {:?}",
|
||||
spectrum
|
||||
.iter()
|
||||
.map(|v| v.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
);
|
||||
|
||||
let avg_intensity = spectrum.iter().fold(0_f32, |x_max, x| x_max.max(*x));
|
||||
|
||||
let g = avg_intensity.min(255.0) as u8;
|
||||
let r = 0_u8;
|
||||
let b = 255 - avg_intensity.min(255.0) as u8;
|
||||
let color: u32 = ((r as u32) << 16) | ((g as u32) << 8) | (b as u32);
|
||||
|
||||
let light_number =
|
||||
(avg_intensity as usize / 50).min(led_driver.get_led_per_strip_count());
|
||||
|
||||
log::debug!(
|
||||
"[Standalone] Average intensity: {}, Color: {:06x}, Light number: {}",
|
||||
avg_intensity,
|
||||
color,
|
||||
light_number
|
||||
);
|
||||
|
||||
for i in 0..light_number {
|
||||
// Set the color for the first `light_number` LEDs
|
||||
led_driver.direct_set_color(color, i);
|
||||
}
|
||||
for i in light_number..led_driver.get_led_per_strip_count() {
|
||||
// Set the remaining LEDs to black
|
||||
led_driver.direct_set_color(0x000000, i);
|
||||
}
|
||||
led_driver.refresh();
|
||||
}
|
||||
None => {
|
||||
log::trace!("[Standalone] No audio data received");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("[Standalone] Audio processor is not initialized");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn exit(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::debug!("[Standalone] Exiting Standalone Mode");
|
||||
self.audio_processor = None;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct AudioProcessorControl {
|
||||
rx: channel::Receiver<Vec<(f32, f32)>>,
|
||||
stop_flag: Arc<AtomicBool>,
|
||||
handle: Option<std::thread::JoinHandle<()>>,
|
||||
}
|
||||
|
||||
impl AudioProcessorControl {
|
||||
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let stop_flag = Arc::new(AtomicBool::new(false));
|
||||
let flag_clone = Arc::clone(&stop_flag);
|
||||
|
||||
let (tx, rx): (
|
||||
channel::Sender<Vec<(f32, f32)>>,
|
||||
channel::Receiver<Vec<(f32, f32)>>,
|
||||
) = crossbeam::channel::bounded(1);
|
||||
|
||||
let mut audio_processor = AudioProcessor::new(tx)?;
|
||||
let join_handle = thread::spawn(move || {
|
||||
log::info!("Starting audio processing thread");
|
||||
while !flag_clone.load(Ordering::Relaxed) {
|
||||
audio_processor.process_audio();
|
||||
}
|
||||
});
|
||||
Ok(AudioProcessorControl {
|
||||
rx,
|
||||
stop_flag,
|
||||
handle: Some(join_handle),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_data(&self) -> Option<Vec<(f32, f32)>> {
|
||||
match self.rx.try_recv() {
|
||||
Ok(data) => Some(data),
|
||||
Err(crossbeam::channel::TryRecvError::Empty) => None,
|
||||
Err(e) => {
|
||||
log::error!("Failed to receive data from channel: {:?}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Drop for AudioProcessorControl {
|
||||
fn drop(&mut self) {
|
||||
log::info!("Stopping audio processing thread");
|
||||
self.stop_flag.store(true, Ordering::Relaxed);
|
||||
let _ = self.handle.take().unwrap().join().map_err(|e| {
|
||||
log::error!("Failed to stop audio processing thread: {:?}", e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
struct AudioProcessor {
|
||||
pcm: alsa::pcm::PCM,
|
||||
spectrum: Vec<(f32, f32)>,
|
||||
tx: channel::Sender<Vec<(f32, f32)>>,
|
||||
}
|
||||
|
||||
impl AudioProcessor {
|
||||
pub fn new(tx: channel::Sender<Vec<(f32, f32)>>) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let hints = alsa::device_name::HintIter::new_str(None, "pcm").unwrap();
|
||||
for hint in hints {
|
||||
// When Direction is None it means that both the PCM supports both playback and capture
|
||||
if hint.name.is_some()
|
||||
&& hint.desc.is_some()
|
||||
&& (hint.direction.is_none()
|
||||
|| hint
|
||||
.direction
|
||||
.map(|dir| dir == alsa::Direction::Capture)
|
||||
.unwrap_or_default())
|
||||
{
|
||||
log::debug!(
|
||||
"pcm: {:<35} desc: {:?}",
|
||||
hint.name.unwrap(),
|
||||
hint.desc.unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let pcm = alsa::PCM::new(
|
||||
"plughw:CARD=sndrpigooglevoi,DEV=0",
|
||||
alsa::Direction::Capture,
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
{
|
||||
// For this example, we assume 44100Hz, one channel, 16 bit audio.
|
||||
let hwp = alsa::pcm::HwParams::any(&pcm).unwrap();
|
||||
hwp.set_channels_near(1).unwrap();
|
||||
hwp.set_rate_near(44100, alsa::ValueOr::Nearest).unwrap();
|
||||
hwp.set_format(alsa::pcm::Format::float()).unwrap();
|
||||
hwp.set_access(alsa::pcm::Access::RWInterleaved).unwrap();
|
||||
pcm.hw_params(&hwp).unwrap();
|
||||
}
|
||||
pcm.start()?;
|
||||
|
||||
Ok(AudioProcessor {
|
||||
pcm,
|
||||
spectrum: Vec::new(),
|
||||
tx,
|
||||
})
|
||||
}
|
||||
|
||||
fn process_audio(&mut self) {
|
||||
// Placeholder for audio processing logic
|
||||
// This should return a vector of tuples representing frequency and amplitude
|
||||
let start = Instant::now();
|
||||
|
||||
let binding = &self.pcm;
|
||||
let io = binding.io_f32().unwrap();
|
||||
let mut buf = [0f32; 2048];
|
||||
// Block while waiting for 2048 samples to be read from the device.
|
||||
let nb_samples = io.readi(&mut buf).unwrap();
|
||||
let elapsed_1 = start.elapsed();
|
||||
|
||||
log::trace!(
|
||||
"[Standalone] Read {} samples in {:?}",
|
||||
nb_samples,
|
||||
elapsed_1
|
||||
);
|
||||
|
||||
let start = Instant::now();
|
||||
if nb_samples >= 2048 {
|
||||
let data = buf[..2048].to_vec();
|
||||
let res: spectrum_analyzer::FrequencySpectrum = samples_fft_to_spectrum(
|
||||
&hann_window(&data),
|
||||
44100,
|
||||
FrequencyLimit::Range(20_f32, 20000_f32),
|
||||
// FrequencyLimit::All,
|
||||
Some(÷_by_N_sqrt),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
if self.spectrum.is_empty() {
|
||||
self.spectrum = Vec::from_iter(
|
||||
res.data()
|
||||
.iter()
|
||||
.map(|(fr, fr_val)| (fr.val(), fr_val.val() * 5000.0_f32)),
|
||||
);
|
||||
} else {
|
||||
res.data().iter().zip(self.spectrum.iter_mut()).for_each(
|
||||
|((fr, fr_val), (fr_old, fr_old_val))| {
|
||||
*fr_old = fr.val();
|
||||
let old_val = *fr_old_val * 0.84;
|
||||
let max = (*fr_val * 5000.0_f32.into()).max(FrequencyValue::from(old_val));
|
||||
*fr_old_val = max.val();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
self.tx
|
||||
.try_send(self.spectrum.clone())
|
||||
.expect("Failed to send audio data");
|
||||
|
||||
let elapsed_2 = start.elapsed();
|
||||
log::trace!("{elapsed_1:?} {elapsed_2:?}");
|
||||
} else {
|
||||
log::trace!("{elapsed_1:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub use led_driver::LedDriver;
|
||||
@@ -32,7 +32,7 @@ fn setup() -> GlobalContext {
|
||||
std::process::exit(0);
|
||||
})
|
||||
.expect("Error setting SIGINT/SIGTERM/SIGHUP handler");
|
||||
let led_driver = LedDriver::new(5);
|
||||
let led_driver = LedDriver::new(5, 3);
|
||||
|
||||
let (tx, rx) = unbounded();
|
||||
let mode_manager = ModeManager::new(rx);
|
||||
@@ -57,7 +57,7 @@ fn run(ctx: &mut GlobalContext) {
|
||||
|
||||
if elapsed > period {
|
||||
log::warn!(
|
||||
"Mode {:?} execution took too long: {:?}/{:?}ms",
|
||||
"Mode {:?} execution took too long: {:?}/{:?}",
|
||||
ctx.mode_manager.get_current_mode(),
|
||||
elapsed,
|
||||
period
|
||||
@@ -70,7 +70,6 @@ fn run(ctx: &mut GlobalContext) {
|
||||
|
||||
fn cleanup() {
|
||||
log::info!("Cleaning up before quitting...");
|
||||
// Perform cleanup here
|
||||
}
|
||||
|
||||
impl LightSabre {
|
||||
+5
-2
@@ -1,5 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
VSCODE_WS="$(pwd)"
|
||||
SSH_REMOTE="raspberrypi.local"
|
||||
|
||||
@@ -12,7 +15,7 @@ TARGET_CWD="/tmp"
|
||||
|
||||
cargo build
|
||||
|
||||
ssh "${TARGET_USER}@${SSH_REMOTE}" "sudo killall lldb-server ${APP}"
|
||||
ssh "${TARGET_USER}@${SSH_REMOTE}" "sudo killall lldb-server ${APP}" || true
|
||||
|
||||
if ! rsync -avz "${BUILD_BIN_FILE}" "${TARGET_USER}@${SSH_REMOTE}:${TARGET_BIN_FILE}"; then
|
||||
# If rsync doesn't work, it may not be available on target. Fallback to trying SSH copy.
|
||||
@@ -26,5 +29,5 @@ if [[ "$1" == "--debug" ]]; then
|
||||
ssh "${TARGET_USER}@${SSH_REMOTE}" "sh -c 'cd ${TARGET_CWD}; sudo RUST_LOG=debug lldb -o run ${TARGET_BIN_FILE}'"
|
||||
else
|
||||
echo "Running in release mode"
|
||||
ssh "${TARGET_USER}@${SSH_REMOTE}" "sh -c 'cd ${TARGET_CWD}; sudo RUST_LOG=info ${TARGET_BIN_FILE}'"
|
||||
ssh "${TARGET_USER}@${SSH_REMOTE}" "sh -c 'cd ${TARGET_CWD}; sudo RUST_LOG=${RUST_LOG} ${TARGET_BIN_FILE}'"
|
||||
fi
|
||||
Reference in New Issue
Block a user