login

<     >

2022-10-14 12:36:14 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

add amplitude window

diff --git a/qms.c b/qms.c
index f60ab37..a720386 100644
--- a/qms.c
+++ b/qms.c
@@ -10,15 +10,18 @@ typedef struct TrackState {
 typedef struct VoiceState {
     unsigned int phase_acc;   /* fixed point with NEXP.16 precision */
     unsigned int phase_step;  /* fixed point with NEXP.16 precision */
-    int velocity;    /* 0x00-0x7F */
-    int pitch;       /* 0x00-0x7F */
-    int wheel;       /* S7.8    default (zero) means center */
-    int note_age;    /* for amplitude envelope */
+    int velocity;     /* 0x00-0x7F */
+    int pitch;        /* 0x00-0x7F */
+    int wheel;        /* S7.8    default (zero) means center */
+    int note_age;     /* for amplitude envelope */
+    /* current computed amplitude (for smoothing) - left & right */
+    int lamp, ramp;
 } VoiceState;
 
 static int16_t wavetables[NPACS][N];
 static TrackState tracks[NTRACKS];
 static VoiceState voices[NTRACKS][NVOICES];
+static int32_t windows[NTRACKS][NVOICES][K][2];
 
 /* sine approximation using Bhaskara I's formula
  * input is in [0;2048]
@@ -139,29 +142,41 @@ void
 qms_advance(unsigned int sample_i, unsigned int nsamples)
 {
     int32_t left, right;
-    int32_t amp;
+    int32_t wave_sample;
     int16_t *pac;
-    int lvol, rvol; /* 0 - 2^14 */
+    int32_t tlamp, tramp; /* 0 - 2^14 */
+    int32_t vamp;         /* 0 - 2^14 */
+    int32_t vlamp, vramp; /* 0 - 2^28 */
+    int32_t *win_addr;
     TrackState *track;
     VoiceState *voice;
     int ti, vi;
-    for (; nsamples; nsamples--) {
+    for (; nsamples; nsamples--, sample_i++) {
         left = right = 0;
         for (ti = 0; ti < NTRACKS; ti++) {
             track = &tracks[ti];
-            lvol = (63 - track->pan) * (127 - track->vol);
-            rvol = (63 + track->pan) * (127 - track->vol);
+            tlamp = (63 - track->pan) * (127 - track->vol);
+            tramp = (63 + track->pan) * (127 - track->vol);
             pac = wavetables[track->pac];
             for (vi = 0; vi < NVOICES; vi++) {
                 voice = &voices[ti][vi];
-                amp = pac[voice->phase_acc >> 16];
-                amp = amp * voice->velocity >> 7;
-                if (voice->note_age < 16)
-                    amp = amp * (16 - voice->note_age++) >> 4;
-                else if (voice->note_age < track->atk + 16)
-                    amp = amp * (voice->note_age++ - 16) / track->atk;
-                left  += amp * lvol >> 14;
-                right += amp * rvol >> 14;
+                win_addr = windows[ti][vi][sample_i & (K-1)];
+                vamp = voice->velocity;
+                if (voice->note_age++ < track->atk)
+                    vamp = vamp * (voice->note_age * 0x7F / track->atk);
+                else
+                    vamp = vamp * 0x7F;
+                vlamp = tlamp * vamp;
+                vramp = tramp * vamp;
+                voice->lamp += vlamp - win_addr[0];
+                win_addr[0] = vlamp;
+                voice->ramp += vramp - win_addr[1];
+                win_addr[1] = vramp;
+                wave_sample = pac[voice->phase_acc >> 16];
+                //~ left  += wave_sample * (vlamp >> 12) >> 16;
+                //~ right += wave_sample * (vramp >> 12) >> 16;
+                left  += wave_sample * (voice->lamp >> 16) >> 16;
+                right += wave_sample * (voice->ramp >> 16) >> 16;
                 voice->phase_acc += voice->phase_step;
                 voice->phase_acc &= (1 << (NEXP + 16)) - 1;
             }

diff --git a/qms.h b/qms.h
index 5514eba..9780394 100644
--- a/qms.h
+++ b/qms.h
@@ -14,6 +14,8 @@
 #define N       (1 << NEXP)
 /* sample rate in samples per second*/
 #define R       44100
+/* size of amplitude window in samples */
+#define K       16
 
 typedef enum EvType {END, PAC, VOL, PAN, VEL, PITCH, WHEEL} EvType;