SG 3 lat temu
rodzic
commit
0d638e8bcc
2 zmienionych plików z 198 dodań i 3 usunięć
  1. 1 2
      speaker_hal.c
  2. 197 1
      zero_tracker.c

+ 1 - 2
speaker_hal.c

@@ -43,8 +43,7 @@ void tracker_speaker_deinit() {
 
 static FuriHalInterruptISR tracker_isr;
 static void* tracker_isr_context;
-
-void tracker_interrupt_cb(void* context) {
+static void tracker_interrupt_cb(void* context) {
     UNUSED(context);
 
     if(LL_TIM_IsActiveFlag_UPDATE(TIM2)) {

+ 197 - 1
zero_tracker.c

@@ -15,6 +15,69 @@
  */
 typedef uint16_t NoteRecord;
 
+#define NOTE_NONE 0
+#define NOTE_C2 1
+#define NOTE_Cs2 2
+#define NOTE_D2 3
+#define NOTE_Ds2 4
+#define NOTE_E2 5
+#define NOTE_F2 6
+#define NOTE_Fs2 7
+#define NOTE_G2 8
+#define NOTE_Gs2 9
+#define NOTE_A2 10
+#define NOTE_As2 11
+#define NOTE_B2 12
+#define NOTE_C3 13
+#define NOTE_Cs3 14
+#define NOTE_D3 15
+#define NOTE_Ds3 16
+#define NOTE_E3 17
+#define NOTE_F3 18
+#define NOTE_Fs3 19
+#define NOTE_G3 20
+#define NOTE_Gs3 21
+#define NOTE_A3 22
+#define NOTE_As3 23
+#define NOTE_B3 24
+#define NOTE_C4 25
+#define NOTE_Cs4 26
+#define NOTE_D4 27
+#define NOTE_Ds4 28
+#define NOTE_E4 29
+#define NOTE_F4 30
+#define NOTE_Fs4 31
+#define NOTE_G4 32
+#define NOTE_Gs4 33
+#define NOTE_A4 34
+#define NOTE_As4 35
+#define NOTE_B4 36
+#define NOTE_C5 37
+#define NOTE_Cs5 38
+#define NOTE_D5 39
+#define NOTE_Ds5 40
+#define NOTE_E5 41
+#define NOTE_F5 42
+#define NOTE_Fs5 43
+#define NOTE_G5 44
+#define NOTE_Gs5 45
+#define NOTE_A5 46
+#define NOTE_As5 47
+#define NOTE_B5 48
+#define NOTE_C6 49
+#define NOTE_Cs6 50
+#define NOTE_D6 51
+#define NOTE_Ds6 52
+#define NOTE_E6 53
+#define NOTE_F6 54
+#define NOTE_Fs6 55
+#define NOTE_G6 56
+#define NOTE_Gs6 57
+#define NOTE_A6 58
+#define NOTE_As6 59
+#define NOTE_B6 60
+#define NOTE_KILL 63
+
 uint8_t record_get_note(NoteRecord note) {
     return note & 0x3F;
 }
@@ -27,6 +90,33 @@ uint8_t record_get_effect_data(NoteRecord note) {
     return (note >> 10) & 0x3F;
 }
 
+#define RECORD_MAKE(note, effect, data) \
+    ((NoteRecord)(((note)&0x3F) | (((effect)&0xF) << 6) | (((data)&0x3F) << 10)))
+
+#define NOTES_PER_OCT 12
+const float notes_oct[NOTES_PER_OCT] = {
+    130.813f,
+    138.591f,
+    146.832f,
+    155.563f,
+    164.814f,
+    174.614f,
+    184.997f,
+    195.998f,
+    207.652f,
+    220.00f,
+    233.082f,
+    246.942f,
+};
+
+float note_to_freq(uint8_t note) {
+    if(note == NOTE_NONE) return 0.0f;
+    note = note - NOTE_C2;
+    uint8_t octave = note / NOTES_PER_OCT;
+    uint8_t note_in_oct = note % NOTES_PER_OCT;
+    return notes_oct[note_in_oct] * (1 << octave);
+}
+
 #define PATTERN_SIZE 64
 
 typedef struct {
@@ -38,8 +128,114 @@ typedef struct {
     NoteRow* rows;
 } NotePattern;
 
+NoteRow row = {
+    .notes =
+        {
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            RECORD_MAKE(NOTE_F2, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            //
+            RECORD_MAKE(NOTE_E4, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            RECORD_MAKE(NOTE_E4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_D5, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            RECORD_MAKE(NOTE_F2, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            //
+            RECORD_MAKE(NOTE_C5, 0, 0),
+            RECORD_MAKE(NOTE_C3, 0, 0),
+            RECORD_MAKE(NOTE_C5, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_B4, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            RECORD_MAKE(NOTE_G2, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            //
+            RECORD_MAKE(NOTE_E4, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            RECORD_MAKE(NOTE_E4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_E5, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_D5, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            RECORD_MAKE(NOTE_G2, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            //
+            RECORD_MAKE(NOTE_C5, 0, 0),
+            RECORD_MAKE(NOTE_D3, 0, 0),
+            RECORD_MAKE(NOTE_C5, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            RECORD_MAKE(0, 0, 0),
+            //
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_A4, 0, 0),
+            RECORD_MAKE(NOTE_KILL, 0, 0),
+        },
+};
+
+uint8_t counter = 0;
+uint8_t counter_limit = 2;
+
+uint8_t row_counter = 0;
+
 void tracker_interrupt_body() {
+    if(counter == 0) {
+        uint8_t note = record_get_note(row.notes[row_counter]);
+        if(note == NOTE_KILL) {
+            tracker_speaker_stop();
+        } else if(note > 0 && note < NOTE_KILL) {
+            float freq = note_to_freq(note);
+            tracker_speaker_play(freq, 0.5f);
+        }
+        row_counter = (row_counter + 1) % PATTERN_SIZE;
+    }
+    counter = (counter + 1) % counter_limit;
+}
+
+void tracker_interrupt_cb() {
     tracker_debug_set(true);
+    tracker_interrupt_body();
     tracker_debug_set(false);
 }
 
@@ -48,7 +244,7 @@ int32_t zero_tracker_app(void* p) {
 
     tracker_debug_init();
     tracker_speaker_init();
-    tracker_interrupt_init(120.0f, tracker_interrupt_body, NULL);
+    tracker_interrupt_init(60.0f, tracker_interrupt_cb, NULL);
 
     while(1) {
         furi_delay_ms(1000);