Skip to content

Commit

Permalink
feat: toggle metronome sound
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanleiby committed Aug 9, 2024
1 parent 6abdf8e commit 45dbba0
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 24 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@
name = "macroix"
version = "0.1.0"
edition = "2021"
rust-version = "1.80"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
confy = "0.5.1"
# egui-macroquad = { version = "0.15.0", default_features = false }
kira = "0.8.5"
log = "0.4.21"
macroquad = { version = "0.4.4", default_features = false }
midir = "0.9.1"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.108"
simple_logger = "4.3.3"
# fix build error
time = "0.3.36"

# From README:
# > Adding the following snippet to your Cargo.toml ensures that all dependencies compile in release even in debug mode.
Expand Down
27 changes: 10 additions & 17 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
- tweak strictness .. just a lil more generous on timing? ... Dial it it!
Could add sliders for (1) num correct (2) Bpm step (3) Correctness sensitivity

## asap

(_what's must-have to make it useful to me? what's very important to make it engaging to me?_)

**Golden mode so I can jam with it**

- [ ] make gold reachable
Expand All @@ -18,23 +14,14 @@

**Look good for energizing dev**

- [ ] Make UI look nice-ish
- [ ] do a pass in Figma
- [ ] better font
- [ ] funklet inspired colors and look
- [ ] show/hide noisy stuff

## soon

- [ ] quick start + gets you into flow
- idea: saves whatever loop, BPM you were doing last time -- recovers on next start
- capture progress over time (graph it, etc)
- capture progress over time (graph it, etc)
- [..] add better debugging for midi signals, so I can filter to important ones (e.g. can ignore polyphonic aftertouch 167 on changing HH pedal in terms of hitting notes on the beat)

- can translate to names from here https://midi.org/expanded-midi-1-0-messages-list, then log better
- proximate reason.. to figure out problem with closed HH not triggering

- commit UI prototypes (tauri, iced) to Github (optionally, migrate into macroix repo if reasonable to centralize)
- (bug) explore triggering
- [ ] double triggering of some TD17 notes (e.g. 2x hihat hits or 2x open hihat hits, esp on hard hits?)
- [ ] non triggering (hit too soft? event getting dropped?)
Expand All @@ -60,6 +47,12 @@
- [x] e.g. hacky is a button to reset -> press "r"
- another idea is "fade out" by age (e.g. just keep last K loops, or actually fade over time until gone by Kth loop)
- UX v2: Design
- commit UI prototypes (tauri, iced) to Github (optionally, migrate into macroix repo if reasonable to centralize)
- [ ] Make UI look nice-ish
- [ ] do a pass in Figma
- [ ] better font
- [ ] funklet inspired colors and look
- [ ] show/hide noisy stuff
- prototype in Figma: core interactions, colors, layout, etc
- might we show music as sheet music notation (e.g. https://github.com/jaredforth/lilypond-rs or various others)
- Explore similar existing offerings
Expand Down Expand Up @@ -91,7 +84,7 @@
- [ ] fix BPM
- assuming each beat in grid is a 16th note, it should be BPM \* 2 (so 120 = 60)
- I think ideally the data model for user_hits and desired_hits aligns nicely, i.e. 1.0 is beat 1, 2.0 is beat 2. So e.g. 16th notes are 0.25 in length
- [ ] Refactor message passing .. should be typed (see `main.rs` in `rx.try_recv`)
- [x] Refactor message passing .. should be typed (see `main.rs` in `rx.try_recv`)
- [ ] unit tests
- consider + document which pieces can be unit tested (and iterated on more effectively than manual testing)
- ex. write unit tests re: the accuracy summary metric
Expand Down Expand Up @@ -126,8 +119,6 @@
- [x] support >1 midi value per voice
- [ ] allow easy rebinding within the app
- [ ] save calibrated offset (latency) config per connected midi device / system (TD17 = -0.01) .. i have multiple for testing
- Feature: Metronome
- [ ] toggle metronome on/off
- Feature: Volume control
- [ ] global
- [ ] per voice (inl metronome)
Expand Down Expand Up @@ -218,6 +209,8 @@

## done

- Feature: Metronome
- [x] toggle metronome on/off
- [x] log levels that allow easy filtering
- [x] (bug) GOLDEN MODE logic is broken. Denominator seems to be correct user_hits instead of desired notes
- [x] refactor so i don't need explicit branches for each of 4 instruments everywhere..
Expand Down
27 changes: 25 additions & 2 deletions src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct Audio {
clock: ClockHandle,
last_scheduled_tick: f64,
bpm: f64,
metronome_enabled: bool,

pub user_hits: Vec<UserHit>,
calibration_input: VecDeque<f64>,
Expand Down Expand Up @@ -75,6 +76,7 @@ impl Audio {
clock,
last_scheduled_tick: -1.,
bpm: DEFAULT_BPM,
metronome_enabled: false,

user_hits: vec![],
calibration_input: VecDeque::new(),
Expand Down Expand Up @@ -142,8 +144,21 @@ impl Audio {
.await?;
}

// if metronome on, schedule it
// (&voices.metronome, "res/sounds/click.wav"),
if self.is_metronome_enabled() {
// TODO: play a different sound at start of each measure
// clicks on quarter notes
let metronome_notes = vec![0., 2., 4., 6., 8., 10., 12., 14.];
let sound_path = "res/sounds/click.wav";
schedule_audio(
&metronome_notes,
sound_path,
&mut self.manager,
&self.clock,
self.last_scheduled_tick,
tick_to_schedule,
)
.await?;
}

self.last_scheduled_tick = tick_to_schedule;

Expand Down Expand Up @@ -185,6 +200,14 @@ impl Audio {
}
}

pub fn toggle_metronome(self: &mut Self) {
self.metronome_enabled = !self.metronome_enabled;
}

pub fn is_metronome_enabled(self: &Self) -> bool {
self.metronome_enabled
}

/// saves a user's hits, so they can be displayed and checked for accuracy
pub fn track_user_hit(self: &mut Self, instrument: Instrument, processing_delay_s: f64) {
// convert processing delay to ticks, based on BPM
Expand Down
17 changes: 17 additions & 0 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ impl UI {

draw_gold_mode(gold_mode);

draw_metronome(audio);

if flags.ui_debug_mode {
draw_debug_grid();
}
Expand Down Expand Up @@ -405,6 +407,21 @@ fn draw_loop_choices<'a, 'b: 'a>(
});
}

fn draw_metronome<'a>(audio: &'a mut Audio) {
widgets::Window::new(hash!(), UI_TOP_LEFT + vec2(0., 200.), vec2(320., 200.))
.label("Metronome")
.titlebar(true)
.ui(&mut *root_ui(), |ui| {
if ui.button(
None,
format!("Metronome {:?}", audio.is_metronome_enabled()),
) {
log::info!("toggle metronome");
audio.toggle_metronome();
}
});
}

fn draw_gold_mode(gold_mode: &GoldMode) {
draw_text(
format!(
Expand Down

0 comments on commit 45dbba0

Please sign in to comment.