#3882 Mathematica Manipulation of Oscillator Waves
#3882 Mathematica Manipulation of Oscillator Waves
#3882 Describe the various ways Mathematica could be used to shape the oscillator waves for a synth
Mathematica (Wolfram Language) is exceptionally powerful for sound synthesis because it treats audio not just as a "stream of sound," but as computable mathematical functions.
Here are the primary ways you can use Mathematica to shape oscillator waves, moving from basic math to complex data export.
1. Additive Synthesis (Harmonic Construction)
The most fundamental way to shape a wave in Mathematica is by summing sine waves. You can visualize and listen to how adding harmonics changes the waveform from a pure tone to a complex shape (like a square or sawtooth approximation).
The Math: You sum a fundamental frequency $f$ with integer multiples (harmonics).
Wolfram Approach: Use
SumorTableto define the harmonic series.
(* Create a Square Wave approximation using odd harmonics *)
harmonics = 20;
freq = 220; (* Hz *)
wave[t_] := Sum[Sin[2 Pi (2 n - 1) freq t] / (2 n - 1), {n, 1, harmonics}];
(* Visualize it *)
Plot[wave[t], {t, 0, 0.01}]
(* Hear it *)
Play[wave[t], {t, 0, 1}]
2. Non-Linear Waveshaping (Distortion Functions)
This is where Mathematica shines. You can feed a standard wave (like a Sine) into a non-linear transfer function to "bend" the shape. This simulates analog distortion or saturation.
Sigmoid/Tanh Shaping: Simulates "tube" saturation or soft clipping.
f(t) = \tanh(A \cdot \sin(\omega t))Chebyshev Polynomials: Used to manipulate specific harmonics without affecting others.
(* Hard clipping/shaping a sine wave *)
drive = 5;
shapedWave[t_] := Tanh[drive * Sin[2 Pi 220 t]];
Play[shapedWave[t], {t, 0, 1}]
3. Frequency Modulation (FM) & Phase Modulation
You can easily prototype FM synthesis algorithms by nesting functions. Because Mathematica handles symbolic math, you can experiment with complex modulation ratios that would be tedious to dial in on hardware.
The Math: The frequency of the carrier wave is modulated by the amplitude of a modulator wave.
y(t) = A \sin(2\pi f_c t + I \sin(2\pi f_m t))
carrier = 440;
modulator = 110;
index = 5; (* Modulation index *)
fmWave[t_] := Sin[2 Pi carrier t + index * Sin[2 Pi modulator t]];
Play[fmWave[t], {t, 0, 2}]
4. Generating Wavetables for Hardware/Software Synths
If you are building a digital synth or coding a VST, you rarely generate math in real-time; you use a Wavetable. Mathematica allows you to calculate a single cycle of a highly complex wave and export it as a list of values (CSV) or a .wav file to load into synths like Serum, Pigments, or an Arduino/Daisy microcontroller.
Process: Generate a list of numerical values for exactly one cycle of the wave, then normalize them between -1.0 and 1.0.
(* Generate one cycle of a complex function *)
sampleRate = 44100;
freq = 44100/2048; (* To fit exactly 2048 samples *)
data = Table[N[Sin[2 Pi freq t] + 0.5*Sin[2 Pi 2 freq t]], {t, 0, 1/freq, 1/sampleRate}];
(* Export to CSV for coding or WAV for samplers *)
Export["wavetable.csv", data]
Export["wavetable.wav", Audio[data, SampleRate -> 44100]]
5. Chaotic and Exotic Functions
You can use Mathematica to generate noise and textures that do not exist in standard oscillators by utilizing chaotic attractors or fractal math.
Logistic Map: Can create "noise" that has a pitch.
Random Walk / Brownian Noise: Good for control voltages (LFOs).
(* Using a chaotic function for noise generation *)
data = NestList[4 # (1 - #) &, 0.1, 44100]; (* Logistic Map *)
Audio[data, SampleRate -> 44100]
Summary Table of Mathematica Audio Functions
| Function | Purpose | Application |
Play[f[t], {t, 0, d}] | Quick audio preview | Testing math concepts audibly. |
AudioGenerator[type] | Built-in primitives | Generating standard Sine, Square, Noise. |
Audio[data] | Convert list to sound | Creating wavetables from raw data arrays. |
Export["file.wav", obj] | Save file | Moving your wave to a DAW or hardware sampler. |
Next Step
Would you like me to write a script that generates a Wavetable bank (a series of evolving waves) based on a specific formula, which you could then export as a .wav file?
Yes
Here is a Mathematica script designed to create a Wavetable Bank suitable for modern synthesizers like Serum, Vital, or Pigments.
This script generates a sequence of 64 frames (individual single-cycle waves). As the bank progresses, the waveform morphs from a pure Sine wave into a complex, rich FM-style wave.
The Script: Morphing Phase Distortion
We will use Phase Modulation for this example. We start with a Sine wave and progressively add a second Sine wave inside the phase of the first. This mimics the "FM Amount" knob turning up on a synth.
Copy and paste this into a Mathematica notebook:
(* 1. CONFIGURATION *)
sampleRate = 44100;
frameSize = 2048; (* Standard frame size for Serum/Vital *)
numFrames = 64; (* Number of slots in the wavetable *)
(* 2. THE MORPH FORMULA *)
(* t is time (0 to 1), m is the morph amount (0 to 1) *)
(* As m increases, the wave gets more "gnarly" *)
waveFunction[t_, m_] := Sin[2 Pi t + (m * 3.0) * Sin[2 Pi t]];
(* 3. GENERATE THE DATA *)
(* We create a list of lists, then flatten it into one long audio stream *)
wavetableData = Table[
(* Calculate the 'morph' amount for this specific frame *)
morphAmount = frameIndex / (numFrames - 1.0);
(* Generate one single cycle (one frame) *)
Table[
waveFunction[i/frameSize, morphAmount],
{i, 0, frameSize - 1}
],
{frameIndex, 0, numFrames - 1}
];
(* Flatten the table into a single stream of samples *)
audioStream = Flatten[wavetableData];
(* 4. NORMALIZE *)
(* Ensure the audio peaks at -0.1 dB so it doesn't clip *)
maxVal = Max[Abs[audioStream]];
normalizedStream = audioStream / maxVal * 0.99;
(* 5. EXPORT *)
(* Create the audio object *)
audioObj = Audio[normalizedStream, SampleRate -> sampleRate];
(* Export to .wav file in your Documents folder (or change path) *)
exportPath = FileNameJoin[{$UserDocumentsDirectory, "MorphingFM_Wavetable.wav"}];
Export[exportPath, audioObj]
(* 6. VISUALIZE (Optional) *)
(* Show the first, middle, and last frame to verify the morph *)
ListLinePlot[{
wavetableData[[1]],
wavetableData[[32]],
wavetableData[[64]]
}, PlotLabel -> "First, Middle, and Last Frames"]
How to use this file
Run the code: It will save
MorphingFM_Wavetable.wavto your Documents folder.Importing to Serum/Vital:
Open the Wavetable Editor in your synth.
Drag and drop this
.wavfile onto the editor.Select "Import: 2048 samples (samples)" or "Import as Wavetable" if prompted.
The Result: You will see a 3D terrain of waves. As you turn the "Wavetable Position" (WT Pos) knob, the sound will smoothly sweep from a dull hum to a bright, metallic buzz.
Why 2048 Samples?
Most modern wavetable synths (Serum, Vital, Ableton Wavetable) prefer a frame size of 2048 samples. If the math calculates exactly 2048 points for one cycle, the synth knows exactly where to "slice" the file to create the separate frames without you having to manually edit loop points.
Next Step
Would you like me to modify this script to use Additive Synthesis instead (specifically controlling the volume of odd vs. even harmonics) to create a "Vintage Organ to Square Wave" morph?
From <https://gemini.google.com/app/> Google Gemini 3.0 Pro (Thinking)

Comments
Post a Comment