Skip to content

Creating wavetables for Surge

EvilDragon edited this page Jun 8, 2022 · 1 revision

PREVIOUSLY IN THIS SERIES: Overview of wavetables in Surge
NEXT IN THIS SERIES: Creating wavetables with WaveEdit


There are many ways to create Wavetables for Surge. This Wiki will outline some free and open source solutions, and link to information about some closed source options as well.

The Surge team provides a number of tools to aid in creating Wavetables, written by contributor @baconpaul:

  • add-surge-metadata.py
  • wt-tool.py
  • generated.py
  • normalize-i16-to-i15.py

Currently these tools require running Python3 from the command line. If you don't know what Python is and you have never used the command line - FEAR NOT, it's not that hard, and can be really fun. In the following section of this document you'll find instructions for beginners.

The awesome open source tool WaveEdit can be used alongside the Python tools to create Wavetables for Surge using a graphical interface. You'll still need to use the command line a bit so you can reference sections of this page as needed. The WaveEdit For Surge Guide is here.

Contents

Setting Up Bash
Installing Python3 And Other Tools
Downloading the tools
Getting Files Ready
Using wt-tool.py
Using add-surge-metadata.py and normalize-i16-to-i15.py
Other Ways To Make Wavetables

Setting Up Bash

This guide covers using Python3 from a "Bash shell" which is a text based environment for interacting with files and running commands on your computer. This is a great article on getting started with Bash:

Basics of Bash for Beginners

MacOS and Linux users already have built-in ways of running Bash. If you understand what "ls" "~/" and "cd" mean, you should be ready to move on. Fire up "Terminal" (for Mac OS) or whatever terminal emulator you have around on Linux and read the next section. For Windows users read on here.....

The article above covers an easy way to install a Bash command line in Windows.... but in this case, I would personally suggest this guide for Cygwin, as it gives an easy way to install other tools you will need. When you get to the part of the above guide that mentions "Selecting Packages" install python3, sox and espeak. If you already finished the installer and forgot to install those just re-run the Cygwin setup_x86 or setup_x86_64 file.

Installing Python3 And Other Tools

Now that you are in Bash you'll need to install some command line tools in order to follow all the instructions listed here. Three applications to be clear: python3, sox and espeak.
NOTE: You only need to install Python3 in order to use the Python Wavetable tools. SoX and espeak are used in some examples coming up (and are both generally useful and lite-weight packages)

Linux
As a Linux user, you will already have a way to install packages from the command line. If you are on Ubuntu or another Debian based distro, you would install those programs with the following command:

sudo apt-get install python3 sox espeak

You likely already have Python3 installed if you are running Linux, but the above command will ensure you have it. After they are installed move on....

MacOS
The easiest way to install command line applications in MacOS is to first install Homebrew. To install just open the "Terminal" application and paste this into the command line:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"   

This will install Xcode command line tools as well as Homebrew.

Once Homebrew is installed, you can install applications from the command line using the "brew" command. The following command will install the tools needed for this guide:

brew install python3 sox espeak

Windows
If you followed the instructions above on installing Cygwin and adding the extra packages, you will already have everything you need.

Downloading the tools

Assuming you have all the necessary command line applications installed, it's time to download the Surge team Wavetable tools!

Recommended for this guide:
For the purposes of these tutorials, I'd recommend these commands to download all the files from the command line:

Create a folder called Scripts in your User folder, and moves to it:

mkdir ~/Scripts/ && cd ~/Scripts/  

Download the contents of the folder to your current location:

svn checkout https://github.com/surge-synthesizer/surge/trunk/scripts/wt-tool   

Move all of the tools directly into the Scripts folder and remove the wt-tool folder:

