Compare commits
3 Commits
8efb9c031e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 497cc3b61c | |||
| 7b3bd7e2e5 | |||
| 3d42a7b61b |
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
/target
|
||||
test.iq
|
||||
# test.iq
|
||||
test.py
|
||||
/frames
|
||||
*.png
|
||||
*.mp4
|
||||
|
||||
214
Cargo.lock
generated
214
Cargo.lock
generated
@ -635,9 +635,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593"
|
||||
|
||||
[[package]]
|
||||
name = "calloop"
|
||||
@ -1421,15 +1421,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
|
||||
checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi 6.0.0",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1603,12 +1601,6 @@ version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.5.2"
|
||||
@ -1709,12 +1701,6 @@ dependencies = [
|
||||
"zerovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "id-arena"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "1.1.0"
|
||||
@ -1772,9 +1758,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "imgref"
|
||||
version = "1.12.1"
|
||||
version = "1.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2"
|
||||
checksum = "89194689a993ab15268672e99e7b0e19da2da3268ac682e8f02d29d4d1434cd7"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
@ -1784,8 +1770,6 @@ checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.17.1",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1821,12 +1805,6 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.22.4"
|
||||
@ -1935,12 +1913,6 @@ dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.3"
|
||||
@ -2859,16 +2831,6 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.5.0"
|
||||
@ -3259,19 +3221,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.150"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_repr"
|
||||
version = "0.1.20"
|
||||
@ -3468,9 +3417,9 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
version = "2.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3495,7 +3444,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.4.2",
|
||||
"getrandom 0.4.3",
|
||||
"once_cell",
|
||||
"rustix 1.1.4",
|
||||
"windows-sys 0.61.2",
|
||||
@ -3705,12 +3654,6 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "unit-prefix"
|
||||
version = "0.5.2"
|
||||
@ -3805,16 +3748,7 @@ version = "1.0.4+wasi-0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
|
||||
dependencies = [
|
||||
"wit-bindgen 0.57.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip3"
|
||||
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
||||
dependencies = [
|
||||
"wit-bindgen 0.51.0",
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3872,40 +3806,6 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
||||
dependencies = [
|
||||
"bitflags 2.13.0",
|
||||
"hashbrown 0.15.5",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wayland-backend"
|
||||
version = "0.3.15"
|
||||
@ -4606,100 +4506,12 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
dependencies = [
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
"syn",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.13.0",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder",
|
||||
"wasm-metadata",
|
||||
"wasmparser",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "writeable"
|
||||
version = "0.6.3"
|
||||
@ -4969,12 +4781,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.5.1"
|
||||
|
||||
@ -4,9 +4,9 @@ use std::path::Path;
|
||||
|
||||
use crate::line_assembler::VideoFrame;
|
||||
|
||||
// PAL
|
||||
// PAL: 1280 samples per line
|
||||
const WIDTH: u32 = 1280;
|
||||
const HEIGHT: u32 = 288;
|
||||
const HEIGHT: u32 = 480; // NTSC (576 for PAL)
|
||||
|
||||
pub fn save_frames(frames: &[VideoFrame], output_dir: &str, sig_min: f32, sig_max: f32) {
|
||||
fs::create_dir_all(output_dir).expect("Could not create output directory");
|
||||
@ -22,7 +22,6 @@ pub fn save_frames(frames: &[VideoFrame], output_dir: &str, sig_min: f32, sig_ma
|
||||
let mut img = GrayImage::new(WIDTH, HEIGHT);
|
||||
|
||||
for y in 0..HEIGHT as usize {
|
||||
// If the frame has fewer lines than HEIGHT, fill the rest with black
|
||||
let line = frame.lines.get(y);
|
||||
|
||||
for x in 0..WIDTH as usize {
|
||||
|
||||
@ -8,6 +8,8 @@ pub struct VideoFrame {
|
||||
pub lines: Vec<VideoLine>,
|
||||
}
|
||||
|
||||
const LINES_PER_FRAME: usize = 480; // NTSC (576 for PAL)
|
||||
|
||||
pub struct LineAssembler<I> {
|
||||
pub inner: I,
|
||||
pub current_line: Vec<Sample>,
|
||||
@ -37,22 +39,57 @@ where
|
||||
self.current_line.push(s);
|
||||
}
|
||||
Ok(SyncEvent::HSync) => {
|
||||
// Save the finished line
|
||||
let line = VideoLine {
|
||||
samples: std::mem::take(&mut self.current_line),
|
||||
};
|
||||
|
||||
self.current_frame.push(line);
|
||||
}
|
||||
Ok(SyncEvent::VSync) => {
|
||||
// Frame finished
|
||||
|
||||
if self.current_frame.len() >= LINES_PER_FRAME {
|
||||
let frame = VideoFrame {
|
||||
lines: std::mem::take(&mut self.current_frame),
|
||||
};
|
||||
return Some(Ok(frame));
|
||||
}
|
||||
}
|
||||
Ok(SyncEvent::VSync) => {
|
||||
// test without vsync
|
||||
}
|
||||
Err(e) => return Some(Err(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl<I, E> Iterator for LineAssembler<I>
|
||||
// where
|
||||
// I: Iterator<Item = Result<SyncEvent, E>>,
|
||||
// {
|
||||
// type Item = Result<VideoFrame, E>;
|
||||
//
|
||||
// fn next(&mut self) -> Option<Self::Item> {
|
||||
// loop {
|
||||
// match self.inner.next()? {
|
||||
// Ok(SyncEvent::VideoSample(s)) => {
|
||||
// self.current_line.push(s);
|
||||
// }
|
||||
// Ok(SyncEvent::HSync) => {
|
||||
// // Save the finished line
|
||||
// let line = VideoLine {
|
||||
// samples: std::mem::take(&mut self.current_line),
|
||||
// };
|
||||
//
|
||||
// self.current_frame.push(line);
|
||||
// }
|
||||
// Ok(SyncEvent::VSync) => {
|
||||
// // Frame finished
|
||||
// let frame = VideoFrame {
|
||||
// lines: std::mem::take(&mut self.current_frame),
|
||||
// };
|
||||
// self.current_line.clear();
|
||||
// return Some(Ok(frame));
|
||||
// }
|
||||
// Err(e) => return Some(Err(e)),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
201
src/main.rs
201
src/main.rs
@ -1,7 +1,7 @@
|
||||
use crate::fm_demod::Sample;
|
||||
use crate::iq_reader::FileSource;
|
||||
use crate::pipeline::{AfterDemodPiplineExt, DspPipelineExt, SyncPipelineExt};
|
||||
use egui_plot::{Line, Plot};
|
||||
use egui_plot::{HLine, Line, Plot, VLine};
|
||||
use indicatif::ProgressIterator;
|
||||
|
||||
mod agc;
|
||||
@ -17,16 +17,84 @@ mod sync;
|
||||
mod utils;
|
||||
|
||||
const SAMPLE_RATE: f32 = 20_000_000.0;
|
||||
const SYNC_THRESHOLD: f32 = -0.3;
|
||||
const LOWPASS_ALPHA: f32 = 0.6;
|
||||
const SYNC_THRESHOLD: f32 = -0.4;
|
||||
const LOWPASS_ALPHA: f32 = 0.7;
|
||||
|
||||
// fn main() -> eframe::Result {
|
||||
fn main() {
|
||||
// fn main() {
|
||||
let taps: [f32; 64] = [
|
||||
-0.00015813,
|
||||
-0.00047836,
|
||||
-0.00080166,
|
||||
-0.00110309,
|
||||
-0.00132172,
|
||||
-0.00136203,
|
||||
-0.00111203,
|
||||
-0.00047680,
|
||||
0.00057973,
|
||||
0.00199526,
|
||||
0.00358456,
|
||||
0.00504093,
|
||||
0.00597041,
|
||||
0.00595859,
|
||||
0.00466189,
|
||||
0.00190795,
|
||||
-0.00221520,
|
||||
-0.00730261,
|
||||
-0.01262639,
|
||||
-0.01719077,
|
||||
-0.01984753,
|
||||
-0.01945971,
|
||||
-0.01509023,
|
||||
-0.00618502,
|
||||
0.00728221,
|
||||
0.02473253,
|
||||
0.04499119,
|
||||
0.06638976,
|
||||
0.08695132,
|
||||
0.10463402,
|
||||
0.11759778,
|
||||
0.12445312,
|
||||
0.12445312,
|
||||
0.11759778,
|
||||
0.10463402,
|
||||
0.08695132,
|
||||
0.06638976,
|
||||
0.04499119,
|
||||
0.02473253,
|
||||
0.00728221,
|
||||
-0.00618502,
|
||||
-0.01509023,
|
||||
-0.01945971,
|
||||
-0.01984753,
|
||||
-0.01719077,
|
||||
-0.01262639,
|
||||
-0.00730261,
|
||||
-0.00221520,
|
||||
0.00190795,
|
||||
0.00466189,
|
||||
0.00595859,
|
||||
0.00597041,
|
||||
0.00504093,
|
||||
0.00358456,
|
||||
0.00199526,
|
||||
0.00057973,
|
||||
-0.00047680,
|
||||
-0.00111203,
|
||||
-0.00136203,
|
||||
-0.00132172,
|
||||
-0.00110309,
|
||||
-0.00080166,
|
||||
-0.00047836,
|
||||
-0.00015813,
|
||||
];
|
||||
|
||||
let source = FileSource::new("test.iq", 32769).unwrap();
|
||||
let samples: Vec<f32> = source
|
||||
.skip(10_000)
|
||||
.take(100_000)
|
||||
.take(10_000)
|
||||
.agc(SAMPLE_RATE, 1.0, 0.001, 100.0)
|
||||
// .fir(taps, 1)
|
||||
.demodulate()
|
||||
.dc_block(0.997)
|
||||
.lowpass(LOWPASS_ALPHA)
|
||||
@ -41,12 +109,12 @@ fn main() {
|
||||
|
||||
let source = FileSource::new("test.iq", 32769).unwrap();
|
||||
|
||||
// let taps = [0.5; 64];
|
||||
|
||||
let frames: Vec<_> = source
|
||||
.take(50_000_000)
|
||||
.skip(10_000)
|
||||
.take(5_000_000)
|
||||
.progress()
|
||||
.agc(SAMPLE_RATE, 1.0, 0.001, 100.0)
|
||||
// .fir(taps, 1)
|
||||
.demodulate()
|
||||
.dc_block(0.997)
|
||||
.lowpass(LOWPASS_ALPHA)
|
||||
@ -59,21 +127,63 @@ fn main() {
|
||||
|
||||
frame::save_frames(&frames, "frames", min, max);
|
||||
|
||||
// let source2 = FileSource::new("test.iq", 32769).unwrap();
|
||||
//
|
||||
// let samples: Vec<Sample> = source2
|
||||
// .skip(10_000)
|
||||
// .take(10_000)
|
||||
// .progress()
|
||||
// .agc(20_000_000.0, 1.0, 0.001, 100.0)
|
||||
// // .fir::<64>(taps, 4)
|
||||
// .demodulate()
|
||||
// .dc_block(0.997)
|
||||
// .lowpass(0.75)
|
||||
// .filter_map(|r| r.ok())
|
||||
// .collect();
|
||||
//
|
||||
// eframe::run_ui_native("DSP", Default::default(), move |ui, _frame| {
|
||||
let source = FileSource::new("test.iq", 32769).unwrap();
|
||||
let samples: Vec<Sample> = source
|
||||
.skip(40_000)
|
||||
.take(1_000_000)
|
||||
.progress()
|
||||
.agc(20_000_000.0, 1.0, 0.001, 100.0)
|
||||
// .fir::<64>(taps, 1)
|
||||
.demodulate()
|
||||
.dc_block(0.997)
|
||||
.lowpass(0.75)
|
||||
.filter_map(|r| r.ok())
|
||||
.collect();
|
||||
|
||||
let source = FileSource::new("test.iq", 32769).unwrap();
|
||||
let sync_events: Vec<(usize, &str)> = {
|
||||
use crate::sync::SyncEvent;
|
||||
let mut events = Vec::new();
|
||||
|
||||
let source = FileSource::new("test.iq", 32769).unwrap();
|
||||
let mut separator = source
|
||||
.progress()
|
||||
.skip(40_000)
|
||||
.take(1_000_000)
|
||||
.agc(SAMPLE_RATE, 1.0, 0.001, 100.0)
|
||||
.demodulate()
|
||||
.dc_block(0.997)
|
||||
.lowpass(LOWPASS_ALPHA)
|
||||
.sync_separate(SAMPLE_RATE, SYNC_THRESHOLD);
|
||||
|
||||
while let Some(r) = separator.next() {
|
||||
if let Ok(evt) = r {
|
||||
let pos = separator.samples_consumed;
|
||||
match evt {
|
||||
SyncEvent::HSync => events.push((pos, "h")),
|
||||
SyncEvent::VSync => {
|
||||
events.push((pos, "v"));
|
||||
println!("vsync\n")
|
||||
}
|
||||
SyncEvent::VideoSample(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
events
|
||||
};
|
||||
|
||||
let _ = eframe::run_native(
|
||||
"DSP debug",
|
||||
Default::default(),
|
||||
Box::new(move |_cc| {
|
||||
Ok(Box::new(DebugApp {
|
||||
samples,
|
||||
sync_events,
|
||||
}))
|
||||
}),
|
||||
);
|
||||
|
||||
// let _ = eframe::run_ui_native("DSP", Default::default(), move |ui, _frame| {
|
||||
// egui::CentralPanel::default().show(ui, |ui| {
|
||||
// Plot::new("plot").show(ui, |plot_ui| {
|
||||
// plot_ui.line(Line::new(
|
||||
@ -87,5 +197,48 @@ fn main() {
|
||||
// ))
|
||||
// })
|
||||
// });
|
||||
// })
|
||||
// });
|
||||
}
|
||||
|
||||
struct DebugApp {
|
||||
samples: Vec<Sample>,
|
||||
sync_events: Vec<(usize, &'static str)>,
|
||||
}
|
||||
|
||||
impl eframe::App for DebugApp {
|
||||
fn ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||
Plot::new("plot").show(ui, |plot_ui| {
|
||||
plot_ui.line(Line::new(
|
||||
"Signal",
|
||||
self.samples
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, x)| [i as f64, *x as f64])
|
||||
.collect::<Vec<_>>(),
|
||||
));
|
||||
|
||||
plot_ui.hline(
|
||||
HLine::new("Threshold", SYNC_THRESHOLD as f64)
|
||||
.color(egui::Color32::YELLOW)
|
||||
.width(4.0),
|
||||
);
|
||||
|
||||
for (pos, kind) in &self.sync_events {
|
||||
let x = *pos as f64;
|
||||
match *kind {
|
||||
"h" => plot_ui.vline(
|
||||
VLine::new("HSync", x)
|
||||
.color(egui::Color32::from_rgb(80, 160, 255))
|
||||
.width(4.0),
|
||||
),
|
||||
"v" => plot_ui.vline(
|
||||
VLine::new("VSync", x)
|
||||
.color(egui::Color32::BROWN)
|
||||
.width(10.0),
|
||||
),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ pub struct SyncSeparator<I> {
|
||||
pub hsync_min: usize,
|
||||
pub hsync_max: usize,
|
||||
pub vsync_min: usize,
|
||||
pub samples_consumed: usize,
|
||||
}
|
||||
|
||||
impl<I> SyncSeparator<I> {
|
||||
@ -30,13 +31,15 @@ impl<I> SyncSeparator<I> {
|
||||
inner,
|
||||
state: SyncState::Active,
|
||||
sync_threshold,
|
||||
hsync_min: us(3.5),
|
||||
hsync_max: us(6.0),
|
||||
hsync_min: us(2.0),
|
||||
hsync_max: us(10.0),
|
||||
vsync_min: us(25.0),
|
||||
samples_consumed: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_sample(&mut self, sample: Sample) -> Option<SyncEvent> {
|
||||
self.samples_consumed += 1;
|
||||
match self.state {
|
||||
SyncState::Active => {
|
||||
if sample < self.sync_threshold {
|
||||
@ -58,7 +61,7 @@ impl<I> SyncSeparator<I> {
|
||||
} else if pulse_len >= self.hsync_min && pulse_len <= self.hsync_max {
|
||||
Some(SyncEvent::HSync)
|
||||
} else {
|
||||
None
|
||||
Some(SyncEvent::VideoSample(sample))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user