// trriggy - a trigger/drum replacer in Rust // Copyright (C) 2018 Harald Eilertsen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . use hound; use std::io::Read; use std::iter::FromIterator; #[derive(Default)] struct Trigger { trigged: bool, playing: bool, acc: u32, sample_pos: usize, sample: Vec, } impl Trigger { pub fn new(samples: hound::WavReader) -> Trigger { Trigger::default().read_samples(samples) } fn read_samples(mut self, mut reader: hound::WavReader) -> Trigger { self.sample = Vec::from_iter(reader.samples().map(|s| s.unwrap())); self } pub fn process(&mut self, sample: i16) -> i16 { let mut res = 0i16; let abs = sample.abs() as u32; self.acc = (self.acc + abs) / 2; if !self.trigged && self.acc > 1000 { self.trigged = true; self.playing = true; self.sample_pos = 0; } else if self.trigged && self.acc < 50 { self.trigged = false; } if self.playing { res = self.sample[self.sample_pos]; self.sample_pos += 1; } if self.sample_pos == self.sample.len() { self.playing = false; } res } } fn print_wavspec(spec: &hound::WavSpec, r: &hound::WavReader) { println!(" channels: {}", spec.channels); println!(" samplerate: {}", spec.sample_rate); println!(" bits/sample: {}", spec.bits_per_sample); println!(" sample format: {}", match spec.sample_format { hound::SampleFormat::Int => "integer", hound::SampleFormat::Float => "floating point", }); println!(" duration: {} samples/{} sec/{} min", r.duration(), r.duration()/spec.sample_rate, r.duration()/(spec.sample_rate * 60)); } fn main() { let filename = "test.wav"; let mut reader = hound::WavReader::open(&filename).unwrap(); println!("Reading file {}:", &filename); let spec = reader.spec(); print_wavspec(&spec, &reader); println!("Using sample file: {}", "bd.wav"); let mut sample_file = hound::WavReader::open("bd.wav").unwrap(); print_wavspec(&sample_file.spec(), &sample_file); println!("Writing to output: {}", "output.wav"); let mut output = hound::WavWriter::create("output.wav", spec).unwrap(); let samples = reader.samples::(); let mut triggey = Trigger::new(sample_file); samples .map(|s| s.unwrap()) .for_each(|s| { output.write_sample(triggey.process(s)).unwrap(); }); output.finalize().unwrap(); }