[Solved ]How to build a VST host

DSP, Plugin and Host development discussion.
Post Reply New Topic
RELATED
PRODUCTS

Post

Hi!

I've just read an old post http://www.kvraudio.com/forum/viewtopic.php?t=312012
and I was wandering if anybody could send me another working link to download Aciddose's work (or similar), cause I'm interesting in making my own host and I need a simple, clear "starting point".
Thanks in advance.

Andrea
Last edited by Andrea11111 on Mon May 06, 2013 11:31 am, edited 1 time in total.

Post

Aciddose might reply to PM's since he's still around.
Herrman Seib has contributed his VstHost to the OpenSource community.
See link at the bottom of http://www.hermannseib.com/english/vsthost.htm
We are the KVR collective. Resistance is futile. You will be assimilated. Image
My MusicCalc is served over https!!

Post


Post

Hi!

I've already look up those sources, but they are a bit too intricated for me.
I'm building a VST Host using Qt (found also QTractor as possible guide), but it seems to give me problems during processReplacing() call.
I'm trying to fill input buffer with data read from a file, where I had previously saved the pcm output of an audio track (just to focus on the problem of building a VST Host; then it will be integrated in a bigger project).
Am I supposed to fill this input buffer with values between -1.0 and 1.0 (I've read it somewhere..)? or the function is able to manage itself this thing?
At the moment I'm just filling the input buffer with data read from the file (I can see values outstanding that interval) and maybe that's the wrong point, is it?

thanks to all.

Post

Edit: I don't think it's a problem of scaling, because it gives me segmentation fault also with an input buffer of zeros..

Post

I'll try to post some code..

Reading source file and put it's content into a QByteArray:

Code: Select all

QFile *sourceFile = new QFile;   
sourceFile->setFileName("absolute//path");
sourceFile->open(QIODevice::ReadOnly);
QByteArray line;
while (!sourceFile->atEnd())
{
     line = sourceFile->readAll();
}
Creating input and output buffer; filling input buffer with data from QBytearray.

Code: Select all

int channel = 1;
float **mInBuffer = new float *[channel];
int mBufferSize = 10000;
for (int i=0; i < channel; i++)
    mInBuffer[i] = new float[mBufferSize]();

float **mOutBuffer = new float *[channel];
for (int i=0; i < channel; i++)
    mOutBuffer[0] = new float[mBufferSize]();

for (int i=0; i < mBufferSize; i++)
{
   mInBuffer[0][i] = (float)line.data()[i];
}

sourceFile->close();
Trying to process audio after having loaded one plugin (AEffect *plugin):

Code: Select all

QFile *destinationFile = new QFile;
destinationFile->setFileName("absolute//path//destination");
destinationFile->open(QIODevice::WriteOnly);

plugin->processReplacing(plugin, mInBuffer, mOutBuffer, mBufferSize);
Any help will be appreciate! =P

Post

VstBooard is also using QT, perhaps you'll find answers looking at some of its source.

http://code.google.com/p/vstboard/source/browse

Post

Code: Select all

for (int i=0; i < channel; i++)
    mOutBuffer[0] = new float[mBufferSize]();
works for exactly 1 channel. Presumably you meant instead.
  • Did you take the PlugIn's number of input/output channels into consideration? If you send one channel but the PlugIn expects two or more, instant kaboom is guaranteed...
  • Did you initialize the PlugIn correctly so that it knows about sample rate, maximum buffer size, is processing and resumed?
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Thanks for your help.

First of all, the plugin I'm using for the test is the free GLow.
I was not considering plugin->numInputs, because I thought that the number of inputs was one of my choice. A qDebug() << plugin->numInputs replies me 2; but if I am taking data from a file, I've got only that channel: how can I manage it?

I've tried to follow this guide http://teragonaudio.com/article/How-to- ... -host.html.
Some more code lines:

Code: Select all

dispatcher(plugin, effSetSampleRate, 0, 0, NULL, format.sampleRate());
dispatcher(plugin, effSetBlockSize, 0, mBufferSize, NULL, 0.0f);
where

Code: Select all

QAudioFormat format;
format.setSampleRate(8000);
format.setChannelCount(1);
format.setSampleSize(16);
format.setCodec("audio/pcm");
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::UnSignedInt);
According to the guide, the plugin seems to be loaded correctly, as its main function is named VSTPluginMain, plugin->magic = kEffectMagic is true and the plugin's uniqueID is 1735999847 (verified online); moreover the gui appears, so I think it's correct.

Thanks again for your help.

Post

Andrea11111 wrote:I was not considering plugin->numInputs, because I thought that the number of inputs was one of my choice. A qDebug() << plugin->numInputs replies me 2; but if I am taking data from a file, I've got only that channel: how can I manage it?
Just pass in a second buffer, prefilled with zeroes. Or pass in the same buffer address for both channels. Or copy the contents of the first buffer to a second one (safer than the aforementioned method, but needs more CPU cycles). Your choice.

You got to respect numOutputs as well, BTW. Passing in more buffer pointers than requested is OK, but since processReplacing only gets float**s for inputs and outputs, it can't know how many pointers are passed in and therefore absolutely needs at least as many pointers as specified by numInputs / numOutputs.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Thanks to all!

It worked! It was a problem due to the number of inputs.
:D

Post

Sorry for re-opening a solved post.

Just a quick question: what's the maximum plugin's number of input/output channels? 1 for mono, 2 for stereo,...?

Thanks.

Post

Andrea11111 wrote:Sorry for re-opening a solved post.

Just a quick question: what's the maximum plugin's number of input/output channels? 1 for mono, 2 for stereo,...?

Thanks.
There is no such thing. You can have any number. Practical examples would be a compressor with a side-chain would typically ask for 4 input channels as two stereo pairs. An utility multi-band splitter with N bands could have N stereo outputs (and hence 2*N total output channels).. and so on.

I have no idea how "speaker arrangements" for multi-channel are supposed to work (or how widely they are supported in practice), but in terms of multiple mono or stereo signals (and the SDK helper class methods) there's getInputProperties and getOutputProperties, which you can call for each input/output to determine some properties, like the names of the channels, whether they are active, and whether they are part of stereo pairs.

It's possible to differentiate between 2 mono inputs and a single stereo input by checking whether the plugin sets the "PinIsStereo" flag in the pin-properties, although... if the pin-property methods are not supported by a given plugin (which I'd bet is fairly common), then grouping 2 inputs or 2 outputs into a stereo pair is usually the sensible thing to do.

It's not terribly common for plugins to have crazy amounts of inputs or outputs, but in theory there's nothing stopping someone from writing something like a large mixer with separate inputs for each tracks. That said, there are also hosts that simply refuse to work with such plugins, so it really depends on how compatible you want to be and whether you're planning to support modular routing, etc.

Also.. please don't use the plugin "unique ID" for anything. Certainly don't assume that an "unique ID" would actually be "unique" to a particular plugin; some hosts do and sorting out conflicts is rather frustrating (and occasionally does happen, because actually registering the IDs is probably more of an exception than the rule). Plus it prevents using multiple versions of the same plugin at the same time, since most hosts that care about "unique ID" will also place silly restrictions on loading patches with different "unique ID" such that changing the ID between versions would instantly break patch compatibility. Really, don't use it for anything (except writing to .fxp/.fxb files for the purpose of compatibility).

Post Reply

Return to “DSP and Plugin Development”