LTVA1 před 3 roky
rodič
revize
c46d95431e

+ 3 - 1
flizzer_tracker.c

@@ -126,7 +126,7 @@ int32_t flizzer_tracker_app(void *p)
     UNUSED(st);
     UNUSED(st);
     furi_record_close(RECORD_STORAGE);
     furi_record_close(RECORD_STORAGE);
 
 
-    FlizzerTrackerApp *tracker = init_tracker(44100, 50, false, 1024);
+    FlizzerTrackerApp *tracker = init_tracker(44100, 50, true, 1024);
 
 
     // Текущее событие типа кастомного типа FlizzerTrackerEvent
     // Текущее событие типа кастомного типа FlizzerTrackerEvent
     FlizzerTrackerEvent event;
     FlizzerTrackerEvent event;
@@ -229,6 +229,8 @@ int32_t flizzer_tracker_app(void *p)
 
 
         if(event.type == EventTypeLoadSong)
         if(event.type == EventTypeLoadSong)
         {
         {
+            stop_song(tracker);
+
             tracker->dialogs = furi_record_open(RECORD_DIALOGS);
             tracker->dialogs = furi_record_open(RECORD_DIALOGS);
             tracker->is_loading = true;
             tracker->is_loading = true;
 
 

+ 1 - 0
flizzer_tracker.h

@@ -119,6 +119,7 @@ typedef enum
     INST_PWMDEPTH,
     INST_PWMDEPTH,
     INST_PWMDELAY,
     INST_PWMDELAY,
 
 
+    INST_PROGRESTART,
     INST_PROGRAMEPERIOD,
     INST_PROGRAMEPERIOD,
     /* ========= */
     /* ========= */
     INST_PARAMS,
     INST_PARAMS,

+ 13 - 0
input/instrument.c

@@ -400,6 +400,12 @@ void edit_instrument_param(FlizzerTrackerApp *tracker, uint8_t selected_param, i
 
 
             break;
             break;
         }
         }
+
+        case INST_PROGRESTART:
+        {
+            flipbit(inst->flags, TE_PROG_NO_RESTART);
+            break;
+        }
     }
     }
 }
 }
 
 
@@ -474,6 +480,7 @@ void instrument_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *even
             case INST_ENABLEKEYSYNC:
             case INST_ENABLEKEYSYNC:
             case INST_ENABLEVIBRATO:
             case INST_ENABLEVIBRATO:
             case INST_ENABLEPWM:
             case INST_ENABLEPWM:
