First crude working versiom. Slow as crap
This commit is contained in:
parent
da0c5081e9
commit
cc8afc1b07
|
@ -33,6 +33,12 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.7.6"
|
||||
|
@ -77,7 +83,7 @@ checksum = "7915e26e0786f91768d23de32afafa4ee5e2ea76be21c0ecd8e14441543c1655"
|
|||
dependencies = [
|
||||
"enumflags2",
|
||||
"futures",
|
||||
"rand 0.8.4",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"zbus",
|
||||
|
@ -215,10 +221,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
name = "bit_field"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -239,10 +245,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "0.5.3"
|
||||
name = "bytemuck"
|
||||
version = "1.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
||||
checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
|
@ -328,7 +334,7 @@ version = "0.24.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"block",
|
||||
"cocoa-foundation",
|
||||
"core-foundation 0.9.2",
|
||||
|
@ -344,7 +350,7 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"block",
|
||||
"core-foundation 0.9.2",
|
||||
"core-graphics-types",
|
||||
|
@ -355,9 +361,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
|
@ -420,7 +426,7 @@ version = "0.19.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"core-foundation 0.7.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
|
@ -432,7 +438,7 @@ version = "0.22.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"core-foundation 0.9.2",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
|
@ -445,7 +451,7 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"core-foundation 0.9.2",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
|
@ -464,6 +470,59 @@ dependencies = [
|
|||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cty"
|
||||
version = "0.2.2"
|
||||
|
@ -506,12 +565,21 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "deque"
|
||||
version = "0.3.1"
|
||||
name = "deflate"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||
checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70"
|
||||
dependencies = [
|
||||
"rand 0.3.14",
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -615,6 +683,12 @@ dependencies = [
|
|||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.16.0"
|
||||
|
@ -622,14 +696,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "55673de2eb96660dde25ba7b2d36a7054beead1a2bec74dcfd5eb05a1e1ba76d"
|
||||
|
||||
[[package]]
|
||||
name = "enum_primitive"
|
||||
version = "0.1.0"
|
||||
name = "encoding"
|
||||
version = "0.2.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f79eff5be92a4d7d5bddf7daa7d650717ea71628634efe6ca7bcda85b2183c23"
|
||||
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
|
||||
dependencies = [
|
||||
"num",
|
||||
"encoding-index-japanese",
|
||||
"encoding-index-korean",
|
||||
"encoding-index-simpchinese",
|
||||
"encoding-index-singlebyte",
|
||||
"encoding-index-tradchinese",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-japanese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-korean"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-simpchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-singlebyte"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding-index-tradchinese"
|
||||
version = "1.20141219.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
|
||||
dependencies = [
|
||||
"encoding_index_tests",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_index_tests"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.3"
|
||||
|
@ -679,6 +808,22 @@ version = "2.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4badb9489a465cb2c555af1f00f0bfd8cecd6fc12ac11da9d5b40c5dd5f0200"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"deflate 1.0.0",
|
||||
"flume",
|
||||
"half",
|
||||
"inflate",
|
||||
"lebe",
|
||||
"smallvec",
|
||||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.7.0"
|
||||
|
@ -690,12 +835,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "0.2.14"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
||||
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz-sys",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.10.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d04dafd11240188e146b6f6476a898004cace3be31d4ec5e08e216bf4947ac0"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"nanorand",
|
||||
"pin-project",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -823,12 +983,6 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
|
||||
|
||||
[[package]]
|
||||
name = "gdk-pixbuf-sys"
|
||||
version = "0.15.1"
|
||||
|
@ -866,18 +1020,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.9.0"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01c7c19a035de94bd7afbaa62c241aadfbdf1a70f560b348d2312eafa566ca16"
|
||||
checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"lzw",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -936,12 +1092,6 @@ dependencies = [
|
|||
"takeable-option",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
|
||||
[[package]]
|
||||
name = "glutin"
|
||||
version = "0.28.0"
|
||||
|
@ -1043,12 +1193,27 @@ dependencies = [
|
|||
"system-deps",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
|
@ -1069,27 +1234,32 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
|||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.10.3"
|
||||
version = "0.24.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "559d5ebbe9ec73111799e49c07717944b244f8accf5de33a8a8128bc3ecd2e00"
|
||||
checksum = "e94ac3d41f882c624a82d7945952032388488681f45f9d4077999a6c85688d61"
|
||||
dependencies = [
|
||||
"byteorder 0.5.3",
|
||||
"enum_primitive",
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"exr",
|
||||
"gif",
|
||||
"glob",
|
||||
"jpeg-decoder",
|
||||
"jpeg-decoder 0.2.1",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
"png",
|
||||
"scoped_threadpool",
|
||||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflate"
|
||||
version = "0.1.1"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7e0062d2dc2f17d2f13750d95316ae8a2ff909af0fda957084f5defd87c43bb"
|
||||
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
|
@ -1111,11 +1281,16 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
|||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.1.8"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be50b418a1fc5d198588d9a4f682ef808a55db4084dce39d09bb0562525bb8c"
|
||||
checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2"
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbcf0244f6597be39ab8d9203f574cafb529ae8c698afa2182f7b3c3205a4a9c"
|
||||
dependencies = [
|
||||
"byteorder 0.5.3",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
|
@ -1146,6 +1321,12 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.117"
|
||||
|
@ -1180,12 +1361,6 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzw"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
version = "0.0.6"
|
||||
|
@ -1225,16 +1400,6 @@ version = "0.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz-sys"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d1f4d337a01c32e1f2122510fed46393d53ca35a7f429cb0450abaedfa3ed54"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
|
@ -1267,13 +1432,22 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "729eb334247daa1803e0a094d0a5c55711b85571179f5ec6e53eccfdf7008958"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"jni-sys",
|
||||
"ndk-sys",
|
||||
"num_enum",
|
||||
|
@ -1319,7 +1493,7 @@ version = "0.22.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
|
@ -1332,7 +1506,7 @@ version = "0.23.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
|
@ -1365,36 +1539,14 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.1.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bde7c03b09e7c6a301ee81f6ddf66d7a28ec305699e3d3b056d2fc56470e3120"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.1.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b14378471f7c2adc5262f05b4701ef53e8da376453a8d8fee48e51db745e49"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rand 0.3.14",
|
||||
"rustc-serialize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.32"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb24d9bfb3f222010df27995441ded1e954f8f69cd35021f6bef02ca9552fb92"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"autocfg",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1404,19 +1556,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "287a1c9969a847055e1122ec0ea7a5c5d6f72aad97934e131c83d5c08ab4e45c"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"num-traits 0.1.36",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.1.35"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54ff603b8334a72fbb27fe66948aac0abaaa40231b3cecd189e76162f6f38aaf"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"rustc-serialize",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1426,11 +1577,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a16a42856a256b39c6d3484f097f6713e14feacd9bfb02290917904fae46c81c"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.1.0"
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8890e6084723d57d0df8d2720b0d60c6ee67d6c93e7169630e4371e88765dcad"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
|
@ -1576,6 +1737,26 @@ version = "2.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.8"
|
||||
|
@ -1596,14 +1777,15 @@ checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
|||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.5.2"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997"
|
||||
checksum = "c845088517daa61e8a57eee40309347cea13f273694d1385c553e7a57127763b"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0",
|
||||
"flate2",
|
||||
"inflate",
|
||||
"num-iter",
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"deflate 0.9.1",
|
||||
"encoding",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1668,15 +1850,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2791d88c6defac799c3f20d74f094ca33b9332612d9aef9078519c82e4fe04a5"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.4"
|
||||
|
@ -1728,14 +1901,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "0.5.0"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b6a6e05e0e6b703e9f2ad266eb63f3712e693a17a2702b95a23de14ce8defa9"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
dependencies = [
|
||||
"deque",
|
||||
"libc",
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
"rand 0.3.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1744,7 +1930,7 @@ version = "0.2.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1796,12 +1982,6 @@ version = "0.1.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.0"
|
||||
|
@ -1894,7 +2074,7 @@ version = "0.15.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1325f292209cee78d5035530932422a30aa4c8fda1a16593ac083c1de211e68a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"calloop",
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
|
@ -1927,6 +2107,15 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "511254be0c5bcf062b019a6c89c01a664aa359ded62f78aa72c6fc137c0590e5"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
|
@ -1989,6 +2178,26 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||
dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0247608e998cb6ce39dfc8f4a16c50361ce71e5b52e6d24ea1227ea8ea8ee0b2"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"jpeg-decoder 0.1.22",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
|
@ -2106,7 +2315,7 @@ version = "0.29.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"downcast-rs",
|
||||
"libc",
|
||||
"nix 0.22.3",
|
||||
|
@ -2155,7 +2364,7 @@ version = "0.29.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"wayland-client",
|
||||
"wayland-commons",
|
||||
"wayland-scanner",
|
||||
|
@ -2204,6 +2413,12 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e"
|
||||
|
||||
[[package]]
|
||||
name = "wepoll-ffi"
|
||||
version = "0.1.2"
|
||||
|
@ -2290,7 +2505,7 @@ version = "0.26.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"cocoa",
|
||||
"core-foundation 0.9.2",
|
||||
"core-graphics 0.22.3",
|
||||
|
@ -2377,7 +2592,7 @@ dependencies = [
|
|||
"async-recursion",
|
||||
"async-task",
|
||||
"async-trait",
|
||||
"byteorder 1.4.3",
|
||||
"byteorder",
|
||||
"derivative",
|
||||
"enumflags2",
|
||||
"event-listener",
|
||||
|
@ -2389,7 +2604,7 @@ dependencies = [
|
|||
"nix 0.23.1",
|
||||
"once_cell",
|
||||
"ordered-stream",
|
||||
"rand 0.8.4",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"sha1",
|
||||
|
@ -2430,7 +2645,7 @@ version = "3.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49ea5dc38b2058fae6a5b79009388143dadce1e91c26a67f984a0fc0381c8033"
|
||||
dependencies = [
|
||||
"byteorder 1.4.3",
|
||||
"byteorder",
|
||||
"enumflags2",
|
||||
"libc",
|
||||
"serde",
|
||||
|
|
|
@ -5,6 +5,6 @@ authors = ["Sebastian <sebastian@sebastians-site.de>"]
|
|||
|
||||
[dependencies]
|
||||
hound = "*"
|
||||
image = "*"
|
||||
image = "0.24.0"
|
||||
eframe = "0.16.0"
|
||||
rfd = "0.7.0"
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time;
|
||||
|
||||
use amdemod::SquaringAMDemodulator;
|
||||
use aptsyncer::{APTSyncer, SyncedSample};
|
||||
use firfilter::FIRFilter;
|
||||
use resamplers::{Downsampler, Upsampler};
|
||||
use utils::float_sample_iterator;
|
||||
|
||||
const LINES_PER_SECOND: u32 = 2;
|
||||
const PIXELS_PER_LINE: u32 = 2080;
|
||||
|
||||
const LOWPASS_COEFFS: [f32; 63] = [
|
||||
-7.383784e-03,
|
||||
-3.183046e-03,
|
||||
2.255039e-03,
|
||||
7.461166e-03,
|
||||
1.091908e-02,
|
||||
1.149109e-02,
|
||||
8.769802e-03,
|
||||
3.252932e-03,
|
||||
-3.720606e-03,
|
||||
-1.027446e-02,
|
||||
-1.447403e-02,
|
||||
-1.486427e-02,
|
||||
-1.092423e-02,
|
||||
-3.307958e-03,
|
||||
6.212477e-03,
|
||||
1.511364e-02,
|
||||
2.072873e-02,
|
||||
2.096037e-02,
|
||||
1.492345e-02,
|
||||
3.347624e-03,
|
||||
-1.138407e-02,
|
||||
-2.560252e-02,
|
||||
-3.507114e-02,
|
||||
-3.591225e-02,
|
||||
-2.553830e-02,
|
||||
-3.371569e-03,
|
||||
2.882645e-02,
|
||||
6.711368e-02,
|
||||
1.060042e-01,
|
||||
1.394643e-01,
|
||||
1.620650e-01,
|
||||
1.700462e-01,
|
||||
1.620650e-01,
|
||||
1.394643e-01,
|
||||
1.060042e-01,
|
||||
6.711368e-02,
|
||||
2.882645e-02,
|
||||
-3.371569e-03,
|
||||
-2.553830e-02,
|
||||
-3.591225e-02,
|
||||
-3.507114e-02,
|
||||
-2.560252e-02,
|
||||
-1.138407e-02,
|
||||
3.347624e-03,
|
||||
1.492345e-02,
|
||||
2.096037e-02,
|
||||
2.072873e-02,
|
||||
1.511364e-02,
|
||||
6.212477e-03,
|
||||
-3.307958e-03,
|
||||
-1.092423e-02,
|
||||
-1.486427e-02,
|
||||
-1.447403e-02,
|
||||
-1.027446e-02,
|
||||
-3.720606e-03,
|
||||
3.252932e-03,
|
||||
8.769802e-03,
|
||||
1.149109e-02,
|
||||
1.091908e-02,
|
||||
7.461166e-03,
|
||||
2.255039e-03,
|
||||
-3.183046e-03,
|
||||
-7.383784e-03,
|
||||
];
|
||||
|
||||
pub fn decode<T>(input_file: &str, output_file: &str, progress_update: T) -> Result<(), String>
|
||||
where
|
||||
T: Fn(f32, image::GrayImage) -> bool,
|
||||
{
|
||||
let mut reader = hound::WavReader::open(input_file)
|
||||
.map_err(|err| format!("Could not open inputfile: {}", err))?;
|
||||
|
||||
if reader.spec().channels != 1 {
|
||||
panic!("Expected a mono file");
|
||||
}
|
||||
|
||||
let sample_rate = reader.spec().sample_rate;
|
||||
println!("Samplerate: {}", sample_rate);
|
||||
if sample_rate != 48000 {
|
||||
return Err("Expected a 48kHz sample rate".to_owned());
|
||||
}
|
||||
|
||||
let sample_count = reader.len();
|
||||
let seconds = (sample_count as f32) / (sample_rate as f32);
|
||||
let lines = (seconds.ceil() as u32) * LINES_PER_SECOND;
|
||||
println!("File contains {} seconds or {} lines", seconds, lines);
|
||||
|
||||
let mut img = image::ImageBuffer::new(PIXELS_PER_LINE, lines);
|
||||
|
||||
let coeffs = &LOWPASS_COEFFS;
|
||||
|
||||
let samples = float_sample_iterator(&mut reader);
|
||||
|
||||
let demod = SquaringAMDemodulator::from(samples);
|
||||
let filter = FIRFilter::from(demod, coeffs);
|
||||
let upsampler = Upsampler::from(filter, 13);
|
||||
let downsampler = Downsampler::from(upsampler, 150);
|
||||
let syncer = APTSyncer::from(downsampler);
|
||||
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mut max_level = 0.0;
|
||||
let mut has_sync = false;
|
||||
|
||||
let mut progress = 0;
|
||||
let step = sample_count * 13 / 150 / 10;
|
||||
|
||||
let mut previous_sample = 0.0;
|
||||
|
||||
print!("0%");
|
||||
std::io::stdout().flush().unwrap();
|
||||
for synced_sample in syncer {
|
||||
progress += 1;
|
||||
|
||||
if progress % step == 0 {
|
||||
print!("...{}%", progress / step * 10);
|
||||
std::io::stdout().flush().unwrap();
|
||||
}
|
||||
|
||||
let sample = match synced_sample {
|
||||
SyncedSample::Sample(s) => s,
|
||||
SyncedSample::SyncA(s) => {
|
||||
if !has_sync {
|
||||
max_level = 0.0;
|
||||
has_sync = true;
|
||||
}
|
||||
x = 0;
|
||||
s
|
||||
}
|
||||
SyncedSample::SyncB(s) => {
|
||||
if x < (PIXELS_PER_LINE / 2) {
|
||||
let skip_distance = (PIXELS_PER_LINE / 2) - x;
|
||||
let color = (previous_sample / max_level * 255.0) as u8;
|
||||
for i in 0..skip_distance {
|
||||
img.put_pixel(x + i, y, image::Luma([color]));
|
||||
}
|
||||
}
|
||||
if !has_sync {
|
||||
max_level = 0.0;
|
||||
has_sync = true;
|
||||
}
|
||||
x = PIXELS_PER_LINE / 2;
|
||||
s
|
||||
}
|
||||
};
|
||||
|
||||
max_level = f32::max(sample, max_level);
|
||||
let color = (sample / max_level * 255.0) as u8;
|
||||
|
||||
if y < lines {
|
||||
img.put_pixel(x, y, image::Luma([color]));
|
||||
}
|
||||
|
||||
x += 1;
|
||||
if x >= PIXELS_PER_LINE {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
|
||||
previous_sample = sample;
|
||||
|
||||
if !progress_update((progress as f32) / (step * 10) as f32, img.clone()) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
println!("");
|
||||
|
||||
img.save_with_format(&Path::new(output_file), image::ImageFormat::Png)
|
||||
.map_err(|err| format!("Could not save outputfile: {}", err))?;
|
||||
|
||||
println!("Done !");
|
||||
|
||||
Ok(())
|
||||
}
|
360
src/main.rs
360
src/main.rs
|
@ -5,367 +5,25 @@ extern crate rfd;
|
|||
|
||||
mod amdemod;
|
||||
mod aptsyncer;
|
||||
mod decoder;
|
||||
mod firfilter;
|
||||
mod resamplers;
|
||||
mod ui;
|
||||
mod utils;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time;
|
||||
|
||||
use amdemod::SquaringAMDemodulator;
|
||||
use aptsyncer::{APTSyncer, SyncedSample};
|
||||
use firfilter::FIRFilter;
|
||||
use resamplers::{Downsampler, Upsampler};
|
||||
use utils::float_sample_iterator;
|
||||
|
||||
const LINES_PER_SECOND: u32 = 2;
|
||||
const PIXELS_PER_LINE: u32 = 2080;
|
||||
|
||||
const LOWPASS_COEFFS: [f32; 63] = [
|
||||
-7.383784e-03,
|
||||
-3.183046e-03,
|
||||
2.255039e-03,
|
||||
7.461166e-03,
|
||||
1.091908e-02,
|
||||
1.149109e-02,
|
||||
8.769802e-03,
|
||||
3.252932e-03,
|
||||
-3.720606e-03,
|
||||
-1.027446e-02,
|
||||
-1.447403e-02,
|
||||
-1.486427e-02,
|
||||
-1.092423e-02,
|
||||
-3.307958e-03,
|
||||
6.212477e-03,
|
||||
1.511364e-02,
|
||||
2.072873e-02,
|
||||
2.096037e-02,
|
||||
1.492345e-02,
|
||||
3.347624e-03,
|
||||
-1.138407e-02,
|
||||
-2.560252e-02,
|
||||
-3.507114e-02,
|
||||
-3.591225e-02,
|
||||
-2.553830e-02,
|
||||
-3.371569e-03,
|
||||
2.882645e-02,
|
||||
6.711368e-02,
|
||||
1.060042e-01,
|
||||
1.394643e-01,
|
||||
1.620650e-01,
|
||||
1.700462e-01,
|
||||
1.620650e-01,
|
||||
1.394643e-01,
|
||||
1.060042e-01,
|
||||
6.711368e-02,
|
||||
2.882645e-02,
|
||||
-3.371569e-03,
|
||||
-2.553830e-02,
|
||||
-3.591225e-02,
|
||||
-3.507114e-02,
|
||||
-2.560252e-02,
|
||||
-1.138407e-02,
|
||||
3.347624e-03,
|
||||
1.492345e-02,
|
||||
2.096037e-02,
|
||||
2.072873e-02,
|
||||
1.511364e-02,
|
||||
6.212477e-03,
|
||||
-3.307958e-03,
|
||||
-1.092423e-02,
|
||||
-1.486427e-02,
|
||||
-1.447403e-02,
|
||||
-1.027446e-02,
|
||||
-3.720606e-03,
|
||||
3.252932e-03,
|
||||
8.769802e-03,
|
||||
1.149109e-02,
|
||||
1.091908e-02,
|
||||
7.461166e-03,
|
||||
2.255039e-03,
|
||||
-3.183046e-03,
|
||||
-7.383784e-03,
|
||||
];
|
||||
|
||||
use eframe::egui::text_edit::TextEdit;
|
||||
use eframe::egui::widgets::{Button, ProgressBar};
|
||||
use eframe::egui::{Color32, RichText};
|
||||
use eframe::{egui, epi};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum DecoderRunState {
|
||||
RUNNING,
|
||||
CANCELED,
|
||||
DONE,
|
||||
}
|
||||
|
||||
struct DecoderJobState {
|
||||
progress: f32,
|
||||
run_state: DecoderRunState,
|
||||
}
|
||||
|
||||
impl DecoderJobState {
|
||||
fn is_running(&self) -> bool {
|
||||
self.run_state == DecoderRunState::RUNNING
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DecoderJobState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
progress: 0.0,
|
||||
run_state: DecoderRunState::DONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DecoderApp {
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
decoding_state: Arc<Mutex<DecoderJobState>>,
|
||||
}
|
||||
|
||||
impl Default for DecoderApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// Example stuff:
|
||||
input_path: "input.wav".to_owned(),
|
||||
output_path: "output.png".to_owned(),
|
||||
decoding_state: Arc::new(Mutex::new(DecoderJobState::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl epi::App for DecoderApp {
|
||||
fn name(&self) -> &str {
|
||||
"eframe template"
|
||||
}
|
||||
|
||||
/// Called once before the first frame.
|
||||
fn setup(
|
||||
&mut self,
|
||||
_ctx: &egui::CtxRef,
|
||||
_frame: &epi::Frame,
|
||||
_storage: Option<&dyn epi::Storage>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Called each time the UI needs repainting, which may be many times per second.
|
||||
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
|
||||
let Self {
|
||||
input_path,
|
||||
output_path,
|
||||
decoding_state,
|
||||
} = self;
|
||||
|
||||
{
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
|
||||
if !ctx.input().raw.dropped_files.is_empty() && !state.is_running() {
|
||||
if let Some(path) = ctx.input().raw.dropped_files[0].clone().path {
|
||||
*input_path = path.display().to_string();
|
||||
}
|
||||
}
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("APT-Decoder");
|
||||
|
||||
egui::Grid::new("form_grid").num_columns(3).show(ui, |ui| {
|
||||
ui.label("Input Wav File:");
|
||||
ui.add_sized([300.0, 20.0], TextEdit::singleline(input_path));
|
||||
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Open"))
|
||||
.clicked()
|
||||
{
|
||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||
*input_path = path.display().to_string();
|
||||
}
|
||||
};
|
||||
ui.end_row();
|
||||
|
||||
ui.label("Output PNG File:");
|
||||
ui.add_sized([300.0, 20.0], TextEdit::singleline(output_path));
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Save"))
|
||||
.clicked()
|
||||
{
|
||||
if let Some(path) = rfd::FileDialog::new().save_file() {
|
||||
*output_path = path.display().to_string();
|
||||
}
|
||||
};
|
||||
ui.end_row();
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Decode"))
|
||||
.clicked()
|
||||
{
|
||||
let frame = frame.clone();
|
||||
let decoding_state = decoding_state.clone();
|
||||
state.run_state = DecoderRunState::RUNNING;
|
||||
let thread = std::thread::spawn(move || {
|
||||
for i in 0..101 {
|
||||
{
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
if state.run_state == DecoderRunState::CANCELED {
|
||||
frame.request_repaint();
|
||||
return;
|
||||
}
|
||||
state.progress = (i as f32) / 100.0;
|
||||
}
|
||||
frame.request_repaint();
|
||||
|
||||
std::thread::sleep(time::Duration::from_millis(200));
|
||||
}
|
||||
|
||||
{
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
state.progress = 100.0;
|
||||
state.run_state = DecoderRunState::DONE;
|
||||
}
|
||||
});
|
||||
}
|
||||
if ui
|
||||
.add_enabled(
|
||||
state.is_running(),
|
||||
Button::new(RichText::new("Cancel").color(Color32::RED)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
state.run_state = DecoderRunState::CANCELED;
|
||||
}
|
||||
});
|
||||
|
||||
let progressbar = ProgressBar::new(state.progress).show_percentage();
|
||||
ui.add(progressbar);
|
||||
|
||||
ui.separator();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
use ui::DecoderApp;
|
||||
|
||||
fn main() {
|
||||
let app = DecoderApp::default();
|
||||
let native_options = eframe::NativeOptions::default();
|
||||
eframe::run_native(Box::new(app), native_options);
|
||||
|
||||
//let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
/*
|
||||
let args : Vec<String> = std::env::args().collect();
|
||||
|
||||
if args.len() != 3 {
|
||||
println!("Usage: {} <wav file> <output file>", args[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut reader = match hound::WavReader::open(&args[1]) {
|
||||
Err(e) => panic!("Could not open inputfile: {}", e),
|
||||
Ok(r) => r
|
||||
};
|
||||
|
||||
if reader.spec().channels != 1 {
|
||||
panic!("Expected a mono file");
|
||||
}
|
||||
|
||||
let sample_rate = reader.spec().sample_rate;
|
||||
println!("Samplerate: {}", sample_rate);
|
||||
if sample_rate != 48000 {
|
||||
panic!("Expected a 48kHz sample rate");
|
||||
}
|
||||
|
||||
let sample_count = reader.len();
|
||||
let seconds = (sample_count as f32) / (sample_rate as f32);
|
||||
let lines = (seconds.ceil() as u32) * LINES_PER_SECOND;
|
||||
println!("File contains {} seconds or {} lines", seconds, lines);
|
||||
|
||||
let mut img = image::ImageBuffer::new(PIXELS_PER_LINE, lines);
|
||||
|
||||
let coeffs = &LOWPASS_COEFFS;
|
||||
|
||||
let samples = float_sample_iterator(&mut reader);
|
||||
|
||||
let demod = SquaringAMDemodulator::from(samples);
|
||||
let filter = FIRFilter::from(demod, coeffs);
|
||||
let upsampler = Upsampler::from(filter, 13);
|
||||
let downsampler = Downsampler::from(upsampler, 150);
|
||||
let syncer = APTSyncer::from(downsampler);
|
||||
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
let mut max_level = 0.0;
|
||||
let mut has_sync = false;
|
||||
|
||||
let mut progress = 0;
|
||||
let step = sample_count * 13 / 150 / 10;
|
||||
|
||||
let mut previous_sample = 0.0;
|
||||
|
||||
print!("0%");
|
||||
std::io::stdout().flush().unwrap();
|
||||
for synced_sample in syncer {
|
||||
progress += 1;
|
||||
|
||||
if progress % step == 0 {
|
||||
print!("...{}%", progress / step * 10);
|
||||
std::io::stdout().flush().unwrap();
|
||||
}
|
||||
|
||||
let sample = match synced_sample {
|
||||
SyncedSample::Sample(s) => s,
|
||||
SyncedSample::SyncA(s) =>{
|
||||
if !has_sync {
|
||||
max_level = 0.0;
|
||||
has_sync = true;
|
||||
}
|
||||
x = 0;
|
||||
s
|
||||
}
|
||||
SyncedSample::SyncB(s) =>{
|
||||
if x < (PIXELS_PER_LINE / 2) {
|
||||
let skip_distance = (PIXELS_PER_LINE / 2) - x;
|
||||
let color = (previous_sample / max_level * 255.0) as u8;
|
||||
for i in 0..skip_distance {
|
||||
img.put_pixel(x + i,y,image::Luma([color]));
|
||||
}
|
||||
}
|
||||
if !has_sync {
|
||||
max_level = 0.0;
|
||||
has_sync = true;
|
||||
}
|
||||
x = PIXELS_PER_LINE / 2;
|
||||
s
|
||||
}
|
||||
};
|
||||
|
||||
max_level = f32::max(sample, max_level);
|
||||
let color = (sample / max_level * 255.0) as u8;
|
||||
|
||||
if y < lines {
|
||||
img.put_pixel(x,y,image::Luma([color]));
|
||||
}
|
||||
|
||||
x += 1;
|
||||
if x >= PIXELS_PER_LINE {
|
||||
x = 0;
|
||||
y += 1;
|
||||
}
|
||||
|
||||
previous_sample = sample;
|
||||
}
|
||||
println!("");
|
||||
|
||||
let ref mut fout = match File::create(&Path::new(&args[2])) {
|
||||
Err(e) => panic!("Could not open outputfile: {}", e),
|
||||
Ok(f) => f
|
||||
};
|
||||
|
||||
image::ImageLuma8(img).save(fout, image::PNG).unwrap();
|
||||
if args.len() != 3 {
|
||||
println!("Usage: {} <wav file> <output file>", args[0]);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
println!("Done !");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::time;
|
||||
|
||||
use eframe::egui::text_edit::TextEdit;
|
||||
use eframe::egui::widgets::{Button, ProgressBar};
|
||||
use eframe::egui::{Color32, RichText};
|
||||
use eframe::{egui, epi};
|
||||
|
||||
use decoder;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum DecoderRunState {
|
||||
RUNNING,
|
||||
CANCELED,
|
||||
DONE,
|
||||
}
|
||||
|
||||
struct DecoderJobState {
|
||||
progress: f32,
|
||||
image: image::GrayImage,
|
||||
run_state: DecoderRunState,
|
||||
}
|
||||
|
||||
impl DecoderJobState {
|
||||
fn is_running(&self) -> bool {
|
||||
self.run_state == DecoderRunState::RUNNING
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DecoderJobState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
progress: 0.0,
|
||||
image: image::GrayImage::new(1, 1),
|
||||
run_state: DecoderRunState::DONE,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DecoderApp {
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
decoding_state: Arc<Mutex<DecoderJobState>>,
|
||||
}
|
||||
|
||||
impl Default for DecoderApp {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// Example stuff:
|
||||
input_path: "input.wav".to_owned(),
|
||||
output_path: "output.png".to_owned(),
|
||||
decoding_state: Arc::new(Mutex::new(DecoderJobState::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl epi::App for DecoderApp {
|
||||
fn name(&self) -> &str {
|
||||
"eframe template"
|
||||
}
|
||||
|
||||
/// Called once before the first frame.
|
||||
fn setup(
|
||||
&mut self,
|
||||
_ctx: &egui::CtxRef,
|
||||
_frame: &epi::Frame,
|
||||
_storage: Option<&dyn epi::Storage>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Called each time the UI needs repainting, which may be many times per second.
|
||||
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
fn update(&mut self, ctx: &egui::CtxRef, frame: &epi::Frame) {
|
||||
let Self {
|
||||
input_path,
|
||||
output_path,
|
||||
decoding_state,
|
||||
} = self;
|
||||
|
||||
{
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
|
||||
if !ctx.input().raw.dropped_files.is_empty() && !state.is_running() {
|
||||
if let Some(path) = ctx.input().raw.dropped_files[0].clone().path {
|
||||
*input_path = path.display().to_string();
|
||||
}
|
||||
}
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("APT-Decoder");
|
||||
|
||||
egui::Grid::new("form_grid").num_columns(3).show(ui, |ui| {
|
||||
ui.label("Input Wav File:");
|
||||
ui.add_sized(
|
||||
[300.0, 20.0],
|
||||
TextEdit::singleline(input_path).interactive(!state.is_running()),
|
||||
);
|
||||
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Open"))
|
||||
.clicked()
|
||||
{
|
||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||
*input_path = path.display().to_string();
|
||||
}
|
||||
};
|
||||
ui.end_row();
|
||||
|
||||
ui.label("Output PNG File:");
|
||||
ui.add_sized(
|
||||
[300.0, 20.0],
|
||||
TextEdit::singleline(output_path).interactive(!state.is_running()),
|
||||
);
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Save"))
|
||||
.clicked()
|
||||
{
|
||||
if let Some(path) = rfd::FileDialog::new().save_file() {
|
||||
*output_path = path.display().to_string();
|
||||
}
|
||||
};
|
||||
ui.end_row();
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.add_enabled(!state.is_running(), Button::new("Decode"))
|
||||
.clicked()
|
||||
{
|
||||
let frame = frame.clone();
|
||||
let decoding_state = decoding_state.clone();
|
||||
let input_path = input_path.clone();
|
||||
let output_path = output_path.clone();
|
||||
state.run_state = DecoderRunState::RUNNING;
|
||||
std::thread::spawn(move || {
|
||||
decoder::decode(&input_path, &output_path, |progress, image| {
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
state.progress = progress;
|
||||
state.image = image;
|
||||
|
||||
frame.request_repaint();
|
||||
return state.is_running();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let mut state = decoding_state.lock().unwrap();
|
||||
state.run_state = DecoderRunState::DONE;
|
||||
});
|
||||
}
|
||||
if ui
|
||||
.add_enabled(
|
||||
state.is_running(),
|
||||
Button::new(RichText::new("Cancel").color(Color32::RED)),
|
||||
)
|
||||
.clicked()
|
||||
{
|
||||
state.run_state = DecoderRunState::CANCELED;
|
||||
}
|
||||
});
|
||||
|
||||
let progressbar = ProgressBar::new(state.progress).show_percentage();
|
||||
ui.add(progressbar);
|
||||
|
||||
ui.separator();
|
||||
|
||||
let size = [state.image.width() as _, state.image.height() as _];
|
||||
let image_buffer =
|
||||
image::DynamicImage::ImageLuma8(state.image.clone()).into_rgba8();
|
||||
let pixels = image_buffer.as_flat_samples();
|
||||
let epi_img = epi::Image::from_rgba_unmultiplied(size, pixels.as_slice());
|
||||
|
||||
let texture = frame.alloc_texture(epi_img);
|
||||
let size = egui::Vec2::new(size[0] as f32, size[1] as f32);
|
||||
|
||||
ui.image(texture, size);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue