MX пре 1 година
родитељ
комит
7d4878034d

+ 5 - 5
application.fam

@@ -6,11 +6,11 @@ App(
     cdefines=["APP_FLIZZER_TRACKER"],
     stack_size=2 * 1024,
     order=90,
-    fap_version=(0, 9),
-    fap_description="An advanced Flipper Zero chiptune tracker with 4 channels",
-    fap_author="LTVA",
+	fap_version=(0, 10),
+	fap_description="An advanced Flipper Zero chiptune tracker with 4 channels",
+	fap_author="LTVA",
     fap_weburl="https://github.com/LTVA1/flizzer_tracker",
-    fap_icon="flizzer_tracker.png",
-    fap_icon_assets="images",
+	fap_icon="flizzer_tracker.png",
+	fap_icon_assets="images",
     fap_category="Media",
 )

+ 11 - 3
docs/changelog.md

@@ -1,20 +1,28 @@
-# Flizzer Tracker v0.4 #
+# Flizzer Tracker v0.10 #
+## Fixed ##
+- App not responding to keypresses
+
+# Flizzer Tracker v0.9 #
 
 ## Added ##
 - Vxx effect (detune)
 
-# Flizzer Tracker v0.3 #
+# Flizzer Tracker v0.8 #
 
 ## Added ##
 - Qxx effect (set tracker engine rate)
 
-# Flizzer Tracker v0.2 #
+# Flizzer Tracker v0.7 #
 
 ## Added ##
 - Save/load instruments in separate .fzi files
 - Pattern editor now occupies full screen when you focus on it
 - Copypaste menu (hold Back to open it when focused on pattern editor), operates on whole patterns
 
+# Flizzer Tracker v0.2-v0.6 #
+
+- Small fixes for new firmware versions
+
 # Flizzer Tracker v0.1 #
 
 - Initial release

+ 5 - 107
flizzer_tracker.c

@@ -9,8 +9,6 @@
 #include "font.h"
 #include <flizzer_tracker_icons.h>
 
-#include <expansion/expansion.h>
-
 void draw_callback(Canvas* canvas, void* ctx) {
     TrackerViewModel* model = (TrackerViewModel*)ctx;
     FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)(model->tracker);
@@ -90,7 +88,9 @@ bool input_callback(InputEvent* input_event, void* ctx) {
         .type = EventTypeInput, .input = *input_event, .period = final_period};
 
     if(!(tracker->is_loading) && !(tracker->is_saving)) {
-        furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
+        if(event.type == EventTypeInput) {
+            process_input_event(tracker, &event);
+        }
     }
 
     consumed = true;
