Wavetable creation
-
@DanSound I thought about concatenating the 4 audio files into one then using the
setSampleRange()function.That might might allow for instant switching between them, but the pause still exists. I think because even though the whole file is loaded, it still does the recalculations when you change the range.
Engine.loadAudioFilesIntoPool(); const wt = Synth.getAudioSampleProcessor("Wavetable Synthesiser1"); const wc = Synth.getWavetableController("Wavetable Synthesiser1"); wt.setFile("{PROJECT_FOLDER}" + "wavetable1234.wav"); // concatenated audio files const length = 524288; // length of each audio file section of the long file inline function loadWavetable(component, value) { local start = component.get("id").split("n")[1]; // 1-4 start = (parseInt(start) - 1) * length; local end = start + length; Console.print(start); // multiples of 524288 wt.setSampleRange(start, end); } for (b in Content.getAllComponents("Button")) b.setControlCallback(loadWavetable); -
@DanSound The next attempt actually worked!
I load the concatenated file into the wavetable synth then change the LFO range according to which section of the wavetable you want to play. I set the LFO to 25%, so with the offset it goes from 0%-25%, 25%-50% 50%-75% and 75%-100%.
Weirdly I had to use the Table Index Bipolar mod source with an LFO set to unipolar. But it works.
Video here: https://share.cleanshot.com/SZHZH3Lp
Updated project ZIP: https://wmd.d.pr/f/iVTorn
So this is how we can use audio files as wavetables and allow instant switching between them - with no need to build wavetables beforehand
Caveats: the plugin init will take longer because itβs doing calculations on the long concatenated file, and as you might notice in the video the waterfall flickers on a couple of the join points. Might just need to tweak the concatenated file.
const ws = Synth.getChildSynth("Wavetable Synthesiser1"); inline function loadWavetable(component, value) { local start = component.get("id").split("n")[1]; // 1-4 start = (parseInt(start) - 1) * 0.25; // 0%, 25%, 50%, 75% ws.setAttribute(6, start); } for (b in Content.getAllComponents("Button")) b.setControlCallback(loadWavetable); -
@DanSound @Lindon I just found the recent
saveAsHwt(). Makes creating HWT files trivial now.
Just drop an audio file into a Wavetable Synthesiser, then run this code to save a precomputed HWT file.
const wc = Synth.getWavetableController("Wavetable Synthesiser1"); const dir = FileSystem.getFolder(FileSystem.AudioFiles); const out = dir.getChildFile("MyWavetable.hwt"); wc.saveAsHwt(out);For simple wavetables, this seems like the way to go, rather than the whole wavetable creator popup thing.
This totally removes any lag or pause from loading since the HWT is precomputed.
Video here: https://share.cleanshot.com/tD1qGCsv
-
@Lindon said in Wavetable creation:
how does the wavetable player know we are using (say) 2048 samples as our cycle size and not (say) 1024 ???
Short answer: it's clever.
Longer answer: it guesses the cycle length based on the correlation of slices. It starts at 128 then goes up in powers of 2 to 2048. If it finds a very high correlation in the slices at any one of those slice lengths, it returns that as the cycle length.
I suppose this only works on files that morph fairly slowly between waveforms. If your file has a cycle length of 2048 but each cycle is very different to the next, it won't find a suitable cycle length and will fall back to resynthesis.
Also, if your file happens to have Loop Range metadata, it will use that first, before any guessing or resynthesis.
-
@dannytaurus Do you know whether the mode used is resynthesis or resample?? Coz I tried the drag and drop thing, and the resulting wavetables did not sound great. Not as good as the ones I made in the resample mode inside Wavetable Creator.
-
@Orvillain Looks like the full Wavetable Creator tries to find a cycle length from the root-note, but since the dropping an audio file into a wavetable synth doesn't have a root note it does it differently.
Audio files uses [1] metadata Loop Range, then [2] guess cycle range from correlation, then finally [3] resynthesis.
For simple 'traditional' wavetables, the audio file route is probably fine but for more complex ones the full Wavetable C reactor might be better, yeah.
The only reason I went down this whole route of using audio files is because I opened the Wavetable Creator and thought 'Nope!'
. So when I saw using audio files would work for my use case I wanted to learn how to do that. -
@dannytaurus said in Wavetable creation:
I suppose this only works on files that morph fairly slowly between waveforms. If your file has a cycle length of 2048 but each cycle is very different to the next, it won't find a suitable cycle length and will fall back to resynthesis.
This is a bummer.....as I wanted to let the user drop in any wave file they liked, and including one that has no morphing between distinct 2048 long cycles.....
damn, Ok I feel a feature request coming on - a param that tells the wavetable player what the length is of cycles in the current loaded wav file..... how hard can this be?
-
@Lindon How would you make sure the user's file has a cycle length of 2048?
-
@dannytaurus oh I wouldnt ... I would have a param that the user can select from :
512
1024
2048- so if they build their own wavetable wav file they would know it needs to be one of these values...
and the UI would have a combo box allowing them to define the value they are using..
so the script call back would then include this new call:
WavetableController.setCycleLength(value)
- so if they build their own wavetable wav file they would know it needs to be one of these values...
-
@Lindon whilst we are here....
what tool is everyone using to generate morphing wave files ?
so you have wav1 -> wav2 ->wav3 and you want to generate a bunch of morphs between these?
-
@Lindon said in Wavetable creation:
- so if they build their own wavetable wav file they would know it needs to be one of these values...
If they're building their own wavetables, just have them put Loop Range metadata in the file that sets the cycle length.
Then they won't need to choose it from a dropdown.
It makes their wavetables more portable too.