Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 36

Thread: triangle & sawtooth oscillators : how to deal with aliasing ?

  1. #1

    triangle & sawtooth oscillators : how to deal with aliasing ?

    Hello,

    I noticed a lot of aliasing with the triangle & sawtooth oscillators, especially with high pitch notes. Is there a way to improve or smooth this waveforms ?

    Thanks,
    Emmanuel

  2. #2
    Senior Member
    Join Date
    Dec 2019
    Posts
    129
    You can use a bandwidth limited triangle wavetable.

  3. #3
    How do you do that ?

  4. #4
    Senior Member
    Join Date
    Dec 2019
    Posts
    129
    The simplest way would be to construct a soundfont using a free program called Polyphone: https://www.polyphone-soundfonts.com/ for each c note provide a sample of a triangle wave which is not aliased. This can be achieved by sampling any number of free software synthesizers available online. Generally you would need a free DAW like Reaper https://www.reaper.fm/ as well. Export the wavs for each sampled C and import these into Polyphone to create a soundfont. Then you would use the pjrc provided soundfont decoder and voila! You may also be able to find alias free triangle wavs sampled at each C on the internet to save yourself some work but I don't have any ready links... You may find this link helpful as well: https://www.music.mcgill.ca/~gary/30...ndlimited.html Cheers!

  5. #5

  6. #6
    Junior Member
    Join Date
    May 2017
    Posts
    1
    There are very many ways to do anti-aliased oscillator synthesis.
    If the wavetable approach isn't your thing, Mutable Instruments provides some excellent code used in their highly regarded Plaits eurorack module that utilizes the PolyBLEP method for anti-aliased oscillators. The aliasing isn't removed completely, but greatly reduced, and inaudible if you keep your oscillator frequency below 4-5 kHz or so.
    https://github.com/pichenettes/euror...w_oscillator.h

  7. #7
    Senior Member
    Join Date
    Dec 2019
    Posts
    129
    Martin Fink has a good tutorial regarding PolyBLEP algo: http://www.martin-finke.de/blog/arti...ep-oscillator/

  8. #8
    Finally, I used Faust language to add band-limited oscillators.
    Faust can run on Teensy. It is really worth giving a try...
    Emmanuel

  9. #9
    Senior Member Blackaddr's Avatar
    Join Date
    Mar 2017
    Location
    Canada
    Posts
    270
    Quote Originally Posted by emmanuel63 View Post
    Hello,

    I noticed a lot of aliasing with the triangle & sawtooth oscillators, especially with high pitch notes. Is there a way to improve or smooth this waveforms ?

    Thanks,
    Emmanuel
    You can process the triangle or sawtooth with an IIR filter (look at the CMSIS biquads supported by teensy for accelerated filtering) or use the waveform approach. The latter is is certainly more computationally efficient. Which one is easier depends on whether you find it easier to run a couple IIR biquads on it or compute and populate waveform tables.

  10. #10
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    I use this on TSynth for the square and sawtooth waves: https://forum.pjrc.com/threads/41905...-(and-its-use)
    It's fairly effective, you need to load each arbitrary wave with each in-coming note on. It also allows you to pitch modulate if you use a AudioSynthWaveformModulated object.

  11. #11
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    I've been looking into this and have a scheme (currently emulated in Python with scipy.signal) which may be promising, and I think
    I can get this to work with phase-modulation too. Its using a band-limited step-function table, and currently I'm seeing waveforms/
    spectra like this:
    Click image for larger version. 

Name:	square_sawtooth.png 
Views:	18 
Size:	121.3 KB 
ID:	21009

    I'm not sure if its worthwhile for triangle waves, the bottom traces are without any bandwidth limiting. The spectra are
    scaled in dB and go down to -90dB on the y-axis.

    The bad news is that processing load increases with frequency as more and more instances of the step-function table
    have to be in use simultaneously.

  12. #12
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    Right, I've made progress on this, converting Python code to C++ and using integer only arithmetic.
    By adding interpolation to the step-function table I've got a good 80 to 90dB S/N ratio now, across
    the board I think. Here's a couple of representative frequencies, 5.111kHz and 511Hz:

    Click image for larger version. 

Name:	band_limited_waves.JPG 
Views:	24 
Size:	116.8 KB 
ID:	21026

    Next step to look at integrating this into the Audio library framework.

  13. #13
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    So an initial working version on Teensy 4.0. Top spectrum with AudioSynthWaveform square wave,
    bottom with my AudioSynthBandLimit class:

    Click image for larger version. 

