Mercurial > ~darius > hgwebdir.cgi > modulator
comparison modulator.c @ 29:babdb5376356
Fix interpolator setup.
- Don't overflow the shape table at the end of pulse up
- Don't generate bogus offsets
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Thu, 27 Feb 2025 15:19:32 +1030 |
parents | 600a394629e6 |
children | 92fdf2ef995d |
comparison
equal
deleted
inserted
replaced
28:600a394629e6 | 29:babdb5376356 |
---|---|
186 } else { | 186 } else { |
187 shapesamples = plen / 2; | 187 shapesamples = plen / 2; |
188 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2 + 1; | 188 nsamples = shapesamples * 2 * ncode + codegap * (ncode - 1) + slew1 + slew2 + 1; |
189 } | 189 } |
190 | 190 |
191 // Number of steps per samples in the pulse shape | 191 // How far to advance the shape pointer for each sample point |
192 stepsize = qdiv(qint(shapelen), qint(shapesamples)); | 192 // Needs to be 1 less than the shape length otherwise we overflow |
193 // at the end of the pulse up. | |
194 stepsize = qdiv(qint(shapelen - 1), qint(shapesamples)); | |
193 qsprint(stepsize, tmps, sizeof(tmps)); | 195 qsprint(stepsize, tmps, sizeof(tmps)); |
194 printf("shapelen = %d shapesamples = %lu nsamples = %lu stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); | 196 printf("shapelen = %d shapesamples = %lu nsamples = %lu stepsize = %s\n", shapelen, shapesamples, nsamples, tmps); |
195 | 197 |
196 // Check the requested pulse will not overflow given data | 198 // Check the requested pulse will not overflow given data |
197 if (nsamples > datalen) { | 199 if (nsamples > datalen) { |
211 | 213 |
212 // Setup interp 0 lane 0 to generate index into shape table | 214 // Setup interp 0 lane 0 to generate index into shape table |
213 // Mask start is 0 because we use 8 bit samples | 215 // Mask start is 0 because we use 8 bit samples |
214 cfg = interp_default_config(); | 216 cfg = interp_default_config(); |
215 interp_config_set_shift(&cfg, QBITS); | 217 interp_config_set_shift(&cfg, QBITS); |
216 interp_config_set_mask(&cfg, 0, 32 - QBITS); | 218 interp_config_set_mask(&cfg, 0, 32 - QBITS - 1); |
217 interp_config_set_blend(&cfg, true); | 219 interp_config_set_blend(&cfg, true); |
218 interp_set_config(interp0, 0, &cfg); | 220 interp_set_config(interp0, 0, &cfg); |
219 | 221 |
220 // Setup interp 0 lane 1 to LERP each sample pair | 222 // Setup interp 0 lane 1 to LERP each sample pair |
221 cfg = interp_default_config(); | 223 cfg = interp_default_config(); |
285 interp0->base[2] = (uintptr_t)shape; // Start of shape table | 287 interp0->base[2] = (uintptr_t)shape; // Start of shape table |
286 } | 288 } |
287 for (uint16_t i = 0; i < shapesamples; i++) { | 289 for (uint16_t i = 0; i < shapesamples; i++) { |
288 ctrl[idx] = ctrltmp; | 290 ctrl[idx] = ctrltmp; |
289 if (c == 0) { | 291 if (c == 0) { |
292 // First code bit | |
290 // Get sample pair | 293 // Get sample pair |
291 uint8_t *sample_pair = (uint8_t *) interp0->peek[2]; | 294 uint8_t *sample_pair = (uint8_t *) interp0->peek[2]; |
292 // Ask lane 1 for a LERP, using the lane 0 accumulator | 295 // Ask lane 1 for a LERP, using the lane 0 accumulator |
293 interp0->base[0] = sample_pair[0]; | 296 interp0->base[0] = sample_pair[0]; |
294 interp0->base[1] = sample_pair[1]; | 297 interp0->base[1] = sample_pair[1]; |
302 // Already done it before, just copy the previous instance | 305 // Already done it before, just copy the previous instance |
303 data[idx++] = data[bit1startup + i]; | 306 data[idx++] = data[bit1startup + i]; |
304 } | 307 } |
305 if (c == 0) | 308 if (c == 0) |
306 bit1stopup = idx - 1; | 309 bit1stopup = idx - 1; |
310 | |
307 // Pulse down | 311 // Pulse down |
308 // Since the pulse is symmetrical just copy the up slope in reverse | 312 // Since the pulse is symmetrical just copy the up slope in reverse |
309 // XXX: if we had asymmetrical predistortion this wouldn't be true | 313 // XXX: if we had asymmetrical predistortion this wouldn't be true |
310 for (uint16_t i = 0; i < shapesamples; i++) { | 314 for (uint16_t i = 0; i < shapesamples; i++) { |
311 // Could replace this with a separate loop to poke it into place | 315 // Could replace this with a separate loop to poke it into place |