Explorar o código

formatting, portamento, slide, note delay

LTVA1 %!s(int64=3) %!d(string=hai) anos
pai
achega
c4e7e74062

+ 52 - 52
diskop.c

@@ -1,114 +1,114 @@
 #include "diskop.h"
 
-void save_instrument_inner(Stream* stream, Instrument* inst)
+void save_instrument_inner(Stream *stream, Instrument *inst)
 {
-    size_t rwops = stream_write(stream, (uint8_t*)inst->name, sizeof(inst->name));
-    rwops = stream_write(stream, (uint8_t*)&inst->waveform, sizeof(inst->waveform));
-    rwops = stream_write(stream, (uint8_t*)&inst->flags, sizeof(inst->flags));
-    rwops = stream_write(stream, (uint8_t*)&inst->sound_engine_flags, sizeof(inst->sound_engine_flags));
+    size_t rwops = stream_write(stream, (uint8_t *)inst->name, sizeof(inst->name));
+    rwops = stream_write(stream, (uint8_t *)&inst->waveform, sizeof(inst->waveform));
+    rwops = stream_write(stream, (uint8_t *)&inst->flags, sizeof(inst->flags));
+    rwops = stream_write(stream, (uint8_t *)&inst->sound_engine_flags, sizeof(inst->sound_engine_flags));
 
-    rwops = stream_write(stream, (uint8_t*)&inst->base_note, sizeof(inst->base_note));
-    rwops = stream_write(stream, (uint8_t*)&inst->finetune, sizeof(inst->finetune));
+    rwops = stream_write(stream, (uint8_t *)&inst->base_note, sizeof(inst->base_note));
+    rwops = stream_write(stream, (uint8_t *)&inst->finetune, sizeof(inst->finetune));
 
-    rwops = stream_write(stream, (uint8_t*)&inst->slide_speed, sizeof(inst->slide_speed));
+    rwops = stream_write(stream, (uint8_t *)&inst->slide_speed, sizeof(inst->slide_speed));
 
-    rwops = stream_write(stream, (uint8_t*)&inst->adsr, sizeof(inst->adsr));
-    rwops = stream_write(stream, (uint8_t*)&inst->pw, sizeof(inst->pw));
+    rwops = stream_write(stream, (uint8_t *)&inst->adsr, sizeof(inst->adsr));
+    rwops = stream_write(stream, (uint8_t *)&inst->pw, sizeof(inst->pw));
 
-    if(inst->sound_engine_flags & SE_ENABLE_RING_MOD)
+    if (inst->sound_engine_flags & SE_ENABLE_RING_MOD)
     {
-        rwops = stream_write(stream, (uint8_t*)&inst->ring_mod, sizeof(inst->ring_mod));
+        rwops = stream_write(stream, (uint8_t *)&inst->ring_mod, sizeof(inst->ring_mod));
     }
 
-    if(inst->sound_engine_flags & SE_ENABLE_HARD_SYNC)
+    if (inst->sound_engine_flags & SE_ENABLE_HARD_SYNC)
     {
-        rwops = stream_write(stream, (uint8_t*)&inst->hard_sync, sizeof(inst->hard_sync));
+        rwops = stream_write(stream, (uint8_t *)&inst->hard_sync, sizeof(inst->hard_sync));
     }
 
     uint8_t progsteps = 0;
 
-    for(uint8_t i = 0; i < INST_PROG_LEN; i++)
+    for (uint8_t i = 0; i < INST_PROG_LEN; i++)
     {
-        if((inst->program[i] & 0x7fff) != TE_PROGRAM_NOP)
+        if ((inst->program[i] & 0x7fff) != TE_PROGRAM_NOP)
         {
             progsteps = i + 1;
         }
     }
 
-    rwops = stream_write(stream, (uint8_t*)&progsteps, sizeof(progsteps));
+    rwops = stream_write(stream, (uint8_t *)&progsteps, sizeof(progsteps));
 
-    if(progsteps > 0)
+    if (progsteps > 0)
     {
-        rwops = stream_write(stream, (uint8_t*)inst->program, progsteps * sizeof(inst->program[0]));
+        rwops = stream_write(stream, (uint8_t *)inst->program, progsteps * sizeof(inst->program[0]));
     }
 
-    rwops = stream_write(stream, (uint8_t*)&inst->program_period, sizeof(inst->program_period));
+    rwops = stream_write(stream, (uint8_t *)&inst->program_period, sizeof(inst->program_period));
 
-    if(inst->flags & TE_ENABLE_VIBRATO)
+    if (inst->flags & TE_ENABLE_VIBRATO)
     {
-        rwops = stream_write(stream, (uint8_t*)&inst->vibrato_speed, sizeof(inst->vibrato_speed));
-        rwops = stream_write(stream, (uint8_t*)&inst->vibrato_depth, sizeof(inst->vibrato_depth));
-        rwops = stream_write(stream, (uint8_t*)&inst->vibrato_delay, sizeof(inst->vibrato_delay));
+        rwops = stream_write(stream, (uint8_t *)&inst->vibrato_speed, sizeof(inst->vibrato_speed));
+        rwops = stream_write(stream, (uint8_t *)&inst->vibrato_depth, sizeof(inst->vibrato_depth));
+        rwops = stream_write(stream, (uint8_t *)&inst->vibrato_delay, sizeof(inst->vibrato_delay));
     }
 
-    if(inst->flags & TE_ENABLE_PWM)
+    if (inst->flags & TE_ENABLE_PWM)
     {
-        rwops = stream_write(stream, (uint8_t*)&inst->pwm_speed, sizeof(inst->pwm_speed));
-        rwops = stream_write(stream, (uint8_t*)&inst->pwm_depth, sizeof(inst->pwm_depth));
-        rwops = stream_write(stream, (uint8_t*)&inst->pwm_delay, sizeof(inst->pwm_delay));
+        rwops = stream_write(stream, (uint8_t *)&inst->pwm_speed, sizeof(inst->pwm_speed));
+        rwops = stream_write(stream, (uint8_t *)&inst->pwm_depth, sizeof(inst->pwm_depth));
+        rwops = stream_write(stream, (uint8_t *)&inst->pwm_delay, sizeof(inst->pwm_delay));
     }
 
-    if(inst->sound_engine_flags & SE_ENABLE_FILTER)
+    if (inst->sound_engine_flags & SE_ENABLE_FILTER)
     {
-        rwops = stream_write(stream, (uint8_t*)&inst->filter_cutoff, sizeof(inst->filter_cutoff));
-        rwops = stream_write(stream, (uint8_t*)&inst->filter_resonance, sizeof(inst->filter_resonance));
-        rwops = stream_write(stream, (uint8_t*)&inst->filter_type, sizeof(inst->filter_type));
+        rwops = stream_write(stream, (uint8_t *)&inst->filter_cutoff, sizeof(inst->filter_cutoff));
+        rwops = stream_write(stream, (uint8_t *)&inst->filter_resonance, sizeof(inst->filter_resonance));
+        rwops = stream_write(stream, (uint8_t *)&inst->filter_type, sizeof(inst->filter_type));
     }
 
     UNUSED(rwops);
 }
 
