cleanup
This commit is contained in:
@@ -1,10 +1,6 @@
|
|||||||
use std::ops::RangeInclusive;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use eframe::egui;
|
|
||||||
use eframe::egui::{Context, Id, Label, Slider, Window};
|
|
||||||
use rodio::{ChannelCount, SampleRate, Source};
|
use rodio::{ChannelCount, SampleRate, Source};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::gui::Showable;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
|
#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
|
||||||
pub struct Envelope {
|
pub struct Envelope {
|
||||||
@@ -107,39 +103,6 @@ impl<S: Source> Source for EnvelopeSource<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Showable<(Id, String)> for (&mut Envelope, &mut bool) {
|
|
||||||
fn show(&mut self, ctx: &Context, (id, title): &(Id, String)) {
|
|
||||||
let mut open = true;
|
|
||||||
let window = Window::new(title)
|
|
||||||
.id(*id)
|
|
||||||
.open(&mut open)
|
|
||||||
.resizable([false, false])
|
|
||||||
.scroll([false, false]);
|
|
||||||
|
|
||||||
window.show(ctx, |ui| {
|
|
||||||
egui::Grid::new(id).show(ui, |ui| {
|
|
||||||
ui.add(Label::new("Attack"));
|
|
||||||
ui.add(Slider::new(&mut self.0.attack, RangeInclusive::new(0.0, 1.0)));
|
|
||||||
ui.end_row();
|
|
||||||
ui.add(Label::new("Decay"));
|
|
||||||
ui.add(Slider::new(&mut self.0.decay, RangeInclusive::new(0.0, 1.0)));
|
|
||||||
ui.end_row();
|
|
||||||
ui.add(Label::new("Sustain"));
|
|
||||||
ui.add(Slider::new(&mut self.0.sustain, RangeInclusive::new(0.0, 1.0)));
|
|
||||||
ui.end_row();
|
|
||||||
ui.add(Label::new("Hold"));
|
|
||||||
ui.add(Slider::new(&mut self.0.hold, RangeInclusive::new(0.0, 2.0)));
|
|
||||||
ui.end_row();
|
|
||||||
ui.add(Label::new("Release"));
|
|
||||||
ui.add(Slider::new(&mut self.0.release, RangeInclusive::new(0.0, 1.0)));
|
|
||||||
ui.end_row();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
*self.1 = open;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
+2
-4
@@ -1,7 +1,6 @@
|
|||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use eframe::egui::{Color32, Context, Id, PointerButton, Pos2, Rangef, Sense, Ui, Vec2};
|
use eframe::egui::{Color32, Context, Id, PointerButton, Pos2, Rangef, Sense, Ui, Vec2};
|
||||||
use crate::envelope::Envelope;
|
|
||||||
use crate::gui::Showable;
|
use crate::gui::Showable;
|
||||||
use crate::noise::NoteType;
|
use crate::noise::NoteType;
|
||||||
use crate::scale::Scale;
|
use crate::scale::Scale;
|
||||||
@@ -82,14 +81,13 @@ impl Grid {
|
|||||||
|
|
||||||
if response.contains_pointer() {
|
if response.contains_pointer() {
|
||||||
ui.input(|input| {
|
ui.input(|input| {
|
||||||
if input.pointer.button_clicked(PointerButton::Primary) {
|
if input.pointer.button_clicked(PointerButton::Primary) &&
|
||||||
if let Some(pos) = input.pointer.latest_pos() {
|
let Some(pos) = input.pointer.latest_pos() {
|
||||||
let x = ((pos.x - rect.left()) / 20.0).floor() as usize;
|
let x = ((pos.x - rect.left()) / 20.0).floor() as usize;
|
||||||
let y = ((pos.y - rect.top()) / 20.0).floor() as usize;
|
let y = ((pos.y - rect.top()) / 20.0).floor() as usize;
|
||||||
let n = x + y * LOOP_LENGTH as usize;
|
let n = x + y * LOOP_LENGTH as usize;
|
||||||
self.notes[n] = !self.notes[n]
|
self.notes[n] = !self.notes[n]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -55,9 +55,7 @@ impl Tenori {
|
|||||||
ui.add(egui::Slider::new(&mut self.tempo, RangeInclusive::new(20, 180)));
|
ui.add(egui::Slider::new(&mut self.tempo, RangeInclusive::new(20, 180)));
|
||||||
if self.playing {
|
if self.playing {
|
||||||
if ui.button("||").clicked() { self.playing = false }
|
if ui.button("||").clicked() { self.playing = false }
|
||||||
} else {
|
} else if ui.button(">").clicked() { self.playing = true }
|
||||||
if ui.button(">").clicked() { self.playing = true }
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@@ -80,7 +78,7 @@ impl Tenori {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn save_to_file<P: AsRef<Path>>(&self, filename: P) -> Result<(), String> {
|
fn save_to_file<P: AsRef<Path>>(&self, filename: P) -> Result<(), String> {
|
||||||
let serialized = toml::to_string(&PersistedTenori::from(&*self)).map_err(|e| e.to_string())?;
|
let serialized = toml::to_string(&PersistedTenori::from(self)).map_err(|e| e.to_string())?;
|
||||||
fs::write(filename, serialized).map_err(|e| e.to_string())
|
fs::write(filename, serialized).map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use rodio::mixer::Mixer;
|
use rodio::mixer::Mixer;
|
||||||
use rodio::Source;
|
use rodio::Source;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::envelope::Envelope;
|
|
||||||
use crate::timbre::Timbre;
|
use crate::timbre::Timbre;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@@ -36,21 +35,6 @@ fn freq(tone: i32) -> f32 {
|
|||||||
440.0 * 1.0595f32.powf(tone as f32)
|
440.0 * 1.0595f32.powf(tone as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NoteType {
|
|
||||||
fn source(self, tone: i32) -> Box<dyn Source + Send> {
|
|
||||||
let freq = freq(tone);
|
|
||||||
let source: Box<dyn Source + Send> = match self {
|
|
||||||
NoteType::Sine => Box::new(rodio::source::SineWave::new(freq)),
|
|
||||||
NoteType::Triangle => Box::new(rodio::source::TriangleWave::new(freq)),
|
|
||||||
NoteType::Sawtooth => Box::new(rodio::source::SawtoothWave::new(freq)),
|
|
||||||
NoteType::Square => Box::new(rodio::source::SquareWave::new(freq)),
|
|
||||||
NoteType::Noise => Box::new(rodio::source::noise::WhiteUniform::new(44100)
|
|
||||||
.low_pass_with_q(freq as u32, 2.0))
|
|
||||||
};
|
|
||||||
source
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Note {
|
impl Note {
|
||||||
pub fn play(self, mixer: &Mixer) {
|
pub fn play(self, mixer: &Mixer) {
|
||||||
let freq = freq(self.tone);
|
let freq = freq(self.tone);
|
||||||
|
|||||||
+6
-6
@@ -33,21 +33,21 @@ impl Default for Timbre {
|
|||||||
|
|
||||||
impl Timbre {
|
impl Timbre {
|
||||||
pub fn source(&self, frequency: f32) -> EnvelopeSource<MixerSource> {
|
pub fn source(&self, frequency: f32) -> EnvelopeSource<MixerSource> {
|
||||||
let (mut mixer, source) = rodio::mixer::mixer(1, 44100);
|
let (mixer, source) = rodio::mixer::mixer(1, 44100);
|
||||||
if self.sine > 0.0 {
|
if self.sine > 0.0 {
|
||||||
mixer.add(SineWave::new(frequency).amplify_normalized(self.sine))
|
mixer.add(SineWave::new(frequency).amplify(self.sine))
|
||||||
}
|
}
|
||||||
if self.triangle > 0.0 {
|
if self.triangle > 0.0 {
|
||||||
mixer.add(TriangleWave::new(frequency).amplify_normalized(self.triangle))
|
mixer.add(TriangleWave::new(frequency).amplify(self.triangle))
|
||||||
}
|
}
|
||||||
if self.square > 0.0 {
|
if self.square > 0.0 {
|
||||||
mixer.add(SquareWave::new(frequency).amplify_normalized(self.square))
|
mixer.add(SquareWave::new(frequency).amplify(self.square))
|
||||||
}
|
}
|
||||||
if self.sawtooth > 0.0 {
|
if self.sawtooth > 0.0 {
|
||||||
mixer.add(SawtoothWave::new(frequency).amplify_normalized(self.sawtooth))
|
mixer.add(SawtoothWave::new(frequency).amplify(self.sawtooth))
|
||||||
}
|
}
|
||||||
if self.noise > 0.0 {
|
if self.noise > 0.0 {
|
||||||
mixer.add(WhiteUniform::new(44100).amplify_normalized(self.noise))
|
mixer.add(WhiteUniform::new(44100).amplify(self.noise))
|
||||||
}
|
}
|
||||||
self.envelope.modulate(source)
|
self.envelope.modulate(source)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user