summaryrefslogtreecommitdiff
path: root/source/plugin/Plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/plugin/Plugin.c')
-rw-r--r--source/plugin/Plugin.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/source/plugin/Plugin.c b/source/plugin/Plugin.c
new file mode 100644
index 0000000..a307e8e
--- /dev/null
+++ b/source/plugin/Plugin.c
@@ -0,0 +1,205 @@
+//
+// Plugin.c - MrsWatson
+// Created by Nik Reiman on 1/3/12.
+// Copyright (c) 2012 Teragon Audio. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "audio/AudioSettings.h"
+#include "logging/EventLogger.h"
+#include "plugin/Plugin.h"
+#include "plugin/PluginGain.h"
+#include "plugin/PluginLimiter.h"
+#include "plugin/PluginPassthru.h"
+#include "plugin/PluginVst2x.h"
+#include "plugin/PluginSilence.h"
+
+static PluginInterfaceType _guessPluginInterfaceType(const CharString pluginName, const CharString pluginSearchRoot)
+{
+ PluginInterfaceType pluginType = PLUGIN_TYPE_INVALID;
+
+ if (pluginName == NULL || charStringIsEmpty(pluginName)) {
+ logError("Attempt to guess plugin with empty name");
+ return pluginType;
+ }
+
+ logDebug("Trying to find plugin '%s'", pluginName->data);
+
+ if (pluginVst2xExists(pluginName, pluginSearchRoot)) {
+ logInfo("Plugin '%s' is of type VST2.x", pluginName->data);
+ pluginType = PLUGIN_TYPE_VST_2X;
+ } else if (!strncmp(INTERNAL_PLUGIN_PREFIX, pluginName->data, strlen(INTERNAL_PLUGIN_PREFIX))) {
+ logInfo("Plugin '%s' is an internal plugin", pluginName->data);
+ pluginType = PLUGIN_TYPE_INTERNAL;
+ } else {
+ logError("Plugin '%s' could not be found", pluginName->data);
+ }
+
+ return pluginType;
+}
+
+static void _logPluginLocation(const CharString location)
+{
+ logInfo("Location (internal):", location->data);
+}
+
+static void _listAvailablePluginsInternal(void)
+{
+ CharString internalLocation = newCharStringWithCString("(Internal)");
+ _logPluginLocation(internalLocation);
+ logInfo(" %s", kInternalPluginPassthruName);
+ logInfo(" %s", kInternalPluginSilenceName);
+ freeCharString(internalLocation);
+}
+
+void listAvailablePlugins(const CharString pluginRoot)
+{
+ listAvailablePluginsVst2x(pluginRoot);
+ _listAvailablePluginsInternal();
+}
+
+/**
+ * Used to check if an internal plugin (ie, starting with "mrs_" matches an
+ * internal plugin name. This function only compares to the length of the
+ * internal name, so that extra parameters can be appended to the end of the
+ * plugin name argument.
+ * @param pluginName Plugin name to check
+ * @param internalName Internal name to compare against
+ * @return True if the plugin is a match
+ */
+static boolByte _internalPluginNameMatches(const CharString pluginName, const char *internalName)
+{
+ return (boolByte)(strncmp(pluginName->data, internalName, strlen(internalName)) == 0);
+}
+
+// Plugin newPlugin(PluginInterfaceType interfaceType, const CharString pluginName, const CharString pluginLocation) {
+Plugin pluginFactory(const CharString pluginName, const CharString pluginRoot)
+{
+ PluginInterfaceType interfaceType = _guessPluginInterfaceType(pluginName, pluginRoot);
+
+ if (interfaceType == PLUGIN_TYPE_INVALID) {
+ return NULL;
+ }
+
+ switch (interfaceType) {
+ case PLUGIN_TYPE_VST_2X:
+ return newPluginVst2x(pluginName, pluginRoot);
+
+ case PLUGIN_TYPE_INTERNAL:
+ if (_internalPluginNameMatches(pluginName, kInternalPluginGainName)) {
+ return newPluginGain(pluginName);
+ } else if (_internalPluginNameMatches(pluginName, kInternalPluginLimiterName)) {
+ return newPluginLimiter(pluginName);
+ } else if (_internalPluginNameMatches(pluginName, kInternalPluginPassthruName)) {
+ return newPluginPassthru(pluginName);
+ } else if (_internalPluginNameMatches(pluginName, kInternalPluginSilenceName)) {
+ return newPluginSilence(pluginName);
+ } else {
+ logError("'%s' is not a recognized internal plugin", pluginName->data);
+ return NULL;
+ }
+
+ default:
+ logError("Could not find plugin type for '%s'", pluginName->data);
+ return NULL;
+ }
+}
+
+boolByte openPlugin(Plugin self)
+{
+ if (self == NULL) {
+ logError("There is no plugin to open");
+ return false;
+ } else if (self->isOpen) {
+ return true;
+ }
+
+ if (!self->openPlugin(self)) {
+ logError("Plugin '%s' could not be opened", self->pluginName->data);
+ return false;
+ } else {
+ self->inputBuffer = newSampleBuffer((ChannelCount)self->getSetting(self, PLUGIN_NUM_INPUTS), getBlocksize());
+ self->outputBuffer = newSampleBuffer((ChannelCount)self->getSetting(self, PLUGIN_NUM_OUTPUTS), getBlocksize());
+ self->isOpen = true;
+ }
+
+ return true;
+}
+
+boolByte closePlugin(Plugin self)
+{
+ if (self == NULL) {
+ logError("There is no plugin to open");
+ return false;
+ }
+
+ self->closePlugin(self);
+ freeSampleBuffer(self->inputBuffer);
+ self->inputBuffer = NULL;
+ freeSampleBuffer(self->outputBuffer);
+ self->outputBuffer = NULL;
+ self->isOpen = false;
+ return true;
+}
+
+Plugin _newPlugin(PluginInterfaceType interfaceType, PluginType pluginType)
+{
+ Plugin plugin = (Plugin)malloc(sizeof(PluginMembers));
+
+ plugin->interfaceType = interfaceType;
+ plugin->pluginType = pluginType;
+ plugin->pluginName = newCharString();
+ plugin->pluginLocation = newCharString();
+ plugin->pluginAbsolutePath = newCharString();
+
+ plugin->inputBuffer = NULL;
+ plugin->outputBuffer = NULL;
+ plugin->isOpen = false;
+
+ return plugin;
+}
+
+void freePlugin(Plugin self)
+{
+ if (self != NULL) {
+ if (self->extraData != NULL) {
+ self->freePluginData(self->extraData);
+ free(self->extraData);
+ }
+
+ if (self->inputBuffer != NULL) {
+ freeSampleBuffer(self->inputBuffer);
+ }
+ if (self->outputBuffer != NULL) {
+ freeSampleBuffer(self->outputBuffer);
+ }
+ freeCharString(self->pluginName);
+ freeCharString(self->pluginLocation);
+ freeCharString(self->pluginAbsolutePath);
+ free(self);
+ }
+}