Mercurial > ~darius > hgwebdir.cgi > modulator
view test.c @ 30:92fdf2ef995d default tip
Use 32 bit rather than 16 bit ints for loop vars.
No risk of overflow and is actually faster.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Thu, 27 Feb 2025 15:24:17 +1030 |
parents | 2db42eaba3c8 |
children |
line wrap: on
line source
#include <sys/errno.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #if 1 #include <q.h> #else // We want Q24.8 - Q16.16 is too small for sample calculations #define FPT_WBITS 24 #include "fptc-lib/src/fptc.h" #define q_t fpt #define qmul fpt_mul #define qdiv fpt_div #define qtoi fpt2i #define qint i2fpt #define qsub(x, y) ((x) - (y)) #define qsprint(n, s, len) fpt_str(n, s, 3) #endif #include "shaped-trap.h" unsigned compute_pulse(uint8_t *data, unsigned datalen, uint16_t plen, char *code, uint8_t ncode, uint8_t shapelen, const uint8_t *shape, uint8_t codegap, uint8_t slew1, uint8_t slew2, uint8_t dcofs) { uint32_t shapesamples, nsamples, idx; q_t dcscale, stepsize; char tmps[20]; dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255)); qsprint(dcscale, tmps, sizeof(tmps)); printf("dcscale = %s\n", tmps); if (ncode == 1) { // Number of samples for half of the pulse // Do division first so we don't overflow Q16.16 shapesamples = qtoi(qmul(qdiv(qint(plen), qint(100)), qint(shapelen))); // Number of samples for everything nsamples = shapesamples * 2 + slew1 + slew2; } else { shapesamples = plen; nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2; } // Number of samples per step in the pulse shape stepsize = qdiv(qint(shapesamples), qint(shapelen)); qsprint(stepsize, tmps, sizeof(tmps)); printf("shapelen = %d shapesamples = %u nsamples = %u stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); if (nsamples > datalen) { printf("Pulse too long (%d > %u)\n", nsamples, datalen); return 0; } if (shapesamples < 2) { printf("Pulse too short (%u < %d)\n", shapesamples, 2); return 0; } if (qtoi(shapesamples) > 65535) { printf("Shape too long (%u > %d)\n", qtoi(shapesamples), 65535); return 0; } idx = 0; // Up slew for (uint16_t i = 0; i < slew1; i++) data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); for (uint16_t c = 0; c < ncode; c++) { // Pulse up for (uint16_t i = 0; i < shapesamples; i++) data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale)); // Pulse down for (uint16_t i = 0; i < shapesamples; i++) data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale)); // Code gap if (c < ncode - 1) for (uint16_t i = 0; i < codegap; i++) data[idx++] = dcofs; } // Down slew for (uint16_t i = 0; i < slew2; i++) data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); return idx - 1; } int main(int argc, char **argv) { uint8_t data[65536], codegap, slew1, slew2, dcofs; uint16_t plen; uint32_t idx; char *code; if (argc != 7) { printf("Bad usage\n"); exit(1); } plen = atoi(argv[1]); code = argv[2]; codegap = atoi(argv[3]); slew1 = atoi(argv[4]); slew2 = atoi(argv[5]); dcofs = atoi(argv[6]); if ((idx = compute_pulse(data, sizeof(data), plen, code, strlen(code), sizeof(shaped_trap), shaped_trap, codegap, slew1, slew2, dcofs)) == 0) { printf("Failed to build pulse\n"); exit(1); } FILE *fh; if ((fh = fopen("/tmp/out.bin", "w")) == NULL) { printf("Unable to open file: %s\n", strerror(errno)); exit(1); } fwrite(data, idx, 1, fh); fclose(fh); exit(0); }