@@ -100,9 +100,6 @@ bool input_callback(InputEvent* input_event, void* ctx) {
 int32_t flizzer_tracker_app(void* p) {
     UNUSED(p);
 
-    Expansion* expansion = furi_record_open(RECORD_EXPANSION);
-    expansion_disable(expansion);
-
     Storage* storage = furi_record_open(RECORD_STORAGE);
     bool st = storage_simply_mkdir(storage, APPSDATA_FOLDER);
     st = storage_simply_mkdir(storage, FLIZZER_TRACKER_FOLDER);
@@ -112,106 +109,10 @@ int32_t flizzer_tracker_app(void* p) {
 
     FlizzerTrackerApp* tracker = init_tracker(44100, 50, true, 1024);
 
-    // Текущее событие типа кастомного типа FlizzerTrackerEvent
-    FlizzerTrackerEvent event;
-
     view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+    view_dispatcher_run(tracker->view_dispatcher);
 
-    // Бесконечный цикл обработки очереди событий
-    while(!(tracker->quit)) {
-        // Выбираем событие из очереди в переменную event (ждём бесконечно долго, если очередь пуста)
-        // и проверяем, что у нас получилось это сделать
-        furi_check(
-            furi_message_queue_get(tracker->event_queue, &event, FuriWaitForever) == FuriStatusOk);
-
-        // Наше событие — это нажатие кнопки
-        if(event.type == EventTypeInput) {
-            process_input_event(tracker, &event);
-        }
-
-        if(event.type == EventTypeSaveSong) {
-            save_song(tracker, tracker->filepath);
-        }
-
-        if(event.type == EventTypeSaveInstrument) {
-            save_instrument(tracker, tracker->filepath);
-        }
-
-        if(event.type == EventTypeLoadSong) {
-            stop_song(tracker);
-
-            tracker->tracker_engine.sequence_position = tracker->tracker_engine.pattern_position =
-                tracker->current_instrument = 0;
-
-            tracker->dialogs = furi_record_open(RECORD_DIALOGS);
-            tracker->is_loading = true;
-
-            FuriString* path;
-            path = furi_string_alloc();
-            furi_string_set(path, FLIZZER_TRACKER_FOLDER);
-
-            DialogsFileBrowserOptions browser_options;
-            dialog_file_browser_set_basic_options(
-                &browser_options, SONG_FILE_EXT, &I_flizzer_tracker_module);
-            browser_options.base_path = FLIZZER_TRACKER_FOLDER;
-            browser_options.hide_ext = false;
-
-            bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options);
-
-            furi_record_close(RECORD_DIALOGS);
-
-            const char* cpath = furi_string_get_cstr(path);
-
-            if(ret && strcmp(&cpath[strlen(cpath) - 4], SONG_FILE_EXT) == 0) {
-                bool result = load_song_util(tracker, path);
-                UNUSED(result);
-            }
-
-            else {
-                furi_string_free(path);
-                tracker->is_loading = false;
-            }
-        }
-
-        if(event.type == EventTypeLoadInstrument) {
-            stop_song(tracker);
-
-            tracker->dialogs = furi_record_open(RECORD_DIALOGS);
-            tracker->is_loading_instrument = true;
-
-            FuriString* path;
-            path = furi_string_alloc();
-            furi_string_set(path, FLIZZER_TRACKER_INSTRUMENTS_FOLDER);
-
-            DialogsFileBrowserOptions browser_options;
-            dialog_file_browser_set_basic_options(
-                &browser_options, INST_FILE_EXT, &I_flizzer_tracker_instrument);
-            browser_options.base_path = FLIZZER_TRACKER_FOLDER;
-            browser_options.hide_ext = false;
-
-            bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options);
-
-            furi_record_close(RECORD_DIALOGS);
-
-            const char* cpath = furi_string_get_cstr(path);
-
-            if(ret && strcmp(&cpath[strlen(cpath) - 4], INST_FILE_EXT) == 0) {
-                bool result = load_instrument_util(tracker, path);
-                UNUSED(result);
-            }
-
-            else {
-                furi_string_free(path);
-                tracker->is_loading = false;
-            }
-        }
-
-        if(event.type == EventTypeSetAudioMode) {
-            sound_engine_PWM_timer_init(tracker->external_audio);
-
-            tracker->sound_engine.external_audio_output = tracker->external_audio;
-        }
-    }
+    //here program hangs until view_dispatcher_stop() is called!
 
     stop();
 
@@ -219,8 +120,5 @@ int32_t flizzer_tracker_app(void* p) {
 
     deinit_tracker(tracker);
 
-    expansion_enable(expansion);
-    furi_record_close(RECORD_EXPANSION);
-
     return 0;
 }

+ 14 - 4
init_deinit.c

@@ -5,15 +5,25 @@
 
 #define AUDIO_MODES_COUNT 2
 
+static void tracker_redraw_update_model(void* context) {
+    FlizzerTrackerApp* tracker = context;
+
+    view_commit_model(tracker->tracker_view->view, true);
+}
+
 TrackerView* tracker_view_alloc(FlizzerTrackerApp* tracker) {
     TrackerView* tracker_view = malloc(sizeof(TrackerView));
     tracker_view->view = view_alloc();
     tracker_view->context = tracker;
     view_set_context(tracker_view->view, tracker_view);
-    view_allocate_model(tracker_view->view, ViewModelTypeLocking, sizeof(TrackerViewModel));
+    view_allocate_model(tracker_view->view, ViewModelTypeLockFree, sizeof(TrackerViewModel));
     view_set_draw_callback(tracker_view->view, draw_callback);
     view_set_input_callback(tracker_view->view, input_callback);
 
+    view_dispatcher_set_event_callback_context(tracker->view_dispatcher, tracker);
+    view_dispatcher_set_tick_event_callback(
+        tracker->view_dispatcher, tracker_redraw_update_model, 250);
+
     return tracker_view;
 }
 
@@ -67,13 +77,13 @@ FlizzerTrackerApp* init_tracker(
 
     tracker->tracker_view = tracker_view_alloc(tracker);
 
+    with_view_model(
+        tracker->tracker_view->view, TrackerViewModel * model, { model->tracker = tracker; }, true);
+
     view_dispatcher_add_view(tracker->view_dispatcher, VIEW_TRACKER, tracker->tracker_view->view);
     view_dispatcher_attach_to_gui(
         tracker->view_dispatcher, tracker->gui, ViewDispatcherTypeFullscreen);
 
-    with_view_model(
-        tracker->tracker_view->view, TrackerViewModel * model, { model->tracker = tracker; }, true);
-
     tracker->storage = furi_record_open(RECORD_STORAGE);
     tracker->stream = file_stream_alloc(tracker->storage);
 

+ 75 - 35
input_event.c

@@ -2,6 +2,8 @@
 
 #include "diskop.h"
 
+#include <flizzer_tracker_icons.h>
+
 #define AUDIO_MODES_COUNT 2
 
 void return_from_keyboard_callback(void* ctx) {
@@ -62,8 +64,7 @@ void return_from_keyboard_callback(void* ctx) {
         }
 
         else {
-            FlizzerTrackerEvent event = {.type = EventTypeSaveSong, .input = {{0}}, .period = 0};
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
+            save_song(tracker, tracker->filepath);
         }
     }
 
@@ -85,9 +86,7 @@ void return_from_keyboard_callback(void* ctx) {
         }
 
         else {
-            FlizzerTrackerEvent event = {
-                .type = EventTypeSaveInstrument, .input = {{0}}, .period = 0};
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
+            save_instrument(tracker, tracker->filepath);
         }
     }
 }
