Discussion:
[music-dsp] wavetable filtering
alexandre niger
2018-06-29 14:19:58 UTC
Permalink
Hello everyone,

I just joined the list in order to find help in making a wavetable synth. This synth would do both morphing and frequency wavetables. Morphing is a way to play different waveforms over time and so to get an additional sound dimension. Frequency wavetables are used to avoid aliasing by filtering harmonics the higher the frequency go. I started with the frequency wavetables and then I will do the morphing between different waveforms.

As an intern at Rebel Technology, I started making wavetables patches from earlevel articles. In those patches, common waveforms are generated inside the code (tri, square, saw). Now I want to generate some more complex waveforms from an editor called WaveEdit (free). They come as 256 samples single cycle .wav files. Then I change them into static data in a header file. Once I have this, I can start with frequency wavetables. The key point of frequency wavetables is the filtering. I have to filter enough harmonics so the aliased frequencies do not come back under 18KHz (audiable range). But I must not filter too much if I don't want to get gain loss.

At the moment I managed to make a 3550 taps FIR to filter every octave wavetables. Unfortunately, with complex harmonic rich waveforms, I still have audiable aliasing from 2kHz and gain/amplitude difference when wavetables cross.
So now I am wondering:
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough. According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.

You can have a look at the patch code but you won't be able to try it if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.

Best,

Alex
gm
2018-06-29 14:39:42 UTC
Permalink
You could use FFT where you can also make the waves symmetric
which prevents phase cancellations when you blend waves.
Post by alexandre niger
Hello everyone,
I just joined the list in order to find help in making a wavetable
synth. This synth would do both morphing and frequency wavetables.
Morphing is a way to play different waveforms over time and so to get
an additional sound dimension. Frequency wavetables are used to avoid
aliasing by filtering harmonics the higher the frequency go. I started
with the frequency wavetables and then I will do the morphing between
different waveforms.
As an intern at Rebel Technology, I started making wavetables patches
from earlevel articles. In those patches, common waveforms are
generated inside the code (tri, square, saw). Now I want to generate
some more complex waveforms from an editor called WaveEdit (free).
They come as 256 samples single cycle .wav files. Then I change them
into static data in a header file. Once I have this, I can start with
frequency wavetables. The key point of frequency wavetables is the
filtering. I have to filter enough harmonics so the aliased
frequencies do not come back under 18KHz (audiable range). But I must
not filter too much if I don't want to get gain loss.
At the moment I managed to make a 3550 taps FIR to filter every octave
wavetables. Unfortunately, with complex harmonic rich waveforms, I
still have audiable aliasing from 2kHz and gain/amplitude difference
when wavetables cross.
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough.
According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when
filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.
You can have a look at the patch code but you won't be able to try it
if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.
Best,
Alex
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
robert bristow-johnson
2018-06-29 22:20:46 UTC
Permalink
 
you don't really need symmetric to prevent phase cancellations.  you just need to make the phases of each harmonic (and in wavetable synthesis, **each** partial or overtone is harmonic) of the two wavetables that you're crossfading or blending to be aligned.
what even
symmetry does is line up all of the harmonics represented as cosines all with phase of zero.  or odd symmetry lines up all of the harmonics as sines with phase of zero.  since they all have phase of zero, they're all lined up.  but if you extract the wavetables from a sampled note,
your waveshape will likely have neither even nor odd symmetry.  and sometimes phase is salient; it affects the waveshape.  so unlike Andrew Horner, i would not toss the phase information for each harmonic to the wind.  i would preserve that information.
you can circularly shift
a wavetable and keep its waveshape.  a good way to optimally align the phase of the harmonics (without disassembling the wave into harmonics and changing the waveform by shifting harmonics independently) is to *circularly* cross-correlate one wavetable with the other.  the correlation lag
that gives you the maximum (positive) correlation is the lag value used to "spin" or "rotate" one wavetable w.r.t. the other to line up the waveforms.
if sequential wavetables are extracted directly from a sampled note (with waveshape and timbre that evolves in time after
the onset), this is what you would do anyway.  the set of wavetables **should** be aligned when you load them ready to rock-n-roll in your wavetable synth.



---------------------------- Original Message ----------------------------

Subject: Re: [music-dsp] wavetable filtering

From: "gm" <***@voxangelica.net>

Date: Fri, June 29, 2018 7:39 am

To: music-***@music.columbia.edu

--------------------------------------------------------------------------
Post by gm
You could use FFT where you can also make the waves symmetric
which prevents phase cancellations when you blend waves.
Post by alexandre niger
Hello everyone,
I just joined the list in order to find help in making a wavetable
synth. This synth would do both morphing and frequency wavetables.
Morphing is a way to play different waveforms over time and so to get
an additional sound dimension. Frequency wavetables are used to avoid
aliasing by filtering harmonics the higher the frequency go. I started
with the frequency wavetables and then I will do the morphing between
different waveforms.
As an intern at Rebel Technology, I started making wavetables patches
from earlevel articles. In those patches, common waveforms are
generated inside the code (tri, square, saw). Now I want to generate
some more complex waveforms from an editor called WaveEdit (free).
They come as 256 samples single cycle .wav files. Then I change them
into static data in a header file. Once I have this, I can start with
frequency wavetables. The key point of frequency wavetables is the
filtering. I have to filter enough harmonics so the aliased
frequencies do not come back under 18KHz (audiable range). But I must
not filter too much if I don't want to get gain loss.
At the moment I managed to make a 3550 taps FIR to filter every octave
wavetables. Unfortunately, with complex harmonic rich waveforms, I
still have audiable aliasing from 2kHz and gain/amplitude difference
when wavetables cross.
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough.
According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when
filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.
You can have a look at the patch code but you won't be able to try it
if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.
Best,
Alex
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
 
 
 


