Finalizes fft, working-ish bfsk

This commit is contained in:
2025-09-26 17:12:48 +02:00
parent 00b4756138
commit 25a2dd47c3
9 changed files with 169 additions and 4941 deletions

View File

@ -15,11 +15,34 @@ mod nco;
use bfsk::BFSKMod;
use complex::Complex;
use complex::Complex32;
use fft::DFTAlgorithm;
use nco::Nco;
use plotters::prelude::*;
use fft::DFTAlgorithm;
use crate::{bfsk::BFSKDem, fft::{create_fft, dft::NaiveDFT, mixed_radix::MixedRadixFFT, rader::RaderFFT, radix2::Radix2FFT, windows, FFTDirection, FFT}};
use crate::{
bfsk::BFSKDem,
fft::{
FFT, FFTDirection, create_fft,
dft::NaiveDFT,
mixed_radix::MixedRadixFFT,
prime_factors,
rader::{RaderFFT, compute_prime_primitive_root, exp_mod},
rader2::{Rader2FFT, next_pow2},
radix2::Radix2FFT,
windows,
},
};
struct QuickLCG(i32);
impl QuickLCG {
pub fn seed(val: i32) -> QuickLCG {
QuickLCG(val % 10)
}
pub fn next(&mut self) -> i32 {
self.0 = self.0.overflowing_mul(9321).0.overflowing_add(5672).0 % 10;
self.0
}
}
// Utilities
fn map<T>(input: T, in_min: T, in_max: T, out_min: T, out_max: T) -> T
@ -30,44 +53,14 @@ where
}
fn main() {
//modulate();
test();
}
fn test()
{
let mut o1 = Nco::new(PI / 2.0);
let mut o2 = Nco::new(PI / 4.0);
let sample_count = 4800;
//let mut fft = FFT::new(sample_count, windows::rectangular);
let mut dft = NaiveDFT::create(sample_count, FFTDirection::Forward);
let mut fft = FFT::new(sample_count, windows::rectangular);
//let mut fft = RaderFFT::create(sample_count, FFTDirection::Forward);
let mut fft_input = vec![Complex32::zero(); sample_count];
for x in fft_input.iter_mut()
{
*x = o1.cexp() + o2.cexp();
o1.step();
o2.step();
}
fft.execute(&fft_input);
dft.execute(&fft_input);
let mut out_file = File::create("out.csv").unwrap();
for (x, y) in fft.get_output().iter().zip(dft.get_output())
{
out_file.write_all(
format!("{},{},\n", x.mag(), y.mag()).as_bytes()
).unwrap();
}
modulate();
//œtest();
}
fn modulate() {
let sample_rate = 44100;
let frequency = 2000.0; //HZ
let bandwidth = 1000.0; //HZ
let bandwidth = 500.0; //HZ
println!("deviation: {}", PI * (bandwidth / sample_rate as f32));
let path = "s.txt";
@ -92,7 +85,7 @@ fn modulate() {
println!("{} samples/bit", sample_rate / baud_rate);
let mut bfsk = BFSKMod::new(
sample_rate / baud_rate,
PI * 0.05, //PI * (bandwidth / sample_rate as f32),
PI * (bandwidth / sample_rate as f32),
&mut bit_stream,
);
@ -111,35 +104,33 @@ fn modulate() {
let mut output_samples = vec![];
while let Some(sample) = bfsk.step_modulate() {
let amplitude = i16::MAX as f32;
let c_sample = lo.cexp() * sample;
let c_sample = sample * lo.cexp();
//let c_sample = sample;
let filtered = prev + (c_sample - prev) * alpha;
output_samples.push(filtered);
//let filtered = prev + (c_sample - prev) * alpha;
output_samples.push(c_sample);
writer
.write_sample((amplitude * c_sample.re) as i16)
.unwrap();
lo.step();
}
writer.finalize().unwrap();
let mut tfft = FFT::new(44100, windows::rectangular);
tfft.execute(&output_samples);
// Write csv
let mut out_csv = File::create("out.csv").unwrap();
for x in output_samples.iter().take(4400)
{
out_csv.write_all(
format!("{},\n", x.mag()).as_bytes()
).unwrap();
let mut of = File::create("out.jpg").unwrap();
let mut fft = FFT::new(110, windows::bartlett);
fft.execute(&output_samples[220..]);
let mut csv = File::create("out.csv").unwrap();
for x in fft.get_output() {
csv.write_all(format!("{},\n", x.mag()).as_bytes()).unwrap();
}
let mut of = File::create("out.txt").unwrap();
let mut bits = vec![];
let mut lodem = Nco::new(-2. * PI * (frequency / sample_rate as f32));
let mut demod = BFSKDem::new(
sample_rate / baud_rate,
PI * 0.05, //PI * (bandwidth / sample_rate as f32),
PI * (bandwidth / sample_rate as f32),
);
for chunk in output_samples.chunks((sample_rate / baud_rate) as usize) {
let base_chunk: Vec<Complex32> = chunk
@ -155,14 +146,26 @@ fn modulate() {
}
for b in bits.chunks(8) {
of.write_all(&[(b[0] as u8)
| ((b[0] as u8) << 1)
| ((b[0] as u8) << 2)
| ((b[0] as u8) << 3)
| ((b[0] as u8) << 4)
| ((b[0] as u8) << 5)
| ((b[0] as u8) << 6)
/*
of.write_all(&[(b[7] as u8)
| ((b[6] as u8) << 1)
| ((b[5] as u8) << 2)
| ((b[4] as u8) << 3)
| ((b[3] as u8) << 4)
| ((b[2] as u8) << 5)
| ((b[1] as u8) << 6)
| ((b[0] as u8) << 7)])
.unwrap();
*/
of.write_all(&[(b[0] as u8)
| ((b[1] as u8) << 1)
| ((b[2] as u8) << 2)
| ((b[3] as u8) << 3)
| ((b[4] as u8) << 4)
| ((b[5] as u8) << 5)
| ((b[6] as u8) << 6)
| ((b[7] as u8) << 7)])
.unwrap();
}
}