-bool save_song(FlizzerTrackerApp* tracker, FuriString* filepath)
+bool save_song(FlizzerTrackerApp *tracker, FuriString *filepath)
 {
-    bool file_removed = storage_simply_remove(tracker->storage, furi_string_get_cstr(filepath)); //just in case
+    bool file_removed = storage_simply_remove(tracker->storage, furi_string_get_cstr(filepath)); // just in case
     bool open_file = file_stream_open(tracker->stream, furi_string_get_cstr(filepath), FSAM_WRITE, FSOM_OPEN_ALWAYS);
 
     uint8_t version = TRACKER_ENGINE_VERSION;
-    size_t rwops = stream_write(tracker->stream, (uint8_t*)SONG_FILE_SIG, sizeof(SONG_FILE_SIG) - 1);
-    rwops = stream_write(tracker->stream, (uint8_t*)&version, sizeof(uint8_t));
+    size_t rwops = stream_write(tracker->stream, (uint8_t *)SONG_FILE_SIG, sizeof(SONG_FILE_SIG) - 1);
+    rwops = stream_write(tracker->stream, (uint8_t *)&version, sizeof(uint8_t));
 
-    TrackerSong* song = &tracker->song;
+    TrackerSong *song = &tracker->song;
 
     /*for(uint32_t i = 0; i < 23444; i++)
     {
         rwops = stream_write(tracker->stream, (uint8_t*)&song->loop_end, sizeof(uint8_t));
     }*/
 
-    rwops = stream_write(tracker->stream, (uint8_t*)song->song_name, sizeof(song->song_name));
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->loop_start, sizeof(song->loop_start));
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->loop_end, sizeof(song->loop_end));
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->pattern_length, sizeof(song->pattern_length));
+    rwops = stream_write(tracker->stream, (uint8_t *)song->song_name, sizeof(song->song_name));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->loop_start, sizeof(song->loop_start));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->loop_end, sizeof(song->loop_end));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->pattern_length, sizeof(song->pattern_length));
 
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->speed, sizeof(song->speed));
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->rate, sizeof(song->rate));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->speed, sizeof(song->speed));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->rate, sizeof(song->rate));
 
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->num_sequence_steps, sizeof(song->num_sequence_steps));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->num_sequence_steps, sizeof(song->num_sequence_steps));
 
-    for(uint16_t i = 0; i < song->num_sequence_steps; i++)
+    for (uint16_t i = 0; i < song->num_sequence_steps; i++)
     {
-        rwops = stream_write(tracker->stream, (uint8_t*)&song->sequence.sequence_step[i], sizeof(song->sequence.sequence_step[0]));
+        rwops = stream_write(tracker->stream, (uint8_t *)&song->sequence.sequence_step[i], sizeof(song->sequence.sequence_step[0]));
     }
 
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->num_patterns, sizeof(song->num_patterns));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->num_patterns, sizeof(song->num_patterns));
 
