summaryrefslogtreecommitdiffstats
path: root/quantum/audio
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/audio')
-rw-r--r--quantum/audio/audio.c52
-rw-r--r--quantum/audio/audio.h9
-rw-r--r--quantum/audio/muse.c2
-rw-r--r--quantum/audio/muse.h3
-rw-r--r--quantum/audio/voices.c2
5 files changed, 47 insertions, 21 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index 2570ad9cd1..28c8267517 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -311,6 +311,10 @@ void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) {
return;
}
+ if (n_count == 0) {
+ return;
+ }
+
if (!audio_initialized) {
audio_init();
}
@@ -547,20 +551,42 @@ void audio_decrease_tempo(uint8_t tempo_change) {
note_tempo -= tempo_change;
}
-// TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/system-tick wrapping around?
+/**
+ * Converts from units of 1/64ths of a beat to milliseconds.
+ *
+ * Round-off error is at most 1 millisecond.
+ *
+ * Conversion will never overflow for duration_bpm <= 699, provided that
+ * note_tempo is at least 10. This is quite a long duration, over ten beats.
+ *
+ * Beware that for duration_bpm > 699, the result may overflow uint16_t range
+ * when duration_bpm is large compared to note_tempo:
+ *
+ * duration_bpm * 60 * 1000 / (64 * note_tempo) > UINT16_MAX
+ *
+ * duration_bpm > (2 * 65535 / 1875) * note_tempo
+ * = 69.904 * note_tempo.
+ */
uint16_t audio_duration_to_ms(uint16_t duration_bpm) {
-#if defined(__AVR__)
- // doing int-math saves us some bytes in the overall firmware size, but the intermediate result is less accurate before being cast to/returned as uint
- return ((uint32_t)duration_bpm * 60 * 1000) / (64 * note_tempo);
- // NOTE: beware of uint16_t overflows when note_tempo is low and/or the duration is long
-#else
- return ((float)duration_bpm * 60) / (64 * note_tempo) * 1000;
-#endif
+ return ((uint32_t)duration_bpm * 1875) / ((uint_fast16_t)note_tempo * 2);
}
+
+/**
+ * Converts from units of milliseconds to 1/64ths of a beat.
+ *
+ * Round-off error is at most 1/64th of a beat.
+ *
+ * This conversion never overflows: since duration_ms <= UINT16_MAX = 65535
+ * and note_tempo <= 255, the result is always in uint16_t range:
+ *
+ * duration_ms * 64 * note_tempo / 60 / 1000
+ * <= 65535 * 2 * 255 / 1875
+ * = 17825.52
+ * <= UINT16_MAX.
+ */
uint16_t audio_ms_to_duration(uint16_t duration_ms) {
-#if defined(__AVR__)
- return ((uint32_t)duration_ms * 64 * note_tempo) / 60 / 1000;
-#else
- return ((float)duration_ms * 64 * note_tempo) / 60 / 1000;
-#endif
+ return ((uint32_t)duration_ms * 2 * note_tempo) / 1875;
}
+
+__attribute__((weak)) void audio_on_user(void) {}
+__attribute__((weak)) void audio_off_user(void) {}
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 75016a1100..a4a908b43c 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -21,12 +21,6 @@
#include "musical_notes.h"
#include "song_list.h"
#include "voices.h"
-#include "quantum.h"
-#include <math.h>
-
-#if defined(__AVR__)
-# include <avr/io.h>
-#endif
#if defined(AUDIO_DRIVER_PWM)
# include "audio_pwm.h"
@@ -280,3 +274,6 @@ bool audio_update_state(void);
#define increase_tempo(t) audio_increase_tempo(t)
#define decrease_tempo(t) audio_decrease_tempo(t)
// vibrato functions are not used in any keyboards
+
+void audio_on_user(void);
+void audio_off_user(void);
diff --git a/quantum/audio/muse.c b/quantum/audio/muse.c
index 01b95671fd..4c23cd7348 100644
--- a/quantum/audio/muse.c
+++ b/quantum/audio/muse.c
@@ -1,5 +1,7 @@
#include "muse.h"
+#include <stdbool.h>
+
enum { MUSE_OFF, MUSE_ON, MUSE_C_1_2, MUSE_C1, MUSE_C2, MUSE_C4, MUSE_C8, MUSE_C3, MUSE_C6, MUSE_B1, MUSE_B2, MUSE_B3, MUSE_B4, MUSE_B5, MUSE_B6, MUSE_B7, MUSE_B8, MUSE_B9, MUSE_B10, MUSE_B11, MUSE_B12, MUSE_B13, MUSE_B14, MUSE_B15, MUSE_B16, MUSE_B17, MUSE_B18, MUSE_B19, MUSE_B20, MUSE_B21, MUSE_B22, MUSE_B23, MUSE_B24, MUSE_B25, MUSE_B26, MUSE_B27, MUSE_B28, MUSE_B29, MUSE_B30, MUSE_B31 };
bool number_of_ones_to_bool[16] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1};
diff --git a/quantum/audio/muse.h b/quantum/audio/muse.h
index ad2f96e43a..7b289cac6c 100644
--- a/quantum/audio/muse.h
+++ b/quantum/audio/muse.h
@@ -1,6 +1,5 @@
#pragma once
-#include "quantum.h"
-#include "process_audio.h"
+#include <stdint.h>
uint8_t muse_clock_pulse(void);
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
index 01f257f4d4..4f511c93ba 100644
--- a/quantum/audio/voices.c
+++ b/quantum/audio/voices.c
@@ -16,7 +16,9 @@
*/
#include "voices.h"
#include "audio.h"
+#include "timer.h"
#include <stdlib.h>
+#include <math.h>
uint8_t note_timbre = TIMBRE_DEFAULT;
bool glissando = false;