Explorar o código

Nested tunings and UI improvements

Ihar Biaspalau hai 10 meses
pai
achega
7f590e52e3
Modificáronse 6 ficheiros con 419 adicións e 156 borrados
  1. 3 0
      .gitignore
  2. 2 0
      constants.h
  3. 41 0
      instruments.h
  4. 232 45
      tuning_fork.c
  5. 116 111
      tunings.h
  6. 25 0
      types.h

+ 3 - 0
.gitignore

@@ -5,4 +5,7 @@ dist/*
 .editorconfig
 .env
 .ufbt
+.cache
 .nova
+.DS_Store
+compile_commands.json

+ 2 - 0
constants.h

@@ -0,0 +1,2 @@
+#define MAX_LABEL_LENGTH     20
+#define MAX_NOTES_PER_TUNING 20

+ 41 - 0
instruments.h

@@ -0,0 +1,41 @@
+#include "tunings.h"
+
+const TUNING Guitar6Tunings[] = {Guitar6Standard, Guitar6DropD, Guitar6D, Guitar6DropC};
+const TUNING Guitar7Tunings[] = {Guitar7Standard, Guitar7DropA};
+const VARIATION GuitarVariations[] = {
+    {"6 strings", (TUNING*)Guitar6Tunings, 4},
+    {"7 strings", (TUNING*)Guitar7Tunings, 2}};
+
+const TUNING Bass4Tunings[] = {Bass4Standard, Bass4Tenor, Bass4DropD, Bass4D};
+const TUNING Bass5Tunings[] = {Bass5Standard, Bass5Tenor, Bass5DropA};
+const VARIATION BassVariations[] = {
+    {"4 strings", (TUNING*)Bass4Tunings, 4},
+    {"5 strings", (TUNING*)Bass5Tunings, 3}};
+
+const TUNING Ukulele4Tunings[] = {Ukulele4Standard};
+const VARIATION UkuleleVariations[] = {{"4 strings", (TUNING*)Ukulele4Tunings, 1}};
+
+const TUNING Banjo5Tunings[] = {Banjo5Standard};
+const VARIATION BanjoVariations[] = {{"5 strings", (TUNING*)Banjo5Tunings, 1}};
+
+const TUNING CigarBox3Tunings[] = {CigarBox3OpenG, CigarBox3OpenD, CigarBox3OpenA};
+const TUNING CigarBox4Tunings[] = {CigarBox4OpenG};
+const VARIATION CigarBoxVariations[] = {
+    {"3 strings", (TUNING*)CigarBox3Tunings, 3},
+    {"4 strings", (TUNING*)CigarBox4Tunings, 1}};
+
+const TUNING ForkTunings[] = {ForkCommon, ForkSarti, ForkMid19Century, Fork18Century, ForkVerdi};
+const TUNING OtherTunings[] = {ScientificPitch};
+const VARIATION MiscellaneousVariations[] = {
+    {"Forks", (TUNING*)ForkTunings, 5},
+    {"Other", (TUNING*)OtherTunings, 1}};
+
+const INSTRUMENT Instruments[] = {
+    {"Guitar", (VARIATION*)GuitarVariations, 2},
+    {"Bass", (VARIATION*)BassVariations, 2},
+    {"Ukulele", (VARIATION*)UkuleleVariations, 1},
+    {"Banjo", (VARIATION*)BanjoVariations, 1},
+    {"CigarBox", (VARIATION*)CigarBoxVariations, 2},
+    {"Miscellaneous", (VARIATION*)MiscellaneousVariations, 2}};
+
+#define INSTRUMENTS_COUNT 6

+ 232 - 45
tuning_fork.c

@@ -12,6 +12,7 @@
 #include <notification/notification_messages.h>
 
 #include "tunings.h"
+#include "instruments.h"
 
 #define VOLUME_STEP             0.1f
 #define DEFAULT_VOLUME          1.0f
@@ -29,20 +30,37 @@ typedef struct {
 } PluginEvent;
 
 enum Page {
-    Tunings,
-    Notes
+    InstrumentsPage,
+    VariationsPage,
+    TuningsPage,
+    NotesPage
 };
 
 typedef struct {
     FuriMutex* mutex;
     bool playing;
     enum Page page;
-    int current_tuning_note_index;
-    int current_tuning_index;
     float volume;
+
+    int current_instrument_index;
+    int current_variation_index;
+    int current_tuning_index;
+    int current_tuning_note_index;
+
+    INSTRUMENT instrument;
+    VARIATION variation;
     TUNING tuning;
 } TuningForkState;
 
+// Getters
+static INSTRUMENT current_instrument(TuningForkState* tuningForkState) {
+    return tuningForkState->instrument;
+}
+
+static VARIATION current_variation(TuningForkState* tuningForkState) {
+    return tuningForkState->variation;
+}
+
 static TUNING current_tuning(TuningForkState* tuningForkState) {
     return tuningForkState->tuning;
 }
@@ -55,6 +73,7 @@ static float current_tuning_note_freq(TuningForkState* tuningForkState) {
     return current_tuning_note(tuningForkState).frequency;
 }
 
+// String helper
 static void safe_string_copy(char* dest, const char* src, size_t size) {
     if(dest && src) {
         strncpy(dest, src, size - 1);
@@ -62,25 +81,91 @@ static void safe_string_copy(char* dest, const char* src, size_t size) {
     }
 }
 
-static void current_tuning_note_label(TuningForkState* tuningForkState, char* outNoteLabel) {
-    if(outNoteLabel) {
-        safe_string_copy(outNoteLabel, current_tuning_note(tuningForkState).label, 20);
+// Labels
+static void current_instrument_label(TuningForkState* tuningForkState, char* outCategoryLabel) {
+    if(outCategoryLabel) {
+        safe_string_copy(
+            outCategoryLabel, current_instrument(tuningForkState).label, MAX_LABEL_LENGTH);
+    }
+}
+
+static void current_variation_label(TuningForkState* tuningForkState, char* outCategoryLabel) {
+    if(outCategoryLabel) {
+        safe_string_copy(
+            outCategoryLabel, current_variation(tuningForkState).label, MAX_LABEL_LENGTH);
     }
 }
 
 static void current_tuning_label(TuningForkState* tuningForkState, char* outTuningLabel) {
     if(outTuningLabel) {
-        safe_string_copy(outTuningLabel, current_tuning(tuningForkState).label, 20);
+        safe_string_copy(outTuningLabel, current_tuning(tuningForkState).label, MAX_LABEL_LENGTH);
     }
 }
 
+static void current_tuning_note_label(TuningForkState* tuningForkState, char* outNoteLabel) {
+    if(outNoteLabel) {
+        safe_string_copy(
+            outNoteLabel, current_tuning_note(tuningForkState).label, MAX_LABEL_LENGTH);
+    }
+}
+
+// Update references
 static void updateTuning(TuningForkState* tuning_fork_state) {
-    tuning_fork_state->tuning = TuningList[tuning_fork_state->current_tuning_index];
+    tuning_fork_state->instrument = Instruments[tuning_fork_state->current_instrument_index];
+    tuning_fork_state->variation =
+        tuning_fork_state->instrument.variations[tuning_fork_state->current_variation_index];
+    tuning_fork_state->tuning =
+        tuning_fork_state->variation.tunings[tuning_fork_state->current_tuning_index];
     tuning_fork_state->current_tuning_note_index = 0;
 }
 
+// Instruments navigation
+static void next_instrument(TuningForkState* tuning_fork_state) {
+    if(tuning_fork_state->current_instrument_index == INSTRUMENTS_COUNT - 1) {
+        tuning_fork_state->current_instrument_index = 0;
+    } else {
+        tuning_fork_state->current_instrument_index += 1;
+    }
+    tuning_fork_state->current_variation_index = 0;
+    tuning_fork_state->current_tuning_index = 0;
+    updateTuning(tuning_fork_state);
+}
+
+static void prev_instrument(TuningForkState* tuning_fork_state) {
+    if(tuning_fork_state->current_instrument_index == 0) {
+        tuning_fork_state->current_instrument_index = INSTRUMENTS_COUNT - 1;
+    } else {
+        tuning_fork_state->current_instrument_index -= 1;
+    }
+    tuning_fork_state->current_variation_index = 0;
+    tuning_fork_state->current_tuning_index = 0;
+    updateTuning(tuning_fork_state);
+}
+
+// Variations navigation
+static void next_variation(TuningForkState* tuning_fork_state) {
+    if(tuning_fork_state->current_variation_index ==
+       tuning_fork_state->instrument.variations_count - 1) {
+        tuning_fork_state->current_variation_index = 0;
+    } else {
+        tuning_fork_state->current_variation_index += 1;
+    }
+    updateTuning(tuning_fork_state);
+}
+
+static void prev_variation(TuningForkState* tuning_fork_state) {
+    if(tuning_fork_state->current_variation_index == 0) {
+        tuning_fork_state->current_variation_index =
+            tuning_fork_state->instrument.variations_count - 1;
+    } else {
+        tuning_fork_state->current_variation_index -= 1;
+    }
+    updateTuning(tuning_fork_state);
+}
+
+// Tunings navigation
 static void next_tuning(TuningForkState* tuning_fork_state) {
-    if(tuning_fork_state->current_tuning_index == TUNINGS_COUNT - 1) {
+    if(tuning_fork_state->current_tuning_index == tuning_fork_state->variation.tunings_count - 1) {
         tuning_fork_state->current_tuning_index = 0;
     } else {
         tuning_fork_state->current_tuning_index += 1;
@@ -89,17 +174,18 @@ static void next_tuning(TuningForkState* tuning_fork_state) {
 }
 
 static void prev_tuning(TuningForkState* tuning_fork_state) {
-    if(tuning_fork_state->current_tuning_index - 1 < 0) {
-        tuning_fork_state->current_tuning_index = TUNINGS_COUNT - 1;
+    if(tuning_fork_state->current_tuning_index == 0) {
+        tuning_fork_state->current_tuning_index = tuning_fork_state->variation.tunings_count - 1;
     } else {
         tuning_fork_state->current_tuning_index -= 1;
     }
     updateTuning(tuning_fork_state);
 }
 
+// Notes navigation
 static void next_note(TuningForkState* tuning_fork_state) {
     if(tuning_fork_state->current_tuning_note_index ==
-       current_tuning(tuning_fork_state).notes_length - 1) {
+       current_tuning(tuning_fork_state).notes_count - 1) {
         tuning_fork_state->current_tuning_note_index = 0;
     } else {
         tuning_fork_state->current_tuning_note_index += 1;
@@ -109,12 +195,13 @@ static void next_note(TuningForkState* tuning_fork_state) {
 static void prev_note(TuningForkState* tuning_fork_state) {
     if(tuning_fork_state->current_tuning_note_index == 0) {
         tuning_fork_state->current_tuning_note_index =
-            current_tuning(tuning_fork_state).notes_length - 1;
+            current_tuning(tuning_fork_state).notes_count - 1;
     } else {
         tuning_fork_state->current_tuning_note_index -= 1;
     }
 }
 
+// Volume adjustments
 static void increase_volume(TuningForkState* tuning_fork_state) {
     if(tuning_fork_state->volume <= (1.0f - VOLUME_STEP)) {
         tuning_fork_state->volume += VOLUME_STEP;
@@ -127,6 +214,7 @@ static void decrease_volume(TuningForkState* tuning_fork_state) {
     }
 }
 
+// Player
 static void play(TuningForkState* tuning_fork_state) {
     if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(1000)) {
         furi_hal_speaker_start(
@@ -146,6 +234,7 @@ static void replay(TuningForkState* tuning_fork_state) {
     play(tuning_fork_state);
 }
 
+// Renderer
 static void render_callback(Canvas* const canvas, void* ctx) {
     furi_assert(ctx);
     TuningForkState* tuning_fork_state = ctx;
@@ -154,29 +243,85 @@ static void render_callback(Canvas* const canvas, void* ctx) {
     FuriString* tempStr = furi_string_alloc();
 
     canvas_draw_frame(canvas, 0, 0, 128, 64);
-
     canvas_set_font(canvas, FontPrimary);
 
-    if(tuning_fork_state->page == Tunings) {
-        char tuningLabel[20];
+    if(tuning_fork_state->page == InstrumentsPage) {
+        char instrumentLabel[MAX_LABEL_LENGTH];
+        current_instrument_label(tuning_fork_state, instrumentLabel);
+        furi_string_printf(tempStr, "< %s >", instrumentLabel);
+        canvas_draw_str_aligned(
+            canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
+    } else if(tuning_fork_state->page == VariationsPage) {
+        char instrumentLabel[MAX_LABEL_LENGTH];
+        char variationLabel[MAX_LABEL_LENGTH];
+
+        current_instrument_label(tuning_fork_state, instrumentLabel);
+        current_variation_label(tuning_fork_state, variationLabel);
+
+        furi_string_printf(tempStr, "%s", instrumentLabel);
+        canvas_draw_str_aligned(canvas, 4, 4, AlignLeft, AlignTop, furi_string_get_cstr(tempStr));
+
+        furi_string_reset(tempStr);
+
+        furi_string_printf(tempStr, "< %s >", variationLabel);
+        canvas_draw_str_aligned(
+            canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
+
+    } else if(tuning_fork_state->page == TuningsPage) {
+        char instrumentLabel[MAX_LABEL_LENGTH];
+        char variationLabel[MAX_LABEL_LENGTH];
+        char tuningLabel[MAX_LABEL_LENGTH];
+
+        current_instrument_label(tuning_fork_state, instrumentLabel);
+        current_variation_label(tuning_fork_state, variationLabel);
         current_tuning_label(tuning_fork_state, tuningLabel);
+
+        furi_string_printf(tempStr, "%s", instrumentLabel);
+        canvas_draw_str_aligned(canvas, 4, 4, AlignLeft, AlignTop, furi_string_get_cstr(tempStr));
+
+        furi_string_reset(tempStr);
+
+        furi_string_printf(tempStr, "%s", variationLabel);
+        canvas_draw_str_aligned(
+            canvas, 124, 4, AlignRight, AlignTop, furi_string_get_cstr(tempStr));
+
+        furi_string_reset(tempStr);
+
         furi_string_printf(tempStr, "< %s >", tuningLabel);
         canvas_draw_str_aligned(
             canvas, 64, 28, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
-        furi_string_reset(tempStr);
+
     } else {
-        char tuningLabel[20];
+        char instrumentLabel[MAX_LABEL_LENGTH];
+        char variationLabel[MAX_LABEL_LENGTH];
+        char tuningLabel[MAX_LABEL_LENGTH];
+
+        current_instrument_label(tuning_fork_state, instrumentLabel);
+        current_variation_label(tuning_fork_state, variationLabel);
         current_tuning_label(tuning_fork_state, tuningLabel);
+
+        furi_string_printf(tempStr, "%s", instrumentLabel);
+        canvas_draw_str_aligned(canvas, 4, 4, AlignLeft, AlignTop, furi_string_get_cstr(tempStr));
+
+        furi_string_reset(tempStr);
+
+        furi_string_printf(tempStr, "%s", variationLabel);
+        canvas_draw_str_aligned(
+            canvas, 124, 4, AlignRight, AlignTop, furi_string_get_cstr(tempStr));
+
+        furi_string_reset(tempStr);
+
         furi_string_printf(tempStr, "%s", tuningLabel);
         canvas_draw_str_aligned(
-            canvas, 64, 8, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
+            canvas, 64, 20, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
+
         furi_string_reset(tempStr);
 
-        char tuningNoteLabel[20];
+        char tuningNoteLabel[MAX_LABEL_LENGTH];
         current_tuning_note_label(tuning_fork_state, tuningNoteLabel);
         furi_string_printf(tempStr, "< %s >", tuningNoteLabel);
         canvas_draw_str_aligned(
-            canvas, 64, 24, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
+            canvas, 64, 32, AlignCenter, AlignCenter, furi_string_get_cstr(tempStr));
         furi_string_reset(tempStr);
     }
 
@@ -184,17 +329,18 @@ static void render_callback(Canvas* const canvas, void* ctx) {
     elements_button_left(canvas, "Prev");
     elements_button_right(canvas, "Next");
 
-    if(tuning_fork_state->page == Notes) {
+    if(tuning_fork_state->page == NotesPage) {
         if(tuning_fork_state->playing) {
-            elements_button_center(canvas, "Stop ");
+            elements_button_center(canvas, "Stop");
         } else {
             elements_button_center(canvas, "Play");
         }
     } else {
         elements_button_center(canvas, "Select");
     }
-    if(tuning_fork_state->page == Notes) {
-        elements_progress_bar(canvas, 8, 36, 112, tuning_fork_state->volume);
+
+    if(tuning_fork_state->page == NotesPage) {
+        elements_progress_bar(canvas, 8, 40, 112, tuning_fork_state->volume);
     }
 
     furi_string_free(tempStr);
@@ -212,10 +358,11 @@ static void input_callback(InputEvent* input_event, void* ctx) {
 static void tuning_fork_state_init(TuningForkState* const tuning_fork_state) {
     if(tuning_fork_state) {
         tuning_fork_state->playing = false;
-        tuning_fork_state->page = Tunings;
+        tuning_fork_state->page = InstrumentsPage;
         tuning_fork_state->volume = DEFAULT_VOLUME;
-        tuning_fork_state->tuning = GuitarStandard6;
-        tuning_fork_state->current_tuning_index = 2;
+        tuning_fork_state->current_instrument_index = 0;
+        tuning_fork_state->current_variation_index = 0;
+        tuning_fork_state->current_tuning_index = 0;
         tuning_fork_state->current_tuning_note_index = 0;
         updateTuning(tuning_fork_state);
     }
@@ -265,7 +412,7 @@ int32_t tuning_fork_app() {
                     // push events
                     switch(event.input.key) {
                     case InputKeyUp:
-                        if(tuning_fork_state->page == Notes) {
+                        if(tuning_fork_state->page == NotesPage) {
                             increase_volume(tuning_fork_state);
                             if(tuning_fork_state->playing) {
                                 replay(tuning_fork_state);
@@ -273,7 +420,7 @@ int32_t tuning_fork_app() {
                         }
                         break;
                     case InputKeyDown:
-                        if(tuning_fork_state->page == Notes) {
+                        if(tuning_fork_state->page == NotesPage) {
                             decrease_volume(tuning_fork_state);
                             if(tuning_fork_state->playing) {
                                 replay(tuning_fork_state);
@@ -281,7 +428,11 @@ int32_t tuning_fork_app() {
                         }
                         break;
                     case InputKeyRight:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            next_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            next_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             next_tuning(tuning_fork_state);
                         } else {
                             next_note(tuning_fork_state);
@@ -291,7 +442,11 @@ int32_t tuning_fork_app() {
                         }
                         break;
                     case InputKeyLeft:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            prev_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            prev_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             prev_tuning(tuning_fork_state);
                         } else {
                             prev_note(tuning_fork_state);
@@ -301,8 +456,12 @@ int32_t tuning_fork_app() {
                         }
                         break;
                     case InputKeyOk:
-                        if(tuning_fork_state->page == Tunings) {
-                            tuning_fork_state->page = Notes;
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            tuning_fork_state->page = VariationsPage;
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            tuning_fork_state->page = TuningsPage;
+                        } else if(tuning_fork_state->page == TuningsPage) {
+                            tuning_fork_state->page = NotesPage;
                         } else {
                             tuning_fork_state->playing = !tuning_fork_state->playing;
                             if(tuning_fork_state->playing) {
@@ -313,13 +472,17 @@ int32_t tuning_fork_app() {
                         }
                         break;
                     case InputKeyBack:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
                             processing = false;
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            tuning_fork_state->page = InstrumentsPage;
+                        } else if(tuning_fork_state->page == TuningsPage) {
+                            tuning_fork_state->page = VariationsPage;
                         } else {
                             tuning_fork_state->playing = false;
                             tuning_fork_state->current_tuning_note_index = 0;
                             stop();
-                            tuning_fork_state->page = Tunings;
+                            tuning_fork_state->page = TuningsPage;
                         }
                         break;
                     default:
@@ -333,7 +496,11 @@ int32_t tuning_fork_app() {
                     case InputKeyDown:
                         break;
                     case InputKeyRight:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            next_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            next_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             next_tuning(tuning_fork_state);
                         } else {
                             next_note(tuning_fork_state);
@@ -344,7 +511,11 @@ int32_t tuning_fork_app() {
 
                         break;
                     case InputKeyLeft:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            prev_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            prev_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             prev_tuning(tuning_fork_state);
                         } else {
                             prev_note(tuning_fork_state);
@@ -357,12 +528,16 @@ int32_t tuning_fork_app() {
                     case InputKeyOk:
                         break;
                     case InputKeyBack:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
                             processing = false;
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            tuning_fork_state->page = InstrumentsPage;
+                        } else if(tuning_fork_state->page == TuningsPage) {
+                            tuning_fork_state->page = VariationsPage;
                         } else {
                             tuning_fork_state->playing = false;
                             stop();
-                            tuning_fork_state->page = Tunings;
+                            tuning_fork_state->page = TuningsPage;
                             tuning_fork_state->current_tuning_note_index = 0;
                         }
                         break;
@@ -377,7 +552,11 @@ int32_t tuning_fork_app() {
                     case InputKeyDown:
                         break;
                     case InputKeyRight:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            next_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            next_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             next_tuning(tuning_fork_state);
                         } else {
                             next_note(tuning_fork_state);
@@ -388,7 +567,11 @@ int32_t tuning_fork_app() {
 
                         break;
                     case InputKeyLeft:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
+                            prev_instrument(tuning_fork_state);
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            prev_variation(tuning_fork_state);
+                        } else if(tuning_fork_state->page == TuningsPage) {
                             prev_tuning(tuning_fork_state);
                         } else {
                             prev_note(tuning_fork_state);
@@ -401,12 +584,16 @@ int32_t tuning_fork_app() {
                     case InputKeyOk:
                         break;
                     case InputKeyBack:
-                        if(tuning_fork_state->page == Tunings) {
+                        if(tuning_fork_state->page == InstrumentsPage) {
                             processing = false;
+                        } else if(tuning_fork_state->page == VariationsPage) {
+                            tuning_fork_state->page = InstrumentsPage;
+                        } else if(tuning_fork_state->page == TuningsPage) {
+                            tuning_fork_state->page = VariationsPage;
                         } else {
                             tuning_fork_state->playing = false;
                             stop();
-                            tuning_fork_state->page = Tunings;
+                            tuning_fork_state->page = TuningsPage;
                             tuning_fork_state->current_tuning_note_index = 0;
                         }
                         break;

+ 116 - 111
tunings.h

@@ -1,38 +1,22 @@
 #ifndef TUNINGS_H
 #define TUNINGS_H
 
-#include "notes.h"
 #include <stdint.h>
+#include "constants.h"
+#include "types.h"
+#include "notes.h"
 
-#define MAX_LABEL_LENGTH     20
-#define MAX_NOTES_PER_TUNING 20
-
-typedef struct {
-    char label[MAX_LABEL_LENGTH];
-    float frequency;
-} NOTE;
-
-typedef struct {
-    char label[MAX_LABEL_LENGTH];
-    uint8_t notes_length;
-    NOTE notes[MAX_NOTES_PER_TUNING];
-} TUNING;
-
-const TUNING TuningForks = {
-    "Tuning forks",
-    6,
-    {
-        {"Common A4 (440)", 440.00f},
-        {"Sarti's A4 (436)", 436.00f},
-        {"1858 A4 (435)", 435.00f},
-        {"Verdi's A4 (432)", 432.00f},
-        {"1750-1820 A4 (423.5)", 423.50f},
-        {"Verdi's C4 (256.00)", 256.00f},
-    }};
+// MISCELLANEOUS
+// Fork Tunings
+const TUNING ForkCommon = {"Common", {{"A4 (440)", 440.00f}}, 1};
+const TUNING ForkSarti = {"Sarti's", {{"A4 (436)", 436.00f}}, 1};
+const TUNING ForkMid19Century = {"1858", {{"A4 (435)", 435.00f}}, 1};
+const TUNING Fork18Century = {"1750-1820", {{"A4 (423.5)", 423.50f}}, 1};
+const TUNING ForkVerdi = {"Verdi's ", {{"C4 (256.00)", 256.00f}}, 1};
 
+// Other Tunings
 const TUNING ScientificPitch = {
-    "Scientific pitch",
-    12,
+    "Scientific Pitch",
     {{"C0 (16Hz)", 16.0f},
      {"C1 (32Hz)", 32.0f},
      {"C2 (64Hz)", 64.0f},
@@ -44,119 +28,140 @@ const TUNING ScientificPitch = {
      {"C8 (4096Hz)", 4096.0f},
      {"C9 (8192Hz)", 8192.0f},
      {"C10 (16384Hz)", 16384.0f},
-     {"C11 (32768Hz)", 32768.0f}}};
+     {"C11 (32768Hz)", 32768.0f}},
+    12};
 
-const TUNING GuitarStandard6 = {
-    "Guitar Standard 6",
-    6,
+// GUITAR
+// 6 strings
+const TUNING Guitar6Standard = {
+    "Standard",
     {{"String 1", E4},
      {"String 2", B3},
      {"String 3", G3},
      {"String 4", D3},
      {"String 5", A2},
-     {"String 6", E2}}};
+     {"String 6", E2}},
+    6};
 
-const TUNING GuitarDropD6 = {
-    "Guitar Drop D 6",
-    6,
+const TUNING Guitar6DropD = {
+    "Drop D",
     {{"String 1", E4},
      {"String 2", B3},
      {"String 3", G3},
      {"String 4", D3},
      {"String 5", A2},
-     {"String 6", D2}}};
+     {"String 6", D2}},
+    6};
 
-const TUNING GuitarD6 = {
-    "Guitar D 6",
-    6,
+const TUNING Guitar6D = {
+    "Standard D",
     {{"String 1", D4},
      {"String 2", A3},
      {"String 3", F3},
      {"String 4", C3},
      {"String 5", G2},
-     {"String 6", D2}}};
+     {"String 6", D2}},
+    6};
 
-const TUNING GuitarDropC6 = {
-    "Guitar Drop C 6",
-    6,
+const TUNING Guitar6DropC = {
+    "Drop C",
     {{"String 1", D4},
      {"String 2", A3},
      {"String 3", F3},
      {"String 4", C3},
      {"String 5", G2},
-     {"String 6", C2}}};
+     {"String 6", C2}},
+    6};
+
+// 7 strings
+const TUNING Guitar7Standard = {
+    "Standard",
+    {{"String 1", E4},
+     {"String 2", B3},
+     {"String 3", G3},
+     {"String 4", D3},
+     {"String 5", A2},
+     {"String 6", E2},
+     {"String 7", B1}},
+    7};
 
-const TUNING GuitarStandard7 = {
-    "Guitar Standard 7",
-    7,
+const TUNING Guitar7DropA = {
+    "Standard",
     {{"String 1", E4},
      {"String 2", B3},
      {"String 3", G3},
      {"String 4", D3},
      {"String 5", A2},
      {"String 6", E2},
-     {"String 7", B1}}};
-
-const TUNING BassStandard4 = {
-    "Bass Standard 4",
-    4,
-    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}}};
-
-const TUNING BassStandardTenor4 = {
-    "Bass Stand Tenor 4",
-    4,
-    {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}}};
-
-const TUNING BassStandard5 = {
-    "Bass Standard 5",
-    5,
-    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", B0}}};
-
-const TUNING BassStandardTenor5 = {
-    "Bass Stand Tenor 5",
-    5,
-    {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}, {"String 5", E1}}};
-
-const TUNING BassDropD4 = {
-    "Bass Drop D 4",
-    4,
-    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", D1}}};
-
-const TUNING BassD4 = {
-    "Bass D 4",
-    4,
-    {{"String 1", F2}, {"String 2", C2}, {"String 3", G1}, {"String 4", D1}}};
-
-const TUNING BassDropA5 = {
-    "Bass Drop A 5",
-    5,
-    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", A0}}};
-
-const TUNING UkuleleStandard4 = {
-    "Ukulele Standard 4",
-    4,
-    {{"String 1", A4}, {"String 2", E4}, {"String 3", C4}, {"String 4", G4}}};
-
-#define TUNINGS_COUNT 15
-
-TUNING TuningList[TUNINGS_COUNT] = {
-    ScientificPitch,
-    TuningForks,
-
-    GuitarStandard6,
-    GuitarDropD6,
-    GuitarD6,
-    GuitarDropC6,
-    GuitarStandard7,
-
-    BassStandard4,
-    BassStandardTenor4,
-    BassStandard5,
-    BassStandardTenor5,
-    BassDropD4,
-    BassD4,
-    BassDropA5,
-
-    UkuleleStandard4};
+     {"String 7", A1}},
+    7};
+
+// BASS
+// 4 strings
+const TUNING Bass4Standard = {
+    "Standard",
+    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}},
+    4};
+
+const TUNING Bass4Tenor = {
+    "Tenor",
+    {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}},
+    4};
+
+const TUNING Bass4DropD = {
+    "Drop D",
+    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", D1}},
+    4};
+
+const TUNING Bass4D = {
+    "D",
+    {{"String 1", F2}, {"String 2", C2}, {"String 3", G1}, {"String 4", D1}},
+    4};
+
+// 5 strings
+const TUNING Bass5Standard = {
+    "Standard",
+    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", B0}},
+    5};
+
+const TUNING Bass5Tenor = {
+    "Tenor",
+    {{"String 1", C3}, {"String 2", G2}, {"String 3", D2}, {"String 4", A1}, {"String 5", E1}},
+    5};
+const TUNING Bass5DropA = {
+    "Drop A",
+    {{"String 1", G2}, {"String 2", D2}, {"String 3", A1}, {"String 4", E1}, {"String 5", A0}},
+    5};
+
+// UKULELE
+// 4 strings
+const TUNING Ukulele4Standard = {
+    "Standard",
+    {{"String 1", A4}, {"String 2", E4}, {"String 3", C4}, {"String 4", G4}},
+    4};
+
+// BANJO
+// 5 strings
+const TUNING Banjo5Standard = {
+    "Standard",
+    {{"String 1", D4}, {"String 2", B3}, {"String 3", G3}, {"String 4", D3}, {"String 5", G4}},
+    5};
+
+// CIGAR BOX
+// 3 strings
+const TUNING CigarBox3OpenG = {"Open G", {{"String 1", G4}, {"String 2", D4}, {"String 3", G3}}, 3};
+
+const TUNING CigarBox3OpenD = {
+    "Open D",
+    {{"String 1", Fs4}, {"String 2", A3}, {"String 3", D3}},
+    3};
+
+const TUNING CigarBox3OpenA = {"Open A", {{"String 1", A4}, {"String 2", E4}, {"String 3", A3}}, 3};
+
+// 4 strings
+const TUNING CigarBox4OpenG = {
+    "Open G",
+    {{"String 1", D4}, {"String 2", B3}, {"String 3", G3}, {"String 4", D3}},
+    4};
 
 #endif //TUNINGS_H

+ 25 - 0
types.h

@@ -0,0 +1,25 @@
+#include <stdint.h>
+#include "constants.h"
+
+typedef struct {
+    char label[MAX_LABEL_LENGTH];
+    float frequency;
+} NOTE;
+
+typedef struct {
+    char label[MAX_LABEL_LENGTH];
+    NOTE notes[MAX_NOTES_PER_TUNING];
+    uint8_t notes_count;
+} TUNING;
+
+typedef struct {
+    char label[MAX_LABEL_LENGTH];
+    TUNING* tunings;
+    uint8_t tunings_count;
+} VARIATION;
+
+typedef struct {
+    char label[MAX_LABEL_LENGTH];
+    VARIATION* variations;
+    uint8_t variations_count;
+} INSTRUMENT;