// find plugins in directory iNumPlugins = FindPlugins (&stPluginFileNames);
For the plugin to be selected for processing, the library can be loaded with the function LoadPluginModule and the API function pointers can be retrieved with the function GetFunctionPointers, both declared in FEAPIHostUtilities.h:
hLibraryHandle = 0; LoadPluginModule (pCurrentPlugin->acFilename, &hLibraryHandle); if (!hLibraryHandle) return -1; else GetFunctionPointers (hLibraryHandle, &stPluginFunctions);
Function GetFunctionPointers verifies the API compliance and writes the function pointers to ::stPluginFunctions.
Now we are ready to create a new instance of the plugin:
// create plug instance fprintf (stdout, "Opening new plugin instance..."); if (stPluginFunctions.pFunCreateInstance ( &hPluginInstance) == FEAPI_kNoError) fprintf (stdout, " Succeeded\n"); else fprintf (stdout, " Failed\n");
After that, information about some basic plugin properties can be retrieved:
fprintf (stdout, "Plugin API version: %d.", pCurrentPlugin->iMajorVersion); fprintf (stdout, "%d.", stPluginFunctions.pFunGetApiVersion ( FEAPI_kMinorVersion)); fprintf (stdout, "%d\n", stPluginFunctions.pFunGetApiVersion ( FEAPI_kSubVersion)); fprintf (stdout, "Minimum supported sample rate: %1.1e\n", stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMinSampleRate)); fprintf (stdout, "Maximum supported sample rate: %1.1e\n", stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMaxSampleRate)); fprintf (stdout, "Minimum number of supported channels: %u\n", (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMinChannels)); fprintf (stdout, "Maximum number of supported channels: %u\n", (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMaxChannels)); fprintf (stdout, "Minimum supported frame size: %u\n", (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMinFrameSize)); fprintf (stdout, "Maximum supported frame size: %u\n", (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kMaxFrameSize)); fprintf (stdout, "Preferred frame size: %d\n", (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kOptFrameSize));
With the available information it is now possible to initialize the plugin:
fprintf (stdout, "Initializing new plugin instance..."); if (stPluginFunctions.pFunInitializePlugin ( hPluginInstance, (float)sfInputInfo.samplerate, sfInputInfo.channels, pCurrentPlugin->iMajorVersion, 0) == FEAPI_kNoError) fprintf (stdout, " Succeeded\n"); else fprintf (stdout, " Failed\n");
and to request detailed information about the plugin parameters:
stPluginFunctions.pFunGetPluginName (hPluginInstance, acResult); fprintf (stdout, "Plugin Name: %s\n", acResult); stPluginFunctions.pFunGetPluginId (hPluginInstance, acResult); fprintf (stdout, "Plugin Id: %s\n", acResult); stPluginFunctions.pFunGetPluginVendor (hPluginInstance, acResult); fprintf (stdout, "Plugin Vendor: %s\n", acResult); fprintf (stdout, "Plugin Vendor version: %d.", stPluginFunctions.pFunGetPluginVendorVersion (hPluginInstance, FEAPI_kMajorVersion)); fprintf (stdout, "%d.", stPluginFunctions.pFunGetPluginVendorVersion (hPluginInstance, FEAPI_kMinorVersion)); fprintf (stdout, "%d\n", stPluginFunctions.pFunGetPluginVendorVersion (hPluginInstance, FEAPI_kSubVersion)); stPluginFunctions.pFunGetPluginCopyright (hPluginInstance, acResult); fprintf (stdout, "Plugin Copyright: %s\n", acResult); stPluginFunctions.pFunGetPluginDescription (hPluginInstance, acResult); fprintf (stdout, "Plugin Description: %s\n", acResult); iNumInputs = stPluginFunctions.pFunGetNumberOfInputs (hPluginInstance); fprintf (stdout, "Number of input channels: %d\n", iNumInputs); for (i = 0; i < iNumInputs; i++) { stPluginFunctions.pFunGetInputDescription (hPluginInstance, i, &stSignalDescription); fprintf (stdout, "Information about the input %d:\n", i); fprintf (stdout, "\tInput name: %s\n", stSignalDescription.acName); fprintf (stdout, "\tInput description: %s\n", stSignalDescription.acDescription); fprintf (stdout, "\tInput unit: %s\n", stSignalDescription.acUnit); fprintf (stdout, "\tInput range: %e - %e\n", stSignalDescription.fRangeMin, stSignalDescription.fRangeMax); fprintf (stdout, "\tInput sample rate: %f\n", stSignalDescription.fSampleRate); fprintf (stdout, "\n"); } iNumParameters = stPluginFunctions.pFunGetNumberOfParameters (hPluginInstance); fprintf (stdout, "Number of parameters: %d\n", iNumParameters); for (i = 0; i < iNumParameters; i++) { stPluginFunctions.pFunGetParameterDescription (hPluginInstance, i, &stParameterDescription); fprintf (stdout, "Information about the parameter %d:\n", i); fprintf (stdout, "\tParameter name: %s\n", stParameterDescription.acName); fprintf (stdout, "\tParameter description: %s\n", stParameterDescription.acDescription); fprintf (stdout, "\tParameter unit: %s\n", stParameterDescription.acUnit); fprintf (stdout, "\tParameter range: %e - %e\n", stParameterDescription.fRangeMin, stParameterDescription.fRangeMax); fprintf (stdout, "\tParameter default: %e\n", stParameterDescription.fDefaultValue); fprintf (stdout, "\tParameter quantized to: %e\n", stParameterDescription.fQuantizedTo); fprintf (stdout, "\tParameter changeable in real-time: %s\n", (stParameterDescription.bIsChangeableInRealTime)? "Yes" : "No"); fprintf (stdout, "\n"); }
Then, the actual processing can take place. Since in this host implementation the input buffer size does not matter, we ask the plugin about its preferred buffer size. Therefore, we call
iNumOfFramesNeeded = (int)stPluginFunctions.pFunGetPluginProperty (hPluginInstance, FEAPI_kOptFrameSize);
In the next step, the process function can be called with the requested amount of input audio data:
//processing stPluginFunctions.pFunProcess ( hPluginInstance, (const float**)ppfDataSorted, ptInputTimeStamp, iNumFramesRead);
Now, the current results can be retrieved, if available. First, the size of the results is queried to assure that the host buffers have sufficient size to hold the result values. Then, all results are retrieved and printed to an output text file if requested:
// get results for (i = 0; i < iNumResults; i++) { // get size of result with index i while ((iValue = stPluginFunctions.pFunGetSizeOfResult (hPluginInstance, i) > 0)) { // adjust memory allocation if required (make sure this is not called often) if (iValue > iMaxResultSizeInValues) { iMaxResultSizeInValues = iValue; ppfResult[i] = (float*) realloc (ppfResult[i], sizeof(*ppfResult[i]) * iMaxResultSizeInValues); } // get results stPluginFunctions.pFunGetResult ( hPluginInstance, i, ppfResult[i], &tOutputTimeStamp); // print result to text file if requested if (pFOutputFile) { for (j = 0; j < iValue; j++) fprintf (pFOutputFile, "\t%1.10g", ppfResult[i][j]); fprintf (pFOutputFile, "\n"); }
After all audio data has been processed and no more audio data is available, the plugin should be noticed about this circumstance:
// no new audio data available or canceled by user; let the plug notice...
stPluginFunctions.pFunProcessDone (hPluginInstance);
After this, the last results can be retrieved (if available) in the same way as described above. Finally, the plugin instance can be destroyed and the library unloaded:
fprintf(stdout, "\nDestroying plugin instance..."); if (stPluginFunctions.pFunDestroyInstance (&hPluginInstance) == 0) fprintf (stdout, " Succeeded\n"); else fprintf (stdout, " Failed\n"); UnloadPluginModule (hLibraryHandle);