--



r b-j                         ***@audioimagination.com



"Imagination is more important than knowledge."

 
 
 
 
Nigel Redmon
2018-06-29 16:40:19 UTC
Permalink
Hi Alexandre,

A couple of comments:

It looks like you’re saying that you’re taking the 256-sample wavetables, and want to create addition levels of bandlimited version fo them, but using time-domain filtering. It would be better to take and FFT, and manipulating the harmonics int he frequency domain. Because these are single-cycle waveform, manipulation in the frequency domain (e.g., zeroing out highs “bins”) will produce perfect results. That is, if you have a harmonic-rich wavetable from WaveEdit, and you want to make a version that can be transposed up an octave without aliasing, FFT the wave, zero out the upper half of the terms, iFFT back to a wavetable. Of course, you only need to convert it to the frequency domain ones, then make as many “filtered” copies of it as you want.

Note that 256 is a small wavetable. As pointed out in my articles, you can’t get both low frequencies and high harmonics with such a small table. A 256-sample sawtooth played at 40 Hz will sound dull (lowpass filtered).

Regards,

Nigel
Post by alexandre niger
Hello everyone,
I just joined the list in order to find help in making a wavetable synth. This synth would do both morphing and frequency wavetables. Morphing is a way to play different waveforms over time and so to get an additional sound dimension. Frequency wavetables are used to avoid aliasing by filtering harmonics the higher the frequency go. I started with the frequency wavetables and then I will do the morphing between different waveforms.
As an intern at Rebel Technology, I started making wavetables patches from earlevel articles. In those patches, common waveforms are generated inside the code (tri, square, saw). Now I want to generate some more complex waveforms from an editor called WaveEdit (free). They come as 256 samples single cycle .wav files. Then I change them into static data in a header file. Once I have this, I can start with frequency wavetables. The key point of frequency wavetables is the filtering. I have to filter enough harmonics so the aliased frequencies do not come back under 18KHz (audiable range). But I must not filter too much if I don't want to get gain loss.
At the moment I managed to make a 3550 taps FIR to filter every octave wavetables. Unfortunately, with complex harmonic rich waveforms, I still have audiable aliasing from 2kHz and gain/amplitude difference when wavetables cross.
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough. According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.
You can have a look at the patch code but you won't be able to try it if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.
Best,
Alex
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
Martin Klang
2018-07-01 12:00:10 UTC
Permalink
I recommended to Alex that he use the output from Andrew Belt's WaveEdit
after reading about it here (9 March 2018 "Wavetable File Formats").

I'm surprised it only outputs 256 sample waveforms. Does that not mean
that you can only go up to the 7th harmonic?


Martin
Post by Nigel Redmon
Hi Alexandre,
It looks like you’re saying that you’re taking the 256-sample
wavetables, and want to create addition levels of bandlimited version
fo them, but using time-domain filtering. It would be better to take
and FFT, and manipulating the harmonics int he frequency domain.
Because these are single-cycle waveform, manipulation in the frequency
domain (e.g., zeroing out highs “bins”) will produce perfect results.
That is, if you have a harmonic-rich wavetable from WaveEdit, and you
want to make a version that can be transposed up an octave without
aliasing, FFT the wave, zero out the upper half of the terms, iFFT
 back to a wavetable. Of course, you only need to convert it to the
frequency domain ones, then make as many “filtered” copies of it as
you want.
Note that 256 is a small wavetable. As pointed out in my articles, you
can’t get both low frequencies and high harmonics with such a small
table. A 256-sample sawtooth played at 40 Hz will sound dull (lowpass
filtered).
Regards,
Nigel
On Jun 29, 2018, at 7:19 AM, alexandre niger
Hello everyone,
I just joined the list in order to find help in making a wavetable
synth. This synth would do both morphing and frequency wavetables.
Morphing is a way to play different waveforms over time and so to get
an additional sound dimension. Frequency wavetables are used to avoid
aliasing by filtering harmonics the higher the frequency go. I
started with the frequency wavetables and then I will do the morphing
between different waveforms.
As an intern at Rebel Technology, I started making wavetables patches
from earlevel articles. In those patches, common waveforms are
generated inside the code (tri, square, saw). Now I want to generate
some more complex waveforms from an editor called WaveEdit (free).
They come as 256 samples single cycle .wav files. Then I change them
into static data in a header file. Once I have this, I can start with
frequency wavetables. The key point of frequency wavetables is the
filtering. I have to filter enough harmonics so the aliased
frequencies do not come back under 18KHz (audiable range). But I must
not filter too much if I don't want to get gain loss.
At the moment I managed to make a 3550 taps FIR to filter every
octave wavetables. Unfortunately, with complex harmonic rich
waveforms, I still have audiable aliasing from 2kHz and
gain/amplitude difference when wavetables cross.
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough.
According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when
filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.
You can have a look at the patch code but you won't be able to try it
if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.
Best,
Alex
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
_______________________________________________
dupswapdrop: music-dsp mailing list
https://lists.columbia.edu/mailman/listinfo/music-dsp
gm
2018-07-01 13:16:25 UTC
Permalink
7th octave, but 127th harmonic

