How would I go about programmatically interacting with VST(i) Plugins to synthesize audio?
Take, for example, the VSTi Triforce, by Tweakbench. Whe开发者_Python百科n loaded up in any VST host on the market, it allows the host to send a (presumably MIDI) signal to the VSTi. The VSTi will then process that signal and output synthesized audio as created by a software instrument within the VSTi.
For example, sending an A4 (MIDI note, I believe) to the VSTi will cause it to synthesize the A above Middle C. It sends the audio data back to the VST Host, which then could either play it on my speakers or save it to .wav or some other audio file format.
Let's say I have Triforce, and am trying to write a program in my language of choice that could interact with the VSTi by sending in an A4 note to be synthesized, and automatically saving it to a file on the system?
Eventually, I'd like to be able to parse an entire one-track MIDI file (using established, stable libraries already available for this purpose) and send it to the VSTi to "render"/synthesize it into an audio file.
How would I go about this, and in what language should I look to build the core framework?
Ultimately, it will be used in a Ruby-based project, so any pointers to specific Ruby resources would be nice as well.
However, I'm just trying to understand basically how the API of a VSTi works. (I've realized that this question is very much related to the question of building a VST host in the first place, albeit one that can only save VST outputs to file and not play them back, and with considerably smaller scope)
Well, since you asked, the ideal language for a project like this is going to be C++. Although there are wrappers for higher-level languages such as Java & .NET for the VST SDK, I couldn't find one for Ruby (though I did find this rather cool project which lets you program VST plugins in Ruby). So you will be stuck doing some degree of C/C++ integration on your own.
That said, you have basically two options here:
- Write a VST Host in C++, and launch it as a separate process from within Ruby.
- Integrate your Ruby code directly to the VST SDK, and load the plugin DLL's/Bundles directly from your code. This is probably the cleaner but harder way to accomplish your goal.
I wrote up a VST host programming tutorial on my blog awhile back which you may find useful in either case. It details how you open and communicate with VST plugins on both Mac OSX and Windows. Once you have gotten your host to load up the plugins, you need to be able to either send MIDI events directly to the plugin, either by reading them from file or some type of communication between your Ruby code and the VST host (ie, a named pipe, socket, file, etc.). If you are unfamiliar with the MIDI protocol, check out these links:
- The MIDI technical fanatic's brainwashing center (silly name, serious resource)
- The Sonic Spot's MIDI file specification (in case you need to read MIDI files)
As you might have already figured out, VST is fundamentally a block-based protocol. You request small blocks of audio data from the plugin, and you send along any MIDI events to the plugin right before it processes that respective block. Be sure not to ignore the MIDI delta field; this will ensure that the plugin starts processing the MIDI event directly on the desired sample. Otherwise, the plugin will sound a bit off-tempo, especially in the case of instruments.
The VST SDK is also based around floating-point blocks, so any data you get back will contain individual samples in the range { -1.0 .. 1.0 }. Depending on your desired output format, you may need to convert these to some other format. Fortunately, there seems to be a Ruby binding for the audiofile library, so you may be able to send your output into that in order to generate a proper AIFF/WAV file.
In all, it'll be a fair amount of work to get to your desired end goal, but it's not impossible by any means. Good luck!
精彩评论