Mercurial > ~darius > hgwebdir.cgi > modulator
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;