initial working version

This commit is contained in:
_ 2020-10-20 11:53:36 +02:00
commit 5ffe22ce17
3 changed files with 161 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

14
Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "waagner"
version = "0.1.0"
authors = ["_ <_@_>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serial = "*"
rodio = "0.12"
walkdir = "*"
rand = { version = "*", features = ["small_rng"] }

146
src/main.rs Normal file
View file

@ -0,0 +1,146 @@
use serial::SerialPort;
use walkdir::WalkDir;
fn main() {
let helptext = "Argument 1 is serial port (for example /dev/ttyACM0, Argument 2 is the directory with the music, no stars.";
let mut args = std::env::args_os();
let _selfname = args.next();
let serialport = args.next().expect(helptext);
let musicdir = args.next().expect(helptext);
println!("opening serial port");
let mut port = serial::open(&serialport).expect("could not open serial port");
port.reconfigure(&|settings| {
settings.set_baud_rate(serial::Baud115200)?;
settings.set_char_size(serial::Bits8);
settings.set_parity(serial::ParityNone);
settings.set_stop_bits(serial::Stop1);
settings.set_flow_control(serial::FlowNone);
Ok(())
})
.expect("could not configure port");
port.set_timeout(std::time::Duration::from_secs(30))
.expect("could not set timeout");
println!("serial port opened");
println!("skimming music dir");
let walker = WalkDir::new(musicdir).into_iter();
let walker = walker.filter_entry(|e| {
e.file_name()
.to_str()
.map(|s| !s.starts_with('.'))
.unwrap_or(true)
});
let mut music = Vec::new();
for entry in walker {
match entry {
Err(e) => eprintln!("error when reading music dir, continuing: {:?}", e),
Ok(entry) => {
if entry.file_type().is_file() && entry.path().extension() != Some(std::ffi::OsStr::new("jpg")){
music.push(entry.path().to_owned());
}
}
}
}
println!("music dir skimmed");
use rand::seq::SliceRandom;
use rand::SeedableRng;
let mut rng = rand::rngs::SmallRng::seed_from_u64(0);
music.shuffle(&mut rng);
println!("loaded {} \"songs\"", music.len());
/*
for i in (0..music.len()).rev() {
enum Err{
Empty,
File,
}
let c = || -> Result<(), Err> {
// we might run out of music cause we are deliting inline, this is fine.
let choice = &music.get(i).ok_or(Err::Empty)?;
let f = std::fs::File::open(&choice).map_err(|_| Err::File)?;
let rdr = BufReader::new(f);
let _d = rodio::Decoder::new(rdr).map_err(|_| Err::File)?;
Ok(())
};
match (c)() {
Err(Err::File) => {dbg!(music.remove(i));},
_ => (),
}
}
*/
println!("checked all songs");
println!("opening audio output");
let (_stream, stream_handle) = rodio::OutputStream::try_default()
.expect("could not open audio output, or could not find any");
let mut sink = rodio::Sink::try_new(&stream_handle).expect("could not create sink");
println!("audio output opened");
use std::io::BufRead;
use std::io::BufReader;
let mut port = BufReader::new(port);
// wage has valid range 0-5000
let mut max: usize = 5000;
let mut preval = 0;
let mut prechoice = 0;
let mut readbuf = String::new();
let mut n_changed = 0;
use std::io::Write;
port.get_mut().write(b"r").unwrap();
loop {
readbuf.clear();
port.read_line(&mut readbuf).unwrap();
//println!("got line: {}", readbuf);
let err = "got invalid message from wage";
let w: usize = readbuf.trim().parse().expect(err);
if w == 8888 || w == 69_69_69_69 {
// special values: 8888 and 69696969
// are turned off and EEEE
} else {
max = max.max(w);
let choice = (w * (music.len() - 1)) / max;
let absdiff = w.max(preval) - w.min(preval);
if absdiff > 1 && choice != prechoice {
n_changed += 1;
} else {
n_changed = 0;
}
if n_changed >= 7 {
let choicef = &music[(music.len() - 1) - choice];
println!("changing song to {:?}", choicef);
let mut c = || -> Result<(), ()> {
let f = std::fs::File::open(choicef).map_err(|_| ())?;
let rdr = BufReader::new(f);
let d = rodio::Decoder::new(rdr).map_err(|_| ())?;
//let s = rodio::source::SineWave::new(440);
let newsink =
rodio::Sink::try_new(&stream_handle).expect("could not create sink");
newsink.append(d);
sink.stop();
sink = newsink;
Ok(())
};
if let Err(_error) = (c)() {
println!("music was not music");
let r = music.remove((music.len() - 1) - choice);
println!("removed {:?}", r);
} else {
preval = w;
prechoice = choice;
n_changed = 0;
}
}
}
std::thread::sleep(std::time::Duration::from_millis(100));
port.get_mut().write(b"r").unwrap();
}
}