cp ./wt-tool/* ./ && sudo rm -r wt-tool  

Now you should be in the ~/Scripts folder with all the scripts downloaded. You can move on.

Download tools manually:
If for some reason you'd like to download the tools manually one at a time:
https://github.com/surge-synthesizer/surge/tree/master/scripts/
Click on the script you'd like to download and in the next page Right click on "Raw"......
Select "Save link as" to the location of your choice.

Advanced Users:
If you are familiar with Github and have downloaded Surge's source code or cloned the Surge repository, you will find all these tools downloaded to the "Scripts" folder. If you create a "Scripts" folder as shown above, it will make it easier to follow along with the examples exactly as written. You can of course replace "~/Scripts" with your scripts location in any of the examples.

Getting Files Ready

  • wt-tool.py can take a list of single cycle waveforms and turn them into one ".wt" file.
  • add-surge-metadata.py can take some waveforms already joined together in a file and tag them as a Wavetable.

With both methods the waveforms should have a power-of-2 sample length (for instance 64, 128, 512, 1024 .....) and should all be the same length. If you don't obey these conventions, your wavetable won't work as expected.

Here are some free single cycle waveforms from Adventure Kid that have been resized to power-of-2 sample lengths for use in creating Surge Wavetables: (right click and save link as...)
AKWF-1024.zip (upscaled)
AKWF-512.zip (downscaled)
AKWF-64.zip (very downscaled Lofi)

Download and unzip the waveforms and choose a couple you think are interesting. Use whatever length you want, but remember all the cycles of your Wavetable need to be the same length! wt-tool will not resize them!!!

You can test out how a single cycle waveform sounds using the incredibly useful open-source sample editor Audacity. Open a single cycle waveform and press "shift+spacebar" to initiate loop playback; this will repeat the file over and over, allowing you to hear the pitch and timbre of the waveform. (press spacebar to stop)

Once you have selected two or more waveforms you'd like to turn into a Wavetable, you can move on.....

Advanced Users:
If you have a single cycle waveform that is NOT a power of 2 count and you'd like to use it, you can use the following process:

First divide the size of your single cycle waveform by the size you'd like to convert to. Say we want to convert one of the original Adventure Kid waveforms to something Surge can work with. Adventure Kid waveforms are 600 samples. But let's pretend we don't know that.

The following command will let you know sample lengths for all files in a directory:

soxi *wav

That should give you some output like this:

Input File     : 'AKWF_0002.wav'
Channels       : 1
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:00:00.01 = 600 samples = 1.02041 CDDA sectors
File Size      : 1.34k
Bit Rate       : 790k
Sample Encoding: 16-bit Signed Integer PCM

We can see now that it's 600 samples!
If we to go larger to 1024, we would make the following calculation:
600 / 1024 = 0.5859
0.5859 is the number we will want to use as the "speed" multiplier in SoX.

NOTE:
In this case we could round off to 0.586 and be fine. When going from larger to much smaller sample sizes, you may need to round off MORE to get the expected results, for instance:
600 / 64 = 9.375
but you will need to give SoX a speed value of 9.4 to get a 64 sample waveform out of this.

The following command will change the wavetable:

sox ./"file to convert" ./"new file name" speed 0.5859  

Adventure Kid waveforms are 16bit files normalized to 0db. If you are changing the speed of a 16-bit waveform like this it will probably clip in Sox during conversion; it will also likely clip when loaded into Surge. We probably don't want to hard clip so we may as well apply attenuation while we are using SoX since its a simple command. wt-tool.py also offers normalisation so this is at your discretion.

The following SoX command will safely attenuate a 16-bit normalized file:

sox ./"file to convert".wav ./"new file name".wav speed 0.5859 gain -6.4

REMEMBER:
If you are aiming to use wt-tool.py it ONLY works with 16-bit wavs so you may need to convert a 24 or 32 bit file to 16 bit. SoX does this effortlessly as well and will automatically dither. Add the "-b 16" option to the SoX command.

sox ./"file to convert" -b 16 ./"new file name" speed 0.5859 gain -6.4

Making Sure Waveforms Are In The Same Folder

For "wt-tool.py" we want all our waveforms to be in the same folder!
Let's take the Waveforms you chose from above and put them in a folder together. Make sure to name them in the order you'd like them to appear. If you want to use a file explorer that will work:

If you'd like to use the command line, something like this will do:

mkdir myWT
cp ./"your old table name".wav ./myWT/sample01.wav
cp ./"your other table name".wav ./myWT/sample02.wav

Using wt-tool.py

Now we can actually use wt-tool!! Assuming you've followed all the instructions so far, the command is:

python3 ~/Scripts/wt-tool.py -a create -d ./myWT/ -f myNewTable.wt

This command will string together every wavetable in the folder myWT. You should get some output like this:

$ python3 ~/Scripts/wt-tool.py -a create -d ./myWT/ -f myNewTable.wt
Creating 'myNewTable.wt' with 2 tables of length 1024
Not applying any normalization

NOTES ON THE COMMAND:

  • The ""-a create" options tells wt-tool.py to create a Wavetable.
  • "-d ./myWT/" tells wt-tool.py to use wav's in that folder.
  • "-f meNewTable.wt" tells wt-tool.py to create a table called meNewTable.wt
  • "-n half" will normalize a 16 bit file so it doesn't clip in Surge. This is optional, but you'll want to do it if your files contain material louder than -6.0db. (the Adventure Kid waveforms available here are already normalized.)

You should now have a working Wavetable!
You can drag and drop this Wavetable file onto Surge's Wavetable oscillator or place it in your "User Data Folder".

Using add-surge-metadata.py and normalize-i16-to-i15.py

Say instead of making a wt file with wt-tool file, you'd like to just combine the single cycle waveforms ourselves and tag them as a Wavetable. This would be especially useful if we have 32-bit waveforms because wt-tool.py doesn't work with them.

If you want you could use a waveform editor like Audacity to combine two wav files into one file:

  • in this example I am "selecting" a clip by double clicking on it
  • a yellow line will show up when you hover by the edge of a clip, click here and paste the second waveform in.

Having a visual tool like Audacity is nice, but in this case it might be easiest to use SoX from the command line since we are already here. SoX will just keep taking inputs and combine them into one file (named by the last name in the list).

I'm going to continue using the renamed Adventure Kid waveforms from the last example, from the previous "wt-tool" section,

you'd use a SoX command like this:

sox ./myWT/sample01.wav ./myWT/sample02.wav myWavetable.wav

IMPORTANT:
If we are using a 16-bit wavetable, and it hasn't been attenuated (reduced in level) yet, it will probably clip when loaded in Surge. To prevent clipping you can run normalize-i16-to-i15.py to normalize to a safe level. This is the same code found inside wt-tool.py. (if using wt-tool.py just add the option -n half)

python3 ~/Scripts/normalize-i16-to-i15.py -n half myWavetable.wav myWavetableNorm.wav

Tag the Wavetable!
Now that you have a nice, formatted WAV file.....
You can tag the WAV file as a Surge Wavetable like so:

python ~/Scripts/add-surge-metadata.py -s "cycle length in samples" -i "file to tag".wav
  • the -s option is for the length in samples of the waveforms
  • -i option means add to the file in place.

Using our continuing example, that would look like this:

python3 ~/Scripts/add-surge-metadata.py -s 1024 -i myWavetable.wav

You should now get output like this, which explains a bit about the Wavetable you created:

['myWavetable.wav']
{'samples': '1024', 'out': None, 'inplace': True}
Input    :  myWavetable.wav
Size     :  1024
Update in place

Now your WAV wavetable should be ready to use in Surge!

Using other tools to create wavetables for Surge

List of things which may appear here later:

  • Creating Surge Wavetables With Audioterm will go here.
  • Bash scripts will go here.
  • Resizing Serum wavetables will go here.