Recent content by sublinear

  1. S

    Is it possible to bitshift using ARM native bitshift operators?

    You can quickly see what different compilers will do, using Godbolt compiler explorer. Just type in a non-inline function and ignore any function-call overhead, like the return at the end (bx lr). https://godbolt.org/z/vPLCD-
  2. S

    Teensy Synthesizer | Waveform aliasing "Problem"

    Good point, you can sum the harmonics up to Nyquist to accurately synthesize these waveforms. When using wavetable synthesis, this is a great way to generate the bandlimited wavetables. But it can be expensive to do this real-time. You can use an inverse-FFT as an efficient oscillator-bank, but...
  3. S

    Teensy 4.0 First Beta Test

    Just curious, what would be the specs on the resampling you want to do? Years ago I wrote a very fast polyphase resampler for a previous Cortex-M4 project that I'm happy to contribute. It used 16-tap precomputed filters to convert standard rates (8k, 11025, 16k, 22050, 32k, 48k) to 44100Hz...
  4. S

    Inner working of filter_biquad

    Hi Paul, The noise-shaping is actually correct, because the signed shift does truncation toward -inf. The quant error is guaranteed to be a positive fraction in [0,1]. If you round instead of truncate (to prevent the 0.5 ULP DC offset) then the error feedback becomes more complicated (and slow)...
  5. S

    Teensy Synthesizer | Waveform aliasing "Problem"

    The original poster is right in that if you generate a trivial square or sawtooth at the target sample rate, it has already aliased and is too late to filter it out. An obvious solution is to generate at an oversampled rate, then downsample to the target rate. The problem is the harmonics of...
  6. S

    A question about the teensy Audio Library Biquad filter header file source file

    To get good performance on older Teensy's, most of the audio code uses fixed-point instead of floating-point math. In this case, biquad coefs are converted to fixed-point with sign bit, one integer bit, and 30 fraction bits. This effectively represents [-2.0, +2.0] with enough fraction bits to...
  7. S

    Teensy 3.6 with SSD1351 OLED

    That's what I did with my Newhaven OLED. In ssd1351.h, I changed it to #define SPICLOCK 16000000 and was able to run the Teensy 3.6 at full speed.
  8. S

    FFT/Convolution object for Teensy Audio library (guitar cabinet simulation )

    I think you're right, the theoretical operation-count for partitioned convolution seems to always be lower than unpartitioned. In practice, when FFTs get too small (32-point RFFT is only a 16-point FFT) the overhead and housekeeping really start to hurt. I'd consider these tunable parameters...
  9. S

    FFT/Convolution object for Teensy Audio library (guitar cabinet simulation )

    @WMXZ For a filter with L=129, I think the standard FFT convolution (N=128 and NFFT=256) is the way to go. With a minimum-phase filter, you'll have near-zero added latency and great efficiency. You can also use a real-FFT to almost double the efficiency of the FFT and complex-multiply. For long...
  10. S

    FFT/Convolution object for Teensy Audio library (guitar cabinet simulation )

    For partitioned convolution, the filter and the output are the same, only the machinery is different. The basic idea is to think of your long filter as the sum of shorter filters (where all but the first include some delay). This paper does a good job explaining it...
  11. S

    FFT/Convolution object for Teensy Audio library (guitar cabinet simulation )

    Nice work! If needed, there are several ways to reduce the latency further: 1) Instead of one big FFT, you can use uniform-partitioned FFT convolution to operate in blocks of 128. Slightly less efficient, but avoids the buffering latency and also distributes the computation. 2) You can reduce...
  12. S

    A little competition :-)

    You forgot that the original code correctly saturates when the left-shift overflows. It's the same problem that Paul describes above with __SSAT(y<<n, 31). Bits are lost during the shift before saturation takes place. Here is an alternate method: int CLIP_2N_SHIFT(int x, int n) { int y =...
Back
Top