use std::sync::mpsc;
#[cfg(feature = "cli")]
use cpal::{
SampleRate, StreamConfig,
traits::{DeviceTrait, HostTrait, StreamTrait},
};
use image::{ImageFormat, ImageReader};
use rsstv::{
SAMPLE_RATE,
common::{DecodeResult, SSTVMode},
martinm1::MartinM1,
};
use hound::{WavReader, WavSpec, WavWriter};
#[cfg(feature = "cli")]
use clap::Parser;
#[cfg(feature = "cli")]
#[derive(Parser)]
struct Args {
#[clap()]
input_file: Option<String>,
#[clap(short, long, default_value = "out.wav")]
ouput_file: String,
#[clap(short, long)]
decode: bool,
#[clap(short, long)]
mic: bool,
}
#[cfg(feature = "cli")]
fn main() {
let args = Args::parse();
let mut mode = MartinM1::new();
if args.decode {
if !args.mic {
let mut reader = WavReader::open(args.input_file.unwrap())
.unwrap();
let samples: Vec<f32> = reader.samples().map(|s| s.unwrap()).collect();
let out = mode.decode(&samples.to_vec());
match out {
DecodeResult::Finished(image) | DecodeResult::Partial(image) => {
image.save_with_format("out.png", ImageFormat::Png).unwrap()
}
DecodeResult::NoneFound => println!("No image found"),
}
} else {
let mut decoder = MartinM1::new();
let host = cpal::default_host();
let device = host.default_input_device().unwrap();
println!("using device {:?}", device.name().unwrap());
let default_config = device.default_input_config().unwrap();
let mut config: StreamConfig = default_config.into();
config.sample_rate = SampleRate(SAMPLE_RATE as u32);
let (tx, rx) = mpsc::channel();
let stream = device
.build_input_stream(
&config,
move |data: &[f32], _| {
tx.send(data.to_vec()).unwrap();
},
|err| println!("{:#?}", err),
None,
)
.unwrap();
stream.play().unwrap();
loop {
let mut buf = Vec::new();
while buf.len() <= 100_000 {
let mut received = rx.recv().unwrap();
buf.append(&mut received);
}
let decode = decoder.decode(&buf);
if let DecodeResult::Partial(ref image) = decode {
image.save_with_format("out.png", ImageFormat::Png).unwrap();
}
if let DecodeResult::Finished(ref image) = decode {
image.save_with_format("out.png", ImageFormat::Png).unwrap();
break;
}
}
drop(stream);
println!("Finished decoding");
}
} else {
let reader = ImageReader::open(args.input_file.unwrap())
.unwrap()
.decode()
.unwrap();
let signal = mode.encode(reader);
let written: &[f32] = &signal.to_samples();
let spec = WavSpec {
channels: 1,
sample_rate: SAMPLE_RATE as u32,
bits_per_sample: 32,
sample_format: hound::SampleFormat::Float
};
let mut writer = WavWriter::create(args.ouput_file, spec).unwrap();
for elem in written {
writer.write_sample(*elem).unwrap();
}
writer.finalize().unwrap();
}
}
#[cfg(not(feature = "cli"))]
fn main() {}