framed com

This commit is contained in:
2025-10-03 02:19:32 +02:00
parent 8a51c4489c
commit e7bb36d655

View File

@ -5,12 +5,11 @@ use std::{
f32::consts::PI,
fs::File,
i16,
io::{Read, Write},
io::{self, Read, Write},
ops::{Add, Div, Mul, Sub},
os::unix::thread,
sync::{
Arc,
mpsc::{self, Receiver, Sender, TryRecvError, sync_channel},
atomic::{AtomicU32, Ordering}, mpsc::{self, channel, sync_channel, Receiver, Sender, TryRecvError}, Arc
},
time::Duration,
};
@ -35,7 +34,7 @@ use cpal::{
use fft::DFTAlgorithm;
use nco::Nco;
use eframe::egui::{self, Color32, Context, Vec2b, debug_text::print};
use eframe::egui::{self, debug_text::print, decode_animated_image_uri, Color32, Context, Vec2b};
use egui_plot::{self, Bar, BarChart, Legend, Line, LineStyle, Plot, PlotPoints, VLine};
use plotters::style::Color;
use rand::{seq::index::sample, Rng};
@ -263,6 +262,9 @@ fn demodulator(
);
// Timing recovery
let mut preamble_count = 0;
let mut bit_index = 0;
let mut last = 0u8;
while let Ok(real_sample) = rx.recv() {
let iq = iq_sampler.sample(real_sample);
@ -272,10 +274,35 @@ fn demodulator(
let matched = matched_filter.next_real(pos_energy.mag() - neg_energy.mag());
if let Some((_, eye)) = elg.next_eye(matched)
if let Some((bit, eye)) = elg.next_eye(matched)
{
let _ = eye_sender.send(eye);
ctx.request_repaint();
last <<= 1;
last |= bit as u8;
if preamble_count >= 2
{
bit_index += 1;
if bit_index == 8
{
if last == 4
{
println!();
preamble_count = 0;
}
else
{
print!("{}", last as char);
bit_index = 0;
}
}
}
if last == 0xD8
{
preamble_count += 1;
}
}
}
}
@ -436,39 +463,74 @@ fn modulate() {
let sample_rate = 48000;
let baud_rate = BAUD_RATE;
// File to modulate
let f = File::open("s.txt").unwrap();
let mut bitstream = std::iter::repeat_n(0b01010101u8, 1)
.chain(std::iter::repeat_n(0b01010111u8, 1))
.chain(f.bytes().map(|x| x.unwrap()))
.chain(std::iter::repeat_n(0u8, 1))
.flat_map(byte_to_bits);
let host = cpal::default_host();
let device = host.default_output_device().unwrap();
let mut supported_configs_range = device.supported_output_configs().unwrap();
let supported_config = supported_configs_range
.find(|config| config.sample_format() == cpal::SampleFormat::F32
&& config.min_sample_rate().0 <= 48000
&& config.max_sample_rate().0 >= 48000)
.expect("Device does not support 48kHz f32 output");
let config = supported_config.with_sample_rate(cpal::SampleRate(48_000)).config();
let mut modulator = BFSKMod::new(
sample_rate / baud_rate,
units::frequency::hz_to_rad_per_sample(deviation, sample_rate as f32),
&mut bitstream,
);
let mut lo = Nco::new(units::frequency::hz_to_rad_per_sample(
frequency,
sample_rate as f32,
));
loop
{
let mut buffer = String::new();
let stdin = io::stdin(); // We get `Stdin` here.
stdin.read_line(&mut buffer).unwrap();
let spec = hound::WavSpec {
channels: 1,
sample_rate,
bits_per_sample: 16,
sample_format: hound::SampleFormat::Int,
};
// Construct payload
let mut bitstream =
std::iter::repeat_n(0b01010101u8, 32)
.chain(std::iter::repeat_n(0b11011000, 1))
.chain(buffer.bytes())
.chain(std::iter::repeat_n(4u8, 32))
.flat_map(byte_to_bits);
let mut writer = hound::WavWriter::create("audio/modulated.wav", spec).unwrap();
for (s, up) in modulator.zip(lo) {
let sample = (s * up).re; // Project to I coords
let amplitude = i16::MAX as f32;
writer.write_sample((sample * amplitude) as i16).unwrap();
let mut modulator = BFSKMod::new(
sample_rate / baud_rate,
units::frequency::hz_to_rad_per_sample(deviation, sample_rate as f32),
&mut bitstream,
);
let mut lo = Nco::new(units::frequency::hz_to_rad_per_sample(
frequency,
sample_rate as f32,
));
// To send
let stream = modulator.zip(lo)
.map(|(s, up)| (s * up).re)
.collect::<Vec<_>>();
let sample_clock = Arc::new(AtomicU32::new(0));
let (tx, rx) = channel::<()>();
let stream = device.build_output_stream(
&config,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
for d in data.iter_mut()
{
if sample_clock.load(Ordering::Relaxed) as usize == stream.len()
{
tx.send(()).unwrap();
break;
}
*d = stream[sample_clock.fetch_add(1, Ordering::Relaxed) as usize]
}
},
move |err| {
eprintln!("Stream error: {}", err);
},
None
).unwrap();
stream.play().unwrap();
let _ = rx.recv();
stream.pause().unwrap();
}
writer.finalize().unwrap();
}
fn byte_to_bits(byte: u8) -> Vec<bool> {