Explorar el Código

legato effect, faster filter

LTVA1 hace 3 años
padre
commit
2bbf2c8502

+ 4 - 2
sound_engine/sound_engine_defs.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 
 #define NUM_CHANNELS 4
@@ -71,8 +72,9 @@ typedef struct
 
 typedef struct
 {
-    int32_t f, q, p;
-    int32_t b0, b1, b2, b3, b4; // filter coefficients
+    // int32_t f, q, p;
+    // int32_t b0, b1, b2, b3, b4; // filter coefficients
+    int32_t cutoff, resonance, low, high, band;
 } SoundEngineFilter;
 
 typedef struct

+ 9 - 18
sound_engine/sound_engine_filter.c

@@ -2,37 +2,28 @@
 
 void sound_engine_filter_set_coeff(SoundEngineFilter *flt, uint32_t frequency, uint16_t resonance)
 {
-    flt->q = 2048 - frequency;
-    flt->p = frequency + ((int32_t)(0.8f * 2048.0f) * frequency / 2048 * flt->q) / 2048;
-    flt->f = flt->p + flt->p - 2048;
-    flt->q = resonance;
+    flt->cutoff = frequency << 3;
+    flt->resonance = ((int32_t)resonance * 3 / 2) - 200;
 }
 
-void sound_engine_filter_cycle(SoundEngineFilter *flt, int32_t input)
+void sound_engine_filter_cycle(SoundEngineFilter *flt, int32_t input) // don't ask me how it works, stolen from Furnace tracker TSU synth
 {
-    input -= flt->q * flt->b4 / 2048; // feedback
-    int32_t t1 = flt->b1;
-    flt->b1 = (input + flt->b0) * flt->p / 2048 - flt->b1 * flt->f / 2048;
-    int32_t t2 = flt->b2;
-    flt->b2 = (flt->b1 + t1) * flt->p / 2048 - flt->b2 * flt->f / 2048;
-    t1 = flt->b3;
-    flt->b3 = (flt->b2 + t2) * flt->p / 2048 - flt->b3 * flt->f / 2048;
-    flt->b4 = (flt->b3 + t1) * flt->p / 2048 - flt->b4 * flt->f / 2048;
-
-    flt->b0 = input;
+    flt->low = flt->low + ((flt->cutoff * flt->band) >> 16);
+    flt->high = input - flt->low - (((256 - flt->resonance) * flt->band) >> 8);
+    flt->band = ((flt->cutoff * flt->high) >> 16) + flt->band;
 }
 
 int32_t sound_engine_output_lowpass(SoundEngineFilter *flt)
 {
-    return flt->b4;
+    return flt->low;
 }
 
 int32_t sound_engine_output_highpass(SoundEngineFilter *flt)
 {
-    return flt->b0 - flt->b4;
+    return flt->high;
 }
 
 int32_t sound_engine_output_bandpass(SoundEngineFilter *flt)
 {
-    return 3 * (flt->b3 - flt->b4);
+    return flt->band;
 }

+ 6 - 6
tracker_engine/do_effects.c

@@ -379,7 +379,7 @@ void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel,
         {
             if (tick == 0)
             {
-                te_channel->filter_resonance = ((opcode & 0xff) << 5);
+                te_channel->filter_resonance = (opcode & 0xff);
                 sound_engine_filter_set_coeff(&se_channel->filter, te_channel->filter_cutoff, te_channel->filter_resonance);
             }
 
@@ -388,11 +388,11 @@ void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel,
 
         case TE_EFFECT_RESONANCE_UP:
         {
-            te_channel->filter_resonance += ((opcode & 0xff) << 2);
+            te_channel->filter_resonance += (opcode & 0xff);
 
-            if (te_channel->filter_resonance > (0xff << 5))
+            if (te_channel->filter_resonance > 0xff)
             {
-                te_channel->filter_resonance = (0xff << 5);
+                te_channel->filter_resonance = 0xff;
             }
 
             sound_engine_filter_set_coeff(&se_channel->filter, te_channel->filter_cutoff, te_channel->filter_resonance);
@@ -401,9 +401,9 @@ void do_command(uint16_t opcode, TrackerEngine *tracker_engine, uint8_t channel,
 
         case TE_EFFECT_RESONANCE_DOWN:
         {
-            te_channel->filter_resonance -= ((opcode & 0xff) << 2);
+            te_channel->filter_resonance -= (opcode & 0xff);
 
-            if (te_channel->filter_resonance > (0xff << 5))
+            if (te_channel->filter_resonance > 0xff)
             {
                 te_channel->filter_resonance = 0;
             }

+ 6 - 1
tracker_engine/tracker_engine.c

@@ -217,7 +217,7 @@ void tracker_engine_trigger_instrument_internal(TrackerEngine *tracker_engine, u
     if (pinst->flags & TE_SET_CUTOFF)
     {
         te_channel->filter_cutoff = ((uint16_t)pinst->filter_cutoff << 3);
-        te_channel->filter_resonance = ((uint16_t)pinst->filter_resonance << 5);
+        te_channel->filter_resonance = (uint16_t)pinst->filter_resonance;
 
         sound_engine_filter_set_coeff(&se_channel->filter, te_channel->filter_cutoff, te_channel->filter_resonance);
     }
@@ -571,6 +571,11 @@ void tracker_engine_advance_tick(TrackerEngine *tracker_engine)
                         te_channel->slide_speed = (opcode & 0xff);
                     }
 
+                    else if ((opcode & 0x7f00) == TE_EFFECT_LEGATO)
+                    {
+                        te_channel->note = te_channel->target_note = te_channel->last_note = ((note + pinst->base_note - MIDDLE_C) << 8) + pinst->finetune;
+                    }
+
                     else
                     {
                         tracker_engine_trigger_instrument_internal(tracker_engine, chan, pinst, note << 8);

+ 1 - 1
tracker_engine/tracker_engine_defs.h

@@ -102,9 +102,9 @@ typedef enum
     TE_EFFECT_ = 0x1e00, //Uxx
     TE_EFFECT_ = 0x1f00, //Vxx
     TE_EFFECT_ = 0x2000, //Wxx
-    TE_EFFECT_ = 0x2100, //Xxx
     */
 
+    TE_EFFECT_LEGATO = 0x2100,          // Xxx
     TE_EFFECT_ARPEGGIO_ABS = 0x2200,    // Yxx
     TE_EFFECT_TRIGGER_RELEASE = 0x2300, // Zxx
 

+ 1 - 0
view/opcode_description.c

@@ -45,6 +45,7 @@ static const OpcodeDescription opcode_desc[] =
         {TE_EFFECT_PROGRAM_RESTART, 0x7f00, "RESTART INSTRUMENT PROGRAM", "P.RES."},
         {TE_EFFECT_SET_RING_MOD_SRC, 0x7f00, "SET RING MODULATION SOURCE CH.", "R.SRC"},
         {TE_EFFECT_SET_HARD_SYNC_SRC, 0x7f00, "SET HARD SYNC SOURCE CHANNEL", "S.SRC"},
+        {TE_EFFECT_LEGATO, 0x7f00, "LEGATO", "LEGATO"},
         {TE_EFFECT_ARPEGGIO_ABS, 0x7f00, "ABSOLUTE ARPEGGIO NOTE", ""},
         {TE_EFFECT_TRIGGER_RELEASE, 0x7f00, "TRIGGER RELEASE", "TR.REL"},