]> OzVa Git service - rust_fft/commitdiff
exhibition changes main
authorMax Value <greenwoodw50@gmail.com>
Sat, 7 Mar 2026 14:40:18 +0000 (14:40 +0000)
committerMax Value <greenwoodw50@gmail.com>
Sat, 7 Mar 2026 14:40:18 +0000 (14:40 +0000)
22 files changed:
Cargo.lock
Cargo.toml
build.rs
src/barrel.cpp
src/capture.cpp [new file with mode: 0644]
src/color.cpp
src/color_functions.rs [new file with mode: 0644]
src/generate_distort.py
src/generate_lut.py [changed mode: 0755->0644]
src/homography.cpp
src/image_array.rs
src/lut/camera.py
src/lut/config.py
src/lut/cube.py [changed mode: 0755->0644]
src/lut/graph.py [changed mode: 0755->0644]
src/lut/test.py [changed mode: 0755->0644]
src/main.rs
src/process.cpp
src/sample_buffer.rs
src/style_utils.rs [new file with mode: 0644]
src/utils.rs [new file with mode: 0644]
todo

index b7efc4ea6e3581e3d5829f432398dfc76a1c329f..61f2e08a0cc16974882527496ef9e448a5adaf51 100644 (file)
@@ -45,7 +45,7 @@ version = "0.8.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "once_cell",
  "version_check",
  "zerocopy",
@@ -80,7 +80,7 @@ checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43"
 dependencies = [
  "alsa-sys",
  "bitflags 2.6.0",
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
 ]
 
