diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2018-12-19 23:31:48 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2018-12-19 23:31:48 +0100 |
commit | 582c59c8c47df77439b6c6800b658bdb54dbfeaf (patch) | |
tree | 82798970793b9ddcc1d6c04f4626cd54932cab67 /src | |
download | trriggy-582c59c8c47df77439b6c6800b658bdb54dbfeaf.tar.gz trriggy-582c59c8c47df77439b6c6800b658bdb54dbfeaf.tar.bz2 trriggy-582c59c8c47df77439b6c6800b658bdb54dbfeaf.zip |
Initial commit.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0210df8 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,108 @@ +// trriggy - a trigger/drum replacer in Rust +// Copyright (C) 2018 Harald Eilertsen <haraldei@anduin.net> +// +// 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 <https://www.gnu.org/licenses/>. + +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<i16>, +} + +impl Trigger { + pub fn new<T: Read>(samples: hound::WavReader<T>) -> Trigger { + Trigger::default().read_samples(samples) + } + + fn read_samples<T: Read>(mut self, mut reader: hound::WavReader<T>) -> 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<R: Read>(spec: &hound::WavSpec, r: &hound::WavReader<R>) { + 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::<i16>(); + 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(); +} |