Wavetable Synthesis (DDS)

I haven’t see anything educational about wavetable synthesis which go above the simple bloody Arduino sketch. So I hope that will be hopeful for those who want to create a digital variable waveform VCO and don’t know where to start.  To understand the little following piece, you’ve to be familiar with DDS and basic programming. The following explanation will deal with 8bit waveforms (256 samples long) .

The idea is to store the waveforms into a consecutive memory space (using a big array)

uint8_t waveforms[] =
{
256 data for wave1,
256 data for wave 2,
256 data for wave 3,
ect...
}

It will end up looking, conceptually, like this : sampler_arrayThen you need a pointer to access the sample location in the array you want to output. In the regular DDS fashion, you use the highest 8bit (phase_index) of your phase accumulator to point to your desired sample. The following phase_accumulator register is 16bit long, hence you get rid of the 8 last bits. Phase_incr is the value you put in to increment the counter.


uint16_t phase_accumulator;
uint8_t phase_index;

phase_accumulator += phase_incr;
phase_index = phase_accumulator >> 8;

send_to_dac(waveforms[phase_index]); 

Doing so, everytimes phase_index wraps around (overflow, goes from 255 to 0) we restart at the location 0. However, if you add an offset to phase_index, you can start the waveform at any location into the array.


phase_accumulator += phase_incr;
phase_index = phase_accumulator >> 8;

send_to_dac(waveforms[phase_index + wave_offset]);

wave_offset can be anything variable. Usually it is loaded with a value from the ADC converter. The trick is to don’t go above  the bounds of your array (otherwise the program will return crap) and usually we want to have the full last waveforms when we end the control parameter and not a portion of it with crap finishing the cycle. So we have to stop at the location of the first byte of your last waveforms. Here’s an example. We have 16 8bit waveforms (16 * 256 = 4096 bytes in your array), the last offset point should be 3840 (4096 – 256 = 3840).

From that you can load any waveforms into the memory and scan through them linearly creating even more waveforms, blending between each others. The trick is actually to scale the value of wave_offset to have something consistent with the size of your array. But  you can also create another table for that value. http://www.electricdruid.net/index.php?page=info.dds http://www.analog.com/media/en/training-seminars/tutorials/MT-085.pdf if this could be helpful to anyone…

Advertisements

Leave a comment

Filed under Uncategorized

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s