"Click"-noise on note start

Hi,
i created a basic wavetable synthesizer that gets it's input over midi and outputs through a single PWM pin.
I have a problem now:
Everytime a note starts to play, i hear a "click"-noise. However this only happens when there is a pause between the new an the old note. If two notes are exactly aligned behind each other in the midi, there is no click. So i guess the "click" thing has something to do with the PWM going "LOW" in the pause between two notes.
But then again, if there are 2 or more notes playing at the same time (i.e. bassline and strings) and there is a pause in for example the bassline channel, the click also appears ...so the PWM-pin-going-low-thing might not be it after all.

Here's the relevant code

static int32_t sum;
  for(int i = 0; i < NUM_CHANNELS; i++)
  {
 
    channel[i].phase += channel[i].speed; //increase phase by note frequency
    //if(channel[i].phase >= 65536) channel[i].phase -= 65536;
      
    uint16_t waveTableIndex = ( channel[i].phase >> 8 ); //get wavetable index
    sum += ( wavetable[3][waveTableIndex] * channel[i].volume * channel[i].volumeMax ); //get sample, apply ADSR and master volume
  }
  
  //get rid of that "click" on note start and end...WHY DOES THIS EVEN HAPPEN!? GRRRR
  //sum = syn_iSmooth32(audioBuffer, sum, 0.925f); //results in a pseudo low pass....meh
  //audioBuffer = sum;
  
  sum >>= 8;
  OC1RS = sum;

wavetable

uint8_t wavetable[4][256] = {
  { //square
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //32
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //32
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //64
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //64
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //32
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, //32
  },
  {}, //sawtooth
  {},//triangle
  { //sine
    127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,
    176,179,182,184,187,190,193,195,198,200,203,205,208,210,213,215,
    217,219,221,224,226,228,229,231,233,235,236,238,239,241,242,244,
    245,246,247,248,249,250,251,251,252,253,253,254,254,254,254,254,
    255,254,254,254,254,254,253,253,252,251,251,250,249,248,247,246,
    245,244,242,241,239,238,236,235,233,231,229,228,226,224,221,219,
    217,215,213,210,208,205,203,200,198,195,193,190,187,184,182,179,
    176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,
    127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,
    78,75,72,70,67,64,61,59,56,54,51,49,46,44,41,39,
    37,35,33,30,28,26,25,23,21,19,18,16,15,13,12,10,
    9,8,7,6,5,4,3,3,2,1,1,0,0,0,0,0,
    0,0,0,0,0,0,1,1,2,3,3,4,5,6,7,8,
    9,10,12,13,15,16,18,19,21,23,25,26,28,30,33,35,
    37,39,41,44,46,49,51,54,56,59,61,64,67,70,72,75,
    78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
  }
};


void wavetable_generateSawtooth(int inTable)
{
  for (int i = 0; i < 256; ++i) {
    wavetable[inTable][i] = i; // sawtooth
  }
}

void wavetable_generateInverseSawtooth(int inTable)
{
  for (int i = 0; i < 256; ++i) {
    wavetable[inTable][i] = 255-i; // sawtooth
  }
}
 
void wavetable_generateTriangle(int inTable)
{
  for (int i = 0; i < 128; ++i) {
    wavetable[inTable][i] = i * 2;
  }
  int value = 255;
  for (int i = 128; i < 256; ++i) {
    wavetable[inTable][i] = value;
    value -= 2;
  }
}

void SetupWavetable()
{
  wavetable_generateSawtooth(1);
  wavetable_generateTriangle(2);
}

Anyone here who had similar problems when playing a tone via pwm?
This i really driving me nuts. :wink:

I have a sort-of similar problem - I use Tone to make a little warble, sort of sounds like a cell phone ring.
Imagine dee-dle-dee-dle-dee-dle-dee-dle-deeee - and this afwul farty kind of noise as it turns off. I have 5 boxes - 4 smaller, 1 larger. All the same circuit, output pin driving a mosfet then the speaker. Only the larger box makes the noise. Nothing I've tried stops it. And nice & loud too as the MOSFET switches ~ 3W across the speaker (12V source thru a 34 ohm resistor into capacitor coupled 4 ohm speaker).

We just laugh about it now, especially when people hear it.

The click noise is the DC shift from nothing to the mid point that represents a zero audio signal. The trick is to bias your output so that the undriven state of the line is a mid voltage.

