This commit is contained in:
2025-10-10 23:37:35 -05:00
parent 9a47b28fdb
commit 4d256f0c19
6 changed files with 11 additions and 114 deletions
+4 -29
View File
@@ -2,36 +2,12 @@ use std::ops::RangeInclusive;
use eframe::egui;
use eframe::egui::{Color32, Context, Id, PointerButton, Pos2, Rangef, Sense, Ui, Vec2};
use crate::gui::Showable;
use crate::noise::NoteType;
use crate::scale::Scale;
use crate::tenori::LOOP_LENGTH;
use crate::timbre::Timbre;
impl NoteType {
fn color(&self) -> Color32 {
match self {
NoteType::Sine => Color32::from_rgb(3, 211, 252),
NoteType::Triangle => Color32::from_rgb(252, 202, 3),
NoteType::Sawtooth => Color32::from_rgb(252, 18, 61),
NoteType::Square => Color32::from_rgb(4, 219, 51),
NoteType::Noise => Color32::from_rgb(240, 240, 240),
}
}
fn name(&self) -> &'static str {
match self {
NoteType::Sine => "Sine",
NoteType::Triangle => "Triangle",
NoteType::Sawtooth => "Sawtooth",
NoteType::Square => "Square",
NoteType::Noise => "Noise"
}
}
}
#[derive(Clone)]
pub struct Grid {
pub note_type: NoteType,
pub volume: f32,
pub scale: Scale,
pub notes: Vec<bool>,
@@ -43,14 +19,13 @@ pub struct Grid {
}
impl Grid {
pub fn for_note_type(note_type: NoteType, id: Id) -> Self {
pub fn new(id: Id) -> Self {
Self {
note_type,
volume: 1.0,
open: true,
scale: Scale::CMajor,
notes: vec![false; (LOOP_LENGTH * LOOP_LENGTH) as usize],
name: format!("{} Track", note_type.name()),
name: "New Track".to_string(),
timbre: Timbre::default(),
timbre_open: false,
id
@@ -67,7 +42,7 @@ impl Grid {
(x * 20 + 10) as f32 + rect.left(),
(y * 20 + 10) as f32 + rect.top());
if *lit {
ui.painter().circle_filled(center, 10.0, self.note_type.color());
ui.painter().circle_filled(center, 10.0, Color32::from_rgb(80, 140, 160));
} else {
ui.painter().circle_stroke(center, 10.0, (1.0, Color32::from_gray(0x88)));
}
@@ -76,7 +51,7 @@ impl Grid {
ui.painter().vline(
cursor * dim + rect.left(),
Rangef::new(rect.top(), rect.top() + dim),
(1.0, self.note_type.color())
(1.0, Color32::from_rgb(80, 140, 160))
);
if response.contains_pointer() {
+5 -18
View File
@@ -3,7 +3,7 @@ use std::ops::RangeInclusive;
use std::path::Path;
use eframe::egui;
use eframe::egui::{Context, Id, TopBottomPanel};
use crate::noise::NoteType;
use crate::grid::Grid;
use crate::saveload::PersistedTenori;
use crate::Tenori;
@@ -33,23 +33,10 @@ impl Tenori {
}
});
ui.menu_button("Add track", |ui| {
if ui.button("Square").clicked() {
self.add_window(NoteType::Square)
}
if ui.button("Sine").clicked() {
self.add_window(NoteType::Sine)
}
if ui.button("Triangle").clicked() {
self.add_window(NoteType::Triangle)
}
if ui.button("Sawtooth").clicked() {
self.add_window(NoteType::Sawtooth)
}
if ui.button("Noise").clicked() {
self.add_window(NoteType::Noise)
}
});
if ui.button("Add track").clicked() {
let id = self.window_id();
self.grids.push(Grid::new(id));
}
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
ui.add(egui::Slider::new(&mut self.tempo, RangeInclusive::new(20, 180)));
-13
View File
@@ -1,22 +1,9 @@
use rodio::mixer::Mixer;
use rodio::Source;
use serde::{Deserialize, Serialize};
use crate::timbre::Timbre;
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum NoteType {
Sine,
Triangle,
Sawtooth,
Square,
Noise
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Note {
/// What kind of timbre
pub note_type: NoteType,
/// Which semitone up / down from A4
pub tone: i32,
-4
View File
@@ -1,7 +1,6 @@
use eframe::egui::Id;
use serde::{Deserialize, Serialize};
use crate::grid::Grid;
use crate::noise::NoteType;
use crate::scale::Scale;
use crate::tenori::Tenori;
use crate::timbre::Timbre;
@@ -32,7 +31,6 @@ impl PersistedTenori {
#[derive(Serialize, Deserialize)]
struct PersistedGrid {
note_type: NoteType,
volume: f32,
scale: Scale,
notes: String,
@@ -44,7 +42,6 @@ impl From<&Grid> for PersistedGrid {
fn from(value: &Grid) -> Self {
let notes: String = value.notes.iter().map(|n| if *n { '1' } else { '0' }).collect();
Self {
note_type: value.note_type,
volume: value.volume,
scale: value.scale,
name: value.name.clone(),
@@ -58,7 +55,6 @@ impl PersistedGrid {
pub fn into_grid(self, id: Id) -> Grid {
let notes: Vec<_> = self.notes.chars().map(|c| c == '1').collect();
Grid {
note_type: self.note_type,
volume: self.volume,
scale: self.scale,
name: self.name,
+1 -7
View File
@@ -2,7 +2,7 @@ use std::time::Instant;
use rodio::OutputStream;
use crate::grid::Grid;
use crate::dialog::Dialog;
use crate::noise::{Note, NoteType};
use crate::noise::Note;
pub const LOOP_LENGTH: u32 = 16;
@@ -90,11 +90,6 @@ impl Tenori {
self.timer / LOOP_LENGTH as f32
}
pub fn add_window(&mut self, note_type: NoteType) {
let id = self.window_id();
self.grids.push(Grid::for_note_type(note_type, id));
}
pub fn notes_for_beat(&self) -> Vec<Note> {
let mut notes = vec![];
let beat = self.beat();
@@ -103,7 +98,6 @@ impl Tenori {
for tone in grid.notes(beat).into_iter() {
notes.push(Note {
note_type: grid.note_type,
tone,
volume: grid.volume,
timbre: grid.timbre
+1 -43
View File
@@ -1,8 +1,6 @@
use std::ops::RangeInclusive;
use std::time::Duration;
use eframe::egui;
use eframe::egui::{Checkbox, Context, Id, Label, Slider, Window};
use rodio::mixer::MixerSource;
use eframe::egui::{Context, Id, Label, Slider, Window};
use rodio::Source;
use rodio::source::{SawtoothWave, SineWave, SquareWave, TriangleWave, WhiteUniform};
use serde::{Deserialize, Serialize};
@@ -16,12 +14,6 @@ pub struct Timbre {
square: f32,
sawtooth: f32,
noise: f32,
d_gain: f32,
d_thresh: f32,
reverb: f32,
reverb_duration: f32,
filter: bool,
filter_q: f32,
envelope: Envelope
}
@@ -33,12 +25,6 @@ impl Default for Timbre {
square: 1.0,
sawtooth: 0.0,
noise: 0.0,
d_gain: 1.0,
d_thresh: 10.0,
reverb: 0.0,
reverb_duration: 0.0,
filter: false,
filter_q: 50.0,
envelope: Default::default(),
}
}
@@ -62,18 +48,7 @@ impl Timbre {
if self.noise > 0.0 {
mixer.add(WhiteUniform::new(44100).amplify(self.noise))
}
let source = source.distortion(self.d_gain, self.d_thresh);
let source = source.buffered().reverb(Duration::from_millis((self.reverb_duration * 1000.0) as u64), self.reverb);
self.envelope.modulate(source)
// let (mixer2, m2source) = rodio::mixer::mixer(1, 44100);
// if self.filter {
// // let source = source.low_pass((frequency * self.filter_q) as u32);
// // mixer2.add(self.envelope.modulate(source));
// } else {
// mixer2.add(self.envelope.modulate(source));
// }
// m2source
}
}
@@ -122,23 +97,6 @@ impl Showable<(Id, String)> for (&mut Timbre, &mut bool, &mut String) {
ui.add(Label::new("Release"));
ui.add(Slider::new(&mut self.0.envelope.release, RangeInclusive::new(0.0, 1.0)));
ui.end_row();
ui.add(Label::new("Dist. Gain"));
ui.add(Slider::new(&mut self.0.d_gain, RangeInclusive::new(-10.0, 10.0)));
ui.add(Label::new("Reverb"));
ui.add(Slider::new(&mut self.0.reverb, RangeInclusive::new(0.0, 1.0)));
ui.end_row();
ui.add(Label::new("Dist. Thresh"));
ui.add(Slider::new(&mut self.0.d_thresh, RangeInclusive::new(0.0, 10.0)));
ui.add(Label::new("Rev. Duration"));
ui.add(Slider::new(&mut self.0.reverb_duration, RangeInclusive::new(0.0, 1.0)));
ui.end_row();
// ui.add(Checkbox::new(&mut self.0.filter, "Filter"));
// ui.end_row();
// ui.add(Label::new("Bandwidth"));
// ui.add_enabled(self.0.filter, Slider::new(&mut self.0.filter_q, RangeInclusive::new(0.0, 100.0)));
});
});