+            case INST_PROGRESTART:
             {
             {
                 tracker->selected_param++;
                 tracker->selected_param++;
 
 
@@ -532,6 +539,7 @@ void instrument_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *even
             case INST_ENABLEKEYSYNC:
             case INST_ENABLEKEYSYNC:
             case INST_ENABLEVIBRATO:
             case INST_ENABLEVIBRATO:
             case INST_ENABLEPWM:
             case INST_ENABLEPWM:
+            case INST_PROGRESTART:
             {
             {
                 tracker->selected_param--;
                 tracker->selected_param--;
 
 
@@ -574,6 +582,11 @@ void instrument_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *even
         tracker->inst_editor_shift = 6;
         tracker->inst_editor_shift = 6;
     }
     }
 
 
+    if (tracker->selected_param > INST_PWMDELAY)
+    {
+        tracker->inst_editor_shift = 12;
+    }
+
     if (tracker->selected_param < INST_CURRENT_NOTE)
     if (tracker->selected_param < INST_CURRENT_NOTE)
     {
     {
         tracker->inst_editor_shift = 0;
         tracker->inst_editor_shift = 0;

+ 2 - 0
input_event.c

@@ -57,6 +57,8 @@ void return_from_keyboard_callback(void *ctx)
 
 
     if(tracker->is_saving)
     if(tracker->is_saving)
     {
     {
+        stop_song(tracker);
+        
         tracker->filepath = furi_string_alloc();
         tracker->filepath = furi_string_alloc();
         furi_string_cat_printf(tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_FOLDER, tracker->filename, SONG_FILE_EXT);
         furi_string_cat_printf(tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_FOLDER, tracker->filename, SONG_FILE_EXT);
 
 

+ 2 - 2
sound_engine/sound_engine_osc.c

@@ -10,7 +10,7 @@ static inline uint16_t sound_engine_saw(uint32_t acc)
     return (acc >> (ACC_BITS - OUTPUT_BITS - 1)) & (WAVE_AMP - 1);
     return (acc >> (ACC_BITS - OUTPUT_BITS - 1)) & (WAVE_AMP - 1);
 }
 }
 
 
-static inline uint16_t sound_engine_triangle(uint32_t acc)
+uint16_t sound_engine_triangle(uint32_t acc)
 {
 {
     return ((((acc & (ACC_LENGTH / 2)) ? ~acc : acc) >> (ACC_BITS - OUTPUT_BITS - 2)) & (WAVE_AMP * 2 - 1));
     return ((((acc & (ACC_LENGTH / 2)) ? ~acc : acc) >> (ACC_BITS - OUTPUT_BITS - 2)) & (WAVE_AMP * 2 - 1));
 }
 }
@@ -251,5 +251,5 @@ uint16_t sound_engine_osc(SoundEngine *sound_engine, SoundEngineChannel *channel
             break;
             break;
     }
     }
 
 
-    return 0;
+    return WAVE_AMP / 2;
 }
 }

+ 2 - 0
sound_engine/sound_engine_osc.h

@@ -2,4 +2,6 @@
 
 
 #include "sound_engine_defs.h"
 #include "sound_engine_defs.h"
 
 
+uint16_t sound_engine_triangle(uint32_t acc);
+
 uint16_t sound_engine_osc(SoundEngine *sound_engine, SoundEngineChannel *channel, uint32_t prev_acc);
 uint16_t sound_engine_osc(SoundEngine *sound_engine, SoundEngineChannel *channel, uint32_t prev_acc);

+ 83 - 10
tracker_engine/tracker_engine.c

@@ -3,6 +3,7 @@
 #include "../flizzer_tracker_hal.h"
 #include "../flizzer_tracker_hal.h"
 
 
 #include <furi_hal.h>
 #include <furi_hal.h>
+#include "../sound_engine/sound_engine_osc.h"
 
 
 void tracker_engine_init(TrackerEngine *tracker_engine, uint8_t rate, SoundEngine *sound_engine)
 void tracker_engine_init(TrackerEngine *tracker_engine, uint8_t rate, SoundEngine *sound_engine)
 {
 {
@@ -150,11 +151,11 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
     SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[chan];
     SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[chan];
     TrackerEngineChannel *te_channel = &tracker_engine->channel[chan];
     TrackerEngineChannel *te_channel = &tracker_engine->channel[chan];
 
 
-    te_channel->flags = TEC_PLAYING | (te_channel->channel_flags & TEC_DISABLED);
+    te_channel->channel_flags = TEC_PLAYING | (te_channel->channel_flags & TEC_DISABLED);
 
 
     if (!(pinst->flags & TE_PROG_NO_RESTART) && pinst->program_period > 0)
     if (!(pinst->flags & TE_PROG_NO_RESTART) && pinst->program_period > 0)
     {
     {
-        te_channel->flags |= TEC_PROGRAM_RUNNING;
+        te_channel->channel_flags |= TEC_PROGRAM_RUNNING;
 
 
         te_channel->program_counter = 0;
         te_channel->program_counter = 0;
         te_channel->program_loop = 0;
         te_channel->program_loop = 0;
@@ -167,7 +168,7 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
     se_channel->waveform = pinst->waveform;
     se_channel->waveform = pinst->waveform;
     se_channel->flags = pinst->sound_engine_flags;
     se_channel->flags = pinst->sound_engine_flags;
 
 
-    te_channel->channel_flags = pinst->flags;
+    te_channel->flags = pinst->flags;
 
 
     te_channel->arpeggio_note = 0;
     te_channel->arpeggio_note = 0;
     te_channel->fixed_note = 0xffff;
     te_channel->fixed_note = 0xffff;
@@ -177,9 +178,25 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
 
 
     te_channel->last_note = te_channel->target_note = note + (int16_t)pinst->finetune;
     te_channel->last_note = te_channel->target_note = note + (int16_t)pinst->finetune;
 
 
+    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)
+    {
+        te_channel->pwm_speed = pinst->pwm_speed;
+        te_channel->pwm_depth = pinst->pwm_depth;
+        te_channel->pwm_delay = pinst->pwm_delay;
+    }
+
     if (pinst->sound_engine_flags & SE_ENABLE_KEYDOWN_SYNC)
     if (pinst->sound_engine_flags & SE_ENABLE_KEYDOWN_SYNC)
     {
     {
-        te_channel->vibrato_position = te_channel->pwm_position = 0;
+        te_channel->vibrato_position = ((ACC_LENGTH / 2 / 2) << 9);
+        te_channel->pwm_position = ((ACC_LENGTH / 2 / 2) << 9);
+
         se_channel->accumulator = 0;
         se_channel->accumulator = 0;
         se_channel->lfsr = RANDOM_SEED;
         se_channel->lfsr = RANDOM_SEED;
     }
     }
@@ -230,12 +247,17 @@ void tracker_engine_execute_track_command(TrackerEngine *tracker_engine, uint8_t
 
 
     uint8_t vol = tracker_engine_get_volume(step);
     uint8_t vol = tracker_engine_get_volume(step);
 
 
-    if (vol != MUS_NOTE_VOLUME_NONE)
+    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);
         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
     // TODO: add actual big ass function that executes commands; add arpeggio commands there
+
+    if(tracker_engine->channel[chan].channel_flags & TEC_DISABLED)
+    {
+        tracker_engine->sound_engine->channel[chan].adsr.volume = 0;
+    }
 }
 }
 
 
 void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
 void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
@@ -243,7 +265,7 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
     SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[chan];
     SoundEngineChannel *se_channel = &tracker_engine->sound_engine->channel[chan];
     TrackerEngineChannel *te_channel = &tracker_engine->channel[chan];
     TrackerEngineChannel *te_channel = &tracker_engine->channel[chan];
 
 
-    if (te_channel->flags & TEC_PLAYING)
+    if (te_channel->channel_flags & TEC_PLAYING)
     {
     {
         if (!(se_channel->flags & SE_ENABLE_GATE))
         if (!(se_channel->flags & SE_ENABLE_GATE))
         {
         {
@@ -263,11 +285,57 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
             }
             }
         }
         }
 
 
-        // TODO: add instrument program execution
+        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->vibrato_delay > 0)
+            {
+                te_channel->vibrato_delay--;
+            }
 
 
-        // TODO: add PWM and vibrato execution
-        uint16_t vib = 0;
-        int32_t chn_note = (te_channel->fixed_note != 0xffff ? te_channel->fixed_note : te_channel->note) + vib + ((int16_t)te_channel->arpeggio_note << 8);
+            else
+            {
+                te_channel->vibrato_position += ((uint32_t)te_channel->vibrato_speed << 21);
+                vib = (int32_t)(sound_engine_triangle(te_channel->vibrato_position >> 9) - WAVE_AMP / 2) * (int32_t)te_channel->vibrato_depth / (256 * 128);
+            }
+        }
+
+        if(te_channel->flags & TE_ENABLE_PWM)
+        {
+            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
+                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)
+            {
+                final_pwm = 0;
+            }
+
+            if(final_pwm > 0xfff)
+            {
+                final_pwm = 0xfff;
+            }
+
+            tracker_engine->sound_engine->channel[chan].pw = final_pwm;
+        }
+
+        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);
 
 
         if (chn_note < 0)
         if (chn_note < 0)
         {
         {
@@ -281,6 +349,11 @@ void tracker_engine_advance_channel(TrackerEngine *tracker_engine, uint8_t chan)
 
 
         tracker_engine_set_note(tracker_engine, chan, (uint16_t)chn_note, false);
         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
+    {
+        tracker_engine->sound_engine->channel[chan].adsr.volume = 0;
+    }
 }
 }
 
 
 void tracker_engine_advance_tick(TrackerEngine *tracker_engine)
 void tracker_engine_advance_tick(TrackerEngine *tracker_engine)

