initial working version
This commit is contained in:
commit
5ffe22ce17
3 changed files with 161 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
14
Cargo.toml
Normal file
14
Cargo.toml
Normal 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
146
src/main.rs
Normal 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();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue