Closed DBraun closed 2 years ago
Good work-in-progress here https://github.com/DBraun/DawDreamer/tree/feature/multichannel
The multichannel branch is merged into main because it works well for Faust but I still want to test these ambisonics plugins more.
hi, I am very interested in this topic, I succesfully installed dawdreamer on linux as docker. I also installed IEM ambisonic plugins (https://plugins.iem.at/) and plugins are succesfully loaded under dawdreamer, I can print their parameters. The problem is
regards!
@piotr-czarnecki Great! There are two relevant methods right now
https://dirt.design/DawDreamer/_generate/dawdreamer.ProcessorBase.html
get_num_input_channels()
and get_num_output_channels()
Those methods work all on processors including PluginProcessors.
Next you can set parameters on a PluginProcessor (https://dirt.design/DawDreamer/_generate/dawdreamer.PluginProcessor.html) with
set_automation(index: int, data: np.array)
or set_parameter(index: int, value: float)
You can refer to the tests: https://github.com/DBraun/DawDreamer/blob/13cf58a8ee4413e553b057722f2c6b9e0b884951/tests/test_plugins.py#L153
The reason I haven't closed this issue is because it's still a bit incomplete. We need a way to configure the bus layout, rather than just using the default. I need to use these methods better https://docs.juce.com/master/classAudioProcessor.html
thank you for so fast reply! I have problem with set_parameter(index: int, value: float). The problem is because my vst plugin should get string value rather than float.
in particular my code looks like:
import dawdreamer as daw
SAMPLE_RATE = 44100
BUFFER_SIZE = 128 # Parameters will undergo automation at this block size. It can be as small as 1 sample.
AMBI_PLUGIN = "/root/.vst3/IEM/StereoEncoder.vst3" # plugin.
engine = daw.RenderEngine(SAMPLE_RATE, BUFFER_SIZE)
engine.set_bpm(120.) # default is 120.
DURATION = 30 # How many seconds we want to render.
plugin = engine.make_plugin_processor("my_plugin", AMBI_PLUGIN)
print(plugin.set_parameter(0, 1000))
print(plugin.get_parameter_name(0))
print(plugin.get_parameter(0))
print(plugin.get_parameter_text(0))
and ouput is:
True
Ambisonics Order
1000.0
Auto
'Ambisonics Order' as well as 'Auto' are actually correct values, but it is incorrect to set this parameter to actually float. The correct values for that parameter are 'Auto', '1st', '2nd', '3rd', '4th', '5th', '6th', '7th' - those are strings. So I think that there should be a way to set string kind parameters.
Additionally I think there is some problem with 'get_num_output_channels()', for that plugin it returns 2. The problem is that It is never 2, it can only be one of: 1, 4, 9, 16, 25, 36, 49, 64.
My understanding is that a menu of strings such as "Auto", "1st" and so on is actually broken into the [0-1] range. So "Auto" might be used when the number is between 0 and 1./N, the next from 1./N and 2/N and so on. So the numbers you pass to set_parameter
should be between 0 and 1, not as large as 1000.
However, there's a bug I need to fix.
This line is missing
setParameter(pair.first, pair.second);
The consequence is that if you update with set_parameter()
and then check with either get_plugin_parameters_description
, get_parameter
, or get_parameter_text
you won't see the update. It works in terms of automation and rendering, but it's confusing to the user. I will try to fix that soon (at least this week).
If get_num_output_channels()
is 2, then that might just be the default. We need to use functions such as canApplyBusesLayout
https://docs.juce.com/master/classAudioProcessor.html#a7e36934d17a82a4264552f7fda1b8889
0.6.3 now has open_editor()
, load_state(filepath: str)
, save_state(filepath: str)
, set_bus(inputs: int, outputs: int)
for Plugin Processor. I also tested IEMPlugins https://github.com/DBraun/DawDreamer/blob/9d286e1171b7f4c89558e5bdb9337649d2803f53/tests/test_plugins.py#L413
David, at first, thank you very much for your effort in this topic!
I have succesfully tested 0.6.3 and confirm that under Windows, IEM plugin works perfectly!!! In particular, I have tested MultiEncoder with two different waves, each assigned to different direction, and rendering 6-th order ambisonic (49 channels). I have than listening under Reaper (https://www.reaper.fm) - result is well.
However found some issue.
Under Windows, IEM plugins in VST3 version actually does not load, only VST2 works (the error is: 'RuntimeError: Unable to load plugin.'). I am not an expert in this, I read on JUCE forum (https://forum.juce.com/t/the-removal-of-juce-s-embedded-vst2-sdk/29994) that VST2 actually are deprecated. Is DawDreamer tested with other plugins in VST3 format? if so maybe something bad is with IEM plugins, however if there are problems with other VST3 plugins maybe it is worth to investigate thsi issue.
Under Ubuntu, exactly same python code unfortunately does not work. The only difference is that I use VST3 instead of VST2. It is not easy to build VST2 version of IEM plugins as VST2 SDK is required (is available on older version of JUCE, so I did not tested this yet). VST3 version however are loadable (there is no issue similar to Windows, plugin loads and it is possible to get output from 'ambisonics_encoder.get_plugin_parameters_description()'), however rendered output is incorrect. The output actually contains proper number of channels, but only first two channels are non zero, all the other channels are just zeros. I think that it is worth to be fixed as I think it is easy to be reproduced. Could you check it? Do you have idea why this may happen?
my code for Windows as well as for Ubuntu is as follows:
plugin_path = "D:\iem\VST3\IEM\MultiEncoder.vst3" # only works with VST2 with path "D:\iem\VST2\IEM\MultiEncoder.dll"
DURATION = 50.
SAMPLE_RATE = 44100
engine = daw.RenderEngine(SAMPLE_RATE, 128)
ambisonics_encoder = engine.make_plugin_processor("ambisonics_encoder", plugin_path)
ambisonics_encoder.record = True
AMBISONICS_ORDER = 6
num_inputs = 2
num_outputs = (AMBISONICS_ORDER+1)**2 # this is a fixed equation
ambisonics_encoder.set_parameter(7, 0.375) # 7 is azimuth of the first sound, 0.375 relates to -45 degrees where zero is in front.
ambisonics_encoder.set_parameter(12, 0.625) # 12 is azimuth of the second sound, 0.625 relates to 45 degrees
ambisonics_encoder.set_bus(num_inputs, num_outputs)
data, rate = librosa.load("1.wav", duration=DURATION+.1, mono=False, sr=SAMPLE_RATE)
data2, rate2 = librosa.load("2.wav", duration=DURATION+.1, mono=False, sr=SAMPLE_RATE)
data = data.mean(axis=0, keepdims=True)
data2 = data2.mean(axis=0, keepdims=True)
playback_data = np.stack((data.reshape(data.shape[1]), data2.reshape(data2.shape[1])))
graph = [
(engine.make_playback_processor("playback", playback_data), []),
(ambisonics_encoder, ["playback"])
]
engine.load_graph(graph)
engine.render(DURATION)
audio = ambisonics_encoder.get_audio()
file_path = f'test_plugin_encoder_2sources-vst3.wav'
wavfile.write(file_path, SAMPLE_RATE, audio.transpose())
Many thanks for great job!
You can download the VST2 library from archive.org I forget the link though. It's also in prior commits of JUCE: https://github.com/juce-framework/JUCE/tree/cf4f12a452611e46d29e4549ce69adac345706b7
Let's migrate the discussion to https://github.com/DBraun/DawDreamer/issues/86
It would make a lot of sense for a Faust or VST processor to be able to output more than one stereo pair. I should test ambisonics-related plugins such as http://research.spa.aalto.fi/projects/sparta_vsts/plugins.html and https://leomccormack.github.io/sparta-site/