+ 1 - 1
tracker_engine/tracker_engine_defs.h

@@ -123,7 +123,7 @@ typedef struct
     uint8_t vibrato_speed, vibrato_depth, vibrato_delay;
     uint8_t vibrato_speed, vibrato_depth, vibrato_delay;
     uint8_t pwm_speed, pwm_depth, pwm_delay;
     uint8_t pwm_speed, pwm_depth, pwm_delay;
 
 
-    uint16_t vibrato_position, pwm_position;
+    uint32_t vibrato_position, pwm_position; //basically accumulators
 
 
     uint8_t extarp1, extarp2;
     uint8_t extarp1, extarp2;
 
 

+ 31 - 22
view/instrument_editor.c

@@ -97,6 +97,7 @@ static const char *instrument_editor_params_description[] =
         "PWM SPEED",
         "PWM SPEED",
         "PWM DEPTH",
         "PWM DEPTH",
         "PWM DELAY (IN TICKS)",
         "PWM DELAY (IN TICKS)",
+        "DON'T RESTART PROGRAM ON KEYDOWN",
         "PROG.PERIOD (00 ACTS SAME AS 01)",
         "PROG.PERIOD (00 ACTS SAME AS 01)",
 };
 };
 
 
@@ -114,7 +115,7 @@ void draw_instrument_view(Canvas *canvas, FlizzerTrackerApp *tracker)
     Instrument *inst = tracker->song.instrument[tracker->current_instrument];
     Instrument *inst = tracker->song.instrument[tracker->current_instrument];
     uint8_t shift = tracker->inst_editor_shift;
     uint8_t shift = tracker->inst_editor_shift;
 
 
