changeset 7:4ad473648949

Copy pulse up in reverse for pulse down. Copy first pulse for subsequent pulses.
author Daniel O'Connor <darius@dons.net.au>
date Sun, 16 Feb 2025 10:09:05 +1030
parents 5bed069f0c33
children 0249d0cecac4
files modulator.c
diffstat 1 files changed, 34 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/modulator.c	Sun Feb 16 09:47:44 2025 +1030
+++ b/modulator.c	Sun Feb 16 10:09:05 2025 +1030
@@ -39,6 +39,7 @@
 #include "dac.pio.h"
 
 // https://github.com/howerj/q
+// Modified to be Q20.12 rather than Q16.16
 #include "q/q.h"
 
 #include "shaped-trap.h"
@@ -83,9 +84,28 @@
 // Need to add pre/postgate/sense/phase counters
 unsigned
 compute_pulse(uint8_t *data, uint8_t *ctrl, unsigned datalen, uint16_t plen, char *code, uint8_t ncode, const uint8_t *shape, uint8_t shapelen, uint8_t codegap, uint8_t slew1, uint8_t slew2, uint8_t dcofs) {
-  uint32_t shapesamples, nsamples, idx;
+  uint32_t shapesamples, nsamples, idx, bit1startup, bit1stopup;
   q_t dcscale, stepsize;
   char tmps[20];
+  interp_config cfg;
+
+  // Setup lane 0 to generate index into shape table
+  // Mask start is 0 because we use 8 bit samples
+  cfg = interp_default_config();
+  interp_config_set_shift(&cfg, QBITS);
+  interp_config_set_mask(&cfg, 0, 32 - QBITS);
+  interp_config_set_blend(&cfg, true);
+  interp_set_config(interp0, 0, &cfg);
+
+  // Setup lane 1 to LERP each sample pair
+  cfg = interp_default_config();
+  interp_config_set_shift(&cfg, QBITS - 8);
+  interp_config_set_signed(&cfg, false);
+  interp_config_set_cross_input(&cfg, true); // unsigned blending
+  interp_set_config(interp0, 1, &cfg);
+
+  interp0->accum[0] = 0; // Initial offset into shape table
+  interp0->base[2] = (uintptr_t)shape; // Start of shape table
 
   dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255));
   qsprint(dcscale, tmps, sizeof(tmps));
@@ -127,18 +147,28 @@
     ctrl[idx] |= PACTIVE;
   }
   for (uint16_t c = 0; c < ncode; c++) {
+    if (c == 0)
+      bit1startup = idx;
+
     uint ctrltmp = PACTIVE;
     if (code[c] == '0')
       ctrltmp |= PHINV;
 
     // Pulse up
     for (uint16_t i = 0; i < shapesamples; i++) {
-      data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale));
+      if (c == 0)
+	data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale));
+      else
+	// Already done it before, just copy the previous instance
+	data[idx++] = data[bit1startup + i];
       ctrl[idx] = ctrltmp;
     }
+    if (c == 0)
+      bit1stopup = idx - 1;
     // Pulse down
+    // Since the pulse is symmetrical just copy the up slope in reverse
     for (uint16_t i = 0; i < shapesamples; i++) {
-      data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale));
+      data[idx++] = data[bit1stopup - i];
       // Could replace this with a separate loop to poke it into place
       // Similarly for TR switch when implemented
       if (i == 0 && c == 0)
@@ -225,7 +255,7 @@
     gpio_init(PICO_DEFAULT_LED_PIN);
     gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
 
-    interp_test(pulse_data, shaped_trap);
+    //interp_test(pulse_data, shaped_trap);
 
     uint32_t idx;
     uint16_t plen = 4000;