harmonics are not octaves but multiples of the fundamental
Post by Martin Klang
I'm surprised it only outputs 256 sample waveforms. Does that not mean
that you can only go up to the 7th harmonic?
alexandre niger
2018-07-03 14:23:17 UTC
Permalink
Thank you for all the help. Gain loss was finally fixed after normalizing.
In an other hand, using fft and inverse effectively gave better results than FIR or IIR. With very rich signals, I can still hear an harmonic difference between WTs. I guess I could fix it by using more WTs than one every octave. I will try every 6 semitones.
Best,
Alex


De: "alexandre niger" <***@ensea.fr>
À: "music-dsp" <music-***@music.columbia.edu>
Envoyé: Vendredi 29 Juin 2018 16:17:47
Objet: [music-dsp] wavetable filtering


Hello everyone,

I just joined the list in order to find help in making a wavetable synth. This synth would do both morphing and frequency wavetables. Morphing is a way to play different waveforms over time and so to get an additional sound dimension. Frequency wavetables are used to avoid aliasing by filtering harmonics the higher the frequency go. I started with the frequency wavetables and then I will do the morphing between different waveforms.

As an intern at Rebel Technology, I started making wavetables patches from earlevel articles. In those patches, common waveforms are generated inside the code (tri, square, saw). Now I want to generate some more complex waveforms from an editor called WaveEdit (free). They come as 256 samples single cycle .wav files. Then I change them into static data in a header file. Once I have this, I can start with frequency wavetables. The key point of frequency wavetables is the filtering. I have to filter enough harmonics so the aliased frequencies do not come back under 18KHz (audiable range). But I must not filter too much if I don't want to get gain loss.

At the moment I managed to make a 3550 taps FIR to filter every octave wavetables. Unfortunately, with complex harmonic rich waveforms, I still have audiable aliasing from 2kHz and gain/amplitude difference when wavetables cross.
So now I am wondering:
About aliasing, should I cascade two FIR instead of increasing the taps?
That could be a solution if the stop band is not attenuated enough. According to octave fir1, stop band attenuation is 50dB to 70dB.
About gain loss, will "harmonic rich signal" always sound lower when filtered even if gain is the same?
I haven't normalize wavetables yet. I might have my answer afterwards.

You can have a look at the patch code but you won't be able to try it if you don't get Rebel Technology Owl files.
https://github.com/alexniger/OLWpatches-RebelTech/blob/master/WTExtWavePatch.hpp
All other links are in the readme.

Best,

Alex
robert bristow-johnson
2018-07-03 19:00:54 UTC
Permalink
Post by alexandre niger
Thank you for all the help. Gain loss was finally fixed after
normalizing.
In an other hand, using fft and inverse effectively gave better
results than FIR or IIR. With very rich signals, I can still hear an
harmonic difference between WTs. I guess I could fix it by using more
WTs than one every octave. I will try every 6 semitones.
other times this topic has come up, i have said exactly that. if your
sample rate is 48 kHz and you're willing to settle for a top bandwidth
of 19.8 kHz, (so with a fixed LPF you are gonna kill anything that
survives between 19.9 and 24 kHz, two wavetables per octave will do it.
so at the bottle of the 6 semitone split, your wavetable will have
harmonics up to 19 kHz, as you increase the pitch to 6 semitones higher
(that's a frequency ratio of sqrt(2)), that 19.8 kHz becomes 28.1 kHz,
which folds over (reflects about 24 kHz) to 19.9 kHz. that's your worst
case. so just blow away everything above 19.8 kHz with a single fixed
and sharp LPF. but since memory is cheap, there should be no reason you
can't go to 3 wavetables per octave. or not even an integer. say one
wavetable for every 5 semitones. no reason you can't do that either.

with 96 kHz sample rate, it's much less of a problem regarding aliasing
above 24 kHz and you can relax your specs with that LPF and the number
of wavetables per octave.

i would suggest mixing or crossfading from the wavetable that is richer
in harmonics to the wavetable missing a few as your note slides up and
down the keyboard. like if you have a wavetable at every C and every
F#, when the note is F, it should be 1/6 scaling the wavetable at C and
5/6 scaling the wavetable at F#. when the note is an A, it should be
1/2 of the wavetable at the F# below and 1/2 of the wavetable at C above.
--
r b-j ***@audioimagination.com

"Imagination is more important than knowledge."
Loading...