From the original SynthMaker forum (2004–2014), with its members’ names and dates.
JIftw ·
Hi !
I'm trying to work on the wave player module.
It already has a simple interpolated read which works fine when I play a wave at a lower rate than the host's sample rate.
My problem is when playing a wave at a higher rate. Aliasing obviously occurs.
The read component is given indexes that 'skip' to achieve high pitch/speed playback, but this is a form of decimation (downsampling) which, sadly, is not preceded by proper low-pass filtering.
If the wave was to be played at a fixed speed, I would merely filter it 'offline'; modify my .wav permanently. But for a synth, the playback speed is variable, therefore the rational decimation factor is too. This is why the lowpass filter needs to be in the synth, before making a poly from the wave (wave read).
Is it possible in SM to take a wav file, generate from it a bunch of prefiltered wavs with various cutoffs, and then the wave read will choose the proper one based on playback rate ?
Perhaps wave tables would be a solution (I'm not sure I understand the concept), but they are limited to 256 samples length, and I have samples that last up to 53 seconds... 😕
Thanks
MegaHurtz ·
It`s not supposed to create aliasses.. But if they do occur the problem is in the way you alter the ramp for pitch.
JIftw ·
It`s not supposed to create aliasses
How come ?
I think all downsampling will alias if it is not preceded by lowpass (unless the original wav doesn't have frequencies above the new nyquist.)
The problem is that in the waveplayer, to play a wav faster/higher, it skips samples
(which is similar to a crude downsampling followed by playing at original sample rate)
example: to play at pitch and speed x 2,
it plays 1 sample , skips the next, repeat
So it aliases because there is no lowpass before the actual waveread !
MegaHurtz ·
there is no time to put anything inbetween. also filters will create aliassing by creating curved ramps.
these need to be straight or mathematicly accurate.
JIftw ·
there is no time to put anything inbetween
Right. I really can't see how it would be possible.
Then, perhaps an oversampled waveplayer ?!
Making it read its samples, and intermediate positions in parallel.
Then filter this.
For every 2x increase in oversampling, it would allow one higher octave without aliasing.
I might try that... tough I worry about CPU usage
Thanks
mHz ·
yes.. but the downsampling will be problematic. and youll end up with the phase distortion,
you wouldnt have had when you yust ran an interpolated version at higher samplerate 😉
rl ·
JIftw wrote: ...
Is it possible in SM to take a wav file, generate from it a bunch of prefiltered wavs with various cutoffs, and then the wave read will choose the proper one based on playback rate ?
Why would you need various cutoffs? I think a single cutoff at half the samplerate should do it. Or maybe I'm misunderstanding.
You could also try to replace the linear interpolation of the default waveplayer with a more sophisticated one (cubic, spline, ...)
I found this an interesting lecture:
http://ldesoras.free.fr/doc/articles/resampler-en.pdf
He's using a FIR filter for interpolation, which is IMHO a bit too computational expensive.
mHz ·
Instantly mentioned the 3rd order hermite there 🙂
JIftw ·
You could also try to replace the linear interpolation of the default waveplayer with a more sophisticated one (cubic, spline, ...)
Not a thorough solution in itself: the aliasing is caused by samples being skipped (to play faster/higher pitch) earlier in the chain, in the waveread primitive.
I've done an 2x oversampled version of the waveplayer.
I've noticed a significant decrease in aliasing.
I'm currently in the process of trying to eliminate a slight phasing artifact which only shows up if:
the sample is looped AND Input frequency approaches half-sampling rate (irrevelant for typical MIDI applications).
I might post the module in the example/wiki section when finished if anyone wants it.
(But I'll ask for help to optimize it 😈 😀 )
JIftw ·
YATTA !!! 😀
Ahem... Mission accomplished. 😇
No more artifacts when looping at high rates.
EDIT: Uploaded to this thread 2xOversampled WavePlayer
Wrote something here? To have a post removed or your name hidden, write to [email protected].