Name:	band_limit_square_screenshot.png 
Views:	10 
Size:	419.1 KB 
ID:	21029

    Code in this branch here: https://github.com/MarkTillotson/Aud...quare_sawtooth

    You can click the compare button for the changes from standard Audiolib

  14. #14
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    And I've patched in a 32 bit version of FFT to lower the noise floor and see the full benefit of the band-limited
    performance, this is sawtooth at 971Hz:
    Click image for larger version. 

Name:	audiolib_sawtooth_imp.JPG 
Views:	14 
Size:	77.3 KB 
ID:	21043

    The noise floor is down to around the theoretical limit for 16 bits, -98dB...

    The higher noise at low frequencies is due to having the microphone input active and forgetting to turn
    the gain down!

  15. #15
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,704
    Quote Originally Posted by MarkT View Post
    Should this code be merged into the main audio library? If so, I need you to put the MIT license header on the new files before I can bring them into the audio library for everyone.

  16. #16
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    I don''t claim its ready yet, comments are welcome, I would like to try to integrate it with AudioSynthWaveform
    and AudioSynthWaveformModulated for one thing.

  17. #17
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Thanks Mark, this is a major improvement and sounds quite clean. Yes if it could be integrated into the existing synth_waveform files, everyone would benefit without making any changes themselves. I can't see any problem with this? Things would sound slightly different but overall, better. Plus having two different objects for AudioSynthWaveform isn't great if your synth uses more than just square and sawtooth. If there's any way to do the same with the variable pulse and triangle waves, that would be outstanding.

    Testing with the PlaySynthMusic example on a T4.1: with current square and sawtooth CPU maxs at 1.22, with band limited, maxes at 10.71. Sounds considerably better.
    Last edited by UHF; 07-20-2020 at 02:46 PM.

  18. #18
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    I'm working on it

  19. #19
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    Right, that was hard work - changing from 64 bit to 32 bit phase representation and figuring out how to integrate with modulation...

    And I've a pull-request for this version: https://github.com/PaulStoffregen/Audio/pull/360
    This version of band limited square and sawtooth waveforms is integrated into AudioSynthWaveform and AudioSynthWaveformModulated.

    The new tone types WAVEFORM_BANDLIMIT_SQUARE, WAVEFORM_BANDLIMIT_SAWTOOTH and WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE are used so side-by-side comparisons with originals can be done.

  20. #20
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    And a 'scope shot of freq modulated:
    Click image for larger version. 

Name:	band_limit_waveform.png 
Views:	14 
Size:	15.0 KB 
ID:	21057

  21. #21
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    I'm testing the code at the moment and it sounds fine until I change the frequency while notes play, using waveform.frequency(XXX); The sound becomes distorted and I also get complete lock-ups with the sound continuing but no other response.

  22. #22
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    Interesting, I'd assumed handling frequency modulation would have been enough to be frequency agile with discrete calls...

    Can't seem to reproduce this, despite changing frequency randomly every few ms - could you post your code?
    Click image for larger version. 

Name:	band_limit_waveform2.png 
Views:	14 
Size:	12.8 KB 
ID:	21062
    Last edited by MarkT; 07-21-2020 at 09:38 AM.

  23. #23
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Try the PlaySynthMusic example (Audio-->Synthesis-->PlaySynthMusic) with the waveforms all set to WAVEFORM_BANDLIMIT_SQUARE:

    Code:
    // allocate a wave type to each channel.
    // The types used and their order is purely arbitrary.
    short wave_type[16] = {
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE,
      WAVEFORM_BANDLIMIT_SQUARE
    };
    Similarly with WAVEFORM_BANDLIMIT_SAWTOOTH

    Some of the oscillators are distorted, some are ok. I tested on a T4.1 and T3.6 with Audio Boards attached.

  24. #24
    Senior Member
    Join Date
    Jul 2020
    Posts
    398
    Quote Originally Posted by UHF View Post
    Try the PlaySynthMusic example (Audio-->Synthesis-->PlaySynthMusic) with the waveforms all set to WAVEFORM_BANDLIMIT_SQUARE:
    ...

    Some of the oscillators are distorted, some are ok. I tested on a T4.1 and T3.6 with Audio Boards attached.
    Ah, yes, it wasn't reseting all the state on subsequent begin()'s. Pushed.

    BTW I noticed the Audio shield (rev D) outputs lineout's inverted, headphone correct polarity (sawtooths make this
    obvious!)

  25. #25
    Senior Member
    Join Date
    Apr 2019
    Posts
    110
    Ok! That's solved the distortion. The problem with the locking-up is I think, because of me over-stretching the T3.6 (CPU maxes at 141), T4.1 seems fine. I'll carry on testing, I'm modifying my TSynth code for T4.1. Many thanks. Were you planning on band-limiting the pulse and variable triangle waves?

Posting Permissions

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