@@ -100,10 +99,8 @@ void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType ty
     if(type == InputTypeShort) {
         tracker->is_saving = true;
         view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
-        // save_song(tracker, tracker->filepath);
-        static FlizzerTrackerEvent event = {
-            .type = EventTypeSaveSong, .input = {{0}}, .period = 0};
-        furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
+
+        save_song(tracker, tracker->filepath);
     }
 }
 
@@ -170,15 +167,8 @@ void submenu_callback(void* context, uint32_t index) {
         switch(index) {
         case SUBMENU_PATTERN_EXIT: {
             tracker->quit = true;
-
-            static InputEvent inevent = {.sequence = 0, .key = InputKeyLeft, .type = InputTypeMAX};
-            FlizzerTrackerEvent event = {
-                .type = EventTypeInput,
-                .input = inevent,
-                .period =
-                    0}; // making an event so tracker does not wait for next keypress and exits immediately
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
             view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+            view_dispatcher_stop(tracker->view_dispatcher);
             break;
         }
 
@@ -206,9 +196,41 @@ void submenu_callback(void* context, uint32_t index) {
         }
 
         case SUBMENU_PATTERN_LOAD_SONG: {
-            FlizzerTrackerEvent event = {.type = EventTypeLoadSong, .input = {{0}}, .period = 0};
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
             view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+
+            stop_song(tracker);
+
+            tracker->tracker_engine.sequence_position = tracker->tracker_engine.pattern_position =
+                tracker->current_instrument = 0;
+
+            tracker->dialogs = furi_record_open(RECORD_DIALOGS);
+            tracker->is_loading = true;
+
+            FuriString* path;
+            path = furi_string_alloc();
+            furi_string_set(path, FLIZZER_TRACKER_FOLDER);
+
+            DialogsFileBrowserOptions browser_options;
+            dialog_file_browser_set_basic_options(
+                &browser_options, SONG_FILE_EXT, &I_flizzer_tracker_module);
+            browser_options.base_path = FLIZZER_TRACKER_FOLDER;
+            browser_options.hide_ext = false;
+
+            bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options);
+
+            furi_record_close(RECORD_DIALOGS);
+
+            const char* cpath = furi_string_get_cstr(path);
+
+            if(ret && strcmp(&cpath[strlen(cpath) - 4], SONG_FILE_EXT) == 0) {
+                bool result = load_song_util(tracker, path);
+                UNUSED(result);
+            }
+
+            else {
+                furi_string_free(path);
+                tracker->is_loading = false;
+            }
             break;
         }
 
@@ -229,14 +251,8 @@ void submenu_callback(void* context, uint32_t index) {
         case SUBMENU_INSTRUMENT_EXIT: {
             tracker->quit = true;
 
-            static InputEvent inevent = {.sequence = 0, .key = InputKeyLeft, .type = InputTypeMAX};
-            FlizzerTrackerEvent event = {
-                .type = EventTypeInput,
-                .input = inevent,
-                .period =
-                    0}; // making an event so tracker does not wait for next keypress and exits immediately
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
             view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+            view_dispatcher_stop(tracker->view_dispatcher);
             break;
         }
 
@@ -258,10 +274,38 @@ void submenu_callback(void* context, uint32_t index) {
         }
 
         case SUBMENU_INSTRUMENT_LOAD: {
-            FlizzerTrackerEvent event = {
-                .type = EventTypeLoadInstrument, .input = {{0}}, .period = 0};
-            furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
             view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+
+            stop_song(tracker);
+
+            tracker->dialogs = furi_record_open(RECORD_DIALOGS);
+            tracker->is_loading_instrument = true;
+
+            FuriString* path;
+            path = furi_string_alloc();
+            furi_string_set(path, FLIZZER_TRACKER_INSTRUMENTS_FOLDER);
+
+            DialogsFileBrowserOptions browser_options;
+            dialog_file_browser_set_basic_options(
+                &browser_options, INST_FILE_EXT, &I_flizzer_tracker_instrument);
+            browser_options.base_path = FLIZZER_TRACKER_FOLDER;
+            browser_options.hide_ext = false;
+
+            bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options);
+
+            furi_record_close(RECORD_DIALOGS);
+
+            const char* cpath = furi_string_get_cstr(path);
+
+            if(ret && strcmp(&cpath[strlen(cpath) - 4], INST_FILE_EXT) == 0) {
+                bool result = load_instrument_util(tracker, path);
+                UNUSED(result);
+            }
+
+            else {
+                furi_string_free(path);
+                tracker->is_loading = false;
+            }
             break;
         }
 
@@ -345,13 +389,9 @@ void audio_output_changed_callback(VariableItem* item) {
 
         tracker->external_audio = audio_modes_values[(index > 1 ? 1 : index)];
 
-        // sound_engine_init(&tracker->sound_engine, tracker->sound_engine.sample_rate, tracker->external_audio, tracker->sound_engine.audio_buffer_size);
-        // sound_engine_init_hardware(tracker->sound_engine.sample_rate, tracker->external_audio, tracker->sound_engine.audio_buffer, tracker->sound_engine.audio_buffer_size);
-
-        FlizzerTrackerEvent event = {.type = EventTypeSetAudioMode, .input = {{0}}, .period = 0};
-        furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
+        sound_engine_PWM_timer_init(tracker->external_audio);
 
-        UNUSED(event);
+        tracker->sound_engine.external_audio_output = tracker->external_audio;
     }
 }
 

