No video

How to turn any mathematical function into a wavetable (for wavetable synthesizers)

  Рет қаралды 162

aquanodemusic

aquanodemusic

Күн бұрын

In this video I show how I wrote a little code that evaluates any 1d or 2d function f(t,x) in such a way that the output is stored as an audio file ready to be imported into wavetable synthesizers (Vital in this case) as sound source.
Here is the code, feel free to copy it and replace y in the function f(t,x) by whatever function you want to sonify:
Make a .wav wavetable out of a 2d function evaluation
Open a folder to let the code know where to store the file
importing necessary packages
from numpy import abs, min, max, sin, pi, array, int16 # Basic mathematical operations
import scipy.io.wavfile as wv # Save the result as a .wav file
define your wavetable function (some sine function by default)
def f(t, x):
'''
Example 2d function: sine wave oscillation
t: vector of time points
x: vector of space points (constant over time)
'''
freq = 20
y = sin(pi*x)**2 * sin(2*pi* (freq (t-t_range[0])/(t_range[1]-t_range[0]))*x) sin(2*pi*t)
return y
evaluate the wavetable function
def evaluate(f,timerange,timesteps,spacerange,spacesteps):
'''
evaluate a 2d function
f: 2d function with t and x input vectors
timerange: start and end points of time evaluation
timesteps: total amount of time steps inbetween the timerange points
spacerange: start and end points of space evaluation
spacesteps: total amount of space steps inbetween the spacerange points
'''
timestep = ( timerange[1] - timerange[0]) / timesteps
spacestep = (spacerange[1] - spacerange[0]) / spacesteps
t_grid = [ timerange[0] + i*timestep for i in range(timesteps)]
x_grid = [spacerange[0] + i*spacestep for i in range(spacesteps)]
y = [[f(t, x) for x in x_grid] for t in t_grid]
return t_grid, x_grid, y
generate the audio file
def generate_wav(t_values,y_values,framerate,name):
u_values_array = array(y_values)
audio_data = []
for t in range(len(t_values)):
frame_data = u_values_array[t, :]
audio_data.extend(frame_data)
audio_data = array(audio_data)
16 bit integer wav audio files can store values from -32768 to 32767
audio_data_normalized = int16(audio_data / max(abs(audio_data)) * 32767)
name += '.wav'
wv.write(name, framerate, audio_data_normalized)
Specify the shape of the result
t_range = [0, 0.5] # start and end value of time evaluation
x_range = [0, 1] # start and end value of space evaluation
frames_amount = 256 # how many frames the wavetable should consist of
dots_per_frame = 2048 # datapoints per frame (2048 points per frame is common)
framerate = 44100 # file resolution in kHz
name = 'Wavetable'
Generate the wavetable output
t_values, x_values, y_values = evaluate(f,t_range,frames_amount,x_range,dots_per_frame)
generate_wav(t_values,y_values,framerate,name)
importing optional packages
from numpy import meshgrid # for plotting
import matplotlib.pyplot as plt # Visualize the result
import matplotlib.animation as anim # Make an animation of the result
Plot equidistant slices of the result in 3D
def plot_slices(t_values, x_values, y_values, num_slices=5):
'''
Plot 5 equidistant slices of the result in 3D
t_values: evaluated time values
x_values: evaluated space values
y_values: evaluated function values
num_slices: number of slices to plot
'''
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
slice_indices = [int(i * len(t_values) / num_slices) for i in range(num_slices)]
for i, slice_idx in enumerate(slice_indices):
x = x_values
y = y_values[slice_idx]
z = [t_values[slice_idx]] * len(x_values)
ax.plot(x, z, y, label=f'Slice at t = {t_values[slice_idx]:.3f}')
ax.set_xlabel('Space')
ax.set_ylabel('Time')
ax.set_zlabel('Amplitude')
ax.view_init(elev=30, azim=30)
plt.legend()
plt.show()
plot the result as an animation
def animate(t_range, t_values, x_values, f_values, frames_amount):
fig, ax = plt.subplots()
line, = ax.plot(x_values, [0 for _ in range(len((x_values)))])
use min and max of space and function to have the function always centered
ax.set_xlim(min(x_values) - 0.1, max(x_values) + 0.1)
ax.set_ylim(min(f_values) - 0.1, max(f_values) + 0.1)
time_text = ax.text(0.02, 0.95, '', transform=ax.transAxes)
frame update
def update(t):
y_values = f_values[t]
line.set_ydata(y_values)
current_time = t_values[t]
time_text.set_text(f'Time: {current_time:.2f} s')
return line, time_text
duration = (t_range[1] - t_range[0]) / frames_amount * 1000
ani = anim.FuncAnimation(fig, update, frames=len(t_values),interval=duration)
plt.show()
plot_surface(t_values, x_values, y_values)
plot_slices(t_values, x_values, y_values)
animate(t_range, t_values, x_values, y_values, frames_amount)

Пікірлер
Everything Starts with a Note-taking System
21:23
Mischa van den Burg
Рет қаралды 237 М.
Parenting hacks and gadgets against mosquitoes 🦟👶
00:21
Let's GLOW!
Рет қаралды 12 МЛН
A little girl was shy at her first ballet lesson #shorts
00:35
Fabiosa Animated
Рет қаралды 21 МЛН
Little brothers couldn't stay calm when they noticed a bin lorry #shorts
00:32
Fabiosa Best Lifehacks
Рет қаралды 17 МЛН
Think Fast, Talk Smart: Communication Techniques
58:20
Stanford Graduate School of Business
Рет қаралды 39 МЛН
Controlling Light Using Holograms And Photographic Film
21:58
The Thought Emporium
Рет қаралды 208 М.
Aquanode Soundscapes - Free Preset Pack for Vital
13:51
aquanodemusic
Рет қаралды 101
How to make music like Carbon Based Lifeforms
9:16
aquanodemusic
Рет қаралды 348
Harder Drive: Hard drives we didn't want or need
36:47
suckerpinch
Рет қаралды 1,6 МЛН
ableton microtones wolfram mathematica
1:59
mikey
Рет қаралды 186
All About Automation/Envelopes in Reaper
26:41
Aarrow Audio
Рет қаралды 525