@@ -207,7 +207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
 dependencies = [
  "addr2line",
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "miniz_oxide 0.8.0",
  "object",
@@ -215,6 +215,29 @@ dependencies = [
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "bindgen"
+version = "0.65.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
+dependencies = [
+ "bitflags 1.3.2",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "log",
+ "peeking_take_while",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn 2.0.87",
+ "which",
+]
+
 [[package]]
 name = "bindgen"
 version = "0.70.1"
@@ -320,9 +343,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
 
 [[package]]
 name = "bytemuck"
-version = "1.18.0"
+version = "1.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae"
+checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
 
 [[package]]
 name = "byteorder"
@@ -392,6 +415,12 @@ dependencies = [
  "target-lexicon",
 ]
 
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -415,6 +444,34 @@ dependencies = [
  "libloading 0.8.5",
 ]
 
+[[package]]
+name = "cocoa"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c49e86fc36d5704151f5996b7b3795385f50ce09e3be0f47a0cfde869681cf8"
+dependencies = [
+ "bitflags 1.3.2",
+ "block",
+ "core-foundation 0.7.0",
+ "core-graphics 0.19.2",
+ "foreign-types 0.3.2",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "cocoa-foundation"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d"
+dependencies = [
+ "bitflags 2.6.0",
+ "block",
+ "core-foundation 0.10.1",
+ "core-graphics-types 0.2.0",
+ "objc",
+]
+
 [[package]]
 name = "codespan-reporting"
 version = "0.11.1"
@@ -447,22 +504,60 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "core-foundation"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
+dependencies = [
+ "core-foundation-sys 0.7.0",
+ "libc",
+]
+
 [[package]]
 name = "core-foundation"
 version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
 dependencies = [
- "core-foundation-sys",
+ "core-foundation-sys 0.8.7",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
+dependencies = [
+ "core-foundation-sys 0.8.7",
  "libc",
 ]
 
+[[package]]
+name = "core-foundation-sys"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
+
 [[package]]
 name = "core-foundation-sys"
 version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
 
+[[package]]
+name = "core-graphics"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation 0.7.0",
+ "foreign-types 0.3.2",
+ "libc",
+]
+
 [[package]]
 name = "core-graphics"
 version = "0.22.3"
@@ -470,8 +565,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
 dependencies = [
  "bitflags 1.3.2",
- "core-foundation",
- "core-graphics-types",
+ "core-foundation 0.9.4",
+ "core-graphics-types 0.1.3",
  "foreign-types 0.3.2",
  "libc",
 ]
@@ -483,8 +578,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
 dependencies = [
  "bitflags 1.3.2",
- "core-foundation",
+ "core-foundation 0.9.4",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics-types"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb"
+dependencies = [
+ "bitflags 2.6.0",
+ "core-foundation 0.10.1",
+ "libc",
+]
+
+[[package]]
+name = "core-media-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "273bf3fc5bf51fd06a7766a84788c1540b6527130a0bce39e00567d6ab9f31f1"
+dependencies = [
+ "cfg-if 0.1.10",
+ "core-foundation-sys 0.7.0",
+ "libc",
+]
+
+[[package]]
+name = "core-video-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828"
+dependencies = [
+ "cfg-if 0.1.10",
+ "core-foundation-sys 0.7.0",
+ "core-graphics 0.19.2",
  "libc",
+ "metal 0.18.0",
+ "objc",
 ]
 
 [[package]]
@@ -494,7 +625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "321077172d79c662f64f5071a03120748d5bb652f5231570141be24cfcd2bace"
 dependencies = [
  "bitflags 1.3.2",
- "core-foundation-sys",
+ "core-foundation-sys 0.8.7",
  "coreaudio-sys",
 ]
 
@@ -504,7 +635,7 @@ version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2ce857aa0b77d77287acc1ac3e37a05a8c95a2af3647d23b15f263bdaeb7562b"
 dependencies = [
- "bindgen",
+ "bindgen 0.70.1",
 ]
 
 [[package]]
@@ -514,7 +645,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "873dab07c8f743075e57f524c583985fbaf745602acbe916a01539364369a779"
 dependencies = [
  "alsa",
- "core-foundation-sys",
+ "core-foundation-sys 0.8.7",
  "coreaudio-rs",
  "dasp_sample",
  "jni",
@@ -545,7 +676,7 @@ version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
@@ -637,6 +768,12 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
 
+[[package]]
+name = "dunce"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
+
 [[package]]
 name = "either"
 version = "1.13.0"
@@ -649,6 +786,16 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
 
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "exr"
 version = "1.73.0"
@@ -689,6 +836,18 @@ dependencies = [
  "miniz_oxide 0.8.0",
 ]
 
+[[package]]
+name = "flume"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "nanorand",
+ "spin",
+]
+
 [[package]]
 name = "foreign-types"
 version = "0.3.2"
@@ -824,9 +983,11 @@ version = "0.2.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
+ "js-sys",
  "libc",
  "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
 ]
 
 [[package]]
@@ -835,7 +996,7 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "r-efi",
  "wasi 0.14.7+wasi-0.2.4",
@@ -939,7 +1100,7 @@ version = "2.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "crunchy",
 ]
 
@@ -986,6 +1147,15 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
 
+[[package]]
+name = "home"
+version = "0.5.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d"
+dependencies = [
+ "windows-sys 0.61.2",
+]
+
 [[package]]
 name = "hound"
 version = "3.5.1"
@@ -1057,7 +1227,7 @@ version = "0.1.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "js-sys",
  "wasm-bindgen",
  "web-sys",
@@ -1099,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
 dependencies = [
  "cesu8",
- "cfg-if",
+ "cfg-if 1.0.0",
  "combine",
  "jni-sys",
  "log",
@@ -1155,6 +1325,12 @@ version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
 [[package]]
 name = "lebe"
 version = "0.5.2"
@@ -1184,7 +1360,7 @@ version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "winapi",
 ]
 
@@ -1194,7 +1370,7 @@ version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "windows-targets 0.52.6",
 ]
 
@@ -1209,6 +1385,12 @@ dependencies = [
  "redox_syscall 0.4.1",
 ]
 
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
+
 [[package]]
 name = "lock_api"
 version = "0.4.12"
@@ -1258,7 +1440,7 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
@@ -1285,6 +1467,21 @@ dependencies = [
  "autocfg",
 ]
 
+[[package]]
+name = "metal"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0"
+dependencies = [
+ "bitflags 1.3.2",
+ "block",
+ "cocoa",
+ "core-graphics 0.19.2",
+ "foreign-types 0.3.2",
+ "log",
+ "objc",
+]
+
 [[package]]
 name = "metal"
 version = "0.26.0"
@@ -1293,7 +1490,7 @@ checksum = "623b5e6cefd76e58f774bd3cc0c6f5c7615c58c03a97815245a25c3c9bdee318"
 dependencies = [
  "bitflags 2.6.0",
  "block",
- "core-graphics-types",
+ "core-graphics-types 0.1.3",
  "foreign-types 0.5.0",
  "log",
  "objc",
@@ -1337,6 +1534,31 @@ dependencies = [
  "windows-sys 0.48.0",
 ]
 
+[[package]]
+name = "mozjpeg"
+version = "0.10.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7891b80aaa86097d38d276eb98b3805d6280708c4e0a1e6f6aed9380c51fec9"
+dependencies = [
+ "arrayvec",
+ "bytemuck",
+ "libc",
+ "mozjpeg-sys",
+ "rgb",
+]
+
+[[package]]
+name = "mozjpeg-sys"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f0dc668bf9bf888c88e2fb1ab16a406d2c380f1d082b20d51dd540ab2aa70c1"
+dependencies = [
+ "cc",
+ "dunce",
+ "libc",
+ "nasm-rs",
+]
+
 [[package]]
 name = "naga"
 version = "0.13.0"
@@ -1358,6 +1580,25 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "nanorand"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
+dependencies = [
+ "getrandom 0.2.15",
+]
+
+[[package]]
+name = "nasm-rs"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34f676553b60ccbb76f41f9ae8f2428dac3f259ff8f1c2468a174778d06a1af9"
+dependencies = [
+ "jobserver",
+ "log",
+]
+
 [[package]]
 name = "ndk"
 version = "0.7.0"
@@ -1423,7 +1664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
 dependencies = [
  "bitflags 1.3.2",
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "memoffset",
 ]
@@ -1436,11 +1677,77 @@ checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
 dependencies = [
  "autocfg",
  "bitflags 1.3.2",
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "memoffset",
 ]
 
+[[package]]
+name = "nokhwa"
+version = "0.10.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4cae50786bfa1214ed441f98addbea51ca1b9aaa9e4bf5369cda36654b3efaa"
+dependencies = [
+ "flume",
+ "image",
+ "nokhwa-bindings-linux",
+ "nokhwa-bindings-macos",
+ "nokhwa-bindings-windows",
+ "nokhwa-core",
+ "paste",
+ "thiserror 2.0.16",
+]
+
+[[package]]
+name = "nokhwa-bindings-linux"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bd666aaa41d14357817bd9a981773a73c4d00b34d344cfc244e47ebd397b1ec"
+dependencies = [
+ "nokhwa-core",
+ "v4l",
+]
+
+[[package]]
+name = "nokhwa-bindings-macos"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de78eb4a2d47a68f490899aa0516070d7a972f853ec2bb374ab53be0bd39b60f"
+dependencies = [
+ "block",
+ "cocoa-foundation",
+ "core-foundation 0.10.1",
+ "core-media-sys",
+ "core-video-sys",
+ "flume",
+ "nokhwa-core",
+ "objc",
+ "once_cell",
+]
+
+[[package]]
+name = "nokhwa-bindings-windows"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "899799275c93ef69bbe8cb888cf6f8249abe751cbc50be5299105022aec14a1c"
+dependencies = [
+ "nokhwa-core",
+ "once_cell",
+ "windows 0.62.2",
+]
+
+[[package]]
+name = "nokhwa-core"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109975552bbd690894f613bce3d408222911e317197c72b2e8b9a1912dc261ae"
+dependencies = [
+ "bytes",
+ "image",
+ "mozjpeg",
+ "thiserror 2.0.16",
+]
+
 [[package]]
 name = "nom"
 version = "7.1.3"
@@ -1707,7 +2014,7 @@ version = "0.9.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "redox_syscall 0.5.3",
  "smallvec",
@@ -1720,6 +2027,12 @@ version = "1.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
 
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
 [[package]]
 name = "percent-encoding"
 version = "2.3.1"
@@ -1820,6 +2133,16 @@ dependencies = [
  "zerocopy",
 ]
 
+[[package]]
+name = "prettyplease"
+version = "0.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
+dependencies = [
+ "proc-macro2",
+ "syn 2.0.87",
+]
+
 [[package]]
 name = "primal-check"
 version = "0.3.4"
@@ -1987,7 +2310,7 @@ dependencies = [
  "av1-grain",
  "bitstream-io",
  "built",
- "cfg-if",
+ "cfg-if 1.0.0",
  "interpolate_name",
  "itertools 0.12.1",
  "libc",
@@ -2032,9 +2355,9 @@ checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
 
 [[package]]
 name = "rayon"
-version = "1.10.0"
+version = "1.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
+checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
 dependencies = [
  "either",
  "rayon-core",
@@ -2042,9 +2365,9 @@ dependencies = [
 
 [[package]]
 name = "rayon-core"
-version = "1.12.1"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
+checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
 dependencies = [
  "crossbeam-deque",
  "crossbeam-utils",
@@ -2106,6 +2429,15 @@ version = "0.8.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
 
+[[package]]
+name = "relative-path"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bca40a312222d8ba74837cb474edef44b37f561da5f773981007a10bbaa992b0"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "renderdoc-sys"
 version = "1.1.0"
@@ -2113,18 +2445,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
 
 [[package]]
-name = "rgb"
-version = "0.8.50"
+name = "resampler"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
+checksum = "80f5ab61459422b1a350caae1aadef48ebae234b12e80248e9ba9557018ef060"
 
 [[package]]
-name = "rscam"
-version = "0.5.5"
+name = "rgb"
+version = "0.8.50"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89056084211cd54924fedf2e2199b906409d1f795cfd8e7e3271061742457018"
+checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a"
 dependencies = [
- "libc",
+ "bytemuck",
 ]
 
 [[package]]
@@ -2136,11 +2468,15 @@ dependencies = [
  "hound",
  "image",
  "libc",
+ "nokhwa",
  "npyz",
  "rand 0.9.2",
- "rscam",
+ "rayon",
+ "relative-path",
+ "resampler",
  "rustfft",
  "show-image",
+ "vcpkg",
 ]
 
 [[package]]
@@ -2166,9 +2502,9 @@ dependencies = [
 
 [[package]]
 name = "rustfft"
-version = "6.2.0"
+version = "6.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43806561bc506d0c5d160643ad742e3161049ac01027b5e6d7524091fd401d86"
+checksum = "21db5f9893e91f41798c88680037dba611ca6674703c1a18601b01a72c8adb89"
 dependencies = [
  "num-complex",
  "num-integer",
@@ -2176,7 +2512,19 @@ dependencies = [
  "primal-check",
  "strength_reduce",
  "transpose",
- "version_check",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+dependencies = [
+ "bitflags 2.6.0",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -2254,7 +2602,7 @@ version = "0.10.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "cpufeatures",
  "digest",
 ]
@@ -2350,6 +2698,15 @@ dependencies = [
  "wayland-protocols",
 ]
 
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
 [[package]]
 name = "spirv"
 version = "0.2.0+1.5.4"
@@ -2488,7 +2845,7 @@ dependencies = [
  "arrayref",
  "arrayvec",
  "bytemuck",
- "cfg-if",
+ "cfg-if 1.0.0",
  "png",
  "tiny-skia-path",
 ]
@@ -2595,6 +2952,26 @@ version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
 
+[[package]]
+name = "v4l"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8fbfea44a46799d62c55323f3c55d06df722fbe577851d848d328a1041c3403"
+dependencies = [
+ "bitflags 1.3.2",
+ "libc",
+ "v4l2-sys-mit",
+]
+
+[[package]]
+name = "v4l2-sys-mit"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6779878362b9bacadc7893eac76abe69612e8837ef746573c4a5239daf11990b"
+dependencies = [
+ "bindgen 0.65.1",
+]
+
 [[package]]
 name = "v_frame"
 version = "0.3.8"
@@ -2606,6 +2983,12 @@ dependencies = [
  "wasm-bindgen",
 ]
 
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
 [[package]]
 name = "vec_map"
 version = "0.8.2"
@@ -2664,7 +3047,7 @@ version = "0.2.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "once_cell",
  "wasm-bindgen-macro",
 ]
@@ -2690,7 +3073,7 @@ version = "0.4.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "js-sys",
  "wasm-bindgen",
  "web-sys",
@@ -2821,7 +3204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "752e44d3998ef35f71830dd1ad3da513e628e2e4d4aedb0ab580f850827a0b41"
 dependencies = [
  "arrayvec",
- "cfg-if",
+ "cfg-if 1.0.0",
  "js-sys",
  "log",
  "naga",
@@ -2873,7 +3256,7 @@ dependencies = [
  "bit-set",
  "bitflags 2.6.0",
  "block",
- "core-graphics-types",
+ "core-graphics-types 0.1.3",
  "d3d12",
  "glow",
  "gpu-alloc",
@@ -2885,7 +3268,7 @@ dependencies = [
  "libc",
  "libloading 0.8.5",
  "log",
- "metal",
+ "metal 0.26.0",
  "naga",
  "objc",
  "parking_lot",
@@ -2913,6 +3296,18 @@ dependencies = [
  "web-sys",
 ]
 
+[[package]]
+name = "which"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
+dependencies = [
+ "either",
+ "home",
+ "once_cell",
+ "rustix",
+]
+
 [[package]]
 name = "widestring"
 version = "1.1.0"
@@ -2965,20 +3360,103 @@ version = "0.54.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49"
 dependencies = [
- "windows-core",
+ "windows-core 0.54.0",
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
+dependencies = [
+ "windows-collections",
+ "windows-core 0.62.2",
+ "windows-future",
+ "windows-numerics",
+]
+
+[[package]]
+name = "windows-collections"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
+dependencies = [
+ "windows-core 0.62.2",
+]
+
 [[package]]
 name = "windows-core"
 version = "0.54.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65"
 dependencies = [
- "windows-result",
+ "windows-result 0.1.2",
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows-core"
+version = "0.62.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link",
+ "windows-result 0.4.1",
+ "windows-strings",
+]
+
+[[package]]
+name = "windows-future"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
+dependencies = [
+ "windows-core 0.62.2",
+ "windows-link",
+ "windows-threading",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.87",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.59.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.87",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-numerics"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
+dependencies = [
+ "windows-core 0.62.2",
+ "windows-link",
+]
+
 [[package]]
 name = "windows-result"
 version = "0.1.2"
@@ -2988,6 +3466,24 @@ dependencies = [
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows-result"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
+dependencies = [
+ "windows-link",
+]
+
 [[package]]
 name = "windows-sys"
 version = "0.45.0"
@@ -3015,6 +3511,15 @@ dependencies = [
  "windows-targets 0.52.6",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.42.2"
@@ -3061,6 +3566,15 @@ dependencies = [
  "windows_x86_64_msvc 0.52.6",
 ]
 
+[[package]]
+name = "windows-threading"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
+dependencies = [
+ "windows-link",
+]
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.42.2"
@@ -3202,8 +3716,8 @@ dependencies = [
  "android-activity",
  "bitflags 1.3.2",
  "cfg_aliases",
- "core-foundation",
- "core-graphics",
+ "core-foundation 0.9.4",
+ "core-graphics 0.22.3",
  "dispatch",
  "instant",
  "libc",
index 4a1f93211aa7b015898de3a2fef2eba2b9ad5f50..de4e9d818eeb5bda890a1914e24428f4f3a60883 100644 (file)
@@ -3,7 +3,7 @@ name = "rust_fft"
 version = "0.1.0"
 edition = "2021"
 build = "build.rs"
-include = ["src/perspective.cpp"]
+include = ["src/process.cpp", "src/barrel.cpp", "src/color.cpp", "src/homography.cpp"]
 
 [dependencies]
 libc = "0.2.161"
@@ -12,16 +12,13 @@ image = "0.25.4"
 show-image = {version = "0.14.0", features = ["image"]}
 hound = "3.5.1"
 cpal = "0.15.3"
-rscam = "0.5.5"
 npyz = "0.8.4"
 rand = "0.9.2"
 nokhwa = {version = "0.10.10", features = ["input-native"]}
 relative-path = "2.0.1"
-yuv = "0.8.9"
-lowpass-filter = "0.3.2"
+rayon = "1.11.0"
+resampler = "0.4.1"
 
 [build-dependencies]
+vcpkg = "0.2"
 cc = "1.0"
-
-[env]
-CXXFLAGS = "-Wunused-parameter -lopencv_core -lopencv_highgui -lopencv_xfeatures2d -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_imgproc -lstdc++"
index dd58d6f08a12a6ac1d41184121e77baed7af4351..2bb949566dce3d2afd308e66d60b8093d2cc2923 100644 (file)
--- a/build.rs
+++ b/build.rs
@@ -2,26 +2,43 @@ fn main() {
        println!("cargo::rerun-if-changed=src/process.cpp");
        println!("cargo::rerun-if-changed=src/homography.cpp");
        println!("cargo::rerun-if-changed=src/color.cpp");
-       println!("cargo::rustc-env=CXXFLAGS=-Wunused-parameter -lopencv_core -lopencv_highgui -lopencv_xfeatures2d -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_features2d");
+       println!("cargo::rerun-if-changed=src/barrel.cpp");
+
+       println!("cargo:rustc-link-search=native=D:\\vcpkg\\installed\\x64-windows-static-md\\lib");
+       
+    println!("cargo:rustc-link-lib=static=opencv_core4");
+    println!("cargo:rustc-link-lib=static=opencv_imgproc4");
+    println!("cargo:rustc-link-lib=static=opencv_imgcodecs4");
+    println!("cargo:rustc-link-lib=static=opencv_highgui4");
+
+       let mut config = vcpkg::Config::new();
+       config.vcpkg_root([r"D:\", "vcpkg"].iter().collect::<std::path::PathBuf>());
+       let lib = config.find_package("opencv4").unwrap();
+       let mut path = lib.include_paths[0].clone();
+       path.push("opencv4");
+
+       println!("{:?}", lib);
 
        cc::Build::new()
                .file("src/process.cpp")
                .cpp(true)
-               .include("/usr/include/opencv4/")
+               .include(&path)
 
                // definitions cross language
-               .define("WINDOW_SIZE", "128")
-               .define("CHUNK_SIZE", "72")
-               .define("IMAGE_WIDTH", "1920")
-               .define("IMAGE_HEIGHT", "1080")
+               .define("WINDOW_SIZE", "64")
+               .define("CHUNK_SIZE", "128")
+               .define("CANVAS_WIDTH", "500")
+               .define("CANVAS_HEIGHT", "1000")
+               .define("IMAGE_WIDTH", "1080")
+               .define("IMAGE_HEIGHT", "1920")
                .define("LUT_SIZE", "12")
 
                //.define("USE_LUT", None)
+               //.define("PASSTHROUGH", None)
 
                .compile("process.a");
 
-       println!("cargo::rustc-flags=-lopencv_core -lopencv_highgui -lopencv_xfeatures2d -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_imgproc -lopencv_features2d");
-
-       println!("cargo:rustc-env=WGPU_BACKEND=gl"); // fix show_image bug(?)
+       println!("cargo:rustc-env=WGPU_BACKEND=primary"); // fix show_image bug(?)
        println!("cargo:rustc-env=WGPU_POWER_PREF=high"); // can switch to low if performance issues
+       
 }
index f2af095949fb3817e84e1c68858b23d1d9b4bfea..44de7515146b9d1045716604790b4c32c20cf6cd 100644 (file)
@@ -1,11 +1,15 @@
-#include "opencv4/opencv2/imgproc.hpp"
+#include "opencv2/imgproc.hpp"
+#include <opencv2/highgui.hpp> 
+#include <opencv2/core.hpp>
+#include <opencv2/imgcodecs.hpp>
 
+using namespace std;
 using namespace cv;
 
 void ApplyUndistort(uint8_t *camera_ptr, float *xmat_ptr, float *ymat_ptr)
 {
-       Mat xmat (IMAGE_HEIGHT, IMAGE_WIDTH, CV_32F, xmat_ptr);
-       Mat ymat (IMAGE_HEIGHT, IMAGE_WIDTH, CV_32F, ymat_ptr);
+       Mat xmat (IMAGE_HEIGHT, IMAGE_WIDTH, CV_16SC2, xmat_ptr);
+       Mat ymat (IMAGE_HEIGHT, IMAGE_WIDTH, CV_16UC1, ymat_ptr);
 
        Mat capture(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, camera_ptr);
        Mat buffer = capture.clone();
@@ -23,4 +27,7 @@ void ApplyUndistort(uint8_t *camera_ptr, float *xmat_ptr, float *ymat_ptr)
         */
 
        remap(buffer, capture, xmat, ymat, INTER_NEAREST);
+
+       cv::imshow("Testing", capture);
+       int k = waitKey(0); // Wait for a keystroke in the window
 }
diff --git a/src/capture.cpp b/src/capture.cpp
new file mode 100644 (file)
index 0000000..afff7dc
--- /dev/null
@@ -0,0 +1 @@
+#include "DeckLink X.Y\Win\Include\DeckLinkAPI.idl";
\ No newline at end of file
index 6cdd2ba447d5e392444c4fa86a4b4b93770ef59b..936a4d5b16387fdd553d14300c182b53e62f21d2 100644 (file)
@@ -1,26 +1,20 @@
 #include <cmath>
-#include "opencv4/opencv2/core.hpp"
-
-#ifndef LUT_SIZE
-const int IMAGE_WIDTH = 1920;
-const int IMAGE_HEIGHT = 1080;
-const int LUT_SIZE = 12;
-#endif
+#include "opencv2/core.hpp"
 
 using namespace std;
 using namespace cv;
 
 // is this damn well right?!?!
-const float SCALER = ((float)LUT_SIZE - 1.) / 255.;
+const float SCALER = ((float) LUT_SIZE - 1.) / 255.;
 
 void ApplyCorrection(uint8_t *buffer_ptr, uint8_t *lut_ptr)
 {
        try
        {
-               Mat capture(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, buffer_ptr);
+               Mat buffer(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3, buffer_ptr);
 
-               MatIterator_<Point3_<uint8_t>> it = capture.begin<Point3_<uint8_t>>();
-               MatIterator_<Point3_<uint8_t>> it_end = capture.end<Point3_<uint8_t>>();
+               MatIterator_<Point3_<uint8_t>> it = buffer.begin<Point3_<uint8_t>>();
+               MatIterator_<Point3_<uint8_t>> it_end = buffer.end<Point3_<uint8_t>>();
 
                /*
                 * Pretty sure that because we're not actually using opencv for anything
@@ -35,9 +29,9 @@ void ApplyCorrection(uint8_t *buffer_ptr, uint8_t *lut_ptr)
                        Point3_<float> scaled (pixel);
                        scaled *= SCALER;
 
-                       int r = floor(scaled.z);
-                       int g = floor(scaled.y);
-                       int b = floor(scaled.x);
+                       int r = (int) floor(scaled.z);
+                       int g = (int) floor(scaled.y);
+                       int b = (int) floor(scaled.x);
 
                        int idx = (((LUT_SIZE * LUT_SIZE) * r) + (LUT_SIZE * g)+ b) * 3;
 
@@ -75,7 +69,7 @@ void ApplyCorrection(uint8_t *buffer_ptr, uint8_t *lut_ptr)
        }
        catch (const std::exception &e) // handle exceptions for rust
        {
-               std::cout << "Exception " << e.what() << std::endl;
+               std::cout << "Exception BANG! " << e.what() << std::endl;
        }
 }
 
diff --git a/src/color_functions.rs b/src/color_functions.rs
new file mode 100644 (file)
index 0000000..9a6cbe8
--- /dev/null
@@ -0,0 +1,60 @@
+use crate::{HUE_MIN, HUE_REL};\r
+\r
+\r
+pub fn _hsv_to_rgb (h: f32, s: f32, v:f32) -> (f32, f32, f32) {\r
+       let mut _h = h * (HUE_REL / 255f32); // [0, HUE_REL) <- should this be ... * (360 / 256) ?????????\r
+       let _s = s / 255f32; // [0, 1]\r
+       let _v = v / 255f32; // [0, 1]\r
+       \r
+       _h += HUE_MIN; // [HUE_MIN, HUE_MAX)\r
+       _h /= 60f32;\r
+\r
+       let c = _s * _v;\r
+       let m = _v - c;\r
+       let x = c * (1f32 - (_h.rem_euclid(2f32) - 1f32).abs());\r
+\r
+       let (mut r, mut g, mut b) = match _h.floor() {\r
+               0.0 => (c, x, 0f32),\r
+               1.0 => (x, c, 0f32),\r
+               2.0 => (0f32, c, x),\r
+               3.0 => (0f32, x, c),\r
+               4.0 => (x, 0f32, c),\r
+               _ => (c, 0f32, x)\r
+       };\r
+\r
+       r = (r + m) * 255f32;\r
+       g = (g + m) * 255f32;\r
+       b = (b + m) * 255f32;\r
+\r
+       (r, g, b)\r
+}\r
+\r
+pub fn _rgb_to_hsv (r: f32, g: f32, b:f32) -> (f32, f32, f32) {\r
+       let v = r.max(g).max(b);\r
+       let c = (v - r.min(g).min(b)) * 255f32;\r
+       let s = if v == 0f32 { 0f32 } else { c / v };\r
+\r
+       let mut h = if c == 0f32 {\r
+               // case 1:\r
+               0f32\r
+       } else if v == r {\r
+               // case 2:\r
+               60f32 * ((g - b) / c).rem_euclid(6f32)\r
+       } else if v == g {\r
+               // case 3:\r
+               60f32 * (((b - r) / c) + 2f32)\r
+       } else {\r
+               // case 4:\r
+               60f32 * (((r - g) / c) + 4f32)\r
+       };\r
+       h *= 255f32 / 360f32;\r
+\r
+       (h, s, v)\r
+}\r
+\r
+pub fn _rgb_to_sv (r: f32, g: f32, b:f32) -> (f32, f32) {\r
+       let v = r.max(g).max(b);\r
+       let s = if v == 0f32 { 0f32 } else { ((v - r.min(g).min(b)) * 255f32) / v }; // only do "c" if we need to\r
+\r
+       (s, v)\r
+}
\ No newline at end of file
index 696e84306c2e61f64539629a2f6b661b51143a4a..61bf320162be93ad5c5449f63a4d82c9f413c0b3 100644 (file)
@@ -45,6 +45,9 @@ newcameramtx, roi = cv.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
 
 # undistort
 mapx, mapy = cv.initUndistortRectifyMap(mtx, dist, None, newcameramtx, (w,h), 5)
+
+mapx, mapy = cv.convertMaps(mapx, mapy, cv.CV_16SC2)
+
 dst = cv.remap(img, mapx, mapy, cv.INTER_LINEAR)
 
 np.save("./data/mapx.npy", mapx)
@@ -55,7 +58,7 @@ x, y, w, h = roi
 dst = dst[y:y+h, x:x+w]
 
 img = cv.resize(img, (w, h))
-dst = np.concat((dst, img), axis=1)
+dst = np.concat((img, dst), axis=1)
 
 cv.namedWindow("Result", cv.WINDOW_GUI_NORMAL)
 cv.imshow('Result', dst)
old mode 100755 (executable)
new mode 100644 (file)
index d4db011..d0e1f64
@@ -26,6 +26,6 @@ if __name__ == "__main__":
        if PASSTHROUGH and CAST_TEST:
                validate(lut)
 
-       save("./data/cube.npy", lut.lut)
+       save("cube.npy", lut.lut)
 
 
index c68c21b0d066c7e29079cb9a0ef90efeef673c41..ffaf80b9338cd4c4631a307dff39511f0fe1becd 100644 (file)
@@ -1,7 +1,9 @@
-#include "opencv4/opencv2/xfeatures2d.hpp"
-#include "opencv4/opencv2/calib3d.hpp"
-#include "opencv4/opencv2/imgproc.hpp"
-#include "opencv4/opencv2/imgcodecs.hpp"
+#include "opencv2/calib3d.hpp"
+#include "opencv2/xfeatures2d.hpp"
+#include "opencv2/imgproc.hpp"
+#include "opencv2/imgcodecs.hpp"
+#include <opencv2/highgui.hpp> 
+#include <opencv2/core.hpp>
 
 using namespace cv;
 using namespace cv::xfeatures2d;
@@ -10,12 +12,14 @@ void FuncGetHomography(uint8_t *camera_ptr, double *homography_ptr)
 {
        try
        {
-               Mat img1 = imread( samples::findFile("./test/calibration.jpg")/*, IMREAD_GRAYSCALE */);
+               Mat img1 = imread( samples::findFile("./test/towers.jpg")/*, IMREAD_GRAYSCALE */);
                Mat img2(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, camera_ptr);
+               cvtColor(img2, img2, COLOR_RGB2BGR);
 
                // detect keypoints and compute descriptors
                int minHessian = 400;
                Ptr<SURF> detector = SURF::create( minHessian );
+               (*detector).setExtended(true);
 
                std::vector<KeyPoint> keypoints1, keypoints2;
                Mat descriptors1, descriptors2;
@@ -56,6 +60,13 @@ void FuncGetHomography(uint8_t *camera_ptr, double *homography_ptr)
                // copy the result to the homography location
                const double* result_ptr = homography.ptr<double>(0);
                std::memcpy(homography_ptr, result_ptr, 72); // size of [f64; 9]
+
+               Mat output;
+               drawMatches(img1, keypoints1, img2, keypoints2, good_matches, output);
+
+               namedWindow("testing", WINDOW_NORMAL);
+               imshow("testing", output);
+               int k = waitKey(0); // Wait for a keystroke in the window
        }
        catch (const std::exception &e) // handle exceptions for rust
        {
@@ -63,13 +74,51 @@ void FuncGetHomography(uint8_t *camera_ptr, double *homography_ptr)
        }
 }
 
-void ApplyHomography(uint8_t *camera_ptr, uint8_t *buffer_ptr, double *homography_ptr)
+#ifndef CUDA
+
+void ApplyHomography(uint8_t *camera_ptr, uint8_t *buffer_ptr, double *homography_ptr) // validated!
 {
        Mat capture(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, camera_ptr);
+       Mat result(CANVAS_HEIGHT, CANVAS_WIDTH, CV_8UC3);
+       Mat homography(3, 3, CV_64F, homography_ptr);
+
+#ifdef PASSTHROUGH
+       Mat buffer(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3);
+#else
        Mat buffer(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3, buffer_ptr);
+#endif // PASSTHROUGH
+
+       warpPerspective(capture, result, homography, Size(CANVAS_WIDTH, CANVAS_HEIGHT)); // try INTER_LINEAR
+       resize(result, buffer, Size(WINDOW_SIZE, CHUNK_SIZE), 0, 0, INTER_NEAREST); // make sure this is right it would probably be a nebulous one to figure out
+}
+
+#else
+
+#include "opencv2/gpu/gpu.hpp"
+
+void ApplyHomography(uint8_t* camera_ptr, uint8_t* buffer_ptr, double* homography_ptr) // validated!
+{
+       Mat capture(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3, camera_ptr);
        Mat homography(3, 3, CV_64F, homography_ptr);
 
-       warpPerspective(capture, capture, homography, capture.size());
-       resize(capture, buffer, buffer.size());
+#ifdef PASSTHROUGH
+       Mat buffer(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3);
+#else
+       Mat buffer(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3, buffer_ptr);
+#endif // PASSTHROUGH
+
+       GpuMat capture_gpu(IMAGE_HEIGHT, IMAGE_WIDTH, CV_8UC3);
+       GpuMat result_gpu(CANVAS_HEIGHT, CANVAS_WIDTH, CV_8UC3);
+       GpuMat homography_gpu(3, 3, CV_64F);
+       GpuMat buffer_gpu(CHUNK_SIZE, WINDOW_SIZE, CV_8UC3);
+
+       capture_gpu.upload(capture);
+       homography_gpu.upload(homography);
+
+       gpu::warpPerspective(capture_gpu, result_gpu, homography_gpu, Size(CANVAS_WIDTH, CANVAS_HEIGHT)); // vvv try INTER_LINEAR
+       gpu::resize(result_gpu, buffer_gpu, Size(WINDOW_SIZE, CHUNK_SIZE), 0, 0, INTER_NEAREST); // make sure this is right it would probably be a nebulous one to figure out
+
+       buffer.download(buffer_gpu);
 }
 
+#endif // CUDA
index d2de10fb12367cf87c5af0f688daf98f5200a395..921debf6f618a2403c4986600d2e145be391b1a6 100644 (file)
-use image::ImageFormat;
-use nokhwa::{Camera, FormatDecoder};
+use nokhwa::{Camera, query};
 use nokhwa::utils::{
        RequestedFormat,
        CameraIndex,
        CameraFormat,
        Resolution,
-       FrameFormat,
-       RequestedFormatType
+       RequestedFormatType,
+       ApiBackend
 };
+use nokhwa::utils::KnownCameraControl::*;
+use nokhwa::utils::ControlValueSetter::*;
 use nokhwa::pixel_format::{RgbFormat, YuyvFormat};
 
 use rustfft::num_complex::Complex;
 
 use npyz::NpyFile;
 
-use yuv::{yuyv422_to_rgb, YuvPackedImage, YuvRange, YuvStandardMatrix};
-
 use std::io::BufReader;
 use std::fs::File;
+use relative_path::RelativePath;
+
+use rayon::prelude::*;
 
 use crate::{
        GetHomography,
        ProcessCapture,
        LUT_LENGTH,
+       LUT_PATH,
+       MAPX_PATH,
+       MAPY_PATH,
        SPECTOGRAM_AREA,
        IMAGE_AREA,
-       IMAGE_WIDTH,
-       IMAGE_HEIGHT,
        VOLUME_MIN,
        VOLUME_REL,
        AMPLITUDE_REL,
        AMPLITUDE_MIN,
        ANGLE_REL,
        ANGLE_MIN,
-       FPS
+       FPS,
+       PASSTHROUGH,
+       IMAGE_WIDTH,
+       IMAGE_HEIGHT,
+       IMAGE_FORMAT,
+       DEBUG
+};
+
+use crate::color_functions::{
+       _hsv_to_rgb,
+       _rgb_to_sv
 };
 
 pub struct ImageArray {
        pub data: Vec<u8>,
        homography: [f64; 9],
        lut: [u8; LUT_LENGTH],
+       mapx_ptr: usize,
+       mapy_ptr: usize,
        camera_buffer: Vec<u8>,
-       camera: Camera,
-       chunks: usize
+       camera: Camera
 }
 
 impl ImageArray {
-       pub fn new (homography: [f64; 9]) -> Self {
-
+       pub fn new (homography: [f64; 9], index: u32, mapx_ptr: usize, mapy_ptr: usize, focus: i64) -> Self {
+               
                // digest the numpy array and setup lut
-               let file = BufReader::new(File::open("./data/cube.npy").unwrap());
+               let lut_path = RelativePath::new(LUT_PATH).as_str();
+               let file = BufReader::new(File::open(lut_path).unwrap());
                let npy = NpyFile::new(file).unwrap();
-
-               // this is a little silly i should handle these things
                let lut: [u8; LUT_LENGTH] = npy.into_vec().unwrap().try_into().unwrap();
-
-               // setup the camera
-               let index = CameraIndex::Index(2);
-               let format = CameraFormat::new(
-                       Resolution { width_x: 1920, height_y: 1080 },
-                       FrameFormat::YUYV,
-                       FPS as u32
-               );
-               let requested = RequestedFormat::new::<YuyvFormat>(
-                       RequestedFormatType::Closest(format)
+               
+               // setup the camera formats
+               let index = CameraIndex::Index(index);
+               let format = RequestedFormat::new::<YuyvFormat>(
+                       RequestedFormatType::Closest(
+                               CameraFormat::new(
+                                       Resolution { width_x: IMAGE_WIDTH as u32, height_y: IMAGE_HEIGHT as u32},
+                                       IMAGE_FORMAT,
+                                       FPS as u32
+                               )
+                       )
                );
-
-               let mut camera = Camera::new(index, requested).unwrap();
+               
+               if DEBUG {
+                       // open the camera with its default to get the list of all its formats & print the backend info
+                       println!("{:#?}", query(ApiBackend::MediaFoundation));
+                       let mut camera = Camera::new(index.clone(), RequestedFormat::new::<YuyvFormat>(RequestedFormatType::None)).unwrap();
+                       println!("{:?}", camera.compatible_list_by_resolution(IMAGE_FORMAT));
+                       println!("{:?}", camera.supported_camera_controls().unwrap());
+               };
+
+               let mut camera = Camera::new(index, format).unwrap();
                camera.open_stream().unwrap();
 
-               // self
+               camera.set_camera_control(Brightness, Integer(255)).unwrap();
+               camera.set_camera_control(Contrast, Integer(128)).unwrap();
+               camera.set_camera_control(Saturation, Integer(128)).unwrap();
+               camera.set_camera_control(Sharpness, Integer(0)).unwrap();
+               camera.set_camera_control(WhiteBalance, Integer(5000)).unwrap();
+               camera.set_camera_control(BacklightComp, Integer(0)).unwrap();
+               camera.set_camera_control(Gain, Integer(0)).unwrap();
+               camera.set_camera_control(Exposure, Integer(-2)).unwrap();
+               camera.set_camera_control(Zoom, Integer(100)).unwrap();
+               camera.set_camera_control(Focus, Integer(focus)).unwrap();
+               
                Self {
                        data: vec![0u8; SPECTOGRAM_AREA * 3],
                        homography,
                        lut,
+                       mapx_ptr,
+                       mapy_ptr,
                        camera_buffer: vec![0u8; IMAGE_AREA],
-                       camera,
-                       chunks: SPECTOGRAM_AREA
+                       camera
                }
        }
 
        pub fn read_camera (&mut self) {
-               let frame = self.camera.frame().unwrap();
-
-               // some code to turn the yuyv into rgb if we need it!
-               // let stride = (IMAGE_WIDTH * 3) as u32;
-               // let vuvy = YuvPackedImage{
-               //      yuy: frame.buffer(),
-               //      yuy_stride: stride,
-               //      width: IMAGE_WIDTH as u32,
-               //      height: IMAGE_HEIGHT as u32
-               // };
-               // let mut rgb = [0u8; IMAGE_AREA];
-               // yuyv422_to_rgb(
-               //      &vuvy,
-               //      &mut rgb,
-               //      stride,
-               //      YuvRange::Full,
-               //      YuvStandardMatrix::Bt601
-               // ).unwrap();
-
+               let frame = self.camera.frame().expect(&format!("Oh no! Camera {} failed", self.camera.info()));
                let decoder = frame.decode_image::<RgbFormat>().unwrap();
 
-               decoder.save_with_format("./image.png", ImageFormat::Png).unwrap();
-
-               self.camera_buffer = decoder.into_vec()[..].into(); // something is wrong here
-
-
+               self.camera_buffer = decoder.into_raw()[..].into();
+                       
                unsafe {
                        ProcessCapture (
                                self.camera_buffer.as_ptr() as usize,
-                                                       self.data.as_ptr() as usize,
-                                                       self.homography.as_ptr() as usize,
-                                                       self.lut.as_ptr() as usize
+                               self.data.as_ptr() as usize,
+                               self.homography.as_ptr() as usize,
+                               self.lut.as_ptr() as usize,
+                               self.mapx_ptr,
+                               self.mapy_ptr
                        );
-               }
+               };
        }
 
        pub fn calibrate (&mut self) {
-               // hopefully dont need this !
-               // for _i in 0..10 {
-               //      self.camera_buffer = self.camera.capture().unwrap()[..].try_into().expect("Image is wrong size"); //delete assignment
-               // }
+               // read straight from the camera so as to not make "read_camera" too convoluted
+               for _ in 0..100 {
+                       self.camera.frame().unwrap();
+               }
+               let frame = self.camera.frame().unwrap();
+               let decoder = frame.decode_image::<RgbFormat>().unwrap();
+               self.camera_buffer = decoder.into_raw()[..].into();
 
                // enter unsafe and get the homography array
-               unsafe {
-                       GetHomography(self.camera_buffer.as_ptr() as usize, self.homography.as_ptr() as usize);
+               if !PASSTHROUGH {
+                       unsafe {
+                               GetHomography(
+                                       self.camera_buffer.as_ptr() as usize,
+                                       self.homography.as_ptr() as usize,
+                                       self.mapx_ptr,
+                                       self.mapy_ptr
+                               );
+                       }
                }
+               if DEBUG { println!("{:#?}", self.homography); }
        }
 
        pub fn read_buffer (&mut self, buffer: &[Complex<f32>]) {
-               let mut r: f32;
-               let mut theta: f32;
-               let mut amplitude: f32;
-
-               let mut hue: f32;
-               let mut angle: f32;
-
-               let mut d:f32;
-               let mut s:f32;
-               let mut v:f32;
-               let mut c:f32;
-               let mut m:f32;
-               let mut x:f32;
-               let mut g:f32;
-               let mut b:f32;
-
-               for i in 0..self.chunks {
-                       (r, theta) = buffer[i].to_polar();
-
-                       // make linear and normalize
-                       amplitude = 20f32 * r.log10();
+               /*
+                       hsv -> amplitude, angle, extra
+                               extra and spectrogram become seperated
+
+                       hsv -> angle, amplitude, extra
+                               extra and spectrogram become seperated
+
+                       hsv -> angle, extra, amplitude
+                               good but color split down middle in strange way
+                               hue mapped to phase is also poor
+
+                       hsv -> amplitude, extra, angle
+                               Looks more integrated but not that much
+                               good noise
+
+                       hsv -> extra, angle, amplitude
+                               enjoy the colors -> laurens fave looks cohesive
+                               visually more interesting. makes the spectrograms minimal & sounds clear
+
+                       hsv -> extra, amplitude, angle
+                               similar to last but slightly worse could be workable but
+                                       
+                       rgb -> all
+                               just different combinations of colors
+                               fairly seperated
+                                       
+                       hsplit -> angle, amplitude
+
+                       hsplit -> amplitude, angle
+
+               */
+               (0..SPECTOGRAM_AREA).into_par_iter().zip(self.data.par_chunks_mut(3)).for_each(|(i, rgb)| {
+                       let (norm, theta) = buffer[i].to_polar();
+                       
+                       // scale amplitude
+                       let mut amplitude = 20f32 * norm.log10();
                        amplitude = ((amplitude - VOLUME_MIN) / (VOLUME_REL / AMPLITUDE_REL)) + AMPLITUDE_MIN;
-
-                       hue = (180f32 / 255f32) * amplitude;
-
-                       angle = (theta.to_degrees() + 180f32) * (ANGLE_REL / 360f32) + ANGLE_MIN;
-
-                       d = hue * (1f32 / 30f32);
-                       s = angle / 255f32;
-                       v = amplitude / 255f32;
-
-                       c = s * v;
-                       m = v - c;
-                       x = c * (1f32 - (d.rem_euclid(2f32) - 1f32).abs());
-
-                       (r, g, b) = match d.floor() {
-                               0.0 => (c, x, 0f32),
-                               1.0 => (x, c, 0f32),
-                               2.0 => (0f32, c, x),
-                               3.0 => (0f32, x, c),
-                               4.0 => (x, 0f32, c),
-                               _ => (c, 0f32, x)
-                       };
-
-                       self.data[i*3] = ((r + m) * 255f32) as u8;
-                       self.data[i*3+1] = ((g + m) * 255f32) as u8;
-                       self.data[i*3+2] = ((b + m) * 255f32) as u8;
-               }
+                       
+                       // scale angle
+                       let angle = (theta.to_degrees() + 180f32) * (ANGLE_REL / 360f32) + ANGLE_MIN;
+                       
+                       // ==============================================
+                       let (r, g, b) = _hsv_to_rgb(amplitude, angle, amplitude);
+                       // ==============================================
+                       
+                       rgb[0] = r as u8;
+                       rgb[1] = g as u8;
+                       rgb[2] = b as u8;
+               });
        }
 
        pub fn write_buffer (&mut self, buffer: &mut [Complex<f32>]) {
-               let mut r: f32;
-               let mut amplitude: f32;
-
-               let mut angle: f32;
-
-               let mut s:f32;
-               let mut v:f32;
-               let mut c:f32;
-               let mut g:f32;
-               let mut b:f32;
+               (0..SPECTOGRAM_AREA).into_par_iter().zip(buffer.par_iter_mut()).for_each(|(i, buffer_point)| {
+                       let r = self.data[i*3] as f32;
+                       let g = self.data[i*3+1] as f32;
+                       let b = self.data[i*3+2] as f32;
 
-               for i in 0..self.chunks {
-                       r = self.data[i*3] as f32;
-                       g = self.data[i*3+1] as f32;
-                       b = self.data[i*3+2] as f32;
-
-                       v = r.max(g).max(b);
-                       c = (v - r.min(g).min(b)) * 255f32;
-                       s = if v == 0f32 { 0f32 } else { c / v };
-
-                       amplitude = (v - AMPLITUDE_MIN) * (VOLUME_REL / AMPLITUDE_REL) + VOLUME_MIN;
+                       // ==========================================
+                       let (mut angle, mut amplitude) = _rgb_to_sv(r, g, b);
+                       // ==========================================
 
+                       // scale amplitude
+                       amplitude = (amplitude - AMPLITUDE_MIN) * (VOLUME_REL / AMPLITUDE_REL) + VOLUME_MIN;
                        amplitude = 10f32.powf(amplitude / 20f32);
-
-                       angle = (s - ANGLE_MIN) / (ANGLE_REL / 360f32) - 180f32;
+                       
+                       // scale angle
+                       angle = (angle - ANGLE_MIN) / (ANGLE_REL / 360f32) - 180f32;
                        angle = angle.to_radians();
 
-                       buffer[i] = Complex::from_polar(amplitude, angle);
-               }
+                       *buffer_point = Complex::from_polar(amplitude, angle);
+               });
        }
 }
index 691d8da7246c3d2d92af5f9507d349e5a763c826..b61890be1282270a0e64bf77880c7ef2345b8f0c 100644 (file)
@@ -15,8 +15,7 @@ class Camera():
 
        # get image from camera and fix perspective
        def get(self, image):
-               small = cv.resize(image, (640,360))
-               cv.imshow("LUT Calibration", small)
+               cv.imshow("LUT Calibration", image)
                cv.waitKey(CAP_WAIT)
 
                if PASSTHROUGH:
index 0239b42f9282bebf22dc42376733ac9b48fed12d..9695e48df312bf2964b860122932e14c62b7f648 100644 (file)
@@ -6,12 +6,12 @@ optimal, conventially 33 is used. This will need to be tested with a camera.
 """
 LUT_SIZE = 12
 
-IMAGE_WIDTH = 1920 #1920
-IMAGE_HEIGHT = 1080 #1080
+IMAGE_WIDTH = 500 #1920
+IMAGE_HEIGHT = 1000 #1080
 
 # size of the qr codes and the space around them (px)
-QR_SIZE = 300
-QR_PADDING = 10
+QR_SIZE = 200
+QR_PADDING = 5
 
 # the wait time between each camera check after we stop generating
 WAIT_TIME = 0.1 #s
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 0d4153cc990b6541f39abf210c5ed78f7accf85a..335eabfc29eccef749f12147309c2f788cd084ae 100644 (file)
 use rustfft::algorithm::Radix4;
 use rustfft::{Fft, FftDirection};
 use rustfft::num_complex::Complex;
-use show_image::{ImageView, ImageInfo, create_window, event};
+
+use show_image::{
+       ImageView,
+       ImageInfo,
+       ArcImage,
+       create_window,
+       event,
+       Color,
+       WindowOptions
+};
+
 use cpal::{StreamConfig, BufferSize, SampleRate};
 use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
+
 use std::sync::{Arc, Mutex};
 use std::sync::mpsc;
-use image::ImageReader;
+use std::time::SystemTime;
+
+use image::{ImageReader, ImageBuffer, Rgb};
+
 use relative_path::RelativePath;
+use nokhwa::utils::FrameFormat;
+
+use rayon::prelude::*;
+
+use npyz::NpyFile;
+
+use resampler::{Attenuation, Latency, ResamplerFir, SampleRate as ResamplerSampleRate};
+
+use std::io::{BufReader, Write};
+use std::fs::File;
 
 mod image_array;
 mod sample_buffer;
+mod style_utils;
+mod color_functions;
+mod utils;
 
 use image_array::ImageArray;
 use sample_buffer::SampleBuffer;
 
-use lowpass_filter::LowpassFilter;
+/*
+NOTES:
+       - to calibrate you have to press enter on the images in the order of A-B-C.
+       - the sample rate is based only off file A and the others are assumed to be the same
+       - could paralelize the fft calls to speed them up?
+       - need to look at how images are displayed to the screen, very inneffective
+*/
 
-const WINDOW_SIZE: usize = 128;
-const CHUNK_SIZE: usize = 72;
+const WINDOW_SIZE: usize = 64; // 32
+const CHUNK_SIZE: usize = 128; // 64
 const SPECTOGRAM_AREA: usize = WINDOW_SIZE * CHUNK_SIZE;
 
+// config of the display windows
+// note: this is only used for the show_image config
+const CANVAS_WIDTH: usize = 500;
+const CANVAS_HEIGHT: usize = 1000;
+
 // configuration of the camera used
-const IMAGE_WIDTH: usize = 1920;
-const IMAGE_HEIGHT: usize = 1080;
+const IMAGE_WIDTH: usize = 1080;
+const IMAGE_HEIGHT: usize = 1920;
 const IMAGE_AREA: usize = IMAGE_WIDTH * IMAGE_HEIGHT * 3;
-const FPS: usize = 5;
+const IMAGE_FORMAT: FrameFormat = FrameFormat::NV12;
+const FPS: usize = 30;
+
+const CAM_A_IDX: u32 = 1;
+const CAM_B_IDX: u32 = 2;
+const CAM_C_IDX: u32 = 0;
+
+const DEV_C12_IDX: usize = 4;
+const DEV_C34_IDX: usize = 2;
+const DEV_C56_IDX: usize = 7;
+const DEV_C78_IDX: usize = 6;
+/*
+const DEV_C12_IDX: usize = 0;
+const DEV_C34_IDX: usize = 0;
+const DEV_C56_IDX: usize = 0;
+const DEV_C78_IDX: usize = 0;
+*/
 
 // maximum and minimum pixel values of angle and amplitude. could be confined to
 // improve performance for quiet sounds.
-const AMPLITUDE_MAX: f32 = 255.0;
-const AMPLITUDE_MIN: f32 = 0.0;
+const AMPLITUDE_MAX: f32 = 245.0;
+const AMPLITUDE_MIN: f32 = 10.0;
 const AMPLITUDE_REL: f32 = AMPLITUDE_MAX - AMPLITUDE_MIN;
 
-const ANGLE_MAX: f32 = 255.0;
-const ANGLE_MIN: f32 = 0.0;
+const ANGLE_MAX: f32 = 245.0;
+const ANGLE_MIN: f32 = 10.0;
 const ANGLE_REL: f32 = ANGLE_MAX - ANGLE_MIN;
 
+// this is a scaling specific to hue that applies idependant of which thing is mapped to it
+const HUE_MAX: f32 = 0.0; // in range of [0,360)
+const HUE_MIN: f32 = 360.0;
+const HUE_REL: f32 = HUE_MAX - HUE_MIN;
+
 // because of the opposingly logarithmic properties of both noise error and volume
 // this maximum value is important. -40 to 100 may not work under real conditions,
 // and -40 to 65 or even lower may produce better results.
-const VOLUME_MAX: f32 = 65.0; // 60 - 65
+const VOLUME_MAX: f32 = 60.0; // 60 - 65
 const VOLUME_MIN: f32 = -40.0;
 const VOLUME_REL: f32 = VOLUME_MAX - VOLUME_MIN;
 
 const LUT_SIZE: usize = 12;
 const LUT_LENGTH: usize = LUT_SIZE * LUT_SIZE * LUT_SIZE * 3;
+const LUT_PATH: &str = "./data/cube.npy";
 
-const DEBUG_MODE: bool = true;
+const MAPX_PATH: &str = "./data/mapx.npy"; 
+const MAPY_PATH: &str = "./data/mapy.npy"; 
 
-const CALIBRATION_PATH: &str = "./test/calibration.jpg";
-const AUDIO_PATH: &str = "./test/example.wav";
+const PASSTHROUGH: bool = false;
+const DEBUG: bool = true;
+const CALIBRATE: bool = true;
+
+const CALIBRATION_PATH: &str = "./test/towers.jpg";
+ const AUDIO_PATH_A: &str = "./test/example_hq.wav";
+ const AUDIO_PATH_B: &str = "./test/example_hq.wav";
+ const AUDIO_PATH_C: &str = "./test/example_hq.wav";
+//const AUDIO_PATH_A: &str = "test/threshold-A_03.wav";
+//const AUDIO_PATH_B: &str = "test/threshold-B_03.wav";
+//const AUDIO_PATH_C: &str = "test/threshold-C_03.wav";
+
+const AUDIO_A_C1: f32 = 1.0; const AUDIO_A_C2: f32 = 0.0;
+const AUDIO_A_C3: f32 = 0.0; const AUDIO_A_C4: f32 = 0.0;
+const AUDIO_A_C5: f32 = 0.0; const AUDIO_A_C6: f32 = 0.0;
+const AUDIO_A_C7: f32 = 0.0; const AUDIO_A_C8: f32 = 0.0;
+
+const AUDIO_B_C1: f32 = 0.0; const AUDIO_B_C2: f32 = 0.0;
+const AUDIO_B_C3: f32 = 0.0; const AUDIO_B_C4: f32 = 0.0;
+const AUDIO_B_C5: f32 = 0.0; const AUDIO_B_C6: f32 = 1.0;
+const AUDIO_B_C7: f32 = 0.0; const AUDIO_B_C8: f32 = 0.0;
+
+const AUDIO_C_C1: f32 = 0.0; const AUDIO_C_C2: f32 = 0.0;
+const AUDIO_C_C3: f32 = 0.0; const AUDIO_C_C4: f32 = 0.0;
+const AUDIO_C_C5: f32 = 1.0; const AUDIO_C_C6: f32 = 0.0;
+const AUDIO_C_C7: f32 = 0.0; const AUDIO_C_C8: f32 = 0.0;
+
+const OUTPUT_RATE: usize = 48000;//Hz
 
 // feedback config
-const WET: f32 = 0.0;
+const WET: f32 = 0.9;
 const DRY: f32 = 1.0;
 
-// audio effects and filtering
-const MAIN_LOWPASS: f32 = 20000.0;
-const FEEDBACK_LOWPASS: f32 = 20000.0;
-const FILTER_SCALING: f32 = 1. / 65535.; // to bring any signal down to +-1
-
 extern "C" {
-  fn GetHomography(camera_ptr: usize, homography_ptr: usize);
-  fn ProcessCapture(camera_ptr: usize, buffer_ptr: usize, homography_ptr: usize, lut_ptr: usize);
+  fn GetHomography(camera_ptr: usize, homography_ptr: usize, xmap_ptr: usize, ymap_ptr: usize);
+  fn ProcessCapture(camera_ptr: usize, buffer_ptr: usize, homography_ptr: usize, lut_ptr: usize, xmap_ptr: usize, ymap_ptr: usize);
 }
 
 #[show_image::main]
 fn main () -> Result<(), Box<dyn std::error::Error>> {
+       println!(" * Info: max delay is {}ms", 44100000 / SPECTOGRAM_AREA);
+       
+       println!(" * Reserving memory");
+
        // pregenerate the fft transformers
        let forward_transform = Radix4::<f32>::new(WINDOW_SIZE, FftDirection::Forward);
        let inverse_transform = Radix4::<f32>::new(WINDOW_SIZE, FftDirection::Inverse);
        let scratch_size = forward_transform.get_inplace_scratch_len();
 
        // preallocate complex space for the ffts
-       let mut buffer = vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA];
+       let mut buffer_a = vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA];
+       let mut buffer_b = vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA];
+       let mut buffer_c = vec![Complex{re: 0f32, im: 0f32}; SPECTOGRAM_AREA];
        let mut scratch = vec![Complex{re: 0f32, im: 0f32}; scratch_size];
 
        // setup communication between the main thread and the audio thread
-       let (tx, rx) = mpsc::channel();
-       let sample_buffer = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
-       let mut samples = SampleBuffer::new(sample_buffer.clone(), tx);
+       let (tx_c12, rx_c12) = mpsc::channel();
+       let (tx_c34, rx_c34) = mpsc::channel();
+       let (tx_c56, rx_c56) = mpsc::channel();
+       let (tx_c78, rx_c78) = mpsc::channel();
+
+       let sample_buffer_c1 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c2 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c3 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c4 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c5 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c6 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c7 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+       let sample_buffer_c8 = Arc::new(Mutex::new([0i16; 2*SPECTOGRAM_AREA]));
+
+       let mut samples_c12 = SampleBuffer::new(sample_buffer_c1.clone(), sample_buffer_c2.clone(), tx_c12);
+       let mut samples_c34 = SampleBuffer::new(sample_buffer_c3.clone(), sample_buffer_c4.clone(), tx_c34);
+       let mut samples_c56 = SampleBuffer::new(sample_buffer_c5.clone(), sample_buffer_c6.clone(), tx_c56);
+       let mut samples_c78 = SampleBuffer::new(sample_buffer_c7.clone(), sample_buffer_c8.clone(), tx_c78);
+
+       // resampler
+       let mut resampler = ResamplerFir::new(
+               1,
+               ResamplerSampleRate::Hz22050,
+               ResamplerSampleRate::Hz48000,
+               Latency::Sample64, // could change to Sample8
+               Attenuation::Db90,
+       );
+
+       // get the map to share it between the image arrays
+       let mapx_path = RelativePath::new(MAPX_PATH).as_str();
+       let mapx_file = BufReader::new(File::open(mapx_path).unwrap());
+       let mapx_npy = NpyFile::new(mapx_file).unwrap();
+       let mapx: Vec<i16> = mapx_npy.into_vec().unwrap();
+
+       let mapy_path = RelativePath::new(MAPY_PATH).as_str();
+       let mapy_file = BufReader::new(File::open(mapy_path).unwrap());
+       let mapy_npy = NpyFile::new(mapy_file).unwrap();
+       let mapy: Vec<u16> = mapy_npy.into_vec().unwrap();
 
        // setup homography space and get ready for the calibration
-       let homography = [0f64; 9]; // homography is a 3x3 matrix of 64-bit floats
-       let mut image_array = ImageArray::new(homography);
+       let homography_a = [0f64; 9]; // homography is a 3x3 matrix of 64-bit floats
+       let homography_b = [0f64; 9]; // homography is a 3x3 matrix of 64-bit floats
+       let homography_c = [0f64; 9]; // homography is a 3x3 matrix of 64-bit floats
+       println!(" * Starting camera A");
+       let mut image_array_a = ImageArray::new(homography_a, CAM_A_IDX, mapx.as_ptr() as usize, mapy.as_ptr() as usize, 190);
+       println!(" * Starting camera B");
+       let mut image_array_b = ImageArray::new(homography_b, CAM_B_IDX, mapx.as_ptr() as usize, mapy.as_ptr() as usize, 172);
+       println!(" * Starting camera C");
+       let mut image_array_c = ImageArray::new(homography_c, CAM_C_IDX, mapx.as_ptr() as usize, mapy.as_ptr() as usize, 236);
 
        // create the debug window
-       let debug_window = create_window("Debug", Default::default())?;
+       let window_options = WindowOptions{
+               preserve_aspect_ratio: false,
+               background_color: Color::black(),
+               start_hidden: false,
+               size: Some([(WINDOW_SIZE * 3) as u32, CHUNK_SIZE as u32]),
+               resizable: true,
+               borderless: false,
+               fullscreen: false,
+               overlays_visible: false,
+               default_controls: false
+       };
+       let debug_window = create_window("Debug", window_options)?;
 
        // get calibration image path
        let calibration_path = RelativePath::new(CALIBRATION_PATH).as_str();
 
        // create window for displaying images and display calibration image
-       let display_window = create_window("Display", Default::default())?;
+       let window_options = WindowOptions{
+               preserve_aspect_ratio: false,
+               background_color: Color::black(),
+               start_hidden: false,
+               size: Some([CANVAS_WIDTH as u32, CANVAS_HEIGHT as u32]),
+               resizable: true,
+               borderless: false,
+               fullscreen: false,
+               overlays_visible: false,
+               default_controls: false
+       };
+       let display_window_a = create_window("Display A", window_options.clone())?;
+       let display_window_b = create_window("Display B", window_options.clone())?;
+       let display_window_c = create_window("Display C", window_options)?;
+
        let calibration_image = ImageReader::open(calibration_path)?.decode()?;
-       display_window.set_image("Display", calibration_image)?;
 
+       display_window_a.set_image("Display A", calibration_image.clone())?;
+       display_window_b.set_image("Display B", calibration_image.clone())?;
+       display_window_c.set_image("Display C", calibration_image)?;
 
-       // wait for the user to press a key before continuing
-       for event in display_window.event_channel()? {
-               if let event::WindowEvent::KeyboardInput(event) = event {
-                       if event.input.key_code == Some(event::VirtualKeyCode::Return) && event.input.state.is_pressed() {
-                               break;
+       let mut arc_data_a: [u8; SPECTOGRAM_AREA * 3];
+       let mut arc_image_a: ArcImage;
+       let mut arc_data_b: [u8; SPECTOGRAM_AREA * 3];
+       let mut arc_image_b: ArcImage;
+       let mut arc_data_c: [u8; SPECTOGRAM_AREA * 3];
+       let mut arc_image_c: ArcImage;
+
+       // calibrate camera
+       if CALIBRATE {
+               println!(" * Calibrating Display A");
+               // wait for the user to press a key before continuing
+               for event in display_window_a.event_channel()? {
+                       if let event::WindowEvent::KeyboardInput(event) = event {
+                               if event.input.key_code == Some(event::VirtualKeyCode::Return) && event.input.state.is_pressed() {
+                                       image_array_a.calibrate();
+                                       break;
+                               }
+                       }
+               }
+       
+               println!(" * Calibrating Display B");
+               for event in display_window_b.event_channel()? {
+                       if let event::WindowEvent::KeyboardInput(event) = event {
+                               if event.input.key_code == Some(event::VirtualKeyCode::Return) && event.input.state.is_pressed() {
+                                       image_array_b.calibrate();
+                                       break;
+                               }
+                       }
+               }
+       
+               println!(" * Calibrating Display C");
+               for event in display_window_c.event_channel()? {
+                       if let event::WindowEvent::KeyboardInput(event) = event {
+                               if event.input.key_code == Some(event::VirtualKeyCode::Return) && event.input.state.is_pressed() {
+                                       image_array_c.calibrate();
+                                       break;
+                               }
                        }
                }
        }
 
-       // calibrate camera
-       image_array.calibrate();
-
-       // get audio path
-       let audio_path = RelativePath::new(AUDIO_PATH).as_str();
-
-       // open audio file
-       let mut reader = hound::WavReader::open(audio_path).unwrap();
-       let file_rate = reader.spec().sample_rate;
-
-       // setup the lowpass filters
-       let main_lowpass = LowpassFilter::new(file_rate, MAIN_LOWPASS);
-       let feedback_lowpass = LowpassFilter::new(file_rate, FEEDBACK_LOWPASS);
-
+       // get audio path and open audio file
+       let audio_path_a = RelativePath::new(AUDIO_PATH_A).as_str();
+       let audio_path_b = RelativePath::new(AUDIO_PATH_B).as_str();
+       let audio_path_c = RelativePath::new(AUDIO_PATH_C).as_str();
+
+       println!(" * Opening audio files");
+
+       let mut reader_a = hound::WavReader::open(audio_path_a).unwrap();
+       let mut reader_b = hound::WavReader::open(audio_path_b).unwrap();
+       let mut reader_c = hound::WavReader::open(audio_path_c).unwrap();
+
+       let file_rate = reader_a.spec().sample_rate;
+       
+       // get inf iter of the samples in the wav file
+    let samples_a: Vec<i16> = reader_a.samples::<i16>().filter_map(Result::ok).collect::<Vec<i16>>();
+       let mut infinite_a = samples_a.iter().copied().cycle();
+       
+    let samples_b: Vec<i16> = reader_b.samples::<i16>().filter_map(Result::ok).collect::<Vec<i16>>();
+       let mut infinite_b = samples_b.iter().copied().cycle();
+       
+    let samples_c: Vec<i16> = reader_c.samples::<i16>().filter_map(Result::ok).collect::<Vec<i16>>();
+       let mut infinite_c = samples_c.iter().copied().cycle();
+       
+       println!(" * Itterators constructed");
+       
+       let mut out_samples_a = [0f32; 11025]; // this is an arbitrary number sorry
+       let mut out_samples_b = [0f32; 11025]; 
+       let mut out_samples_c = [0f32; 11025]; 
+       
        // setup audio output and build output stream
+       println!(" * Output stream setup");
        let host = cpal::default_host();
-       let device = host.default_output_device().expect("No output device available");
+       
+       if DEBUG {
+               for device in host.output_devices().unwrap() {
+                       println!("{:?}", device.name().unwrap());
+               }
+               //println!("{:?}", device.default_output_config());
+               //let configs = device.supported_output_configs().unwrap();
+               //for supported_config in configs {
+               //      println!("{:?}", supported_config);
+               //}
+       }
 
-       let stream = device.build_output_stream(
+       let device_c12 = host.output_devices().unwrap().nth(DEV_C12_IDX).unwrap();
+       let device_c34 = host.output_devices().unwrap().nth(DEV_C34_IDX).unwrap();
+       let device_c56 = host.output_devices().unwrap().nth(DEV_C56_IDX).unwrap();
+       let device_c78 = host.output_devices().unwrap().nth(DEV_C78_IDX).unwrap();
+       
+       // CHANNELS 1-2
+       let stream_c12 = device_c12.build_output_stream(
+               &StreamConfig{
+                       channels: 2,
+                       sample_rate: SampleRate(OUTPUT_RATE as u32),
+                       buffer_size: BufferSize::Fixed(WINDOW_SIZE as u32)
+               },
+               move |data: &mut [i16], _: &cpal::OutputCallbackInfo| {
+                       samples_c12.get_data(data);
+               },
+               move |err| {
+                       eprintln!("An error occurred on the output audio stream: {}", err);
+               },
+               None
+       ).unwrap();
+       println!(" * Starting stream");
+       stream_c12.play().expect("Stream 1-2 play failed");
+       
+       // CHANNELS 3-4
+       let stream_c34 = device_c34.build_output_stream(
+               &StreamConfig{
+                       channels: 2,
+                       sample_rate: SampleRate(OUTPUT_RATE as u32),
+                       buffer_size: BufferSize::Fixed(WINDOW_SIZE as u32)
+               },
+               move |data: &mut [i16], _: &cpal::OutputCallbackInfo| {
+                       samples_c34.get_data(data);
+               },
+               move |err| {
+                       eprintln!("An error occurred on the output audio stream: {}", err);
+               },
+               None
+       ).unwrap();
+       println!(" * Starting stream");
+       stream_c34.play().expect("Stream 3-4 play failed");
+       
+       // CHANNELS 5-6
+       let stream_c56 = device_c56.build_output_stream(
+               &StreamConfig{
+                       channels: 2,
+                       sample_rate: SampleRate(OUTPUT_RATE as u32),
+                       buffer_size: BufferSize::Fixed(WINDOW_SIZE as u32)
+               },
+               move |data: &mut [i16], _: &cpal::OutputCallbackInfo| {
+                       samples_c56.get_data(data);
+               },
+               move |err| {
+                       eprintln!("An error occurred on the output audio stream: {}", err);
+               },
+               None
+       ).unwrap();
+       println!(" * Starting stream");
+       stream_c56.play().expect("Stream 5-6 play failed");
+       
+       // CHANNELS 7-8
+       let stream_c78 = device_c78.build_output_stream(
                &StreamConfig{
                        channels: 2,
-                       sample_rate: SampleRate(file_rate),
+                       sample_rate: SampleRate(OUTPUT_RATE as u32),
                        buffer_size: BufferSize::Fixed(WINDOW_SIZE as u32)
                },
                move |data: &mut [i16], _: &cpal::OutputCallbackInfo| {
-                       samples.get_data(data);
+                       samples_c78.get_data(data);
                },
                move |err| {
-                       eprintln!("an error occurred on the output audio stream: {}", err);
+                       eprintln!("An error occurred on the output audio stream: {}", err);
                },
                None
        ).unwrap();
-       stream.play().expect("Stream play failed");
+       println!(" * Starting stream");
+       stream_c78.play().expect("Stream 7-8 play failed");
 
        // begin looping though the samples until the buffer is full of complex audio with an imag element of 0
        let mut i = 0;
-       for sample in reader.samples::<i16>() {
+
+       let mut value_a: f32;
+       let mut value_b: f32;
+       let mut value_c: f32;
+       let mut now = SystemTime::now();
+
+       println!(" * Efficiency begins");
+       println!(" * See you soon");
+
+       // EFFICIENCY BEGINS
+
+       let mut imagenum = 0;
+
+       loop {
                if i == SPECTOGRAM_AREA {
 
                        // transform and do power scaling
-                       forward_transform.process_with_scratch(&mut buffer, &mut scratch);
-                       for x in buffer.iter_mut() {
-                               *x *= 1f32 / WINDOW_SIZE as f32;
-                       }
-                       image_array.read_buffer(&buffer);
+                       forward_transform.process_with_scratch(&mut buffer_a, &mut scratch);
+                       buffer_a = buffer_a.par_iter_mut()
+                               .map(|x| *x * (1f32 / WINDOW_SIZE as f32))
+                               .collect();
+                       image_array_a.read_buffer(&buffer_a);
+                       
+                       forward_transform.process_with_scratch(&mut buffer_b, &mut scratch);
+                       buffer_b = buffer_b.par_iter_mut()
+                               .map(|x| *x * (1f32 / WINDOW_SIZE as f32))
+                               .collect();
+                       image_array_b.read_buffer(&buffer_b);
+
+                       forward_transform.process_with_scratch(&mut buffer_c, &mut scratch);
+                       buffer_c = buffer_c.par_iter_mut()
+                               .map(|x| *x * (1f32 / WINDOW_SIZE as f32))
+                               .collect();
+                       image_array_c.read_buffer(&buffer_c);
 
                        // show the image on screen
-                       let image = ImageView::new(ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32), &image_array.data);
-                       display_window.set_image ("image", image)?;
+
+                       arc_data_a = image_array_a.data.clone().try_into().unwrap();
+                       arc_image_a = ArcImage::new(
+                               ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32),
+                               Arc::new(arc_data_a)
+                       );
+                       display_window_a.set_image("Display A", arc_image_a)?;
+
+                       arc_data_b = image_array_b.data.clone().try_into().unwrap();
+                       arc_image_b = ArcImage::new(
+                               ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32),
+                               Arc::new(arc_data_b)
+                       );
+                       display_window_b.set_image("Display B", arc_image_b)?;
+
+                       arc_data_c = image_array_c.data.clone().try_into().unwrap();
+                       arc_image_c = ArcImage::new(
+                               ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32),
+                               Arc::new(arc_data_c)
+                       );
+                       display_window_c.set_image("Display C", arc_image_c)?;
 
                        // capture and transform camera view to image
-                       image_array.read_camera();
+                       image_array_a.read_camera();
+                       image_array_b.read_camera();
+                       image_array_c.read_camera();
 
                        // make and display debug image
-                       if DEBUG_MODE {
-                               let debug_image = ImageView::new(ImageInfo::rgb8(WINDOW_SIZE as u32, CHUNK_SIZE as u32), &image_array.data);
+                       if DEBUG {
+                               let mut a_image = image_array_a.data.clone();
+                               let mut b_image = image_array_b.data.clone();
+                               let mut c_image = image_array_c.data.clone();
+
+                               let a_slice: &mut [u8] = a_image.as_mut_slice();
+                               let b_slice: &mut [u8] = b_image.as_mut_slice();
+                               let c_slice: &mut [u8] = c_image.as_mut_slice();
+
+                               let mut a_chunks = a_slice.chunks_mut(WINDOW_SIZE * 3);
+                               let mut b_chunks = b_slice.chunks_mut(WINDOW_SIZE * 3);
+                               let mut c_chunks = c_slice.chunks_mut(WINDOW_SIZE * 3);
+
+                               let mut image_data = vec![0u8;0];
+                               for _ in 0..CHUNK_SIZE {
+                                       let mut line = vec![0u8;0];
+                                       
+                                       let a_line = a_chunks.next().unwrap();
+                                       let b_line = b_chunks.next().unwrap();
+                                       let c_line = c_chunks.next().unwrap();
+
+                                       line.extend_from_slice(a_line);
+                                       line.extend_from_slice(b_line);
+                                       line.extend_from_slice(c_line);
+
+                                       
+                                       image_data.extend_from_slice(line.as_slice());
+                               }
+
+                               if false {
+                                       let save_image: ImageBuffer<Rgb<u8>, Vec<u8>> = ImageBuffer::from_raw((WINDOW_SIZE * 4) as u32, CHUNK_SIZE as u32, image_data.clone()).unwrap();
+                                       imagenum += 1;
+                                       save_image.save(format!("frames/frame-{:0>3}.png", imagenum)).unwrap();
+                               }
+
+                               let debug_image = ImageView::new(ImageInfo::rgb8((WINDOW_SIZE * 3) as u32, CHUNK_SIZE as u32), image_data.as_slice());
                                debug_window.set_image("Debug", debug_image)?;
                        }
 
                        // convert image to audio
-                       image_array.write_buffer(&mut buffer);
-                       inverse_transform.process_with_scratch(&mut buffer, &mut scratch);
+                       image_array_a.write_buffer(&mut buffer_a);
+                       image_array_b.write_buffer(&mut buffer_b);
+                       image_array_c.write_buffer(&mut buffer_c);
+                       inverse_transform.process_with_scratch(&mut buffer_a, &mut scratch);
+                       inverse_transform.process_with_scratch(&mut buffer_b, &mut scratch);
+                       inverse_transform.process_with_scratch(&mut buffer_c, &mut scratch);
 
                        // when a "true" is receved by rx, get lock for sample buffer and fill the last half with the audio
-                       if rx.recv().unwrap() {
-                               let mut write_buffer = sample_buffer.lock().unwrap();
-                               for (i, x) in write_buffer[SPECTOGRAM_AREA..].iter_mut().enumerate() {
-                                       let value = main_lowpass.run(buffer[i].re / i16::MAX as f32);
-                                       *x = (value * i16::MAX) as i16;
-                               }
+                       if DEBUG { now = SystemTime::now(); }
+
+                       let _ = resampler.resample(&buffer_a.iter().rev().map(|x| x.re).collect::<Vec<f32>>(), &mut out_samples_a).unwrap();
+                       let _ = resampler.resample(&buffer_b.iter().rev().map(|x| x.re).collect::<Vec<f32>>(), &mut out_samples_b).unwrap();
+                       let _ = resampler.resample(&buffer_c.iter().rev().map(|x| x.re).collect::<Vec<f32>>(), &mut out_samples_c).unwrap();
+
+
+                       // CHANNELS 1-2
+                       if rx_c12.recv().unwrap() {
+                               if DEBUG { println!("{:?}", now.elapsed().unwrap()); }
+                               sample_buffer_c1.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C1) + (out_samples_b[i] * AUDIO_B_C1) + (out_samples_b[i] * AUDIO_C_C1)) as i16;
+                                       });
+                               sample_buffer_c2.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C2) + (out_samples_b[i] * AUDIO_B_C2) + (out_samples_b[i] * AUDIO_C_C2)) as i16;
+                                       });
+                       }
+                       
+                       // CHANNELS 3-4
+                       if rx_c34.recv().unwrap() {
+                               sample_buffer_c3.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C3) + (out_samples_b[i] * AUDIO_B_C3) + (out_samples_b[i] * AUDIO_C_C3)) as i16;
+                                       });
+                               sample_buffer_c4.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C4) + (out_samples_b[i] * AUDIO_B_C4) + (out_samples_b[i] * AUDIO_C_C4)) as i16;
+                                       });
+                       }
+                       
+                       // CHANNELS 5-6
+                       if rx_c56.recv().unwrap() {
+                               sample_buffer_c5.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C5) + (out_samples_b[i] * AUDIO_B_C5) + (out_samples_b[i] * AUDIO_C_C5)) as i16;
+                                       });
+                               sample_buffer_c6.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C6) + (out_samples_b[i] * AUDIO_B_C6) + (out_samples_b[i] * AUDIO_C_C6)) as i16;
+                                       });
+                       }
+                       
+                       // CHANNELS 7-8
+                       if rx_c78.recv().unwrap() {
+                               sample_buffer_c7.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C7) + (out_samples_b[i] * AUDIO_B_C7) + (out_samples_b[i] * AUDIO_C_C7)) as i16;
+                                       });
+                               sample_buffer_c8.lock().unwrap()[SPECTOGRAM_AREA..]
+                                       .par_iter_mut()
+                                       .enumerate()
+                                       .for_each(|(i, x)| {
+                                               *x = ((out_samples_a[i] * AUDIO_A_C8) + (out_samples_b[i] * AUDIO_B_C8) + (out_samples_b[i] * AUDIO_C_C8)) as i16;
+                                       });
                        }
 
                        i = 0;
                }
+
                // if buffer is not full convert value and add to buffer
-               let mut value = sample.unwrap_or_default() as f32;
-               let feedback_value = feedback_lowpass.run(buffer[i].re / i16::MAX as f32);
-               value = (value * DRY) + (feedback_value * i16::MAX * WET);
+               value_a = (infinite_a.next().unwrap() as f32 * DRY) + (buffer_a[i].re * WET);
+               value_b = (infinite_b.next().unwrap() as f32 * DRY) + (buffer_b[i].re * WET);
+               value_c = (infinite_c.next().unwrap() as f32 * DRY) + (buffer_c[i].re * WET);
+
+               buffer_a[i] = Complex{re: value_a, im: 0f32};
+               buffer_b[i] = Complex{re: value_b, im: 0f32};
+               buffer_c[i] = Complex{re: value_c, im: 0f32};
 
-               buffer[i] = Complex{re: value, im: 0f32};
                i += 1;
        }
-
-       Ok(())
-
 }
index 229981c17fd648565dc66faf4fb6e3d6a4df5a0d..b72a65bfd6c551e0309e28133cc82f80d5def7e1 100644 (file)
@@ -1,10 +1,13 @@
-#include "barrel.cpp"
 #include "homography.cpp"
+#include "barrel.cpp"
+
+#ifdef USE_LUT
 #include "color.cpp"
+#endif
 
 extern "C"
 {
-       void ProcessCapture(uint8_t *camera_ptr, uint8_t *buffer_ptr, double *homography_ptr, uint8_t *lut_ptr)
+       void ProcessCapture(uint8_t *camera_ptr, uint8_t *buffer_ptr, double *homography_ptr, uint8_t *lut_ptr, float* xmat_ptr, float* ymat_ptr)
        {
                /*
                 * Heres the plan:
@@ -22,6 +25,7 @@ extern "C"
                 * even thinking about it in the rust.
                 */
 
+               //ApplyUndistort(camera_ptr, xmat_ptr, ymat_ptr);
                ApplyHomography(camera_ptr, buffer_ptr, homography_ptr);
                #ifdef USE_LUT
                        ApplyCorrection(buffer_ptr, lut_ptr);
@@ -29,8 +33,9 @@ extern "C"
        }
 
        // get homography function (see "homography.cpp")
-       void GetHomography(uint8_t *camera_ptr, double *homography_ptr)
+       void GetHomography(uint8_t *camera_ptr, double *homography_ptr, float* xmat_ptr, float* ymat_ptr)
        {
+               //ApplyUndistort(camera_ptr, xmat_ptr, ymat_ptr);
                FuncGetHomography(camera_ptr, homography_ptr);
        }
 }
index d808f828cb3403ab4145159d4a381f64345276b4..ae2d28bbce75de242cf275b4d66250c4c1891851 100644 (file)
@@ -4,32 +4,38 @@ use std::sync::{Arc, Mutex};
 use crate::SPECTOGRAM_AREA;
 
 pub struct SampleBuffer {
-       buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>,
+       right_buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>,
+       left_buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>,
        index: usize,
        tx: Sender<bool>
 }
 
 impl SampleBuffer {
-       pub fn new(buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>, tx: Sender<bool>) -> Self {
+       pub fn new(right_buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>, left_buffer: Arc<Mutex<[i16; 2 * SPECTOGRAM_AREA]>>, tx: Sender<bool>) -> Self {
+               
                Self {
-                       buffer,
+                       right_buffer,
+                       left_buffer,
                        index: 0,
                        tx
                }
        }
 
        pub fn get_data(&mut self, data: &mut [i16]) {
-               let mut buffer = self.buffer.lock().unwrap();
+               let mut right_buffer = self.right_buffer.lock().unwrap();
+               let mut left_buffer = self.left_buffer.lock().unwrap();
                let length = data.len()/2;
 
                for i in 0..length {
-                       data[i*2] = buffer[i + self.index];
+                       data[i*2] = right_buffer[i + self.index];
+                       data[i*2+1] = left_buffer[i + self.index];
                }
 
                self.index += length;
                if self.index > SPECTOGRAM_AREA {
                        for i in 0..SPECTOGRAM_AREA {
-                               buffer[i] = buffer[i + SPECTOGRAM_AREA];
+                               right_buffer[i] = right_buffer[i + SPECTOGRAM_AREA];
+                               left_buffer[i] = left_buffer[i + SPECTOGRAM_AREA];
                        }
                        self.index -= SPECTOGRAM_AREA;
 
diff --git a/src/style_utils.rs b/src/style_utils.rs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/utils.rs b/src/utils.rs
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/todo b/todo
index 52b5a3563322da4fc71c920760e20972cb5c706a..39b91398454ab9e722b77760614decc6e4491a20 100644 (file)
--- a/todo
+++ b/todo
@@ -1,25 +1,19 @@
 todo:
 - test the lut system in-situ, graph for optimal
-- possibly see if a version can be made that takes mic input
-- implement recording for testing
 - implement image display in unused channel
-
+- get temp guest list together
+- ask R about headcounts and other event things
 - write cpp code for using cuFFT (not supported by rust-cuda)
-- potentially write rust-cuda kernel for the color conversion
+- add 3 to 2 reverse functions
+- implement the video frame reader
+- speed the whole thing up
 
 QUICKLY:
-- make functional with windows
-       - some things that might not be windows compatible:
-               - show-image (YES but might need to mess with the backend)
-               - hound for reading the wav files (YES)
-               - cpal for the audio out (YES look into asio extra feature for lower latency)
-               - rscam for the camera (NO drop in for nokhwa) (IMPLEMENTED)
-               - the file paths (IMPLEMENTED)
 - evaluate if cuda is neccicary
 
 LIBRARIES:
 - FFTW (https://www.fftw.org/fftw3_doc/) for the c++
-- nokhwa (IMPLEMENTED)
+- vid2img (https://github.com/rafaelcaricio/vid2img)
 - fon
 - rayon
 
@@ -36,5 +30,31 @@ CAPTURE ISSUES:
 - reinstate the read loop
 
 AUDIO ISSUES:
-- disable the feedback mix code
-- disable the filtering code
+- implement filtering
+
+CLICKING:
+- check if messing with the itterators is possibly causing some kind of jump
+
+WARP ISSUES:
+- surf.setExtended(True) // set surf to 128 keypoints if its only 64 right now
+
+
+
+
+
+               // some code to turn the yuyv into rgb if we need it!
+               // let stride = (IMAGE_WIDTH * 3) as u32;
+               // let vuvy = YuvPackedImage{
+               //      yuy: frame.buffer(),
+               //      yuy_stride: stride,
+               //      width: IMAGE_WIDTH as u32,
+               //      height: IMAGE_HEIGHT as u32
+               // };
+               // let mut rgb = [0u8; IMAGE_AREA];
+               // yuyv422_to_rgb(
+               //      &vuvy,
+               //      &mut rgb,
+               //      stride,
+               //      YuvRange::Full,
+               //      YuvStandardMatrix::Bt601
+               // ).unwrap();W
\ No newline at end of file