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