Mercurial > ~darius > hgwebdir.cgi > modulator
comparison test.c @ 5:2db42eaba3c8
WIP
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 15 Feb 2025 22:57:18 +1030 |
parents | b6416c4aadc8 |
children |
comparison
equal
deleted
inserted
replaced
4:b6416c4aadc8 | 5:2db42eaba3c8 |
---|---|
2 #include <stdio.h> | 2 #include <stdio.h> |
3 #include <stdint.h> | 3 #include <stdint.h> |
4 #include <stdlib.h> | 4 #include <stdlib.h> |
5 #include <string.h> | 5 #include <string.h> |
6 | 6 |
7 #if 1 | |
7 #include <q.h> | 8 #include <q.h> |
9 #else | |
10 // We want Q24.8 - Q16.16 is too small for sample calculations | |
11 #define FPT_WBITS 24 | |
12 #include "fptc-lib/src/fptc.h" | |
13 #define q_t fpt | |
14 #define qmul fpt_mul | |
15 #define qdiv fpt_div | |
16 #define qtoi fpt2i | |
17 #define qint i2fpt | |
18 #define qsub(x, y) ((x) - (y)) | |
19 #define qsprint(n, s, len) fpt_str(n, s, 3) | |
20 #endif | |
8 | 21 |
9 #include "shaped-trap.h" | 22 #include "shaped-trap.h" |
10 | 23 |
11 int | 24 unsigned |
12 main(int argc, char **argv) { | 25 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) { |
13 uint8_t data[50000], shapelen, codegap, slew1, slew2, dcofs; | |
14 uint16_t plen, ncode; | |
15 uint32_t shapesamples, nsamples, idx; | 26 uint32_t shapesamples, nsamples, idx; |
16 q_t dcscale, stepsize; | 27 q_t dcscale, stepsize; |
17 char *code, tmps[20]; | 28 char tmps[20]; |
18 | |
19 if (argc != 7) { | |
20 printf("Bad usage\n"); | |
21 exit(1); | |
22 } | |
23 plen = atoi(argv[1]); | |
24 code = argv[2]; | |
25 ncode = strlen(code); | |
26 shapelen = sizeof(shaped_trap); | |
27 codegap = atoi(argv[3]); | |
28 slew1 = atoi(argv[4]); | |
29 slew2 = atoi(argv[5]); | |
30 dcofs = atoi(argv[6]); | |
31 | 29 |
32 dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255)); | 30 dcscale = qdiv(qsub(qint(255), qint(dcofs)), qint(255)); |
33 qsprint(dcscale, tmps, sizeof(tmps)); | 31 qsprint(dcscale, tmps, sizeof(tmps)); |
34 printf("dcscale = %s\n", tmps); | 32 printf("dcscale = %s\n", tmps); |
35 | 33 |
36 if (ncode == 1) { | 34 if (ncode == 1) { |
37 // Number of samples for half of the pulse | 35 // Number of samples for half of the pulse |
38 // Can't use q library here because it is Q16.16 so not large enough | 36 // Do division first so we don't overflow Q16.16 |
39 shapesamples = (plen * shapelen) / 100; | 37 shapesamples = qtoi(qmul(qdiv(qint(plen), qint(100)), qint(shapelen))); |
40 // Number of samples for everything | 38 // Number of samples for everything |
41 nsamples = shapesamples * 2 + slew1 + slew2; | 39 nsamples = shapesamples * 2 + slew1 + slew2; |
42 } else { | 40 } else { |
43 shapesamples = plen; | 41 shapesamples = plen; |
44 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2; | 42 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2; |
45 } | 43 } |
46 | 44 |
47 if (nsamples > sizeof(data)) { | |
48 printf("Pulse too long (%d > %lu)\n", nsamples, sizeof(data)); | |
49 exit(1); | |
50 } | |
51 | |
52 // Number of samples per step in the pulse shape | 45 // Number of samples per step in the pulse shape |
53 stepsize = qdiv(qint(shapesamples), qint(shapelen)); | 46 stepsize = qdiv(qint(shapesamples), qint(shapelen)); |
54 qsprint(stepsize, tmps, sizeof(tmps)); | 47 qsprint(stepsize, tmps, sizeof(tmps)); |
55 printf("shapelen = %d shapesamples = %u nsamples = %u stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); | 48 printf("shapelen = %d shapesamples = %u nsamples = %u stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); |
56 | 49 |
50 if (nsamples > datalen) { | |
51 printf("Pulse too long (%d > %u)\n", nsamples, datalen); | |
52 return 0; | |
53 } | |
57 if (shapesamples < 2) { | 54 if (shapesamples < 2) { |
58 printf("Pulse too short (%u < %d)\n", shapesamples, 2); | 55 printf("Pulse too short (%u < %d)\n", shapesamples, 2); |
59 exit(1); | 56 return 0; |
60 } | 57 } |
61 | 58 if (qtoi(shapesamples) > 65535) { |
59 printf("Shape too long (%u > %d)\n", qtoi(shapesamples), 65535); | |
60 return 0; | |
61 } | |
62 idx = 0; | 62 idx = 0; |
63 | 63 |
64 // Up slew | 64 // Up slew |
65 for (uint16_t i = 0; i < slew1; i++) | 65 for (uint16_t i = 0; i < slew1; i++) |
66 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); | 66 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); |
67 | 67 |
68 for (uint16_t c = 0; c < ncode; c++) { | 68 for (uint16_t c = 0; c < ncode; c++) { |
69 // Pulse up | 69 // Pulse up |
70 for (uint16_t i = 0; i < shapesamples; i++) | 70 for (uint16_t i = 0; i < shapesamples; i++) |
71 data[idx++] = dcofs + qtoi(qmul(qint(shaped_trap[qtoi(qdiv(qint(i), stepsize))]), dcscale)); | 71 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(i), stepsize))]), dcscale)); |
72 | 72 |
73 // Pulse down | 73 // Pulse down |
74 for (uint16_t i = 0; i < shapesamples; i++) | 74 for (uint16_t i = 0; i < shapesamples; i++) |
75 data[idx++] = dcofs + qtoi(qmul(qint(shaped_trap[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale)); | 75 data[idx++] = dcofs + qtoi(qmul(qint(shape[qtoi(qdiv(qint(shapesamples - i - 1), stepsize))]), dcscale)); |
76 | 76 |
77 // Code gap | 77 // Code gap |
78 if (c < ncode - 1) | 78 if (c < ncode - 1) |
79 for (uint16_t i = 0; i < codegap; i++) | 79 for (uint16_t i = 0; i < codegap; i++) |
80 data[idx++] = dcofs; | 80 data[idx++] = dcofs; |
82 | 82 |
83 // Down slew | 83 // Down slew |
84 for (uint16_t i = 0; i < slew2; i++) | 84 for (uint16_t i = 0; i < slew2; i++) |
85 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); | 85 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); |
86 | 86 |
87 return idx - 1; | |
88 } | |
89 | |
90 int | |
91 main(int argc, char **argv) { | |
92 uint8_t data[65536], codegap, slew1, slew2, dcofs; | |
93 uint16_t plen; | |
94 uint32_t idx; | |
95 char *code; | |
96 | |
97 if (argc != 7) { | |
98 printf("Bad usage\n"); | |
99 exit(1); | |
100 } | |
101 plen = atoi(argv[1]); | |
102 code = argv[2]; | |
103 codegap = atoi(argv[3]); | |
104 slew1 = atoi(argv[4]); | |
105 slew2 = atoi(argv[5]); | |
106 dcofs = atoi(argv[6]); | |
107 | |
108 if ((idx = compute_pulse(data, sizeof(data), plen, code, strlen(code), sizeof(shaped_trap), shaped_trap, codegap, slew1, slew2, dcofs)) == 0) { | |
109 printf("Failed to build pulse\n"); | |
110 exit(1); | |
111 } | |
112 | |
87 FILE *fh; | 113 FILE *fh; |
88 | |
89 if ((fh = fopen("/tmp/out.bin", "w")) == NULL) { | 114 if ((fh = fopen("/tmp/out.bin", "w")) == NULL) { |
90 printf("Unable to open file: %s\n", strerror(errno)); | 115 printf("Unable to open file: %s\n", strerror(errno)); |
91 exit(1); | 116 exit(1); |
92 } | 117 } |
93 fwrite(data, idx, 1, fh); | 118 fwrite(data, idx, 1, fh); |