From 582c59c8c47df77439b6c6800b658bdb54dbfeaf Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Wed, 19 Dec 2018 23:31:48 +0100 Subject: Initial commit. --- src/main.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/main.rs (limited to 'src') 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 +// +// 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(); +} -- cgit v1.2.3