Mercurial > ~darius > hgwebdir.cgi > modulator
comparison modulator.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 | babdb5376356 |
children |
comparison
equal
deleted
inserted
replaced
29:babdb5376356 | 30:92fdf2ef995d |
---|---|
203 // Check it is not too short | 203 // Check it is not too short |
204 if (shapesamples < 2) { | 204 if (shapesamples < 2) { |
205 printf("Pulse too short (%lu < %d)\n", shapesamples, 2); | 205 printf("Pulse too short (%lu < %d)\n", shapesamples, 2); |
206 return 0; | 206 return 0; |
207 } | 207 } |
208 // Or too long (will overflow for loop variable) | |
209 if (qtoi(shapesamples) > 65535) { | |
210 printf("Shape too long (%u > %d)\n", qtoi(shapesamples), 65535); | |
211 return 0; | |
212 } | |
213 | 208 |
214 // Setup interp 0 lane 0 to generate index into shape table | 209 // Setup interp 0 lane 0 to generate index into shape table |
215 // Mask start is 0 because we use 8 bit samples | 210 // Mask start is 0 because we use 8 bit samples |
216 cfg = interp_default_config(); | 211 cfg = interp_default_config(); |
217 interp_config_set_shift(&cfg, QBITS); | 212 interp_config_set_shift(&cfg, QBITS); |
245 | 240 |
246 memset(pulse_data, 0, datalen); | 241 memset(pulse_data, 0, datalen); |
247 memset(pulse_ctrl, 0, datalen); | 242 memset(pulse_ctrl, 0, datalen); |
248 idx = 0; | 243 idx = 0; |
249 #if 0 | 244 #if 0 |
250 for (uint16_t i = 0; i < 255 * 200; i++) | 245 for (uint32_t i = 0; i < 255 * 200; i++) |
251 data[idx++] = i / 200; | 246 data[idx++] = i / 200; |
252 | 247 |
253 printf("Dummy done\n"); | 248 printf("Dummy done\n"); |
254 return idx; | 249 return idx; |
255 #endif | 250 #endif |
268 data[idx++] = 0; | 263 data[idx++] = 0; |
269 data[idx++] = 255; | 264 data[idx++] = 255; |
270 #endif | 265 #endif |
271 | 266 |
272 // Up slew | 267 // Up slew |
273 for (uint16_t i = 0; i < slew1; i++) { | 268 for (uint32_t i = 0; i < slew1; i++) { |
274 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); | 269 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(i)), qint(slew1))); |
275 } | 270 } |
276 for (uint16_t c = 0; c < ncode; c++) { | 271 for (uint32_t c = 0; c < ncode; c++) { |
277 if (c == 0) | 272 if (c == 0) |
278 bit1startup = idx; | 273 bit1startup = idx; |
279 | 274 |
280 uint ctrltmp = PACTIVE; | 275 uint ctrltmp = PACTIVE; |
281 if (code[c] == '0') | 276 if (code[c] == '0') |
284 // Pulse up | 279 // Pulse up |
285 if (c == 0) { | 280 if (c == 0) { |
286 interp0->accum[0] = 0; // Initial offset into shape table | 281 interp0->accum[0] = 0; // Initial offset into shape table |
287 interp0->base[2] = (uintptr_t)shape; // Start of shape table | 282 interp0->base[2] = (uintptr_t)shape; // Start of shape table |
288 } | 283 } |
289 for (uint16_t i = 0; i < shapesamples; i++) { | 284 for (uint32_t i = 0; i < shapesamples; i++) { |
290 ctrl[idx] = ctrltmp; | 285 ctrl[idx] = ctrltmp; |
291 if (c == 0) { | 286 if (c == 0) { |
292 // First code bit | 287 // First code bit |
293 // Get sample pair | 288 // Get sample pair |
294 uint8_t *sample_pair = (uint8_t *) interp0->peek[2]; | 289 uint8_t *sample_pair = (uint8_t *) interp0->peek[2]; |
309 bit1stopup = idx - 1; | 304 bit1stopup = idx - 1; |
310 | 305 |
311 // Pulse down | 306 // Pulse down |
312 // Since the pulse is symmetrical just copy the up slope in reverse | 307 // Since the pulse is symmetrical just copy the up slope in reverse |
313 // XXX: if we had asymmetrical predistortion this wouldn't be true | 308 // XXX: if we had asymmetrical predistortion this wouldn't be true |
314 for (uint16_t i = 0; i < shapesamples; i++) { | 309 for (uint32_t i = 0; i < shapesamples; i++) { |
315 // Could replace this with a separate loop to poke it into place | 310 // Could replace this with a separate loop to poke it into place |
316 // Similarly for TR switch when implemented | 311 // Similarly for TR switch when implemented |
317 if (i == 0 && c == 0) | 312 if (i == 0 && c == 0) |
318 ctrl[idx] = ctrltmp | SENSE1; | 313 ctrl[idx] = ctrltmp | SENSE1; |
319 else | 314 else |
321 data[idx++] = data[bit1stopup - i]; | 316 data[idx++] = data[bit1stopup - i]; |
322 } | 317 } |
323 | 318 |
324 // Code gap | 319 // Code gap |
325 if (c < ncode - 1) | 320 if (c < ncode - 1) |
326 for (uint16_t i = 0; i < codegap; i++) { | 321 for (uint32_t i = 0; i < codegap; i++) { |
327 ctrl[idx] = ctrltmp; | 322 ctrl[idx] = ctrltmp; |
328 data[idx++] = dcofs; | 323 data[idx++] = dcofs; |
329 } | 324 } |
330 } | 325 } |
331 | 326 |
332 // Down slew | 327 // Down slew |
333 for (uint16_t i = 0; i < slew2 + 1; i++) { | 328 for (uint32_t i = 0; i < slew2 + 1; i++) { |
334 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); | 329 data[idx++] = qtoi(qdiv(qmul(qint(dcofs), qint(slew2 - i)), qint(slew2))); |
335 } | 330 } |
336 | 331 |
337 data[idx++] = 0; | 332 data[idx++] = 0; |
338 ctrl[idx] = 0; | 333 ctrl[idx] = 0; |