Exactly.
Looking at your code, you tried to put a simple LPF-like smoothing, which theoretically would work. But the problem is, even if the PWM carrier ramps up to full volume, the arduino output itself is still jumping directly to 5v.

I had the same problem with my synth. The problem could be solved by having the output centered on the middle of the output range, rather than just adding waveforms to 0. Add a capacitor in series to nix the DC offset, and the middle PWM value will become the new "0" point.
This was actually a problem for me, because no analog LPF's can filter out all of the carrier wave. I ended up getting a nice SPI DAC, since I use my synth for my electronic music-making, and the PWM wave, albeit inaudible, messed up recordings.

...
Imagine dee-dle-dee-dle-dee-dle-dee-dle-deeee - and this afwul farty kind of noise as it turns off.
...
We just laugh about it now, especially when people hear it.

If it were fart sounds i could maybe live with it as a "feature" :smiley: But unfortunally it really does sound more like going rampage on a old TV's antenna...white noise kind of thing

Exactly.
Looking at your code, you tried to put a simple LPF-like smoothing, which theoretically would work. But the problem is, even if the PWM carrier ramps up to full volume, the arduino output itself is still jumping directly to 5v.

I had the same problem with my synth. The problem could be solved by having the output centered on the middle of the output range, rather than just adding waveforms to 0. Add a capacitor in series to nix the DC offset, and the middle PWM value will become the new "0" point.
This was actually a problem for me, because no analog LPF's can filter out all of the carrier wave. I ended up getting a nice SPI DAC, since I use my synth for my electronic music-making, and the PWM wave, albeit inaudible, messed up recordings.

Good idea! So i would convert my wavetables from uint to int and use values between -128 and 128. Initial value for the pwm out would be 128. I will give it a try next week :slight_smile:
Also, which Hardware DAC are you using? I planned on using a DAC also, but never found a nice one (and no, i don't want to use a R2R ladder :wink: ).

In the meantime i update my Synth code a bit. I now have 16 channels with 4 voices each, giving me a total of 64 voices (i plan on adding a more intelligent channel->voice algorythm later where a channel looks for a free voice on NoteOn and simply uses it). I can also change wavetables on the fly. Next step is to add a touchpanel so i can change the ADSR curve on the fly. After that comes storing/loading the ADSR to/from SD/MMC. Can't wait to get this finished :slight_smile:

Here's a short recording of my synthesizer in action

http://soundcloud.com/boh_havoc/bitpad-v0-3-nuvole-bianche

Still looking for a decent DAC :slight_smile:

Quite impressive. :slight_smile:

The best performance and value for money for audio DAC has to be I2S delta-sigma DACs - however they are hard to drive requiring 3 related clocks and bits have to be serially fed to them at Mb/s rates. 24 bit stereo at 48kHz sample rate for under a dollar in surface mount packages (WM8759GED, WM8524GED).
The Arduino isn't really fast enough to drive such a DAC (and do anything else useful!)

Other high resolution 5V or 3V3 ADCs are usually expensive and surface mount. LTC2642CMS is a fast SPI 16 bit DAC as an example, not very cheap, surface mount only...

I'd recommend the MCP4921/4922 (1 or 2 channels).

There's an SPI interface on it, so super easy to interface. 12bit audio on each channel, 2 channels if you get the 4922 chip.

And they're extremely low noise. You just have to (as I just found out) put a very low lowpass filter on the Vref pins, not directly connect them to 5v. I mean really low; I'm using one with a cutoff of around 0.03Hz.

Thanks for the DAC info guys :slight_smile:

I'll go for the MCP4922 first as i can get it cheap from a local shop. I'll keep the LTC2642CMS in mind though and get myself one of these the next time i buy something at farnell.com .

In the meantime i implemented FM Synthesis in addition to wavetable synthesis. I can either use both together (choose wavetables for fm modulator and carrier) or only use wavetables like before. This can be set per Voice, so you don't have to use FM Synthesis for everything if you don't want to.
Next is adding an envelope to both the modulator volume and pitch to get more action in there (i'm currently "emulating" the envelope curves by hand :wink: )

I'll upload a new sample track of the FM Synthesis stuff once i have the DAC working.

Again, thanks for the help so far! :slight_smile:

[edit]
Oh well, i'm having to much fun here :slight_smile:
So here's an example of the current status. No DAC yet.

http://soundcloud.com/boh_havoc/bitpad-v0-35-tyrian-fm-ride