Skip to content

Instantly share code, notes, and snippets.

@garcia
Last active April 17, 2018 03:35
Show Gist options
  • Save garcia/ad2dff9ffd33a8a6800f1ff00d28ce98 to your computer and use it in GitHub Desktop.
Save garcia/ad2dff9ffd33a8a6800f1ff00d28ce98 to your computer and use it in GitHub Desktop.

serumfrequencies.py

This script identifies the base position and Note modulation amount for a frequency knob to match the Note source in Xfer Records's Serum VST, allowing for creative use of tonal filters.

The default values for freq_max and freq_mid correspond to the Filter cutoff (the one in the OSC tab, not the FX module). They can be changed to find the values for other frequency knobs in Serum by identifying their maximum frequency (just crank the knob all the way up) and the exact midpoint frequency (assign the MIDI input value to 0.5 in your host, then click without dragging the knob). The script needs the midpoint frequency instead of the minimum frequency because the minimum (e.g. 8 Hz) isn't precise enough for this task.

Assign the two printed values to the frequency knob and the Note modulation amount for that knob, respectively, in your host application, then tweak the tuning frequency to account for imprecision in the base frequency. (You don't have to use your ears - play an A4, then click without dragging the frequency knob and observe the parenthesized frequency. Adjust the tuning away from 440 in the opposite direction of the frequency bias.)

Unfortunately, if you want to use the non-noise oscillators, you'll have to change their fine tuning to compensate for the tuning frequency.

from math import exp, log
freq_max = 22050
freq_mid = 425
freq_min = exp(log(freq_mid) - (log(freq_max) - log(freq_mid)))
freq_log_range = log(freq_max) - log(freq_min)
def shift_semitones(freq, semitones):
return freq * 2**(semitones/12)
note_a4 = 440
note_c0 = shift_semitones(note_a4, -12*5 + 3)
note_g10 = shift_semitones(note_a4, 12*6 - 2)
note_c0_position = (log(note_c0) - log(freq_min)) / freq_log_range
note_g10_position = (log(note_g10) - log(freq_min)) / freq_log_range
note_range = note_g10_position - note_c0_position
note_range_for_matrix_depth = (note_range + 1) / 2
print(note_c0_position, note_range_for_matrix_depth)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment