Wavetable synthesis. theory, practice, fear?

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Thanks for all your input. I now think i must be doing something really awful. Looking at my scope, the waveform seems to move in the Y axis. That is to say the wave is slowly inching along with each keystroke till it reaches the point of overflow, if a wave had a larger amplitude than the last the whole center point is moved. but maybe its this normal? When i limited the signal as mystran suggested, i could see the signal slowly move to the edge of the upper bound and become nothing. Initially, without the clipping, i thought it was the cause of the trigger feature on the software scope I'm using, but testing other instruments and sound - this does not happen. On other instruments the wave is centered - and showing both channels (red and greed on the softscope, which is not happening either - get stereo sound out though)

What have i done to deserve this? must be something obvious right? Moving a sine on a axis is usually done by adding or subtracting - no where in the program do i do such an operation. Maybe I'm just going crazy, it has been a long night. Anyway - I provided a scope render if you want to see the "feature" for yourself. In this image the wave started with its middle point at the red line, drawn in by me. The blue line indicates the new center.
You do not have the required permissions to view the files attached to this post.

Post

LiteX2 wrote: What have i done to deserve this?
And it's not even April 1 :lol:
~stratum~

Post

LiteX2 wrote:Thanks for all your input. I now think i must be doing something really awful. Looking at my scope, the waveform seems to move in the Y axis. That is to say the wave is slowly inching along with each keystroke till it reaches the point of overflow, if a wave had a larger amplitude than the last the whole center point is moved. but maybe its this normal?
Most likely you have an accumulator (ie. numeric intergrator) somewhere that is accumulating some DC offset, either because you are feeding it something with DC or because you're running it in floating point which usually results in some rounding errors that don't properly cancel out.

Not sure why you would have this problem with wave-tables, but the most obvious solution is to use a leaky integrator.

Post

If the current output in the callback is 0 should not the buffer recenter? if i keep the program running and play normal audio i.e music form youtube, it adheres to the new center line. Until the program is closed - then it drops down again.

Post

I'll just do a quick update here : I AM STUPID AND I SHOULD FEEL BAD!

Heres the news, this line in my mixer - was commented out : //MixOutput = 0.0;
I'm sure you see the problem, in the context of my grievance.

To the other noobs like me, clear your buffers to avoid this stupid mistake - and don't waste good peoples time like I did. And remember to read all your code in cases of total confusion.

To the guys or gals who took the time, I'm grateful - I did learn a lot from the links and advice, thank you! I'll probably post back on the forum with a link to my synth when It's done, if anyone's curious.

Post

LiteX2 wrote: Heres the news, this line in my mixer - was commented out : //MixOutput = 0.0;
Looks like that was caused by an inadequate supply of coffee while coding.
~stratum~

Post


Post

in clang there is a -Wcoffee-underrun flag that will help ;)

Post

LiteX2 wrote:I'll read the earlevel tutorial more carefully, even though his naming conventions give me nightmares.
"Nightmares"...hmm...wondering what naming conventions, had to peek...setFrequency, setPhase, updatePhase, getOuput, waveTable, phasor...nothing jumps out at me as nightmare material. Did you have something in mind in particular? No offense taken, I saw this a few days ago, decided I was curious enough to ask what was so torturous. :wink:

FWIW, in the code I post for my examples, I go for brevity to make it easier to follow, while being fairly efficient (did I miss the mark?). My own code is a bit different (templates and such). I wouldn't have macro'd the choice of linear interpolation and truncation in my own code, for instance, but in this case I wanted the differences to be obvious but putting it one function. But that doesn't seem to be what your'e referring to.
My audio DSP blog: earlevel.com

Post

Hi there!

I'm sorry, "horrible" is not fair! And if we have learned anything from this thread It's that I'm somewhat of an idiot. However, It's lines like this that really make me sweat when reading your code:

"return waveTable->waveTable[int(this->phasor * waveTable->waveTableLen)] - waveTable->waveTable[int(offsetPhasor * waveTable->waveTableLen)]; "

I know of course that you want to keep things simple and not use complicated patterns and unnecessary junk, but compartmentalizing and generalizing some of this I think is possible and may make it easier to read. I'm also a big proponent of using full names - i.e waveTableLength - and when this is difficult making comments with the name description.

Also, not that these guys are my favorite coders (using auto allover makes me cry), but take a look at the way the official JUCE documentation handle comments. And the way they take us on an incremental journey - slowly improving their code as we read along https://docs.juce.com/master/tutorial_w ... synth.html

All that being said, your tutorial series on wavetable and sampling theory really helped me get my head around these concepts in a relatively painless way. So while i have you here, thank you for your help ;)

Post

you are comparing a blog with commercial software:)
~stratum~

Post

LiteX2 wrote:"return waveTable->waveTable[int(this->phasor * waveTable->waveTableLen)] - waveTable->waveTable[int(offsetPhasor * waveTable->waveTableLen)]; "
:lol:

Ok, I get it, that is pretty rough. In my defense, that was the worst one, by far :hihi: The "getOutputMinusOffset" function was a bonus routine, I didn't pay much attention—should have definitely cleaned that up.

I see I was also struggling with the style to use for this. For instance, I normally don't use gratuitous "this->". But in that line and other places I wanted to stress which was a member variable (phasor) and not (offsetPhasor). And normally I'd just use "mPhasor" as a member variable, but that would only be meaningful to some more experienced coders (though I don't think special naming for variable types is so important these days, no one goes through code from a printed listing anymore, and code editors are smart).

Glad the article series was a help!
My audio DSP blog: earlevel.com

Post

earlevel wrote:(though I don't think special naming for variable types is so important these days, no one goes through code from a printed listing anymore, and code editors are smart).
What would be wrong with this:

Code: Select all

return wave->data[int(wave->size * phase)]
     - wave->data[int(wave->size * offsetPhase)];
For what it's worth, I actually spent a little bit of effort to try to make sure to use names that would result in the correct mental associations, which also making it as easy as possible to parse visually.

Post

What would be wrong with this:
I can't see whether "wave->size" is in bytes or in number of samples whereas for some reason my mind would associate "wave->length" with number of samples and not bytes (I don't know why). (Just kidding, but mental associations are subjective things)
~stratum~

Post

mystran wrote:What would be wrong with this:

Code: Select all

return wave->data[int(wave->size * phase)]
     - wave->data[int(wave->size * offsetPhase)];
For what it's worth, I actually spent a little bit of effort to try to make sure to use names that would result in the correct mental associations, which also making it as easy as possible to parse visually.
Nothing wrong with it. For me, a sample has a size (16-bit, etc.), and a buffer of samples has a length, but no big deal. Maybe due to decades of C (sizeof, strlen, etc.). Anyway, like I said, I word things a little differently for examples, and maybe "waveTable->waveTableLen" is over-explaining, but hey. I stress enough about the wording of my articles ;-)
My audio DSP blog: earlevel.com

Post Reply

Return to “DSP and Plugin Development”