167 lines
4.3 KiB
Rust
167 lines
4.3 KiB
Rust
use std::collections::VecDeque;
|
|
use std::fmt::Display;
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::sync::mpmc::sync_channel;
|
|
use std::sync::mpsc;
|
|
|
|
use eframe::NativeOptions;
|
|
use egui_plot::Line;
|
|
use egui_plot::PlotPoints;
|
|
use num::Complex;
|
|
use oxydsp_dsp::blocks::math::basic::Multiplier;
|
|
use oxydsp_dsp::blocks::synthesis::Nco;
|
|
use oxydsp_dsp::blocks::synthesis::OscillatorSource;
|
|
use oxydsp_dsp::blocks::utilities::adapters::Map;
|
|
use oxydsp_dsp::blocks::utilities::adapters::Repeat;
|
|
use oxydsp_dsp::blocks::utilities::channels::TxSink;
|
|
use oxydsp_dsp::blocks::utilities::iter::IterSource;
|
|
use oxydsp_dsp::units::DigitalFrequency;
|
|
use oxydsp_flowgraph::BlockIO;
|
|
use oxydsp_flowgraph::block::Block;
|
|
use oxydsp_flowgraph::block::BlockResult;
|
|
use oxydsp_flowgraph::edge::In;
|
|
use oxydsp_flowgraph::edge::PopIterable;
|
|
use oxydsp_flowgraph::flowgraph;
|
|
use oxydsp_flowgraph::graph::FlowGraph;
|
|
|
|
#[derive(BlockIO)]
|
|
pub struct Printer<T: 'static>
|
|
{
|
|
#[input]
|
|
input: In<T>,
|
|
|
|
n: usize,
|
|
}
|
|
|
|
impl<T: 'static> Printer<T>
|
|
{
|
|
pub fn new(input: In<T>) -> Self
|
|
{
|
|
Self { input, n: 0 }
|
|
}
|
|
}
|
|
|
|
impl<T: 'static> Block for Printer<T>
|
|
where
|
|
T: Display,
|
|
{
|
|
fn work(&mut self) -> oxydsp_flowgraph::block::BlockResult
|
|
{
|
|
for x in self.input.pop_iter()
|
|
{
|
|
if self.n.is_multiple_of(2usize.pow(20))
|
|
{
|
|
println!("{}", x);
|
|
self.n = 0;
|
|
}
|
|
self.n += 1;
|
|
}
|
|
BlockResult::Ok
|
|
}
|
|
}
|
|
|
|
fn main()
|
|
{
|
|
let sample_rate = 48_000;
|
|
let sample_per_symbol = 96;
|
|
let deviation = DigitalFrequency::from_time_frequency(500., sample_rate as f64);
|
|
let carrier = DigitalFrequency::from_time_frequency(1000., sample_rate as f64);
|
|
|
|
let data = (0..255u8).flat_map(to_bits).collect::<Vec<_>>();
|
|
let (bit_stream, bits) = IterSource::new(data.into_iter());
|
|
let (to_freq, freq) = Map::new(bits, move |x| [-deviation, deviation][x as usize]);
|
|
let (repeat, freq) = Repeat::new(freq, sample_per_symbol);
|
|
let (base_oscillator, baseband) = Nco::<f32>::new(freq);
|
|
let (local_oscillator, lo) = OscillatorSource::<f32>::new(carrier.into());
|
|
let (frontend, passband) = Multiplier::new(baseband, lo);
|
|
let (tx, rx) = mpsc::channel::<Complex<f32>>();
|
|
let sink = TxSink::new(passband, tx);
|
|
|
|
let graph = flowgraph![
|
|
bit_stream,
|
|
to_freq,
|
|
repeat,
|
|
base_oscillator,
|
|
local_oscillator,
|
|
frontend,
|
|
sink,
|
|
];
|
|
File::create("out.dot")
|
|
.unwrap()
|
|
.write_all(graph.get_dot().as_bytes())
|
|
.unwrap();
|
|
let j = graph.run();
|
|
let mut output = vec![];
|
|
while let Ok(x) = rx.recv()
|
|
{
|
|
output.push(x);
|
|
}
|
|
let _ = j.join();
|
|
|
|
// Write signal
|
|
let spec = hound::WavSpec {
|
|
channels: 1,
|
|
sample_rate,
|
|
bits_per_sample: 16,
|
|
sample_format: hound::SampleFormat::Int,
|
|
};
|
|
let mut writer = hound::WavWriter::create("mod.wav", spec).unwrap();
|
|
for x in output.iter()
|
|
{
|
|
let amplitude = i16::MAX as f32;
|
|
writer.write_sample((x.re * amplitude) as i16).unwrap();
|
|
}
|
|
writer.finalize().unwrap();
|
|
//
|
|
|
|
eframe::run_simple_native("Plot", NativeOptions::default(), move |ctx, _frame| {
|
|
egui::CentralPanel::default().show(ctx, |ui| {
|
|
egui_plot::Plot::new("hello").show(ui, |plot_ui| {
|
|
plot_ui.line(Line::new(
|
|
"samples",
|
|
output
|
|
.iter()
|
|
.enumerate()
|
|
.map(|(i, s)| [i as f64, s.re as f64])
|
|
.collect::<PlotPoints>(),
|
|
));
|
|
});
|
|
ctx.request_repaint();
|
|
});
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
pub fn to_bits(n: u8) -> [bool; 8]
|
|
{
|
|
[
|
|
(n & 1) == 1,
|
|
(n >> 1) & 1 == 1,
|
|
(n >> 2) & 1 == 1,
|
|
(n >> 3) & 1 == 1,
|
|
(n >> 4) & 1 == 1,
|
|
(n >> 5) & 1 == 1,
|
|
(n >> 6) & 1 == 1,
|
|
(n >> 7) & 1 == 1,
|
|
]
|
|
}
|
|
|
|
pub fn from_bits(n: [bool; 8]) -> u8
|
|
{
|
|
(n[0] as u8)
|
|
| ((n[1] as u8) << 1)
|
|
| ((n[2] as u8) << 2)
|
|
| ((n[3] as u8) << 3)
|
|
| ((n[4] as u8) << 4)
|
|
| ((n[5] as u8) << 5)
|
|
| ((n[6] as u8) << 6)
|
|
| ((n[7] as u8) << 7)
|
|
}
|
|
|
|
pub fn gaussian(sigma: f32, t: f32) -> f32
|
|
{
|
|
let sq = (t - 0.5) / sigma;
|
|
(-sq * sq).exp()
|
|
}
|