-    if (shift == 0)
+    if (shift < 6)
     {
     {
         snprintf(buffer, sizeof(buffer), "INST:%c", to_char(tracker->current_instrument));
         snprintf(buffer, sizeof(buffer), "INST:%c", to_char(tracker->current_instrument));
         draw_generic_n_digit_field(tracker, canvas, EDIT_INSTRUMENT, INST_CURRENTINSTRUMENT, buffer, 0, 5 - shift, 1);
         draw_generic_n_digit_field(tracker, canvas, EDIT_INSTRUMENT, INST_CURRENTINSTRUMENT, buffer, 0, 5 - shift, 1);
@@ -122,35 +123,38 @@ void draw_instrument_view(Canvas *canvas, FlizzerTrackerApp *tracker)
         draw_generic_n_digit_field(tracker, canvas, EDIT_INSTRUMENT, INST_INSTRUMENTNAME, buffer, 4 * 7, 5 - shift, 1);
         draw_generic_n_digit_field(tracker, canvas, EDIT_INSTRUMENT, INST_INSTRUMENTNAME, buffer, 4 * 7, 5 - shift, 1);
     }
     }
 
 
-    snprintf(buffer, sizeof(buffer), "NOTE:%s", notename(inst->base_note));
-    canvas_draw_str(canvas, 0, 11 - shift, buffer);
-
-    if (tracker->editing && tracker->focus == EDIT_INSTRUMENT && tracker->selected_param == INST_CURRENT_NOTE)
+    if (shift < 12)
     {
     {
-        if (tracker->current_digit)
-        {
-            canvas_draw_box(canvas, 19 + 2 * 4, 5 - shift, 5, 7);
-        }
+        snprintf(buffer, sizeof(buffer), "NOTE:%s", notename(inst->base_note));
+        canvas_draw_str(canvas, 0, 11 - shift, buffer);
 
 
-        else
+        if (tracker->editing && tracker->focus == EDIT_INSTRUMENT && tracker->selected_param == INST_CURRENT_NOTE)
         {
         {
-            canvas_draw_box(canvas, 19, 5 - shift, 5 + 4, 7);
+            if (tracker->current_digit)
+            {
+                canvas_draw_box(canvas, 19 + 2 * 4, 5 - shift, 5, 7);
+            }
+
+            else
+            {
+                canvas_draw_box(canvas, 19, 5 - shift, 5 + 4, 7);
+            }
         }
         }
-    }
 
 
-    snprintf(buffer, sizeof(buffer), "FINE:%+02d", inst->finetune);
-    canvas_draw_str(canvas, 37, 11 - shift, buffer);
+        snprintf(buffer, sizeof(buffer), "FINE:%+02d", inst->finetune);
+        canvas_draw_str(canvas, 37, 11 - shift, buffer);
 
 
-    if (tracker->editing && tracker->focus == EDIT_INSTRUMENT && tracker->selected_param == INST_FINETUNE)
-    {
-        if (tracker->current_digit)
+        if (tracker->editing && tracker->focus == EDIT_INSTRUMENT && tracker->selected_param == INST_FINETUNE)
         {
         {
-            canvas_draw_box(canvas, 60 + 4, 5 - shift, 5, 7);
-        }
+            if (tracker->current_digit)
+            {
+                canvas_draw_box(canvas, 60 + 4, 5 - shift, 5, 7);
+            }
 
 
-        else
-        {
-            canvas_draw_box(canvas, 60, 5 - shift, 5, 7);
+            else
+            {
+                canvas_draw_box(canvas, 60, 5 - shift, 5, 7);
+            }
         }
         }
     }
     }
 
 
@@ -206,6 +210,11 @@ 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);
         draw_inst_text_two_digits(tracker, canvas, EDIT_INSTRUMENT, INST_PWMDELAY, "DEL:", 52, 59 - shift, inst->pwm_delay);
     }
     }
 
 
+    if(shift >= 12)
+    {
+        draw_inst_flag(tracker, canvas, EDIT_INSTRUMENT, INST_PROGRESTART, "NO PROG.RESTART", 0, 65 - shift, inst->flags, TE_PROG_NO_RESTART);
+    }
+
     draw_inst_text_two_digits(tracker, canvas, EDIT_INSTRUMENT, INST_PROGRAMEPERIOD, "P.PERIOD:", 81, 56, inst->program_period);
     draw_inst_text_two_digits(tracker, canvas, EDIT_INSTRUMENT, INST_PROGRAMEPERIOD, "P.PERIOD:", 81, 56, inst->program_period);
 
 
     canvas_draw_line(canvas, 0, 57, 127, 57);
     canvas_draw_line(canvas, 0, 57, 127, 57);