-    for(uint16_t i = 0; i < song->num_patterns; i++)
+    for (uint16_t i = 0; i < song->num_patterns; i++)
     {
-        rwops = stream_write(tracker->stream, (uint8_t*)song->pattern[i].step, sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
+        rwops = stream_write(tracker->stream, (uint8_t *)song->pattern[i].step, sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
     }
 
-    rwops = stream_write(tracker->stream, (uint8_t*)&song->num_instruments, sizeof(song->num_instruments));
+    rwops = stream_write(tracker->stream, (uint8_t *)&song->num_instruments, sizeof(song->num_instruments));
 
-    for(uint16_t i = 0; i < song->num_instruments; i++)
+    for (uint16_t i = 0; i < song->num_instruments; i++)
     {
         save_instrument_inner(tracker->stream, song->instrument[i]);
     }
@@ -123,7 +123,7 @@ bool save_song(FlizzerTrackerApp* tracker, FuriString* filepath)
     return false;
 }
 
-bool load_song_util(FlizzerTrackerApp* tracker, FuriString* filepath)
+bool load_song_util(FlizzerTrackerApp *tracker, FuriString *filepath)
 {
     bool open_file = file_stream_open(tracker->stream, furi_string_get_cstr(filepath), FSAM_READ, FSOM_OPEN_ALWAYS);
 

+ 2 - 2
diskop.h

@@ -5,6 +5,6 @@
 
 #define INST_FILE_SIG "FZT!INST"
 
-bool save_song(FlizzerTrackerApp* tracker, FuriString* filepath);
+bool save_song(FlizzerTrackerApp *tracker, FuriString *filepath);
 
-bool load_song_util(FlizzerTrackerApp* tracker, FuriString* filepath);
+bool load_song_util(FlizzerTrackerApp *tracker, FuriString *filepath);

+ 10 - 11
flizzer_tracker.c

@@ -1,10 +1,10 @@
 #include "flizzer_tracker.h"
+#include "diskop.h"
 #include "init_deinit.h"
 #include "input_event.h"
 #include "util.h"
 #include "view/instrument_editor.h"
 #include "view/pattern_editor.h"
-#include "diskop.h"
 
 #include <flizzer_tracker_icons.h>
 
@@ -15,7 +15,7 @@ Glyphs: 95/203
 BBX Build Mode: 0
 */
 // this is a modified version with dot and semicolon moved 1 pixel to the left; lowercase symbols removed to save space
-const uint8_t u8g2_font_tom_thumb_4x6_tr[479] U8G2_FONT_SECTION("u8g2_font_tom_thumb_4x6_tr") =
+const uint8_t u8g2_font_tom_thumb_4x6_tr[479] =
     "A\0\2\2\2\3\2\3\4\3\5\0\0\5\0\5\0\0\340\0\0\1\306 \4@\62!\5u\62+"
     "\42\6\313\63I\5#\10W\62i\250\241\2$\10Wr#\216\230\0%\10W\62\31\265Q\0&\10"
     "W\62J\215\224\4'\5\351\63\2(\6vr\252\14)\7V\62\61%\5*\6O\63\251\3+\7"
@@ -39,13 +39,13 @@ void draw_callback(Canvas *canvas, void *ctx)
 
     canvas_set_color(canvas, ColorXOR);
 
-    if(tracker->is_loading)
+    if (tracker->is_loading)
     {
         canvas_draw_str(canvas, 10, 10, "Loading...");
         return;
     }
 
-    if(tracker->is_saving)
+    if (tracker->is_saving)
     {
         canvas_draw_str(canvas, 10, 10, "Saving...");
         return;
@@ -108,7 +108,7 @@ bool input_callback(InputEvent *input_event, void *ctx)
 
     FlizzerTrackerEvent event = {.type = EventTypeInput, .input = *input_event, .period = final_period};
 
-    if(!(tracker->is_loading) && !(tracker->is_saving))
+    if (!(tracker->is_loading) && !(tracker->is_saving))
     {
         furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
     }
@@ -121,7 +121,7 @@ int32_t flizzer_tracker_app(void *p)
 {
     UNUSED(p);
 
-    Storage* storage = furi_record_open(RECORD_STORAGE);
+    Storage *storage = furi_record_open(RECORD_STORAGE);
     bool st = storage_simply_mkdir(storage, FLIZZER_TRACKER_FOLDER);
     UNUSED(st);
     furi_record_close(RECORD_STORAGE);
@@ -222,12 +222,12 @@ int32_t flizzer_tracker_app(void *p)
             process_input_event(tracker, &event);
         }
 
-        if(event.type == EventTypeSaveSong)
+        if (event.type == EventTypeSaveSong)
         {
             save_song(tracker, tracker->filepath);
         }
 
-        if(event.type == EventTypeLoadSong)
+        if (event.type == EventTypeLoadSong)
         {
             stop_song(tracker);
 
@@ -236,7 +236,7 @@ int32_t flizzer_tracker_app(void *p)
             tracker->dialogs = furi_record_open(RECORD_DIALOGS);
             tracker->is_loading = true;
 
-            FuriString* path;
+            FuriString *path;
             path = furi_string_alloc();
             furi_string_set(path, FLIZZER_TRACKER_FOLDER);
 
@@ -249,7 +249,7 @@ int32_t flizzer_tracker_app(void *p)
 
             furi_record_close(RECORD_DIALOGS);
 
-            if(ret)
+            if (ret)
             {
                 bool result = load_song_util(tracker, path);
                 UNUSED(result);
@@ -259,7 +259,6 @@ int32_t flizzer_tracker_app(void *p)
             {
                 furi_string_free(path);
             }
-
         }
     }
 

+ 4 - 5
flizzer_tracker.h

@@ -9,9 +9,8 @@
 #include <input/input.h>
 #include <notification/notification_messages.h>
 #include <stdio.h>
-#include <toolbox/stream/file_stream.h>
 #include <storage/storage.h>
-#include <u8g2_glue.h>
+#include <toolbox/stream/file_stream.h>
 
 #include <gui/modules/text_input.h>
 #include <gui/view_dispatcher.h>
@@ -162,13 +161,13 @@ typedef struct
     TrackerView *tracker_view;
     ViewDispatcher *view_dispatcher;
     TextInput *text_input;
-    Storage* storage;
+    Storage *storage;
     Stream *stream;
-    FuriString* filepath;
+    FuriString *filepath;
     DialogsApp *dialogs;
     Submenu *pattern_submenu;
     Submenu *instrument_submenu;
-    Widget* overwrite_file_widget;
+    Widget *overwrite_file_widget;
     char filename[FILE_NAME_LEN + 1];
     bool was_it_back_keypress;
     uint32_t current_time;

+ 2 - 2
input/instrument.c

@@ -22,7 +22,7 @@ void edit_instrument_param(FlizzerTrackerApp *tracker, uint8_t selected_param, i
 
             clamp(inst, 0, 0, tracker->song.num_instruments);
 
-            if(check_and_allocate_instrument(&tracker->song, (uint8_t)inst))
+            if (check_and_allocate_instrument(&tracker->song, (uint8_t)inst))
             {
                 tracker->current_instrument = inst;
             }
@@ -422,7 +422,7 @@ void instrument_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *even
         reset_buffer(&tracker->sound_engine);
         tracker_engine_set_song(&tracker->tracker_engine, NULL);
 
-        for(int i = 1; i < SONG_MAX_CHANNELS; i++)
+        for (int i = 1; i < SONG_MAX_CHANNELS; i++)
         {
             tracker->tracker_engine.channel[i].channel_flags &= TEC_PLAYING;
             tracker->tracker_engine.sound_engine->channel[i].frequency = 0;

+ 39 - 37
input/instrument_program.c

@@ -16,13 +16,13 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
 
     if (event->input.key == InputKeyOk && event->input.type == InputTypeLong && tracker->editing)
     {
-        Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+        Instrument *inst = tracker->song.instrument[tracker->current_instrument];
 
-        if(tracker->current_program_step < INST_PROG_LEN - 1)
+        if (tracker->current_program_step < INST_PROG_LEN - 1)
         {
-            if((inst->program[tracker->current_program_step] & 0x7fff) < TE_PROGRAM_LOOP_BEGIN && ((inst->program[tracker->current_program_step + 1] & 0x7fff) < TE_PROGRAM_LOOP_BEGIN || (inst->program[tracker->current_program_step + 1] & 0x7f00) == TE_PROGRAM_LOOP_END)) //so we can unite with loop end as in klystrack
+            if ((inst->program[tracker->current_program_step] & 0x7fff) < TE_PROGRAM_LOOP_BEGIN && ((inst->program[tracker->current_program_step + 1] & 0x7fff) < TE_PROGRAM_LOOP_BEGIN || (inst->program[tracker->current_program_step + 1] & 0x7f00) == TE_PROGRAM_LOOP_END)) // so we can unite with loop end as in klystrack
             {
-                inst->program[tracker->current_program_step] ^= 0x8000; //flipping unite bit
+                inst->program[tracker->current_program_step] ^= 0x8000; // flipping unite bit
             }
         }
 
@@ -37,19 +37,19 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
 
     if (event->input.key == InputKeyBack && event->input.type == InputTypeShort && tracker->editing)
     {
-        Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+        Instrument *inst = tracker->song.instrument[tracker->current_instrument];
         inst->program[tracker->current_program_step] = TE_PROGRAM_NOP;
     }
 
     if (event->input.key == InputKeyUp && event->input.type == InputTypeShort)
     {
-        if(!(tracker->editing))
+        if (!(tracker->editing))
         {
-            if((int16_t)tracker->current_program_step - 1 >= 0)
+            if ((int16_t)tracker->current_program_step - 1 >= 0)
             {
                 tracker->current_program_step--;
 
-                if(tracker->program_position > tracker->current_program_step)
+                if (tracker->program_position > tracker->current_program_step)
                 {
                     tracker->program_position = tracker->current_program_step;
                 }
@@ -63,23 +63,23 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
             }
         }
 
-        if(tracker->editing)
+        if (tracker->editing)
         {
-            Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+            Instrument *inst = tracker->song.instrument[tracker->current_instrument];
             uint16_t opcode = inst->program[tracker->current_program_step];
 
-            switch(tracker->current_digit)
+            switch (tracker->current_digit)
             {
-                case 0: //MSB
+                case 0: // MSB
                 {
                     uint8_t param = ((opcode & 0x7f00) >> 8);
 
-                    if(param < 0xff)
+                    if (param < 0xff)
                     {
                         param++;
                     }
 
-                    if((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_NOP)
+                    if ((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_NOP)
                     {
                         param = 0;
                         inst->program[tracker->current_program_step] = 0;
@@ -93,11 +93,11 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                     break;
                 }
 
-                case 1: //upper digit of param, e.g. eXx
+                case 1: // upper digit of param, e.g. eXx
                 {
                     int8_t nibble = ((opcode & 0x00f0) >> 4);
 
-                    if(nibble + 1 < 0xf)
+                    if (nibble + 1 < 0xf)
                     {
                         nibble++;
                     }
@@ -113,11 +113,11 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                     break;
                 }
 
-                case 2: //lower digit of param, e.g. exX
+                case 2: // lower digit of param, e.g. exX
                 {
                     int8_t nibble = (opcode & 0x000f);
 
-                    if(nibble + 1 < 0xf)
+                    if (nibble + 1 < 0xf)
                     {
                         nibble++;
                     }
@@ -133,7 +133,8 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                     break;
                 }
 
-                default: break;
+                default:
+                    break;
             }
         }
 
@@ -142,13 +143,13 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
 
     if (event->input.key == InputKeyDown && event->input.type == InputTypeShort)
     {
-        if(!(tracker->editing))
+        if (!(tracker->editing))
         {
-            if(tracker->current_program_step + 1 < INST_PROG_LEN)
+            if (tracker->current_program_step + 1 < INST_PROG_LEN)
             {
                 tracker->current_program_step++;
 
-                if(tracker->program_position < tracker->current_program_step - 8)
+                if (tracker->program_position < tracker->current_program_step - 8)
                 {
                     tracker->program_position = tracker->current_program_step - 8;
                 }
@@ -162,18 +163,18 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
             }
         }
 
-        if(tracker->editing)
+        if (tracker->editing)
         {
-            Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+            Instrument *inst = tracker->song.instrument[tracker->current_instrument];
             uint16_t opcode = inst->program[tracker->current_program_step];
 
-            switch(tracker->current_digit)
+            switch (tracker->current_digit)
             {
-                case 0: //MSB
+                case 0: // MSB
                 {
                     uint8_t param = ((opcode & 0x7f00) >> 8);
 
-                    if(param < (TE_PROGRAM_JUMP >> 8) && param > 0)
+                    if (param < (TE_PROGRAM_JUMP >> 8) && param > 0)
                     {
                         param--;
 
@@ -181,31 +182,31 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                         inst->program[tracker->current_program_step] |= ((uint16_t)param << 8);
                     }
 
-                    if((inst->program[tracker->current_program_step] & 0x7f00) == TE_PROGRAM_JUMP && (inst->program[tracker->current_program_step] & 0x7fff) != TE_PROGRAM_END && (inst->program[tracker->current_program_step] & 0x7fff) != TE_PROGRAM_NOP)
+                    if ((inst->program[tracker->current_program_step] & 0x7f00) == TE_PROGRAM_JUMP && (inst->program[tracker->current_program_step] & 0x7fff) != TE_PROGRAM_END && (inst->program[tracker->current_program_step] & 0x7fff) != TE_PROGRAM_NOP)
                     {
                         inst->program[tracker->current_program_step] = TE_PROGRAM_LOOP_END | (inst->program[tracker->current_program_step] & 0x8000);
                     }
 
-                    if((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_END)
+                    if ((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_END)
                     {
-                        //param = (TE_PROGRAM_JUMP >> 8);
+                        // param = (TE_PROGRAM_JUMP >> 8);
                         inst->program[tracker->current_program_step] = TE_PROGRAM_JUMP | (inst->program[tracker->current_program_step] & 0x8000);
                     }
 
-                    if((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_NOP)
+                    if ((inst->program[tracker->current_program_step] & 0x7fff) == TE_PROGRAM_NOP)
                     {
-                        //param = (TE_PROGRAM_END >> 8);
+                        // param = (TE_PROGRAM_END >> 8);
                         inst->program[tracker->current_program_step] = TE_PROGRAM_END | (inst->program[tracker->current_program_step] & 0x8000);
                     }
 
                     break;
                 }
 
-                case 1: //upper digit of param, e.g. eXx
+                case 1: // upper digit of param, e.g. eXx
                 {
                     int8_t nibble = ((opcode & 0x00f0) >> 4);
 
-                    if(nibble - 1 >= 0)
+                    if (nibble - 1 >= 0)
                     {
                         nibble--;
                     }
@@ -221,11 +222,11 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                     break;
                 }
 
-                case 2: //lower digit of param, e.g. exX
+                case 2: // lower digit of param, e.g. exX
                 {
                     int8_t nibble = (opcode & 0x000f);
 
-                    if(nibble - 1 >= 0)
+                    if (nibble - 1 >= 0)
                     {
                         nibble--;
                     }
@@ -241,7 +242,8 @@ void instrument_program_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEve
                     break;
                 }
 
-                default: break;
+                default:
+                    break;
             }
         }
 

+ 1 - 1
input/pattern.c

@@ -199,7 +199,7 @@ void delete_field(TrackerSongPatternStep *step, uint8_t field)
         case 0: // note
         {
             set_note(step, MUS_NOTE_NONE);
-            set_instrument(step, MUS_NOTE_INSTRUMENT_NONE); //also delete instrument
+            set_instrument(step, MUS_NOTE_INSTRUMENT_NONE); // also delete instrument
             break;
         }
 

+ 11 - 11
input_event.c

@@ -6,7 +6,7 @@ void return_from_keyboard_callback(void *ctx)
 {
     FlizzerTrackerApp *tracker = (FlizzerTrackerApp *)ctx;
 
-    if(!tracker->is_loading && !tracker->is_saving)
+    if (!tracker->is_loading && !tracker->is_saving)
     {
         uint8_t string_length = 0;
         char *string = NULL;
@@ -55,14 +55,14 @@ void return_from_keyboard_callback(void *ctx)
 
     view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
 
-    if(tracker->is_saving)
+    if (tracker->is_saving)
     {
         stop_song(tracker);
-        
+
         tracker->filepath = furi_string_alloc();
         furi_string_cat_printf(tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_FOLDER, tracker->filename, SONG_FILE_EXT);
 
-        if(storage_file_exists(tracker->storage, furi_string_get_cstr(tracker->filepath)))
+        if (storage_file_exists(tracker->storage, furi_string_get_cstr(tracker->filepath)))
         {
             view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE);
             return;
@@ -76,29 +76,29 @@ void return_from_keyboard_callback(void *ctx)
     }
 }
 
-void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx)
+void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void *ctx)
 {
     UNUSED(result);
 
-    FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx;
+    FlizzerTrackerApp *tracker = (FlizzerTrackerApp *)ctx;
 
-    if(type == InputTypeShort)
+    if (type == InputTypeShort)
     {
         tracker->is_saving = true;
         view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
-        //save_song(tracker, tracker->filepath);
+        // save_song(tracker, tracker->filepath);
         static FlizzerTrackerEvent event = {.type = EventTypeSaveSong, .input = {0}, .period = 0};
         furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever);
     }
 }
 
-void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx)
+void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void *ctx)
 {
     UNUSED(result);
 
-    FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx;
+    FlizzerTrackerApp *tracker = (FlizzerTrackerApp *)ctx;
 
-    if(type == InputTypeShort)
+    if (type == InputTypeShort)
     {
         tracker->is_saving = false;
         furi_string_free(tracker->filepath);

+ 2 - 2
input_event.h

@@ -17,8 +17,8 @@
 
 void return_from_keyboard_callback(void *ctx);
 
-void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx);
-void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx);
+void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void *ctx);
+void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void *ctx);
 
 void submenu_callback(void *context, uint32_t index);
 void process_input_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *event);

+ 2 - 2
sound_engine/sound_engine.c

@@ -7,12 +7,12 @@
 
 void sound_engine_init(SoundEngine *sound_engine, uint32_t sample_rate, bool external_audio_output, uint32_t audio_buffer_size)
 {
-    if(sound_engine->audio_buffer)
+    if (sound_engine->audio_buffer)
     {
         free(sound_engine->audio_buffer);
     }
 
-    if(sound_engine->sine_lut)
+    if (sound_engine->sine_lut)
     {
         free(sound_engine->sine_lut);
     }

+ 52 - 52
tracker_engine/diskop.c

@@ -1,71 +1,71 @@
 #include "diskop.h"
 
-void load_instrument_inner(Stream* stream, Instrument* inst)
+void load_instrument_inner(Stream *stream, Instrument *inst)
 {
-    size_t rwops = stream_read(stream, (uint8_t*)inst->name, sizeof(inst->name));
-    rwops = stream_read(stream, (uint8_t*)&inst->waveform, sizeof(inst->waveform));
-    rwops = stream_read(stream, (uint8_t*)&inst->flags, sizeof(inst->flags));
-    rwops = stream_read(stream, (uint8_t*)&inst->sound_engine_flags, sizeof(inst->sound_engine_flags));
+    size_t rwops = stream_read(stream, (uint8_t *)inst->name, sizeof(inst->name));
+    rwops = stream_read(stream, (uint8_t *)&inst->waveform, sizeof(inst->waveform));
+    rwops = stream_read(stream, (uint8_t *)&inst->flags, sizeof(inst->flags));
+    rwops = stream_read(stream, (uint8_t *)&inst->sound_engine_flags, sizeof(inst->sound_engine_flags));
 
-    rwops = stream_read(stream, (uint8_t*)&inst->base_note, sizeof(inst->base_note));
-    rwops = stream_read(stream, (uint8_t*)&inst->finetune, sizeof(inst->finetune));
+    rwops = stream_read(stream, (uint8_t *)&inst->base_note, sizeof(inst->base_note));
+    rwops = stream_read(stream, (uint8_t *)&inst->finetune, sizeof(inst->finetune));
 
-    rwops = stream_read(stream, (uint8_t*)&inst->slide_speed, sizeof(inst->slide_speed));
+    rwops = stream_read(stream, (uint8_t *)&inst->slide_speed, sizeof(inst->slide_speed));
 
-    rwops = stream_read(stream, (uint8_t*)&inst->adsr, sizeof(inst->adsr));
-    rwops = stream_read(stream, (uint8_t*)&inst->pw, sizeof(inst->pw));
+    rwops = stream_read(stream, (uint8_t *)&inst->adsr, sizeof(inst->adsr));
+    rwops = stream_read(stream, (uint8_t *)&inst->pw, sizeof(inst->pw));
 
-    if(inst->sound_engine_flags & SE_ENABLE_RING_MOD)
+    if (inst->sound_engine_flags & SE_ENABLE_RING_MOD)
     {
-        rwops = stream_read(stream, (uint8_t*)&inst->ring_mod, sizeof(inst->ring_mod));
+        rwops = stream_read(stream, (uint8_t *)&inst->ring_mod, sizeof(inst->ring_mod));
     }
 
-    if(inst->sound_engine_flags & SE_ENABLE_HARD_SYNC)
+    if (inst->sound_engine_flags & SE_ENABLE_HARD_SYNC)
     {
-        rwops = stream_read(stream, (uint8_t*)&inst->hard_sync, sizeof(inst->hard_sync));
+        rwops = stream_read(stream, (uint8_t *)&inst->hard_sync, sizeof(inst->hard_sync));
     }
 
     uint8_t progsteps = 0;
 
-    rwops = stream_read(stream, (uint8_t*)&progsteps, sizeof(progsteps));
+    rwops = stream_read(stream, (uint8_t *)&progsteps, sizeof(progsteps));
 
-    if(progsteps > 0)
+    if (progsteps > 0)
     {
-        rwops = stream_read(stream, (uint8_t*)inst->program, progsteps * sizeof(inst->program[0]));
+        rwops = stream_read(stream, (uint8_t *)inst->program, progsteps * sizeof(inst->program[0]));
     }
 
-    rwops = stream_read(stream, (uint8_t*)&inst->program_period, sizeof(inst->program_period));
+    rwops = stream_read(stream, (uint8_t *)&inst->program_period, sizeof(inst->program_period));
 
-    if(inst->flags & TE_ENABLE_VIBRATO)
+    if (inst->flags & TE_ENABLE_VIBRATO)
     {
-        rwops = stream_read(stream, (uint8_t*)&inst->vibrato_speed, sizeof(inst->vibrato_speed));
-        rwops = stream_read(stream, (uint8_t*)&inst->vibrato_depth, sizeof(inst->vibrato_depth));
-        rwops = stream_read(stream, (uint8_t*)&inst->vibrato_delay, sizeof(inst->vibrato_delay));
+        rwops = stream_read(stream, (uint8_t *)&inst->vibrato_speed, sizeof(inst->vibrato_speed));
+        rwops = stream_read(stream, (uint8_t *)&inst->vibrato_depth, sizeof(inst->vibrato_depth));
+        rwops = stream_read(stream, (uint8_t *)&inst->vibrato_delay, sizeof(inst->vibrato_delay));
     }
 
-    if(inst->flags & TE_ENABLE_PWM)
+    if (inst->flags & TE_ENABLE_PWM)
     {
-        rwops = stream_read(stream, (uint8_t*)&inst->pwm_speed, sizeof(inst->pwm_speed));
-        rwops = stream_read(stream, (uint8_t*)&inst->pwm_depth, sizeof(inst->pwm_depth));
-        rwops = stream_read(stream, (uint8_t*)&inst->pwm_delay, sizeof(inst->pwm_delay));
+        rwops = stream_read(stream, (uint8_t *)&inst->pwm_speed, sizeof(inst->pwm_speed));
+        rwops = stream_read(stream, (uint8_t *)&inst->pwm_depth, sizeof(inst->pwm_depth));
+        rwops = stream_read(stream, (uint8_t *)&inst->pwm_delay, sizeof(inst->pwm_delay));
     }
 
-    if(inst->sound_engine_flags & SE_ENABLE_FILTER)
+    if (inst->sound_engine_flags & SE_ENABLE_FILTER)
     {
-        rwops = stream_read(stream, (uint8_t*)&inst->filter_cutoff, sizeof(inst->filter_cutoff));
-        rwops = stream_read(stream, (uint8_t*)&inst->filter_resonance, sizeof(inst->filter_resonance));
-        rwops = stream_read(stream, (uint8_t*)&inst->filter_type, sizeof(inst->filter_type));
+        rwops = stream_read(stream, (uint8_t *)&inst->filter_cutoff, sizeof(inst->filter_cutoff));
+        rwops = stream_read(stream, (uint8_t *)&inst->filter_resonance, sizeof(inst->filter_resonance));
+        rwops = stream_read(stream, (uint8_t *)&inst->filter_type, sizeof(inst->filter_type));
     }
 
     UNUSED(rwops);
 }
 
-bool load_song_inner(TrackerSong* song, Stream* stream)
+bool load_song_inner(TrackerSong *song, Stream *stream)
 {
     uint8_t version = 0;
-    size_t rwops = stream_read(stream, (uint8_t*)&version, sizeof(version));
+    size_t rwops = stream_read(stream, (uint8_t *)&version, sizeof(version));
 
-    if(version > TRACKER_ENGINE_VERSION) //if song is of newer version this version of tracker engine can't support
+    if (version > TRACKER_ENGINE_VERSION) // if song is of newer version this version of tracker engine can't support
     {
         return false;
     }
@@ -73,35 +73,35 @@ bool load_song_inner(TrackerSong* song, Stream* stream)
     tracker_engine_deinit_song(song, false);
     memset(song, 0, sizeof(TrackerSong));
 
-    rwops = stream_read(stream, (uint8_t*)song->song_name, sizeof(song->song_name));
-    rwops = stream_read(stream, (uint8_t*)&song->loop_start, sizeof(song->loop_start));
-    rwops = stream_read(stream, (uint8_t*)&song->loop_end, sizeof(song->loop_end));
-    rwops = stream_read(stream, (uint8_t*)&song->pattern_length, sizeof(song->pattern_length));
+    rwops = stream_read(stream, (uint8_t *)song->song_name, sizeof(song->song_name));
+    rwops = stream_read(stream, (uint8_t *)&song->loop_start, sizeof(song->loop_start));
+    rwops = stream_read(stream, (uint8_t *)&song->loop_end, sizeof(song->loop_end));
+    rwops = stream_read(stream, (uint8_t *)&song->pattern_length, sizeof(song->pattern_length));
 
-    rwops = stream_read(stream, (uint8_t*)&song->speed, sizeof(song->speed));
-    rwops = stream_read(stream, (uint8_t*)&song->rate, sizeof(song->rate));
+    rwops = stream_read(stream, (uint8_t *)&song->speed, sizeof(song->speed));
+    rwops = stream_read(stream, (uint8_t *)&song->rate, sizeof(song->rate));
 
-    rwops = stream_read(stream, (uint8_t*)&song->num_sequence_steps, sizeof(song->num_sequence_steps));
+    rwops = stream_read(stream, (uint8_t *)&song->num_sequence_steps, sizeof(song->num_sequence_steps));
 
-    for(uint16_t i = 0; i < song->num_sequence_steps; i++)
+    for (uint16_t i = 0; i < song->num_sequence_steps; i++)
     {
-        rwops = stream_read(stream, (uint8_t*)&song->sequence.sequence_step[i], sizeof(song->sequence.sequence_step[0]));
+        rwops = stream_read(stream, (uint8_t *)&song->sequence.sequence_step[i], sizeof(song->sequence.sequence_step[0]));
     }
 
-    rwops = stream_read(stream, (uint8_t*)&song->num_patterns, sizeof(song->num_patterns));
+    rwops = stream_read(stream, (uint8_t *)&song->num_patterns, sizeof(song->num_patterns));
 
-    for(uint16_t i = 0; i < song->num_patterns; i++)
+    for (uint16_t i = 0; i < song->num_patterns; i++)
     {
-        song->pattern[i].step = (TrackerSongPatternStep*)malloc(sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
+        song->pattern[i].step = (TrackerSongPatternStep *)malloc(sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
         set_empty_pattern(&song->pattern[i], song->pattern_length);
-        rwops = stream_read(stream, (uint8_t*)song->pattern[i].step, sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
+        rwops = stream_read(stream, (uint8_t *)song->pattern[i].step, sizeof(TrackerSongPatternStep) * (song->pattern_length - 1));
     }
 
-    rwops = stream_read(stream, (uint8_t*)&song->num_instruments, sizeof(song->num_instruments));
+    rwops = stream_read(stream, (uint8_t *)&song->num_instruments, sizeof(song->num_instruments));
 
-    for(uint16_t i = 0; i < song->num_instruments; i++)
+    for (uint16_t i = 0; i < song->num_instruments; i++)
     {
-        song->instrument[i] = (Instrument*)malloc(sizeof(Instrument));
+        song->instrument[i] = (Instrument *)malloc(sizeof(Instrument));
         set_default_instrument(song->instrument[i]);
         load_instrument_inner(stream, song->instrument[i]);
     }
@@ -110,13 +110,13 @@ bool load_song_inner(TrackerSong* song, Stream* stream)
     return false;
 }
 
-bool load_song(TrackerSong* song, Stream* stream)
+bool load_song(TrackerSong *song, Stream *stream)
 {
     char header[sizeof(SONG_FILE_SIG) + 2] = {0};
-    size_t rwops = stream_read(stream, (uint8_t*)&header, sizeof(SONG_FILE_SIG) - 1);
+    size_t rwops = stream_read(stream, (uint8_t *)&header, sizeof(SONG_FILE_SIG) - 1);
     header[sizeof(SONG_FILE_SIG)] = '\0';
 
-    if(strcmp(header, SONG_FILE_SIG) == 0)
+    if (strcmp(header, SONG_FILE_SIG) == 0)
     {
         bool result = load_song_inner(song, stream);
         UNUSED(result);

+ 5 - 5
tracker_engine/diskop.h

@@ -1,10 +1,10 @@
 #pragma once
 
-#include <stdio.h>
+#include "tracker_engine.h"
+#include "tracker_engine_defs.h"
 #include <stdbool.h>
-#include <toolbox/stream/file_stream.h>
+#include <stdio.h>
 #include <storage/storage.h>
-#include "tracker_engine_defs.h"
-#include "tracker_engine.h"
+#include <toolbox/stream/file_stream.h>
 
-bool load_song(TrackerSong* song, Stream* stream);
+bool load_song(TrackerSong *song, Stream *stream);

+ 40 - 0
tracker_engine/do_effects.c

@@ -0,0 +1,40 @@
+#include "do_effects.h"
+#include <furi.h>
+
+void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel)
+{
+    TrackerEngineChannel *te_channel = &tracker_engine->channel[channel];
+    SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[channel];
+
+    UNUSED(se_channel);
+
+    switch (opcode & 0x7f00)
+    {
+        case TE_EFFECT_PORTAMENTO_UP:
+        {
+            uint32_t prev = te_channel->note;
+
+            te_channel->note += ((opcode & 0xff) << 2);
+            if (prev > te_channel->note)
+                te_channel->note = 0xffff;
+
+            te_channel->target_note = te_channel->note;
+            break;
+        }
+
+        case TE_EFFECT_PORTAMENTO_DOWN:
+        {
+            int32_t prev = te_channel->note;
+
+            te_channel->note -= ((opcode & 0xff) << 2);
+            if (prev < te_channel->note)
+                te_channel->note = 0;
+
+            te_channel->target_note = te_channel->note;
+            break;
+        }
+
+        default:
+            break;
+    }
+}

+ 5 - 0
tracker_engine/do_effects.h

@@ -0,0 +1,5 @@
+#include "tracker_engine_defs.h"
+#include <stdbool.h>
+#include <stdio.h>
+
+void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel);

+ 63 - 31
tracker_engine/tracker_engine.c

@@ -2,8 +2,8 @@
 
 #include "../flizzer_tracker_hal.h"
 
-#include <furi_hal.h>
 #include "../sound_engine/sound_engine_osc.h"
+#include <furi_hal.h>
 
 void tracker_engine_init(TrackerEngine *tracker_engine, uint8_t rate, SoundEngine *sound_engine)
 {
@@ -78,7 +78,7 @@ void set_command(TrackerSongPatternStep *step, uint16_t command)
     step->command |= command & (0x7fff);
 }
 
-void set_default_instrument(Instrument* inst)
+void set_default_instrument(Instrument *inst)
 {
     memset(inst, 0, sizeof(Instrument));
 
@@ -94,7 +94,7 @@ void set_default_instrument(Instrument* inst)
     inst->adsr.d = 0x28;
     inst->adsr.volume = 0x80;
 
-    for(int i = 0; i < INST_PROG_LEN; i++)
+    for (int i = 0; i < INST_PROG_LEN; i++)
     {
         inst->program[i] = TE_PROGRAM_NOP;
     }
@@ -178,14 +178,16 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
 
     te_channel->last_note = te_channel->target_note = note + (int16_t)pinst->finetune;
 
-    if(pinst->flags & TE_ENABLE_VIBRATO)
+    te_channel->extarp1 = te_channel->extarp2 = 0;
+
+    if (pinst->flags & TE_ENABLE_VIBRATO)
     {
         te_channel->vibrato_speed = pinst->vibrato_speed;
         te_channel->vibrato_depth = pinst->vibrato_depth;
         te_channel->vibrato_delay = pinst->vibrato_delay;
     }
 
-    if(pinst->flags & TE_ENABLE_PWM)
+    if (pinst->flags & TE_ENABLE_PWM)
     {
         te_channel->pwm_speed = pinst->pwm_speed;
         te_channel->pwm_depth = pinst->pwm_depth;
@@ -226,7 +228,7 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
     se_channel->ring_mod = pinst->ring_mod;
     se_channel->hard_sync = pinst->hard_sync;
 
-    te_channel->slide_speed = 0;
+    te_channel->slide_speed = pinst->slide_speed;
 
     se_channel->adsr.a = pinst->adsr.a;
     se_channel->adsr.d = pinst->adsr.d;
@@ -246,15 +248,28 @@ void tracker_engine_execute_track_command(TrackerEngine *tracker_engine, uint8_t
     UNUSED(chan);
 
     uint8_t vol = tracker_engine_get_volume(step);
+    uint16_t opcode = tracker_engine_get_command(step);
 
     if (vol != MUS_NOTE_VOLUME_NONE && !(tracker_engine->channel[chan].channel_flags & TEC_DISABLED))
     {
         tracker_engine->sound_engine->channel[chan].adsr.volume = (int32_t)tracker_engine->sound_engine->channel[chan].adsr.volume * (int32_t)tracker_engine->channel[chan].volume / MAX_ADSR_VOLUME * (int32_t)vol / (MUS_NOTE_VOLUME_NONE - 1);
     }
 
-    // TODO: add actual big ass function that executes commands; add arpeggio commands there
+    if (tracker_engine->channel[chan].instrument != NULL && opcode != 0)
+    {
+        if ((opcode & 0x7f00) == TE_EFFECT_ARPEGGIO)
+        {
+            tracker_engine->channel[chan].extarp1 = ((opcode & 0xf0) >> 4);
+            tracker_engine->channel[chan].extarp2 = (opcode & 0xf);
+        }
 
-    if(tracker_engine->channel[chan].channel_flags & TEC_DISABLED)
+        else
+        {
+            do_command(opcode, tracker_engine, chan);
+        }
+    }
+
+    if (tracker_engine->channel[chan].channel_flags & TEC_DISABLED)
     {
         tracker_engine->sound_engine->channel[chan].adsr.volume = 0;
     }
@@ -276,26 +291,26 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
         {
             if (te_channel->target_note > te_channel->note)
             {
-                te_channel->target_note += fmin(te_channel->slide_speed, te_channel->target_note - te_channel->note);
+                te_channel->note += fmin(te_channel->slide_speed, te_channel->target_note - te_channel->note);
             }
 
             else if (te_channel->target_note < te_channel->note)
             {
-                te_channel->target_note -= fmin(te_channel->slide_speed, te_channel->note - te_channel->target_note);
+                te_channel->note -= fmin(te_channel->slide_speed, te_channel->note - te_channel->target_note);
             }
         }
 
-        if(te_channel->channel_flags & TEC_PROGRAM_RUNNING)
+        if (te_channel->channel_flags & TEC_PROGRAM_RUNNING)
         {
             // TODO: add instrument program execution
         }
-        
+
         int16_t vib = 0;
         int32_t pwm = 0;
 
-        if(te_channel->flags & TE_ENABLE_VIBRATO)
+        if (te_channel->flags & TE_ENABLE_VIBRATO)
         {
-            if(te_channel->vibrato_delay > 0)
+            if (te_channel->vibrato_delay > 0)
             {
                 te_channel->vibrato_delay--;
             }
@@ -307,27 +322,27 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
             }
         }
 
-        if(te_channel->flags & TE_ENABLE_PWM)
+        if (te_channel->flags & TE_ENABLE_PWM)
         {
-            if(te_channel->pwm_delay > 0)
+            if (te_channel->pwm_delay > 0)
             {
                 te_channel->pwm_delay--;
             }
 
             else
             {
-                te_channel->pwm_position += ((uint32_t)te_channel->pwm_speed << 20); //so minimum PWM speed is even lower than minimum vibrato speed
+                te_channel->pwm_position += ((uint32_t)te_channel->pwm_speed << 20); // so minimum PWM speed is even lower than minimum vibrato speed
                 pwm = ((int32_t)sound_engine_triangle((te_channel->pwm_position) >> 9) - WAVE_AMP / 2) * (int32_t)te_channel->pwm_depth / (256 * 16);
             }
 
             int16_t final_pwm = (int16_t)tracker_engine->channel[chan].pw + pwm;
 
-            if(final_pwm < 0)
+            if (final_pwm < 0)
             {
                 final_pwm = 0;
             }
 
-            if(final_pwm > 0xfff)
+            if (final_pwm > 0xfff)
             {
                 final_pwm = 0xfff;
             }
@@ -350,7 +365,7 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
         tracker_engine_set_note(tracker_engine, chan, (uint16_t)chn_note, false);
     }
 
-    if(tracker_engine->channel[chan].channel_flags & TEC_DISABLED) //so we can't set some non-zero volme from inst program too
+    if (tracker_engine->channel[chan].channel_flags & TEC_DISABLED) // so we can't set some non-zero volme from inst program too
     {
         tracker_engine->sound_engine->channel[chan].adsr.volume = 0;
     }
@@ -379,7 +394,14 @@ void tracker_engine_advance_tick(TrackerEngine *tracker_engine)
 
             TrackerSongPattern *pattern = &song->pattern[current_pattern];
 
-            uint8_t note_delay = 0; // TODO: add note delay command
+            uint8_t note_delay = 0;
+
+            uint16_t opcode = tracker_engine_get_command(&pattern->step[pattern_step]);
+
+            if ((opcode & 0x7ff0) == TE_EFFECT_EXT_NOTE_DELAY)
+            {
+                note_delay = (opcode & 0xf);
+            }
 
             if (tracker_engine->current_tick == note_delay)
             {
@@ -401,8 +423,13 @@ void tracker_engine_advance_tick(TrackerEngine *tracker_engine)
                         te_channel->instrument = pinst;
                     }
                 }
-
-                // TODO: add note cut command
+                
+                if(note == MUS_NOTE_CUT)
+                {
+                    sound_engine_enable_gate(tracker_engine->sound_engine, se_channel, 0);
+                    se_channel->adsr.volume = 0;
+                    te_channel->volume = 0;
+                }
 
                 if (note == MUS_NOTE_RELEASE)
                 {
@@ -411,18 +438,23 @@ void tracker_engine_advance_tick(TrackerEngine *tracker_engine)
 
                 else if (pinst && note != MUS_NOTE_RELEASE && note != MUS_NOTE_CUT && note != MUS_NOTE_NONE)
                 {
-                    te_channel->slide_speed = 0;
-
-                    // TODO: add setting slide speed if slide command is there
-
-                    // te_channel->slide_speed = pinst->slide_speed;
+                    //te_channel->slide_speed = 0;
 
                     uint8_t prev_adsr_volume = se_channel->adsr.volume;
 
-                    tracker_engine_trigger_instrument_internal(tracker_engine, chan, pinst, note << 8);
-                    te_channel->note = (note << 8) + pinst->finetune;
+                    if((opcode & 0x7f00) == TE_EFFECT_SLIDE)
+                    {
+                        te_channel->target_note = ((note + pinst->base_note - MIDDLE_C) << 8) + pinst->finetune;
+                        te_channel->slide_speed = (opcode & 0xff);
+                    }
+
+                    else
+                    {
+                        tracker_engine_trigger_instrument_internal(tracker_engine, chan, pinst, note << 8);
+                        te_channel->note = ((note + pinst->base_note - MIDDLE_C) << 8) + pinst->finetune;
 
-                    te_channel->target_note = (note << 8) + pinst->finetune;
+                        te_channel->target_note = ((note + pinst->base_note - MIDDLE_C) << 8) + pinst->finetune;
+                    }
 
                     if (inst == MUS_NOTE_INSTRUMENT_NONE)
                     {

+ 2 - 1
tracker_engine/tracker_engine.h

@@ -1,5 +1,6 @@
 #pragma once
 
+#include "do_effects.h"
 #include "tracker_engine_defs.h"
 
 void tracker_engine_init(TrackerEngine *tracker_engine, uint8_t rate, SoundEngine *sound_engine);
@@ -19,5 +20,5 @@ void set_instrument(TrackerSongPatternStep *step, uint8_t inst);
 void set_volume(TrackerSongPatternStep *step, uint8_t vol);
 void set_command(TrackerSongPatternStep *step, uint16_t command);
 
-void set_default_instrument(Instrument* inst);
+void set_default_instrument(Instrument *inst);
 void set_empty_pattern(TrackerSongPattern *pattern, uint16_t pattern_length);

+ 3 - 1
tracker_engine/tracker_engine_defs.h

@@ -2,6 +2,7 @@
 
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdint.h>
 
 #include "../sound_engine/sound_engine_defs.h"
 
@@ -60,6 +61,7 @@ typedef enum
     TE_EFFECT_SKIP_PATTERN = 0x0d00,
     TE_EFFECT_EXT = 0x0e00,
     /* TODO: add 0exy effects here */
+    TE_EFFECT_EXT_NOTE_DELAY = 0x0ed0,
     TE_EFFECT_SET_SPEED_PROG_PERIOD = 0x0f00,
     /* These effects work only in instrument program */
     TE_PROGRAM_LOOP_BEGIN = 0x7d00,
@@ -123,7 +125,7 @@ typedef struct
     uint8_t vibrato_speed, vibrato_depth, vibrato_delay;
     uint8_t pwm_speed, pwm_depth, pwm_delay;
 
-    uint32_t vibrato_position, pwm_position; //basically accumulators
+    uint32_t vibrato_position, pwm_position; // basically accumulators
 
     uint8_t extarp1, extarp2;
 

+ 4 - 3
util.c

@@ -108,9 +108,9 @@ void change_pattern_length(TrackerSong *song, uint16_t new_length)
     song->pattern_length = new_length;
 }
 
-bool is_default_instrument(Instrument* inst)
+bool is_default_instrument(Instrument *inst)
 {
-    Instrument* ref = malloc(sizeof(Instrument));
+    Instrument *ref = malloc(sizeof(Instrument));
     set_default_instrument(ref);
     bool is_default = memcmp(ref, inst, sizeof(Instrument)) != 0 ? false : true;
     free(ref);
@@ -126,7 +126,8 @@ bool check_and_allocate_instrument(TrackerSong *song, uint8_t inst)
 
     else
     {
-        if(inst >= MAX_INSTRUMENTS) return false;
+        if (inst >= MAX_INSTRUMENTS)
+            return false;
 
         if (!(is_default_instrument(song->instrument[inst - 1]))) // don't let the user flood the song with default instrument
         {

+ 1 - 1
util.h

@@ -5,8 +5,8 @@
 
 #include "flizzer_tracker.h"
 #include "sound_engine/sound_engine_defs.h"
-#include "tracker_engine/tracker_engine_defs.h"
 #include "tracker_engine/tracker_engine.h"
+#include "tracker_engine/tracker_engine_defs.h"
 
 #define clamp(val, add, _min, _max) val = fmin(_max, fmax(_min, (int32_t)val + add))
 #define flipbit(val, bit) \

+ 17 - 17
view/instrument_editor.c

@@ -210,7 +210,7 @@ void draw_instrument_view(Canvas *canvas, FlizzerTrackerApp *tracker)
         draw_inst_text_two_digits(tracker, canvas, EDIT_INSTRUMENT, INST_PWMDELAY, "DEL:", 52, 59 - shift, inst->pwm_delay);
     }
 
-    if(shift >= 12)
+    if (shift >= 12)
     {
         draw_inst_flag(tracker, canvas, EDIT_INSTRUMENT, INST_PROGRESTART, "NO PROG.RESTART", 0, 65 - shift, inst->flags, TE_PROG_NO_RESTART);
     }
@@ -229,27 +229,27 @@ void draw_instrument_view(Canvas *canvas, FlizzerTrackerApp *tracker)
 
 char command_get_char(uint16_t command)
 {
-    if((command >> 8) < 36)
+    if ((command >> 8) < 36)
     {
         return to_char_array[(command >> 8)];
     }
 
-    if(command == TE_PROGRAM_END)
+    if (command == TE_PROGRAM_END)
     {
         return ':';
     }
 
-    if((command & 0xff00) == TE_PROGRAM_JUMP)
+    if ((command & 0xff00) == TE_PROGRAM_JUMP)
     {
         return '^';
     }
 
-    if((command & 0xff00) == TE_PROGRAM_LOOP_END)
+    if ((command & 0xff00) == TE_PROGRAM_LOOP_END)
     {
         return '>';
     }
 
-    if((command & 0xff00) == TE_PROGRAM_LOOP_BEGIN)
+    if ((command & 0xff00) == TE_PROGRAM_LOOP_BEGIN)
     {
         return '<';
     }
@@ -261,28 +261,28 @@ void draw_program_step(Canvas *canvas, uint8_t y, FlizzerTrackerApp *tracker, ui
 {
     char buffer[15];
 
-    Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+    Instrument *inst = tracker->song.instrument[tracker->current_instrument];
     uint16_t opcode = inst->program[index];
 
-    if(opcode != TE_PROGRAM_NOP)
+    if (opcode != TE_PROGRAM_NOP)
     {
         snprintf(buffer, sizeof(buffer), "%01X %c%02X %s", index, command_get_char(opcode & 0x7fff), (opcode & 0xff), get_opcode_description(opcode, true) ? get_opcode_description(opcode, true) : "");
 
-        if(opcode & 0x8000)
+        if (opcode & 0x8000)
         {
-            if(index == 0)
+            if (index == 0)
             {
                 canvas_draw_line(canvas, 84 + 4 * 4 + 2, y, 84 + 4 * 4 + 2, y - 3);
                 canvas_draw_dot(canvas, 84 + 4 * 4 + 1, y - 4);
             }
 
-            if(index > 0 && !(inst->program[index - 1] & 0x8000))
+            if (index > 0 && !(inst->program[index - 1] & 0x8000))
             {
                 canvas_draw_line(canvas, 84 + 4 * 4 + 2, y, 84 + 4 * 4 + 2, y - 3);
                 canvas_draw_dot(canvas, 84 + 4 * 4 + 1, y - 4);
             }
 
-            if(index > 0 && (inst->program[index - 1] & 0x8000))
+            if (index > 0 && (inst->program[index - 1] & 0x8000))
             {
                 canvas_draw_line(canvas, 84 + 4 * 4 + 2, y, 84 + 4 * 4 + 2, y - 5);
             }
@@ -290,7 +290,7 @@ void draw_program_step(Canvas *canvas, uint8_t y, FlizzerTrackerApp *tracker, ui
 
         else
         {
-            if(index > 0 && (inst->program[index - 1] & 0x8000))
+            if (index > 0 && (inst->program[index - 1] & 0x8000))
             {
                 canvas_draw_line(canvas, 84 + 4 * 4 + 2, y - 3, 84 + 4 * 4 + 2, y - 5);
                 canvas_draw_dot(canvas, 84 + 4 * 4 + 1, y - 2);
@@ -308,15 +308,15 @@ void draw_program_step(Canvas *canvas, uint8_t y, FlizzerTrackerApp *tracker, ui
 
 void draw_instrument_program_view(Canvas *canvas, FlizzerTrackerApp *tracker)
 {
-    Instrument* inst = tracker->song.instrument[tracker->current_instrument];
+    Instrument *inst = tracker->song.instrument[tracker->current_instrument];
 
-    for(uint8_t i = tracker->program_position; i < fmin(INST_PROG_LEN, tracker->program_position + 8); i++)
+    for (uint8_t i = tracker->program_position; i < fmin(INST_PROG_LEN, tracker->program_position + 8); i++)
     {
         draw_program_step(canvas, 6 + 6 * i - tracker->program_position * 6, tracker, i);
 
-        if(i == tracker->current_program_step && tracker->focus == EDIT_PROGRAM)
+        if (i == tracker->current_program_step && tracker->focus == EDIT_PROGRAM)
         {
-            if(tracker->editing)
+            if (tracker->editing)
             {
                 canvas_draw_box(canvas, 80 + 8 + tracker->current_digit * 4, 6 * i - tracker->program_position * 6, 5, 7);
             }

+ 2 - 0
view/opcode_description.c

@@ -1,4 +1,5 @@
 #include "opcode_description.h"
+#include <stdint.h>
 
 static const OpcodeDescription opcode_desc[] =
     {
@@ -9,6 +10,7 @@ static const OpcodeDescription opcode_desc[] =
         {TE_EFFECT_VIBRATO, 0x7f00, "VIBRATO", "VIB"},
         {TE_EFFECT_VOLUME_FADE, 0x7f00, "VOLUME FADE", "V.FADE"},
         {TE_EFFECT_SKIP_PATTERN, 0x7f00, "SKIP PATTERN", "P.SKIP"},
+        {TE_EFFECT_EXT_NOTE_DELAY, 0x7ff0, "NOTE DELAY", "N.DEL."},
         {TE_EFFECT_SET_SPEED_PROG_PERIOD, 0x7f00, "SET SPEED (PROG.PER.IN PROGRAM)", "P.PER."},
         {TE_PROGRAM_LOOP_BEGIN, 0x7f00, "PROGRAM LOOP BEGIN", "L.BEG."},
         {TE_PROGRAM_LOOP_END, 0x7f00, "PROGRAM LOOP END", "L.END"},

+ 1 - 1
view/opcode_description.h

@@ -1,7 +1,7 @@
 #pragma once
 
-#include <stdio.h>
 #include "../tracker_engine/tracker_engine_defs.h"
+#include <stdio.h>
 
 typedef struct
 {