Last active
April 8, 2022 19:01
-
-
Save DBraun/1165e9b7538c9b8bd967231f311a902c to your computer and use it in GitHub Desktop.
New RenderMan proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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