Skip to content

Instantly share code, notes, and snippets.

@DBraun
Last active April 8, 2022 19:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DBraun/1165e9b7538c9b8bd967231f311a902c to your computer and use it in GitHub Desktop.
Save DBraun/1165e9b7538c9b8bd967231f311a902c to your computer and use it in GitHub Desktop.
New RenderMan proposal
import numpy as np
from scipy.io import wavfile
import librosa
import renderman as rm
SAMPLE_RATE = 44100
BUFFER_SIZE = 512
REVERB_PLUGIN = "C:/path/to/reverb.dll"
SYNTH_PLUGIN = "C:/path/to/synth.dll"
SYNTH_PRESET1 = "C:/path/to/preset1.fxp"
SYNTH_PRESET2 = "C:/path/to/preset2.fxp"
MIDI_PATH = "C:/path/to/song.mid"
engine = rm.RenderEngine(SAMPLE_RATE, BUFFER_SIZE)
def load_audio_file(file_path, duration=None):
sig, rate = librosa.load(file_path, duration=duration, mono=False, sr=SAMPLE_RATE)
assert(rate == SAMPLE_RATE)
return sig
# Example 1:
# Processing pre-recorded audio example
vocals = load_audio_file("vocals.wav", duration=5.)
piano = load_audio_file("piano.wav", duration=5.)
assert(vocals.dtype == np.float32)
# graph idea is based on https://github.com/magenta/ddsp
# https://github.com/magenta/ddsp#processorgroup-with-a-list
# Also useful for eventually using gin-config.
graph = [
(engine.make_playback_processor("vocals", vocals), []),
(engine.make_playback_processor("piano", piano), []),
(engine.make_filter_processor("filter", "high", 7000.0, .1, 1.), ["vocals"]),
(engine.make_reverb_processor("reverb"), ["piano"]),
(engine.make_add_processor("added"), ["filter", "reverb"]),
]
assert(engine.load_graph(graph))
engine.render(3.)
audio = engine.get_audio() # returns list of lists
audio = np.array(audio, np.float32).transpose()
wavfile.write('remix.wav', SAMPLE_RATE, audio)
print('Example 1 done')
# Example 2:
# Playback of a synthesizer and vocals
serum = engine.make_plugin_processor("serum", SYNTH_PLUGIN)
assert(serum.load_preset(SYNTH_PRESET1))
graph = [
(engine.make_playback_processor("vocals", vocals), []),
(serum, []),
(engine.make_plugin_processor("reverb", REVERB_PLUGIN), ["serum"]),
(engine.make_add_processor("add1"), ["reverb", "vocals"])
]
assert(engine.load_graph(graph))
# MIDI can be added to PluginProcessor objects.
# If we have multiple PluginProcessors, we can add separate MIDI for each.
serum.add_midi_note(60, 127, 0., 1.) # note, velocity, start time sec, duration sec
serum.add_midi_note(67, 127, 0.5, .25)
# serum.load_midi(MIDI_PATH) # we can load from MIDI file.
engine.render(3.) # render duration
audio = engine.get_audio()
audio = np.array(audio, np.float32).transpose()
wavfile.write('my_song_001.wav', SAMPLE_RATE, audio)
# Can still load a new preset without reloading/destroying the graph
assert(serum.load_preset(SYNTH_PRESET2))
serum.clear_midi()
serum.add_midi_note(65, 127, 0.25, .5)
engine.render(3.)
audio = engine.get_audio()
audio = np.array(audio, np.float32).transpose()
wavfile.write('my_song_002.wav', SAMPLE_RATE, audio)
print('Example 2 done')
print("All Done!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment