aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs108
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();
+}