+ 3 - 3
sound_engine/sound_engine_defs.h

@@ -20,9 +20,9 @@
 #define MAX_ADSR (0xff << 17)
 #define MAX_ADSR_VOLUME 0x80
 #define BASE_FREQ 22050
-#define envspd(eng, slope)                                                                       \
-    ((slope) != 0 ?                                                                              \
-         (((uint64_t)MAX_ADSR / ((slope) * (slope) * 256 / 8)) * BASE_FREQ / eng->sample_rate) : \
+#define envspd(eng, slope)                                                                     \
+    ((slope) != 0 ?                                                                            \
+         (((uint64_t)MAX_ADSR / ((slope) * (slope)*256 / 8)) * BASE_FREQ / eng->sample_rate) : \
          ((uint64_t)MAX_ADSR * BASE_FREQ / eng->sample_rate))
 
 typedef enum {

+ 2 - 1
tracker_engine/do_effects.c

@@ -470,7 +470,8 @@ void do_command(
     }
 
     case TE_EFFECT_TRIGGER_RELEASE: {
-        if(tick == (opcode & 0xff)) {
+        if(tick == (opcode & 0xff))
+        {
             sound_engine_enable_gate(tracker_engine->sound_engine, se_channel, 0);
         }
 

+ 2 - 2
tracker_engine/tracker_engine.c

@@ -444,8 +444,8 @@ void tracker_engine_advance_channel(TrackerEngine* tracker_engine, uint8_t chan)
 
         int32_t chn_note = (int16_t)(te_channel->fixed_note != 0xffff ? te_channel->fixed_note :
                                                                         te_channel->note) +
-                           vib + ((int16_t)te_channel->arpeggio_note << 8) +
-                           te_channel->finetune_note;
+                           vib + ((int16_t)te_channel->arpeggio_note << 8) 
+                           + te_channel->finetune_note;
 
         if(chn_note < 0) {
             chn_note = 0;

+ 1 - 1
tracker_engine/tracker_engine_defs.h

@@ -90,7 +90,7 @@ typedef enum {
     TE_EFFECT_SET_SUSTAIN = 0x1700, // Nxx
     TE_EFFECT_SET_RELEASE = 0x1800, // Oxx
     TE_EFFECT_PROGRAM_RESTART = 0x1900, // Pxx
-
+    
     TE_EFFECT_SET_RATE = 0x1a00, //Qxx
 
     TE_EFFECT_SET_RING_MOD_SRC = 0x1b00, // Rxx