Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 12 of 12

Thread: Teensy Synthesizer | Waveform aliasing "Problem"

  1. #1
    Junior Member ohoomens's Avatar
    Join Date
    Feb 2019
    Location
    Hamburg
    Posts
    6

    Teensy Synthesizer | Waveform aliasing "Problem"

    Hey there!
    First of all: Thanks Paul for this wicked platform. It opens up the world of electronics and being creative with it even for programming-noobs like me (I'm starting to get somewhere but I'm by no means a pro!).

    So I'm currently working on my bachelor thesis and I've been building a touch based synthesizer based on the Teensy for about a year now. It's starting to look cool and I've got a lot working already, but currently I'm struggeling with audible aliasing effects (I think it's aliasing at least) on the waveform synthesis, especially on higher frequencies from 800hz upwards - nyquist is probably the limiting factor here? With a sine wave it's obviously not really noticable but with triangle, sawtooth and every other waveform which has high frequency components there are loads of audible artifacts. There seem to be a few other threads about this but I could not find a solution so I thought I put this up again. As far as I could identify the problem: I need to limit the bandwidth before the synthesis happens.

    For all of you pros out there: How can I limit the waveform bandwith so nyquist won't destroy my beautiful sound waves?

    Thanks in advance!

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,530
    A 4th order low pass filter with 16 to 18kHz corner frequency should kill enough of the waveform's harmonics to make them inaudible.

  3. #3
    Junior Member ohoomens's Avatar
    Join Date
    Feb 2019
    Location
    Hamburg
    Posts
    6
    Quote Originally Posted by Theremingenieur View Post
    A 4th order low pass filter with 16 to 18kHz corner frequency should kill enough of the waveform's harmonics to make them inaudible.
    The problem is: The effect on the synthesis already happened before I send it into the mixer, so a low pass would not get rid of the low frequencies and all the stuff that has happened as an effect.

    Here is an image of the spectrum:
    Click image for larger version. 

Name:	TeensySaw.jpg 
Views:	37 
Size:	84.2 KB 
ID:	16022

  4. #4
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,330
    Quote Originally Posted by ohoomens View Post
    The problem is: The effect on the synthesis already happened before I send it into the mixer, so a low pass would not get rid of the low frequencies and all the stuff that has happened as an effect.

    Here is an image of the spectrum:
    Click image for larger version. 

Name:	TeensySaw.jpg 
Views:	37 
Size:	84.2 KB 
ID:	16022
    IMO, what you have is that your saw signal is modulated with 200 Hz (if the frequency axis is correct).
    You see that any frequency component of the saw signal has +- secondary peaks that could be 200 Hz apart similar to the LF peak (the modulation frequency)
    Where are the 200 Hz coming from?
    lets guess: 200 Hz is 1/5 ms, this does not fit with the block size of 128 samples (2.9 ms)
    so I would search for any possible periodicity in your code that would fit with 5ms or 220 samples or similar

  5. #5
    Junior Member ohoomens's Avatar
    Join Date
    Feb 2019
    Location
    Hamburg
    Posts
    6
    Quote Originally Posted by WMXZ View Post
    IMO, what you have is that your saw signal is modulated with 200 Hz (if the frequency axis is correct).
    You see that any frequency component of the saw signal has +- secondary peaks that could be 200 Hz apart similar to the LF peak (the modulation frequency)
    Where are the 200 Hz coming from?
    lets guess: 200 Hz is 1/5 ms, this does not fit with the block size of 128 samples (2.9 ms)
    so I would search for any possible periodicity in your code that would fit with 5ms or 220 samples or similar
    Tested it without anything from my sketch, just plain one waveform (sawtooth) and playing a frequency of 1567.98 Hz (Note: G6) directly to the stereo out without any hardware attached. Tried it with a grounded and a floating system (battery bank + laptop). Any further ideas?

  6. #6
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,330
    Quote Originally Posted by ohoomens View Post
    Tested it without anything from my sketch, just plain one waveform (sawtooth) and playing a frequency of 1567.98 Hz (Note: G6) directly to the stereo out without any hardware attached. Tried it with a grounded and a floating system (battery bank + laptop). Any further ideas?
    where is the sketch, cannot find it.

  7. #7
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,530
    The low pass filter had naturally to be implemented on digital level, directly after the stage which creates too much harmonics. And if later stages add new harmonics above the NyQuil then frequency, again a filter is required. No digital or analog signal block should be driven with signals which risk to generate aliasing.
    Another point to take care of, is saturation (the digital equivalent to analog hard clipping), which gives similar ugly ghost tones. You’ll have to make sure that it won’t ever happen by doing worst case calculations.

  8. #8
    Junior Member ohoomens's Avatar
    Join Date
    Feb 2019
    Location
    Hamburg
    Posts
    6
    Quote Originally Posted by WMXZ View Post
    where is the sketch, cannot find it.
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioSynthWaveform       waveform1;      //xy=459,120
    AudioMixer4              mixer1;         //xy=630,140
    AudioOutputAnalogStereo  dacs1;          //xy=790,140
    AudioConnection          patchCord1(waveform1, 0, mixer1, 0);
    AudioConnection          patchCord2(mixer1, 0, dacs1, 0);
    AudioConnection          patchCord3(mixer1, 0, dacs1, 1);
    // GUItool: end automatically generated code
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(10);
      
      mixer1.gain(0, 0.1);
    
      waveform1.begin(WAVEFORM_SAWTOOTH);
      waveform1.amplitude(0.5);
      waveform1.frequency(1567.98);
    }
    
    void loop() {
      Serial.println("Playing...");
    }
    @Theremingenieur Ok, got it but how?

  9. #9
    Junior Member
    Join Date
    Apr 2014
    Location
    Seattle, WA
    Posts
    12
    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 these waveforms diminish slowly with frequency, so the high oversampling required makes this a very expensive approach.

    For specific waveforms used by subtractive synth, its possible to generate a bandlimited waveform to begin with. Search for minBLEP or polyBLEP. The basic idea is to do fixups that add Gibbs ringing at the discontinuities.

    For arbitrary waveforms, you can do bandlimited wavetable synthesis. If the wavetable stores freqs up to Nyquist, you'll need expensive (with arbitrary cutoff) filtering to pitch it down without aliasing. One trick is to use multiple wavetables, prefiltered for each octave, to facilitate simple interpolation (2-tap linear, 4-tap Lagrange, etc). This is basically the same idea as MIP-maps for textures.

  10. #10
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,330
    If you really wanted an exact sawtooth, or triangular or rectangular waveform, you hardly can generate it in ad sampled way, as you need very large bandwidth to generate the signals. Alternatively to using 'analog' simulating bandwidth, you could synthesise your sawtooth with a sum of sinusoids that are properly weighted (look up the Fourier coefficients in any math book) and limited to 1/2 sampling frequency.

  11. #11
    Junior Member
    Join Date
    Apr 2014
    Location
    Seattle, WA
    Posts
    12
    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 it gets ugly if you want to continuously modulate the pitch.

  12. #12
    Junior Member
    Join Date
    Mar 2019
    Posts
    5
    Using the sum of single sinosoids is not only a possible workaround for the aliasing of the available waveforms. Beside the weighting of the tones (set levels) to shape the sound it gives the extra opportunity to change each frequency to add some "analog character" by taste.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •