diff --git a/Cargo.lock b/Cargo.lock index e11f367..11e7df1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -55,11 +61,21 @@ dependencies = [ name = "ntw" version = "0.1.0" dependencies = [ + "ntw_dsp", "ntw_flowgraph", "ntw_flowgraph_macros", "ringbuf", ] +[[package]] +name = "ntw_dsp" +version = "0.1.0" +dependencies = [ + "ntw_flowgraph", + "ntw_flowgraph_macros", + "num", +] + [[package]] name = "ntw_flowgraph" version = "0.1.0" @@ -78,6 +94,79 @@ dependencies = [ "syn", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "petgraph" version = "0.8.3" diff --git a/Cargo.toml b/Cargo.toml index 47a9577..8f3a3e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2024" [dependencies] ntw_flowgraph = {path = "ntw_flowgraph"} ntw_flowgraph_macros = {path = "ntw_flowgraph_macros"} +ntw_dsp = {path = "ntw_dsp"} ringbuf = "0.4.8" diff --git a/ntw_dsp/.gitignore b/ntw_dsp/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/ntw_dsp/.gitignore @@ -0,0 +1 @@ +/target diff --git a/ntw_dsp/Cargo.lock b/ntw_dsp/Cargo.lock new file mode 100644 index 0000000..b672c5b --- /dev/null +++ b/ntw_dsp/Cargo.lock @@ -0,0 +1,260 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + +[[package]] +name = "ntw_dsp" +version = "0.1.0" +dependencies = [ + "ntw_flowgraph", + "ntw_flowgraph_macros", + "num", +] + +[[package]] +name = "ntw_flowgraph" +version = "0.1.0" +dependencies = [ + "ntw_flowgraph_macros", + "petgraph", + "ringbuf", +] + +[[package]] +name = "ntw_flowgraph_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", + "serde", +] + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "portable-atomic-util" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9db96d7fa8782dd8c15ce32ffe8680bbd1e978a43bf51a34d39483540495f5" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ringbuf" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe47b720588c8702e34b5979cb3271a8b1842c7cb6f57408efa70c779363488c" +dependencies = [ + "crossbeam-utils", + "portable-atomic", + "portable-atomic-util", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" diff --git a/ntw_dsp/Cargo.toml b/ntw_dsp/Cargo.toml new file mode 100644 index 0000000..9ecf186 --- /dev/null +++ b/ntw_dsp/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ntw_dsp" +version = "0.1.0" +edition = "2024" + +[dependencies] +ntw_flowgraph = {path = "../ntw_flowgraph/"} +ntw_flowgraph_macros = {path = "../ntw_flowgraph_macros/"} +num = "0.4.3" diff --git a/ntw_dsp/src/blocks.rs b/ntw_dsp/src/blocks.rs new file mode 100644 index 0000000..5b61997 --- /dev/null +++ b/ntw_dsp/src/blocks.rs @@ -0,0 +1,5 @@ +pub mod complex; +pub mod iter; +pub mod map; +pub mod nco; +pub mod tee; diff --git a/ntw_dsp/src/blocks/complex.rs b/ntw_dsp/src/blocks/complex.rs new file mode 100644 index 0000000..e731027 --- /dev/null +++ b/ntw_dsp/src/blocks/complex.rs @@ -0,0 +1,24 @@ +use ntw_flowgraph::Block; +use ntw_flowgraph::inout::{In, Out}; +use ntw_flowgraph_macros::Block; +use num::Complex; + +#[derive(Block)] +pub struct Im +{ + #[input] + input: In>, + + #[output] + output: Out, +} + +#[derive(Block)] +pub struct Re +{ + #[input] + input: In>, + + #[output] + output: Out, +} diff --git a/ntw_dsp/src/blocks/iter.rs b/ntw_dsp/src/blocks/iter.rs new file mode 100644 index 0000000..fcb0e32 --- /dev/null +++ b/ntw_dsp/src/blocks/iter.rs @@ -0,0 +1,50 @@ +use std::iter::Peekable; + +use ntw_flowgraph::{ + BlockWork, + inout::{In, Out, Stream}, +}; +use ntw_flowgraph_macros::Block; + +#[derive(Block)] +pub struct IterSource +where + I: Iterator, +{ + iter: Peekable, + + #[output] + output: Out, +} + +impl IterSource +where + I: Iterator, +{ + pub fn new(iter: I) -> (Self, In) + { + let (output, input) = Stream::make(1024); + ( + Self { + iter: iter.peekable(), + output, + }, + input, + ) + } +} + +impl BlockWork for IterSource +where + I: Iterator, +{ + fn work(&mut self) + { + self.output.push_iter(&mut self.iter); + } + + fn ready(&mut self) -> bool + { + self.iter.peek().is_some() && self.output.vacant_len() > 0 + } +} diff --git a/ntw_dsp/src/blocks/map.rs b/ntw_dsp/src/blocks/map.rs new file mode 100644 index 0000000..f100084 --- /dev/null +++ b/ntw_dsp/src/blocks/map.rs @@ -0,0 +1,45 @@ +use ntw_flowgraph::{ + Block, BlockWork, + inout::{In, Out, Stream}, +}; +use ntw_flowgraph_macros::Block; + +#[derive(Block)] +pub struct Map +where + F: Fn(I) -> O, +{ + #[input] + input: In, + + #[output] + output: Out, + + map: F, +} + +impl Map +where + F: Fn(I) -> O, +{ + pub fn new(input: In, map: F) -> (Self, In) + { + let (output, b) = Stream::make(1024); + (Self { input, output, map }, b) + } +} + +impl BlockWork for Map +where + F: Fn(I) -> O, +{ + fn work(&mut self) + { + self.output.push_iter(self.input.pop_iter().map(&self.map)); + } + + fn ready(&self) -> bool + { + self.input.available_len() > 0 && self.output.vacant_len() > 0 + } +} diff --git a/ntw_dsp/src/blocks/nco.rs b/ntw_dsp/src/blocks/nco.rs new file mode 100644 index 0000000..3fa2052 --- /dev/null +++ b/ntw_dsp/src/blocks/nco.rs @@ -0,0 +1,52 @@ +use ntw_flowgraph::Block; +use ntw_flowgraph::inout::{In, Stream}; +use ntw_flowgraph::{BlockWork, inout::Out}; +use ntw_flowgraph_macros::Block; +use num::Complex; + +use crate::Frequency; +use crate::generation::Nco; + +#[derive(Block)] +pub struct ComplexNco +{ + inner: crate::generation::Nco, + + #[output] + out: Out>, +} + +impl BlockWork for ComplexNco +{ + fn work(&mut self) + { + self.out.push_iter(&mut self.inner); + } + + fn ready(&self) -> bool + { + self.out.vacant_len() > 0 + } +} + +impl BlockWork for ComplexNco +{ + fn work(&mut self) + { + self.out.push_iter(&mut self.inner); + } + + fn ready(&self) -> bool + { + self.out.vacant_len() > 0 + } +} + +impl ComplexNco +{ + pub fn new(nco: Nco) -> (Self, In>) + { + let (a, b) = Stream::make(1024); + (Self { inner: nco, out: a }, b) + } +} diff --git a/ntw_dsp/src/blocks/tee.rs b/ntw_dsp/src/blocks/tee.rs new file mode 100644 index 0000000..9d93ca0 --- /dev/null +++ b/ntw_dsp/src/blocks/tee.rs @@ -0,0 +1,57 @@ +use ntw_flowgraph_macros::Block; +use ntw_flowgraph::{Block, BlockWork, inout::{In, Out, Stream}}; + +#[derive(Block)] +pub struct Tee +{ + #[input] + input: In + + #[output] + output_1: Out + + #[output] + output_2: Out +} + +impl Tee +{ + pub fn new(input: In) -> (Tee, In, In) + { + let (output_1, in_1) = Stream::make(1024); + let (output_2, in_2) = Stream::make(1024); + ( + Tee + { + input, + output_1, + output_2, + }, + in_1, + in_2 + ) + } +} + +impl BlockWork for Tee +{ + fn work(&mut self) + { + let len = self.output_1.vacant_len().min(self.output_2.vacant_len()) + .min(self.input.available_len()); + + for _ in 0..len + { + let elem = self.input.try_pop().unwrap(); // Should be available because of len check + + self.output_1.try_push(elem.clone()); + self.output_2.try_push(elem); + } + } + + fn ready(&self) -> bool { + self.input.available_len() > 0 && + self.output_1.vacant_len() > 0 && + self.output_2.vacant_len() > 0 + } +} diff --git a/ntw_dsp/src/generation.rs b/ntw_dsp/src/generation.rs new file mode 100644 index 0000000..858678e --- /dev/null +++ b/ntw_dsp/src/generation.rs @@ -0,0 +1,111 @@ +use std::{f64::consts::PI, marker::PhantomData}; + +use num::Complex; + +use crate::Frequency; + +pub struct Nco +{ + // Phase offset : 0 = 0, usize::MAX = 2*pi + phase: usize, + + // Frequency : d(erivative) of phase + // Radians per sample + d_phase: Frequency, + + _phantom: PhantomData, +} + +impl Nco +{ + pub fn new(frequency: Frequency) -> Self + { + Nco:: { + phase: 0, + d_phase: frequency, + _phantom: Default::default(), + } + } + + pub fn set_frequency(&mut self, frequency: Frequency) + { + self.d_phase = frequency; + } + + pub fn set_phase(&mut self, phase: f64) + { + self.phase = ((phase / (2. * PI)) * usize::MAX as f64).floor() as usize; + } + + pub fn step(&mut self) + { + let (new, _) = self.phase.overflowing_add(self.d_phase.0); + self.phase = new; + } +} + +impl Nco +{ + pub fn sample_sin(&self) -> f32 + { + let t = (self.phase as f32 / usize::MAX as f32) * 2. * std::f32::consts::PI; + t.sin() + } + + pub fn sample_cos(&self) -> f32 + { + let t = (self.phase as f32 / usize::MAX as f32) * 2. * std::f32::consts::PI; + t.cos() + } + + pub fn sample(&self) -> Complex + { + let t = (self.phase as f32 / usize::MAX as f32) * 2. * std::f32::consts::PI; + Complex::new(t.cos(), t.sin()) + } +} + +impl Nco +{ + pub fn sample_sin(&self) -> f64 + { + let t = (self.phase as f64 / usize::MAX as f64) * 2. * std::f64::consts::PI; + t.sin() + } + + pub fn sample_cos(&self) -> f64 + { + let t = (self.phase as f64 / usize::MAX as f64) * 2. * std::f64::consts::PI; + t.cos() + } + + pub fn sample(&self) -> Complex + { + let t = (self.phase as f64 / usize::MAX as f64) * 2. * std::f64::consts::PI; + Complex::new(t.cos(), t.sin()) + } +} + +impl Iterator for Nco +{ + type Item = Complex; + + fn next(&mut self) -> Option + { + let v = self.sample(); + self.step(); + Some(v) + } +} + +impl Iterator for Nco +{ + type Item = Complex; + + fn next(&mut self) -> Option + { + let v = self.sample(); + self.step(); + Some(v) + } +} diff --git a/ntw_dsp/src/lib.rs b/ntw_dsp/src/lib.rs new file mode 100644 index 0000000..c117b15 --- /dev/null +++ b/ntw_dsp/src/lib.rs @@ -0,0 +1,37 @@ +use std::f64::consts::PI; + +pub mod blocks; +pub mod generation; + +#[derive(Clone, Copy, PartialEq, Debug)] +pub struct Frequency(pub usize); + +impl Frequency +{ + pub fn from_rad(radians_per_sample: f64) -> Frequency + { + let f = euclid_mod(radians_per_sample, 2. * PI); + Frequency(((f / (2. * PI)) * (usize::MAX as f64)).floor() as usize) + } + + pub fn as_rad(&self) -> f64 + { + ((self.0 as f64) / (usize::MAX as f64)) * 2. * PI + } + + pub fn from_frequency(frequency: f64, sample_rate: f64) -> Frequency + { + Self::from_rad((frequency / sample_rate) * 2. * PI) + } + + pub fn as_frequency(&self, sample_rate: f64) -> f64 + { + (self.as_rad() / (2. * PI)) * sample_rate + } +} + +fn euclid_mod(a: f64, m: f64) -> f64 +{ + let r = a % m; + if r < 0.0 { r + m } else { r } +} diff --git a/ntw_flowgraph/src/graph.rs b/ntw_flowgraph/src/graph.rs index db0d0d4..28b2958 100644 --- a/ntw_flowgraph/src/graph.rs +++ b/ntw_flowgraph/src/graph.rs @@ -1,9 +1,9 @@ -use crate::Block; +use crate::{Block, BlockWork, RunnableBlock}; use petgraph::graph::DiGraph; pub struct Graph { - blocks: Vec>, + blocks: Vec>, } impl Graph @@ -13,7 +13,7 @@ impl Graph Graph { blocks: vec![] } } - pub fn add_block(&mut self, block: impl Block + 'static) + pub fn add_block(&mut self, block: impl Block + BlockWork + 'static) { block.set_block_index(self.blocks.len()); self.blocks.push(Box::new(block)); @@ -23,14 +23,16 @@ impl Graph { // Compute the topo_order let mut digraph = DiGraph::<(), (), usize>::with_capacity(self.blocks.len(), 1); + let len = self.blocks.len(); + (0..len).for_each(|_| { + digraph.add_node(()); + }); - for block in self.blocks.iter() + for (i, block) in self.blocks.iter().enumerate() { - let node = digraph.add_node(()); - for next in block.get_successors() { - digraph.add_edge(node, next.into(), ()); + digraph.add_edge(i.into(), next.into(), ()); } } diff --git a/ntw_flowgraph/src/inout.rs b/ntw_flowgraph/src/inout.rs index 32ee788..b951db4 100644 --- a/ntw_flowgraph/src/inout.rs +++ b/ntw_flowgraph/src/inout.rs @@ -3,6 +3,7 @@ use ringbuf::SharedRb; use ringbuf::consumer::PopIter; use ringbuf::storage::Heap; use ringbuf::traits::Consumer; +use ringbuf::traits::Observer; use ringbuf::traits::Producer; use ringbuf::traits::Split; use ringbuf::wrap::caching::Caching; @@ -61,6 +62,11 @@ impl In { self.rb.pop_iter() } + + pub fn available_len(&self) -> usize + { + self.rb.occupied_len() + } } impl Out @@ -81,4 +87,9 @@ impl Out { self.rb.push_iter(iter) } + + pub fn vacant_len(&self) -> usize + { + self.rb.vacant_len() + } } diff --git a/ntw_flowgraph/src/lib.rs b/ntw_flowgraph/src/lib.rs index 16337b6..68da34d 100644 --- a/ntw_flowgraph/src/lib.rs +++ b/ntw_flowgraph/src/lib.rs @@ -4,11 +4,14 @@ pub mod inout; pub trait BlockWork { fn work(&mut self); - fn ready(&self) -> bool; + fn ready(&mut self) -> bool; } -pub trait Block: BlockWork +pub trait Block { fn set_block_index(&self, index: usize); fn get_successors(&self) -> Vec; } + +pub trait RunnableBlock: Block + BlockWork {} +impl RunnableBlock for T where T: Block + BlockWork {} diff --git a/ntw_flowgraph_macros/Cargo.lock b/ntw_flowgraph_macros/Cargo.lock index 5a50dce..3850141 100644 --- a/ntw_flowgraph_macros/Cargo.lock +++ b/ntw_flowgraph_macros/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ntw_flowgraph_macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -20,15 +29,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "streams_macros" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "syn" version = "2.0.117" diff --git a/ntw_flowgraph_macros/src/lib.rs b/ntw_flowgraph_macros/src/lib.rs index 1055f61..9cbb60f 100644 --- a/ntw_flowgraph_macros/src/lib.rs +++ b/ntw_flowgraph_macros/src/lib.rs @@ -113,10 +113,13 @@ pub fn block_derive(item: TokenStream) -> TokenStream let set_index_func = set_block_index_func(&derive); let get_successors_func = get_successors_func(&derive); let struct_path = input.ident; + let struct_where = input.generics.where_clause.clone(); + let struct_generics = input.generics; //item quote! { - impl Block for #struct_path + impl #struct_generics ntw_flowgraph::Block for #struct_path #struct_generics + #struct_where { #set_index_func #get_successors_func diff --git a/src/main.rs b/src/main.rs index ed3ef91..ea71d31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,9 @@ +use std::fmt::Display; + +use ntw_dsp::Frequency; +use ntw_dsp::blocks::map::Map; +use ntw_dsp::blocks::nco::ComplexNco; +use ntw_dsp::generation::Nco; use ntw_flowgraph::Block; use ntw_flowgraph::BlockWork; use ntw_flowgraph::graph::Graph; @@ -39,7 +45,7 @@ impl BlockWork for VecSource fn ready(&self) -> bool { - self.vector.len() > 0 && self.out.rb.vacant_len() > 0 + !self.vector.is_empty() && self.out.vacant_len() > 0 } } @@ -73,15 +79,13 @@ impl BlockWork for Adder && let Some(b) = self.in_b.rb.try_pop() && self.out.rb.vacant_len() > 0 { - let _ = self.out.rb.try_push(a + b); + let _ = self.out.try_push(a + b); } } fn ready(&self) -> bool { - self.in_a.rb.occupied_len() > 0 - && self.in_b.rb.occupied_len() > 0 - && self.out.rb.vacant_len() > 0 + self.in_a.available_len() > 0 && self.in_b.available_len() > 0 && self.out.vacant_len() > 0 } } @@ -95,13 +99,13 @@ impl Adder } #[derive(Block)] -pub struct PrintSink +pub struct PrintSink { #[input] - stream: In, + stream: In, } -impl BlockWork for PrintSink +impl BlockWork for PrintSink { fn work(&mut self) { @@ -113,13 +117,13 @@ impl BlockWork for PrintSink fn ready(&self) -> bool { - self.stream.rb.occupied_len() > 0 + self.stream.available_len() > 0 } } -impl PrintSink +impl PrintSink { - pub fn new(stream: In) -> PrintSink + pub fn new(stream: In) -> PrintSink { PrintSink { stream } } @@ -127,17 +131,15 @@ impl PrintSink fn main() { - let (vector_a, a) = VecSource::new((0..15).collect()); - let (vector_b, b) = VecSource::new((0..15).collect()); - let (adder, sum) = Adder::new(a, b); - let printer = PrintSink::new(sum); + let (nco, out) = ComplexNco::::new(Nco::new(Frequency::from_rad(0.001))); + let (map, im) = Map::new(out, |x| x.im); + let printer = PrintSink::new(im); let mut graph = Graph::new(); graph.add_block(printer); - graph.add_block(adder); - graph.add_block(vector_a); - graph.add_block(vector_b); + graph.add_block(map); + graph.add_block(nco); graph.run(); }