I'm currently working on a very basic wavetable synthesizer. I'll try my best to give an understandable overview.
I have a single lookup-waveform with 4096 points, which is sampled by the audio thread. In general, however, a single oscillator has multiple waveforms, which can be morphed by a position
parameter. For example, let's take two sine waves where the second one has half the period of the first one. When we play those back at frequency = 440Hz
and position = 0.5
, we would hear two equally loud tones at 440Hz and 880Hz. Here's a link to the audio (See Sidenote 2).
Due to performance reasons I generate the lookup table on another thread whenever the position parameter changes. And therein lies my problem. Even when I don't change the table position and just periodically generate my lookup table, I get weird, unpredictable glitches. Since the audio data in the table doesn't change in this case, I can only explain this by torn reads. Is that correct? And if so, how do I get around it? Do I use a double-buffer with an atomic pointer-swap after I finish generating the data?
Again, here's the audio for this recording (See Sidenote 2). Also, some oscilloscope data:
Sidenote 1: Populating my lookup table takes ~50,000ns
without optimizations and ~10,000ns
with optimizations. But the glitches seem to happen with the same probability.
Sidenote 2: The website I uploaded the audio to seems to have introduced some weird harmonics, which are not audible in my video. Just so you know.
Found it! I accidentally set an old scanner position after generating my lookup table. If the latter took too long my position was basically reset to a few microseconds earlier, which explains the visual setback in the oscilloscope.