Browse Source

Add carla-discovery, fully Windows supported

tags/v0.9.0
falkTX 13 years ago
parent
commit
5cd9bad71f
8 changed files with 2560 additions and 1 deletions
  1. +19
    -0
      .gitignore
  2. +55
    -0
      src/carla-discovery/Makefile
  3. +895
    -0
      src/carla-discovery/carla-discovery.cpp
  4. +437
    -0
      src/carla-includes/dssi/dssi.h
  5. +272
    -0
      src/carla-includes/dssi/seq_event-compat.h
  6. +603
    -0
      src/carla-includes/ladspa/ladspa.h
  7. +279
    -0
      src/carla-includes/vestige/aeffectx.h
  8. +0
    -1
      src/ladspa_rdf.py

+ 19
- 0
.gitignore View File

@@ -0,0 +1,19 @@
.directory
.fuse-*
.*.kate-swp
*~

*.o
*.a
*.exe
*.so
*.dll

*.pyc
ui_*.py
icons_rc.py

carla-discovery-*

aeffect.h
aeffectx.h

+ 55
- 0
src/carla-discovery/Makefile View File

@@ -0,0 +1,55 @@
#!/usr/bin/make -f
# Makefile for Carla-Discovery #
# ----------------------------------------- #
# Created by falkTX
#

CXX ?= g++

BUILD_FLAGS = -ffast-math -fomit-frame-pointer -mtune=generic -msse -O2 -Wall -I../carla-includes $(CXXFLAGS)
BUILD_FLAGS += -DVESTIGE_HEADER -I../carla-includes/vestige # Comment this line to not use vestige header
LINK_FLAGS = $(LDFLAGS)

32BIT_FLAGS = -m32
64BIT_FLAGS = -m64 #-fPIC

UNIX_32BIT_FLAGS = -L/usr/lib32 -L/usr/lib/i386-linux-gnu $(32BIT_FLAGS)
UNIX_64BIT_FLAGS = -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu $(64BIT_FLAGS)
UNIX_LINK_FLAGS = -ldl $(LINK_FLAGS)

WIN32_FLAGS = $(32BIT_FLAGS) -static
WIN64_FLAGS = $(64BIT_FLAGS) -static

ifeq ($(FLUIDSYNTH),)
else
BUILD_FLAGS += `pkg-config --cflags fluidsynth` -DWANT_FLUIDSYNTH
LINK_FLAGS += `pkg-config --libs fluidsynth`
endif


all:
@echo "Build type must be unix32, unix64, win32 or win64"

unix32: carla-discovery-unix32

unix64: carla-discovery-unix64

win32: carla-discovery-win32.exe

win64: carla-discovery-win64.exe


carla-discovery-unix32: carla-discovery.cpp
$(CXX) carla-discovery.cpp $(BUILD_FLAGS) $(UNIX_32BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@

carla-discovery-unix64: carla-discovery.cpp
$(CXX) carla-discovery.cpp $(BUILD_FLAGS) $(UNIX_64BIT_FLAGS) $(UNIX_LINK_FLAGS) -o $@

carla-discovery-win32.exe: carla-discovery.cpp
$(CXX) carla-discovery.cpp $(BUILD_FLAGS) $(WIN32_FLAGS) $(LINK_FLAGS) -o $@

carla-discovery-win64.exe: carla-discovery.cpp
$(CXX) carla-discovery.cpp $(BUILD_FLAGS) $(WIN64_FLAGS) $(LINK_FLAGS) -o $@

clean:
rm -f carla-discovery-*

+ 895
- 0
src/carla-discovery/carla-discovery.cpp View File

@@ -0,0 +1,895 @@
/* Carla Plugin discovery code */

#ifndef nullptr
const class {
public:
template<class T> operator T*() const
{
return 0;
}

template<class C, class T> operator T C::*() const
{
return 0;
}

private:
void operator&() const;
} nullptr_ = {};
#define nullptr nullptr_
#endif

#if defined(__WIN32__) || defined(__WIN64__)
#include <windows.h>
#ifndef __WINDOWS__
#define __WINDOWS__
#endif
#else
#include <dlfcn.h>
#ifndef __cdecl
#define __cdecl
#endif
#endif

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

#include "ladspa/ladspa.h"
#include "dssi/dssi.h"

#define VST_FORCE_DEPRECATED 0
#include "aeffectx.h"

#if VESTIGE_HEADER
#warning Using vestige header
#define kVstVersion 2400
#define effGetPlugCategory 35
#define effSetBlockSizeAndSampleRate 43
#define effShellGetNextPlugin 70
#define effStartProcess 71
#define effStopProcess 72
#define effSetProcessPrecision 77
#define kVstProcessPrecision32 0
#define kPlugCategUnknown 0
#define kPlugCategSynth 2
#define kPlugCategAnalysis 3
#define kPlugCategMastering 4
#define kPlugCategRoomFx 6
#define kPlugCategRestoration 8
#define kPlugCategShell 10
#define kPlugCategGenerator 11
#endif

// we don't need to support SoundFonts in 32bit or Wine builds
#ifdef WANT_FLUIDSYNTH
#include <fluidsynth.h>
#endif

#define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl;

// fake values to test plugins with
const unsigned int bufferSize = 512;
const unsigned int sampleRate = 44100;

// ------------------------------ Carla main defs ------------------------------
// plugin hints
const unsigned int PLUGIN_HAS_GUI = 0x01;
const unsigned int PLUGIN_IS_BRIDGE = 0x02;
const unsigned int PLUGIN_IS_SYNTH = 0x04;
const unsigned int PLUGIN_USES_CHUNKS = 0x08;
const unsigned int PLUGIN_CAN_DRYWET = 0x10;
const unsigned int PLUGIN_CAN_VOL = 0x20;
const unsigned int PLUGIN_CAN_BALANCE = 0x40;

enum PluginType {
PLUGIN_NONE = 0,
PLUGIN_LADSPA = 1,
PLUGIN_DSSI = 2,
PLUGIN_LV2 = 3,
PLUGIN_VST = 4,
PLUGIN_SF2 = 5
};

enum PluginInfoCategory {
PLUGIN_CATEGORY_NONE = 0,
PLUGIN_CATEGORY_SYNTH = 1,
PLUGIN_CATEGORY_DELAY = 2, // also Reverb
PLUGIN_CATEGORY_EQ = 3,
PLUGIN_CATEGORY_FILTER = 4,
PLUGIN_CATEGORY_DYNAMICS = 5, // Amplifier, Compressor, Gate
PLUGIN_CATEGORY_MODULATOR = 6, // Chorus, Flanger, Phaser
PLUGIN_CATEGORY_UTILITY = 7, // Analyzer, Converter, Mixer
PLUGIN_CATEGORY_OUTRO = 8 // used to check if a plugin has a category
};

// ------------------------------ library functions ------------------------------
void* lib_open(const char* filename)
{
#ifdef __WINDOWS__
return LoadLibraryA(filename);
#else
return dlopen(filename, RTLD_LAZY);
#endif
}

int lib_close(void* lib)
{
#ifdef __WINDOWS__
return FreeLibrary((HMODULE)lib);
#else
return dlclose(lib);
#endif
}

void* lib_symbol(void* lib, const char* symbol)
{
#ifdef __WINDOWS__
return (void*)GetProcAddress((HMODULE)lib, symbol);
#else
return dlsym(lib, symbol);
#endif
}

const char* lib_error(const char* filename)
{
#ifdef __WINDOWS__
static char libError[2048];
memset(libError, 0, sizeof(char)*2048);

LPVOID winErrorString;
DWORD winErrorCode = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, winErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&winErrorString, 0, nullptr);

snprintf(libError, 2048, "%s: error code %li: %s", filename, winErrorCode, (const char*)winErrorString);
LocalFree(winErrorString);

return libError;
#else
(void)filename;
return dlerror();
#endif
}

// ------------------------------ VST Stuff ------------------------------
typedef AEffect* (*VST_Function)(audioMasterCallback);

intptr_t VstCurrentUniqueId = 0;

bool VstPluginCanDo(AEffect* effect, const char* feature)
{
return (effect->dispatcher(effect, effCanDo, 0, 0, (void*)feature, 0.0f) == 1);
}

intptr_t VstHostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
std::cout << "VstHostCallback(" << effect << ", " << opcode << ", " << index << ", " << value << ", " << ptr << ", " << opt << ")" << std::endl;

switch (opcode)
{
case audioMasterAutomate:
if (effect)
effect->setParameter(effect, index, opt);
break;

case audioMasterVersion:
return kVstVersion;
case audioMasterCurrentId:
return VstCurrentUniqueId;

case audioMasterGetTime:
static VstTimeInfo timeInfo;
memset(&timeInfo, 0, sizeof(VstTimeInfo));
timeInfo.sampleRate = sampleRate;
return (intptr_t)&timeInfo;

case audioMasterGetSampleRate:
return sampleRate;

case audioMasterGetBlockSize:
return bufferSize;

case audioMasterGetVendorString:
if (ptr)
strcpy((char*)ptr, "falkTX");
break;

case audioMasterGetProductString:
if (ptr)
strcpy((char*)ptr, "Carla-Discovery");
break;

case audioMasterGetVendorVersion:
return 0x05; // 0.5

case audioMasterCanDo:
std::cout << "VstHostCallback:audioMasterCanDo - " << (char*)ptr << std::endl;

if (strcmp((char*)ptr, "sendVstEvents") == 0)
return 1;
else if (strcmp((char*)ptr, "sendVstMidiEvent") == 0)
return 1;
else if (strcmp((char*)ptr, "sendVstTimeInfo") == 0)
return 1;
else if (strcmp((char*)ptr, "receiveVstEvents") == 0)
return 1;
else if (strcmp((char*)ptr, "receiveVstMidiEvent") == 0)
return 1;
#if !VST_FORCE_DEPRECATED
else if (strcmp((char*)ptr, "receiveVstTimeInfo") == 0)
return -1;
#endif
else if (strcmp((char*)ptr, "reportConnectionChanges") == 0)
return 1;
else if (strcmp((char*)ptr, "acceptIOChanges") == 0)
return 1;
else if (strcmp((char*)ptr, "sizeWindow") == 0)
return 1;
else if (strcmp((char*)ptr, "offline") == 0)
return 1;
else if (strcmp((char*)ptr, "openFileSelector") == 0)
return -1;
else if (strcmp((char*)ptr, "closeFileSelector") == 0)
return -1;
else if (strcmp((char*)ptr, "startStopProcess") == 0)
return 1;
else if (strcmp((char*)ptr, "shellCategory") == 0)
return 1;
else if (strcmp((char*)ptr, "sendVstMidiEventFlagIsRealtime") == 0)
return -1;
else
{
std::cerr << "VstHostCallback:audioMasterCanDo - Got uninplemented feature request '" << (char*)ptr << "'" << std::endl;
return 0;
}

case audioMasterGetLanguage:
return kVstLangEnglish;

default:
break;
}
return 0;
}

// ------------------------------ Plugin Check ------------------------------
void do_ladspa_check(void* lib_handle)
{
LADSPA_Handle handle;
const LADSPA_Descriptor* descriptor;
LADSPA_Descriptor_Function descfn = (LADSPA_Descriptor_Function)lib_symbol(lib_handle, "ladspa_descriptor");

if (descfn == nullptr)
{
DISCOVERY_OUT("error", "Not a LADSPA plugin");
return;
}

unsigned long i = 0;
while ((descriptor = descfn(i++)))
{
handle = descriptor->instantiate(descriptor, sampleRate);

if (handle)
{
DISCOVERY_OUT("init", "-----------");
DISCOVERY_OUT("name", descriptor->Name);
DISCOVERY_OUT("label", descriptor->Label);
DISCOVERY_OUT("maker", descriptor->Maker);
DISCOVERY_OUT("copyright", descriptor->Copyright);
DISCOVERY_OUT("id", descriptor->UniqueID);

int hints = 0;
PluginInfoCategory category = PLUGIN_CATEGORY_NONE;

int audio_ins = 0;
int audio_outs = 0;
int audio_total = 0;
int midi_ins = 0;
int midi_outs = 0;
int midi_total = 0;
int parameters_ins = 0;
int parameters_outs = 0;
int parameters_total = 0;
int programs_total = 0;

for (unsigned long j=0; j < descriptor->PortCount; j++)
{
const LADSPA_PortDescriptor PortDescriptor = descriptor->PortDescriptors[j];
if (PortDescriptor & LADSPA_PORT_AUDIO)
{
if (PortDescriptor & LADSPA_PORT_INPUT)
audio_ins += 1;
else if (PortDescriptor & LADSPA_PORT_OUTPUT)
audio_outs += 1;
audio_total += 1;
}
else if (PortDescriptor & LADSPA_PORT_CONTROL)
{
if (PortDescriptor & LADSPA_PORT_INPUT)
parameters_ins += 1;
else if (PortDescriptor & LADSPA_PORT_OUTPUT)
{
if (strcmp(descriptor->PortNames[j], "latency") != 0 && strcmp(descriptor->PortNames[j], "_latency") != 0)
parameters_outs += 1;
}
parameters_total += 1;
}
}

// small crash-free plugin test
float bufferAudio[bufferSize][audio_total];
memset(&bufferAudio, 0, sizeof(float)*bufferSize*audio_total);

float bufferParams[parameters_total];
memset(&bufferParams, 0, sizeof(float)*parameters_total);

for (unsigned long j=0, iA=0, iP=0; j < descriptor->PortCount; j++)
{
const LADSPA_PortDescriptor PortDescriptor = descriptor->PortDescriptors[j];
if (PortDescriptor & LADSPA_PORT_AUDIO)
descriptor->connect_port(handle, j, bufferAudio[iA++]);
else if (PortDescriptor & LADSPA_PORT_CONTROL)
descriptor->connect_port(handle, j, &bufferParams[iP++]);
}

if (descriptor->activate)
descriptor->activate(handle);

descriptor->run(handle, bufferSize);

if (descriptor->deactivate)
descriptor->deactivate(handle);

DISCOVERY_OUT("hints", hints);
DISCOVERY_OUT("category", category);
DISCOVERY_OUT("audio.ins", audio_ins);
DISCOVERY_OUT("audio.outs", audio_outs);
DISCOVERY_OUT("audio.total", audio_total);
DISCOVERY_OUT("midi.ins", midi_ins);
DISCOVERY_OUT("midi.outs", midi_outs);
DISCOVERY_OUT("midi.total", midi_total);
DISCOVERY_OUT("parameters.ins", parameters_ins);
DISCOVERY_OUT("parameters.outs", parameters_outs);
DISCOVERY_OUT("parameters.total", parameters_total);
DISCOVERY_OUT("programs.total", programs_total);
DISCOVERY_OUT("end", "------------");

if (descriptor->cleanup)
descriptor->cleanup(handle);
}
else
DISCOVERY_OUT("error", "Failed to init LADSPA plugin");
}
}

void do_dssi_check(void* lib_handle)
{
LADSPA_Handle handle;
const LADSPA_Descriptor* ldescriptor;
const DSSI_Descriptor* descriptor;
DSSI_Descriptor_Function descfn = (DSSI_Descriptor_Function)lib_symbol(lib_handle, "dssi_descriptor");

if (descfn == nullptr)
{
DISCOVERY_OUT("error", "Not a DSSI plugin");
return;
}

unsigned long i = 0;
while ((descriptor = descfn(i++)))
{
ldescriptor = descriptor->LADSPA_Plugin;
handle = ldescriptor->instantiate(ldescriptor, sampleRate);

if (handle)
{
DISCOVERY_OUT("init", "-----------");
DISCOVERY_OUT("name", ldescriptor->Name);
DISCOVERY_OUT("label", ldescriptor->Label);
DISCOVERY_OUT("maker", ldescriptor->Maker);
DISCOVERY_OUT("copyright", ldescriptor->Copyright);
DISCOVERY_OUT("id", ldescriptor->UniqueID);

int hints = 0;
PluginInfoCategory category = PLUGIN_CATEGORY_NONE;

int audio_ins = 0;
int audio_outs = 0;
int audio_total = 0;
int midi_ins = 0;
int midi_outs = 0;
int midi_total = 0;
int parameters_ins = 0;
int parameters_outs = 0;
int parameters_total = 0;
int programs_total = 0;

for (unsigned long j=0; j < ldescriptor->PortCount; j++)
{
const LADSPA_PortDescriptor PortDescriptor = ldescriptor->PortDescriptors[j];
if (PortDescriptor & LADSPA_PORT_AUDIO)
{
if (PortDescriptor & LADSPA_PORT_INPUT)
audio_ins += 1;
else if (PortDescriptor & LADSPA_PORT_OUTPUT)
audio_outs += 1;
audio_total += 1;
}
else if (PortDescriptor & LADSPA_PORT_CONTROL)
{
if (PortDescriptor & LADSPA_PORT_INPUT)
parameters_ins += 1;
else if (PortDescriptor & LADSPA_PORT_OUTPUT)
{
if (strcmp(ldescriptor->PortNames[j], "latency") != 0 && strcmp(ldescriptor->PortNames[j], "_latency") != 0)
parameters_outs += 1;
}
parameters_total += 1;
}
}

if (descriptor->run_synth || descriptor->run_multiple_synths)
{
midi_ins = 1;
midi_total = 1;
}

if (midi_ins > 0 && audio_outs > 0)
hints |= PLUGIN_IS_SYNTH;

if (descriptor->get_program)
{
while ((descriptor->get_program(handle, programs_total)))
programs_total += 1;
}

// small crash-free plugin test
float bufferAudio[bufferSize][audio_total];
memset(&bufferAudio, 0, sizeof(float)*bufferSize*audio_total);

float bufferParams[parameters_total];
memset(&bufferParams, 0, sizeof(float)*parameters_total);

snd_seq_event_t midiEvents[2];
memset(&midiEvents, 0, sizeof(snd_seq_event_t)*2);

unsigned long midiEventCount = 2;

midiEvents[0].type = SND_SEQ_EVENT_NOTEON;
midiEvents[0].data.note.note = 64;
midiEvents[0].data.note.velocity = 100;

midiEvents[1].type = SND_SEQ_EVENT_NOTEOFF;
midiEvents[1].data.note.note = 64;
midiEvents[1].data.note.velocity = 0;
midiEvents[1].time.tick = bufferSize/2;

for (unsigned long j=0, iA=0, iP=0; j < ldescriptor->PortCount; j++)
{
const LADSPA_PortDescriptor PortDescriptor = ldescriptor->PortDescriptors[j];
if (PortDescriptor & LADSPA_PORT_AUDIO)
ldescriptor->connect_port(handle, j, bufferAudio[iA++]);
else if (PortDescriptor & LADSPA_PORT_CONTROL)
ldescriptor->connect_port(handle, j, &bufferParams[iP++]);
}

if (ldescriptor->activate)
ldescriptor->activate(handle);

if (descriptor->run_synth)
descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount);
else if (descriptor->run_multiple_synths)
{
snd_seq_event_t* midiEventsPtr[] = { midiEvents, nullptr };
descriptor->run_multiple_synths(1, &handle, bufferSize, midiEventsPtr, &midiEventCount);
}
else
ldescriptor->run(handle, bufferSize);

if (ldescriptor->deactivate)
ldescriptor->deactivate(handle);

DISCOVERY_OUT("hints", hints);
DISCOVERY_OUT("category", category);
DISCOVERY_OUT("audio.ins", audio_ins);
DISCOVERY_OUT("audio.outs", audio_outs);
DISCOVERY_OUT("audio.total", audio_total);
DISCOVERY_OUT("midi.ins", midi_ins);
DISCOVERY_OUT("midi.outs", midi_outs);
DISCOVERY_OUT("midi.total", midi_total);
DISCOVERY_OUT("parameters.ins", parameters_ins);
DISCOVERY_OUT("parameters.outs", parameters_outs);
DISCOVERY_OUT("parameters.total", parameters_total);
DISCOVERY_OUT("programs.total", programs_total);
DISCOVERY_OUT("end", "------------");

if (ldescriptor->cleanup)
ldescriptor->cleanup(handle);
}
else
DISCOVERY_OUT("error", "Failed to init DSSI plugin");
}
}

void do_lv2_check(const char* bundle)
{
// TODO
(void)bundle;
}

void do_vst_check(void* lib_handle)
{
VST_Function vstfn = (VST_Function)lib_symbol(lib_handle, "VSTPluginMain");
if (vstfn == nullptr)
{
if (vstfn == nullptr)
{
#ifdef TARGET_API_MAC_CARBON
vstfn = (VST_Function)lib_symbol(lib_handle, "main_macho");
if (vstfn == nullptr)
#endif
vstfn = (VST_Function)lib_symbol(lib_handle, "main");
}
}

if (vstfn == nullptr)
{
DISCOVERY_OUT("error", "Not a VST plugin");
return;
}

AEffect* effect = vstfn(VstHostCallback);

if (effect && effect->magic == kEffectMagic)
{
const char* c_name;
const char* c_product;
const char* c_vendor;
char buf_str[255] = { 0 };

effect->dispatcher(effect, effGetEffectName, 0, 0, buf_str, 0.0f);
c_name = strdup((buf_str[0] != 0) ? buf_str : "");
buf_str[0] = 0;
effect->dispatcher(effect, effGetProductString, 0, 0, buf_str, 0.0f);
c_product = strdup((buf_str[0] != 0) ? buf_str : "");

buf_str[0] = 0;
effect->dispatcher(effect, effGetVendorString, 0, 0, buf_str, 0.0f);
c_vendor = strdup((buf_str[0] != 0) ? buf_str : "");
VstCurrentUniqueId = effect->uniqueID;
intptr_t VstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f);

while (true)
{
DISCOVERY_OUT("init", "-----------");
effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
DISCOVERY_OUT("name", c_name);
DISCOVERY_OUT("label", c_product);
DISCOVERY_OUT("maker", c_vendor);
DISCOVERY_OUT("copyright", c_vendor);
DISCOVERY_OUT("id", VstCurrentUniqueId);
int hints = 0;
PluginInfoCategory category = PLUGIN_CATEGORY_NONE;
switch (VstCategory)
{
case kPlugCategUnknown:
category = PLUGIN_CATEGORY_NONE;
break;
case kPlugCategSynth:
category = PLUGIN_CATEGORY_SYNTH;
break;
case kPlugCategAnalysis:
category = PLUGIN_CATEGORY_UTILITY;
break;
case kPlugCategMastering:
category = PLUGIN_CATEGORY_DYNAMICS;
break;
case kPlugCategRoomFx:
category = PLUGIN_CATEGORY_DELAY;
break;
case kPlugCategRestoration:
category = PLUGIN_CATEGORY_UTILITY;
break;
case kPlugCategGenerator:
category = PLUGIN_CATEGORY_SYNTH;
break;
default:
category = PLUGIN_CATEGORY_OUTRO;
}
if (effect->flags & effFlagsHasEditor)
hints |= PLUGIN_HAS_GUI;
if (effect->flags & effFlagsIsSynth)
{
hints |= PLUGIN_IS_SYNTH;
if (category == PLUGIN_CATEGORY_NONE)
category = PLUGIN_CATEGORY_SYNTH;
}
int audio_ins = effect->numInputs;
int audio_outs = effect->numOutputs;
int audio_total = audio_ins + audio_outs;
int midi_ins = 0;
int midi_outs = 0;
int midi_total = 0;
int parameters_ins = effect->numParams;
int parameters_outs = 0;
int parameters_total = parameters_ins;
int programs_total = effect->numPrograms;
if (VstPluginCanDo(effect, "receiveVstEvents") || VstPluginCanDo(effect, "receiveVstMidiEvent") || effect->flags & effFlagsIsSynth)
midi_ins = 1;
if (VstPluginCanDo(effect, "sendVstEvents") || VstPluginCanDo(effect, "sendVstMidiEvent"))
midi_outs = 1;
midi_total = midi_ins + midi_outs;
// small crash-free plugin test
float** bufferAudioIn = new float* [audio_ins];
for (int j=0; j < audio_ins; j++)
{
bufferAudioIn[j] = new float [bufferSize];
memset(bufferAudioIn[j], 0, sizeof(float)*bufferSize);
}
float** bufferAudioOut = new float* [audio_outs];
for (int j=0; j < audio_outs; j++)
{
bufferAudioOut[j] = new float [bufferSize];
memset(bufferAudioOut[j], 0, sizeof(float)*bufferSize);
}
struct {
int32_t numEvents;
intptr_t reserved;
VstEvent* data[2];
} events;
VstMidiEvent midiEvents[2];
memset(&midiEvents, 0, sizeof(VstMidiEvent)*2);
midiEvents[0].type = kVstMidiType;
midiEvents[0].byteSize = sizeof(VstMidiEvent);
midiEvents[0].midiData[0] = 0x90;
midiEvents[0].midiData[1] = 64;
midiEvents[0].midiData[2] = 100;
midiEvents[1].type = kVstMidiType;
midiEvents[1].byteSize = sizeof(VstMidiEvent);
midiEvents[1].midiData[0] = 0x90;
midiEvents[1].midiData[1] = 64;
midiEvents[1].deltaFrames = bufferSize/2;
events.numEvents = 2;
events.reserved = 0;
events.data[0] = (VstEvent*)&midiEvents[0];
events.data[1] = (VstEvent*)&midiEvents[1];
#if !VST_FORCE_DEPRECATED
effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, bufferSize, nullptr, sampleRate);
#endif
effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, sampleRate);
effect->dispatcher(effect, effSetBlockSize, 0, bufferSize, nullptr, 0.0f);
effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
if (midi_ins == 1)
effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);
if (effect->flags & effFlagsCanReplacing)
effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
#if !VST_FORCE_DEPRECATED
else
effect->process(effect, bufferAudioIn, bufferAudioOut, bufferSize);
#endif
effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
for (int j=0; j < audio_ins; j++)
delete[] bufferAudioIn[j];
for (int j=0; j < audio_outs; j++)
delete[] bufferAudioOut[j];
delete[] bufferAudioIn;
delete[] bufferAudioOut;
DISCOVERY_OUT("hints", hints);
DISCOVERY_OUT("category", category);
DISCOVERY_OUT("audio.ins", audio_ins);
DISCOVERY_OUT("audio.outs", audio_outs);
DISCOVERY_OUT("audio.total", audio_total);
DISCOVERY_OUT("midi.ins", midi_ins);
DISCOVERY_OUT("midi.outs", midi_outs);
DISCOVERY_OUT("midi.total", midi_total);
DISCOVERY_OUT("parameters.ins", parameters_ins);
DISCOVERY_OUT("parameters.outs", parameters_outs);
DISCOVERY_OUT("parameters.total", parameters_total);
DISCOVERY_OUT("programs.total", programs_total);

effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
DISCOVERY_OUT("end", "------------");
if (VstCategory == kPlugCategShell)
{
buf_str[0] = 0;
VstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, buf_str, 0.0f);
if (VstCurrentUniqueId != 0)
{
free((void*)c_name);
c_name = strdup((buf_str[0] != 0) ? buf_str : "");
}
else
break;
}
else
break;
}
free((void*)c_name);
free((void*)c_product);
free((void*)c_vendor);
}
else
DISCOVERY_OUT("error", "Failed to init VST plugin");
}

void do_sf2_check(const char* filename)
{
#ifdef WANT_FLUIDSYNTH
if (fluid_is_soundfont(filename))
{
fluid_settings_t* f_settings = new_fluid_settings();
fluid_synth_t* f_synth = new_fluid_synth(f_settings);
int f_id = fluid_synth_sfload(f_synth, filename, 0);

if (f_id >= 0)
{
int programs = 0;
fluid_sfont_t* f_sfont;
fluid_preset_t f_preset;

f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id);

// initial check to know how much midi-programs we get
f_sfont->iteration_start(f_sfont);
while (f_sfont->iteration_next(f_sfont, &f_preset))
programs += 1;

DISCOVERY_OUT("init", "-----------");
DISCOVERY_OUT("name", "");
DISCOVERY_OUT("label", "");
DISCOVERY_OUT("maker", "");
DISCOVERY_OUT("copyright", "");
DISCOVERY_OUT("id", 0);

DISCOVERY_OUT("hints", 0);
DISCOVERY_OUT("category", PLUGIN_CATEGORY_SYNTH);
DISCOVERY_OUT("audio.ins", 0);
DISCOVERY_OUT("audio.outs", 2);
DISCOVERY_OUT("audio.total", 2);
DISCOVERY_OUT("midi.ins", 1);
DISCOVERY_OUT("midi.outs", 0);
DISCOVERY_OUT("midi.total", 1);
DISCOVERY_OUT("programs.total", programs);

// defined in Carla
DISCOVERY_OUT("parameters.ins", 13);
DISCOVERY_OUT("parameters.outs", 1);
DISCOVERY_OUT("parameters.total", 14);

DISCOVERY_OUT("end", "------------");
}
else
DISCOVERY_OUT("error", "Failed to load SF2 file");

delete_fluid_synth(f_synth);
delete_fluid_settings(f_settings);
}
else
DISCOVERY_OUT("error", "Not a SF2 file");
#else
(void)filename;
DISCOVERY_OUT("error", "SF2 support not available");
#endif
}

// ------------------------------ main entry point ------------------------------
int main(int argc, char* argv[])
{
if (argc != 3)
return 1;

const char* type_str = argv[1];
const char* filename = argv[2];

bool open_lib;
PluginType type;
void* handle = 0;

if (strcmp(type_str, "LADSPA") == 0)
{
open_lib = true;
type = PLUGIN_LADSPA;
}
else if (strcmp(type_str, "DSSI") == 0)
{
open_lib = true;
type = PLUGIN_DSSI;
}
else if (strcmp(type_str, "LV2") == 0)
{
open_lib = false;
type = PLUGIN_LV2;
}
else if (strcmp(type_str, "VST") == 0)
{
open_lib = true;
type = PLUGIN_VST;
}
else if (strcmp(type_str, "SF2") == 0)
{
open_lib = false;
type = PLUGIN_SF2;
}
else
{
open_lib = false;
type = PLUGIN_NONE;
}

if (open_lib)
{
handle = lib_open(filename);

if (handle == nullptr)
{
const char* error = lib_error(filename);
// Since discovery can find multi-architecture binaries, don't print ELF related errors
if (error && (strstr(error, "wrong ELF class") == nullptr || strstr(error, "Bad EXE format") == nullptr))
DISCOVERY_OUT("error", error);
return 1;
}
}

switch (type)
{
case PLUGIN_LADSPA:
do_ladspa_check(handle);
break;
case PLUGIN_DSSI:
do_dssi_check(handle);
break;
case PLUGIN_LV2:
do_lv2_check(filename);
break;
case PLUGIN_VST:
do_vst_check(handle);
break;
case PLUGIN_SF2:
do_sf2_check(filename);
break;
default:
break;
}

if (open_lib)
lib_close(handle);

return 0;
}

+ 437
- 0
src/carla-includes/dssi/dssi.h View File

@@ -0,0 +1,437 @@
/* -*- c-basic-offset: 4 -*- */

/* dssi.h

DSSI version 1.0
Copyright (c) 2004, 2009 Chris Cannam, Steve Harris and Sean Bolton
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA
*/

#ifndef DSSI_INCLUDED
#define DSSI_INCLUDED

#include "../ladspa/ladspa.h"
#include "seq_event-compat.h"

#define DSSI_VERSION "1.0"
#define DSSI_VERSION_MAJOR 1
#define DSSI_VERSION_MINOR 0

#ifdef __cplusplus
extern "C" {
#endif

/*
There is a need for an API that supports hosted MIDI soft synths
with GUIs in Linux audio applications. In time the GMPI initiative
should comprehensively address this need, but the requirement for
Linux applications to be able to support simple hosted synths is
here now, and GMPI is not. This proposal (the "DSSI Soft Synth
Interface" or DSSI, pronounced "dizzy") aims to provide a simple
solution in a way that we hope will prove complete and compelling
enough to support now, yet not so compelling as to supplant GMPI or
any other comprehensive future proposal.

For simplicity and familiarity, this API is based as far as
possible on existing work -- the LADSPA plugin API for control
values and audio processing, and the ALSA sequencer event types for
MIDI event communication. The GUI part of the proposal is quite
new, but may also be applicable retroactively to LADSPA plugins
that do not otherwise support this synth interface.
*/

typedef struct _DSSI_Program_Descriptor {

/** Bank number for this program. Note that DSSI does not support
MIDI-style separation of bank LSB and MSB values. There is no
restriction on the set of available banks: the numbers do not
need to be contiguous, there does not need to be a bank 0, etc. */
unsigned long Bank;

/** Program number (unique within its bank) for this program.
There is no restriction on the set of available programs: the
numbers do not need to be contiguous, there does not need to
be a program 0, etc. */
unsigned long Program;

/** Name of the program. */
const char * Name;

} DSSI_Program_Descriptor;


typedef struct _DSSI_Descriptor {

/**
* DSSI_API_Version
*
* This member indicates the DSSI API level used by this plugin.
* If we're lucky, this will never be needed. For now all plugins
* must set it to 1.
*/
int DSSI_API_Version;

/**
* LADSPA_Plugin
*
* A DSSI synth plugin consists of a LADSPA plugin plus an
* additional framework for controlling program settings and
* transmitting MIDI events. A plugin must fully implement the
* LADSPA descriptor fields as well as the required LADSPA
* functions including instantiate() and (de)activate(). It
* should also implement run(), with the same behaviour as if
* run_synth() (below) were called with no synth events.
*
* In order to instantiate a synth the host calls the LADSPA
* instantiate function, passing in this LADSPA_Descriptor
* pointer. The returned LADSPA_Handle is used as the argument
* for the DSSI functions below as well as for the LADSPA ones.
*/
const LADSPA_Descriptor *LADSPA_Plugin;

/**
* configure()
*
* This member is a function pointer that sends a piece of
* configuration data to the plugin. The key argument specifies
* some aspect of the synth's configuration that is to be changed,
* and the value argument specifies a new value for it. A plugin
* that does not require this facility at all may set this member
* to NULL.
*
* This call is intended to set some session-scoped aspect of a
* plugin's behaviour, for example to tell the plugin to load
* sample data from a particular file. The plugin should act
* immediately on the request. The call should return NULL on
* success, or an error string that may be shown to the user. The
* host will free the returned value after use if it is non-NULL.
*
* Calls to configure() are not automated as timed events.
* Instead, a host should remember the last value associated with
* each key passed to configure() during a given session for a
* given plugin instance, and should call configure() with the
* correct value for each key the next time it instantiates the
* "same" plugin instance, for example on reloading a project in
* which the plugin was used before. Plugins should note that a
* host may typically instantiate a plugin multiple times with the
* same configuration values, and should share data between
* instances where practical.
*
* Calling configure() completely invalidates the program and bank
* information last obtained from the plugin.
*
* Reserved and special key prefixes
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* The DSSI: prefix
* ----------------
* Configure keys starting with DSSI: are reserved for particular
* purposes documented in the DSSI specification. At the moment,
* there is one such key: DSSI:PROJECT_DIRECTORY. A host may call
* configure() passing this key and a directory path value. This
* indicates to the plugin and its UI that a directory at that
* path exists and may be used for project-local data. Plugins
* may wish to use the project directory as a fallback location
* when looking for other file data, or as a base for relative
* paths in other configuration values.
*
* The GLOBAL: prefix
* ------------------
* Configure keys starting with GLOBAL: may be used by the plugin
* and its UI for any purpose, but are treated specially by the
* host. When one of these keys is used in a configure OSC call
* from the plugin UI, the host makes the corresponding configure
* call (preserving the GLOBAL: prefix) not only to the target
* plugin but also to all other plugins in the same instance
* group, as well as their UIs. Note that if any instance
* returns non-NULL from configure to indicate error, the host
* may stop there (and the set of plugins on which configure has
* been called will thus depend on the host implementation).
* See also the configure OSC call documentation in RFC.txt.
*/
char *(*configure)(LADSPA_Handle Instance,
const char *Key,
const char *Value);

#define DSSI_RESERVED_CONFIGURE_PREFIX "DSSI:"
#define DSSI_GLOBAL_CONFIGURE_PREFIX "GLOBAL:"
#define DSSI_PROJECT_DIRECTORY_KEY \
DSSI_RESERVED_CONFIGURE_PREFIX "PROJECT_DIRECTORY"

/**
* get_program()
*
* This member is a function pointer that provides a description
* of a program (named preset sound) available on this synth. A
* plugin that does not support programs at all should set this
* member to NULL.
*
* The Index argument is an index into the plugin's list of
* programs, not a program number as represented by the Program
* field of the DSSI_Program_Descriptor. (This distinction is
* needed to support synths that use non-contiguous program or
* bank numbers.)
*
* This function returns a DSSI_Program_Descriptor pointer that is
* guaranteed to be valid only until the next call to get_program,
* deactivate, or configure, on the same plugin instance. This
* function must return NULL if passed an Index argument out of
* range, so that the host can use it to query the number of
* programs as well as their properties.
*/
const DSSI_Program_Descriptor *(*get_program)(LADSPA_Handle Instance,
unsigned long Index);
/**
* select_program()
*
* This member is a function pointer that selects a new program
* for this synth. The program change should take effect
* immediately at the start of the next run_synth() call. (This
* means that a host providing the capability of changing programs
* between any two notes on a track must vary the block size so as
* to place the program change at the right place. A host that
* wanted to avoid this would probably just instantiate a plugin
* for each program.)
*
* A plugin that does not support programs at all should set this
* member NULL. Plugins should ignore a select_program() call
* with an invalid bank or program.
*
* A plugin is not required to select any particular default
* program on activate(): it's the host's duty to set a program
* explicitly. The current program is invalidated by any call to
* configure().
*
* A plugin is permitted to re-write the values of its input
* control ports when select_program is called. The host should
* re-read the input control port values and update its own
* records appropriately. (This is the only circumstance in
* which a DSSI plugin is allowed to modify its own input ports.)
*/
void (*select_program)(LADSPA_Handle Instance,
unsigned long Bank,
unsigned long Program);

/**
* get_midi_controller_for_port()
*
* This member is a function pointer that returns the MIDI
* controller number or NRPN that should be mapped to the given
* input control port. If the given port should not have any MIDI
* controller mapped to it, the function should return DSSI_NONE.
* The behaviour of this function is undefined if the given port
* number does not correspond to an input control port. A plugin
* that does not want MIDI controllers mapped to ports at all may
* set this member NULL.
*
* Correct values can be got using the macros DSSI_CC(num) and
* DSSI_NRPN(num) as appropriate, and values can be combined using
* bitwise OR: e.g. DSSI_CC(23) | DSSI_NRPN(1069) means the port
* should respond to CC #23 and NRPN #1069.
*
* The host is responsible for doing proper scaling from MIDI
* controller and NRPN value ranges to port ranges according to
* the plugin's LADSPA port hints. Hosts should not deliver
* through run_synth any MIDI controller events that have already
* been mapped to control port values.
*
* A plugin should not attempt to request mappings from
* controllers 0 or 32 (MIDI Bank Select MSB and LSB).
*/
int (*get_midi_controller_for_port)(LADSPA_Handle Instance,
unsigned long Port);

/**
* run_synth()
*
* This member is a function pointer that runs a synth for a
* block. This is identical in function to the LADSPA run()
* function, except that it also supplies events to the synth.
*
* A plugin may provide this function, run_multiple_synths() (see
* below), both, or neither (if it is not in fact a synth). A
* plugin that does not provide this function must set this member
* to NULL. Authors of synth plugins are encouraged to provide
* this function if at all possible.
*
* The Events pointer points to a block of EventCount ALSA
* sequencer events, which is used to communicate MIDI and related
* events to the synth. Each event is timestamped relative to the
* start of the block, (mis)using the ALSA "tick time" field as a
* frame count. The host is responsible for ensuring that events
* with differing timestamps are already ordered by time.
*
* See also the notes on activation, port connection etc in
* ladpsa.h, in the context of the LADSPA run() function.
*
* Note Events
* ~~~~~~~~~~~
* There are two minor requirements aimed at making the plugin
* writer's life as simple as possible:
*
* 1. A host must never send events of type SND_SEQ_EVENT_NOTE.
* Notes should always be sent as separate SND_SEQ_EVENT_NOTE_ON
* and NOTE_OFF events. A plugin should discard any one-point
* NOTE events it sees.
*
* 2. A host must not attempt to switch notes off by sending
* zero-velocity NOTE_ON events. It should always send true
* NOTE_OFFs. It is the host's responsibility to remap events in
* cases where an external MIDI source has sent it zero-velocity
* NOTE_ONs.
*
* Bank and Program Events
* ~~~~~~~~~~~~~~~~~~~~~~~
* Hosts must map MIDI Bank Select MSB and LSB (0 and 32)
* controllers and MIDI Program Change events onto the banks and
* programs specified by the plugin, using the DSSI select_program
* call. No host should ever deliver a program change or bank
* select controller to a plugin via run_synth.
*/
void (*run_synth)(LADSPA_Handle Instance,
unsigned long SampleCount,
snd_seq_event_t *Events,
unsigned long EventCount);

/**
* run_synth_adding()
*
* This member is a function pointer that runs an instance of a
* synth for a block, adding its outputs to the values already
* present at the output ports. This is provided for symmetry
* with LADSPA run_adding(), and is equally optional. A plugin
* that does not provide it must set this member to NULL.
*/
void (*run_synth_adding)(LADSPA_Handle Instance,
unsigned long SampleCount,
snd_seq_event_t *Events,
unsigned long EventCount);

/**
* run_multiple_synths()
*
* This member is a function pointer that runs multiple synth
* instances for a block. This is very similar to run_synth(),
* except that Instances, Events, and EventCounts each point to
* arrays that hold the LADSPA handles, event buffers, and
* event counts for each of InstanceCount instances. That is,
* Instances points to an array of InstanceCount pointers to
* DSSI plugin instantiations, Events points to an array of
* pointers to each instantiation's respective event list, and
* EventCounts points to an array containing each instantiation's
* respective event count.
*
* A host using this function must guarantee that ALL active
* instances of the plugin are represented in each call to the
* function -- that is, a host may not call run_multiple_synths()
* for some instances of a given plugin and then call run_synth()
* as well for others. 'All .. instances of the plugin' means
* every instance sharing the same LADSPA label and shared object
* (*.so) file (rather than every instance sharing the same *.so).
* 'Active' means any instance for which activate() has been called
* but deactivate() has not.
*
* A plugin may provide this function, run_synths() (see above),
* both, or neither (if it not in fact a synth). A plugin that
* does not provide this function must set this member to NULL.
* Plugin authors implementing run_multiple_synths are strongly
* encouraged to implement run_synth as well if at all possible,
* to aid simplistic hosts, even where it would be less efficient
* to use it.
*/
void (*run_multiple_synths)(unsigned long InstanceCount,
LADSPA_Handle *Instances,
unsigned long SampleCount,
snd_seq_event_t **Events,
unsigned long *EventCounts);

/**
* run_multiple_synths_adding()
*
* This member is a function pointer that runs multiple synth
* instances for a block, adding each synth's outputs to the
* values already present at the output ports. This is provided
* for symmetry with both the DSSI run_multiple_synths() and LADSPA
* run_adding() functions, and is equally optional. A plugin
* that does not provide it must set this member to NULL.
*/
void (*run_multiple_synths_adding)(unsigned long InstanceCount,
LADSPA_Handle *Instances,
unsigned long SampleCount,
snd_seq_event_t **Events,
unsigned long *EventCounts);

/**
* set_custom_data()
*/
int (*set_custom_data)(LADSPA_Handle Instance, void *Data, unsigned long DataLength);

/**
* get_custom_data()
*/
int (*get_custom_data)(LADSPA_Handle Instance, void **Data, unsigned long *DataLength);

} DSSI_Descriptor;

/**
* DSSI supports a plugin discovery method similar to that of LADSPA:
*
* - DSSI hosts may wish to locate DSSI plugin shared object files by
* searching the paths contained in the DSSI_PATH and LADSPA_PATH
* environment variables, if they are present. Both are expected
* to be colon-separated lists of directories to be searched (in
* order), and DSSI_PATH should be searched first if both variables
* are set.
*
* - Each shared object file containing DSSI plugins must include a
* function dssi_descriptor(), with the following function prototype
* and C-style linkage. Hosts may enumerate the plugin types
* available in the shared object file by repeatedly calling
* this function with successive Index values (beginning from 0),
* until a return value of NULL indicates no more plugin types are
* available. Each non-NULL return is the DSSI_Descriptor
* of a distinct plugin type.
*/

const DSSI_Descriptor *dssi_descriptor(unsigned long Index);
typedef const DSSI_Descriptor *(*DSSI_Descriptor_Function)(unsigned long Index);

/*
* Macros to specify particular MIDI controllers in return values from
* get_midi_controller_for_port()
*/

#define DSSI_CC_BITS 0x20000000
#define DSSI_NRPN_BITS 0x40000000

#define DSSI_NONE -1
#define DSSI_CONTROLLER_IS_SET(n) (DSSI_NONE != (n))

#define DSSI_CC(n) (DSSI_CC_BITS | (n))
#define DSSI_IS_CC(n) (DSSI_CC_BITS & (n))
#define DSSI_CC_NUMBER(n) ((n) & 0x7f)

#define DSSI_NRPN(n) (DSSI_NRPN_BITS | ((n) << 7))
#define DSSI_IS_NRPN(n) (DSSI_NRPN_BITS & (n))
#define DSSI_NRPN_NUMBER(n) (((n) >> 7) & 0x3fff)

#ifdef __cplusplus
}
#endif

#endif /* DSSI_INCLUDED */

+ 272
- 0
src/carla-includes/dssi/seq_event-compat.h View File

@@ -0,0 +1,272 @@
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/

#ifndef __ALSA_SEQ_EVENT_COMPAT_H
#define __ALSA_SEQ_EVENT_COMPAT_H

/**
* Sequencer event data type
*/
typedef unsigned char snd_seq_event_type_t;

/** Sequencer event type */
enum snd_seq_event_type {
/** system status; event data type = #snd_seq_result_t */
SND_SEQ_EVENT_SYSTEM = 0,
/** returned result status; event data type = #snd_seq_result_t */
SND_SEQ_EVENT_RESULT,

/** note on and off with duration; event data type = #snd_seq_ev_note_t */
SND_SEQ_EVENT_NOTE = 5,
/** note on; event data type = #snd_seq_ev_note_t */
SND_SEQ_EVENT_NOTEON,
/** note off; event data type = #snd_seq_ev_note_t */
SND_SEQ_EVENT_NOTEOFF,
/** key pressure change (aftertouch); event data type = #snd_seq_ev_note_t */
SND_SEQ_EVENT_KEYPRESS,

/** controller; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_CONTROLLER = 10,
/** program change; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_PGMCHANGE,
/** channel pressure; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_CHANPRESS,
/** pitchwheel; event data type = #snd_seq_ev_ctrl_t; data is from -8192 to 8191) */
SND_SEQ_EVENT_PITCHBEND,
/** 14 bit controller value; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_CONTROL14,
/** 14 bit NRPN; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_NONREGPARAM,
/** 14 bit RPN; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_REGPARAM,

/** SPP with LSB and MSB values; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_SONGPOS = 20,
/** Song Select with song ID number; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_SONGSEL,
/** midi time code quarter frame; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_QFRAME,
/** SMF Time Signature event; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_TIMESIGN,
/** SMF Key Signature event; event data type = #snd_seq_ev_ctrl_t */
SND_SEQ_EVENT_KEYSIGN,

/** MIDI Real Time Start message; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_START = 30,
/** MIDI Real Time Continue message; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_CONTINUE,
/** MIDI Real Time Stop message; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_STOP,
/** Set tick queue position; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_SETPOS_TICK,
/** Set real-time queue position; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_SETPOS_TIME,
/** (SMF) Tempo event; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_TEMPO,
/** MIDI Real Time Clock message; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_CLOCK,
/** MIDI Real Time Tick message; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_TICK,
/** Queue timer skew; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_QUEUE_SKEW,
/** Sync position changed; event data type = #snd_seq_ev_queue_control_t */
SND_SEQ_EVENT_SYNC_POS,

/** Tune request; event data type = none */
SND_SEQ_EVENT_TUNE_REQUEST = 40,
/** Reset to power-on state; event data type = none */
SND_SEQ_EVENT_RESET,
/** Active sensing event; event data type = none */
SND_SEQ_EVENT_SENSING,

/** Echo-back event; event data type = any type */
SND_SEQ_EVENT_ECHO = 50,
/** OSS emulation raw event; event data type = any type */
SND_SEQ_EVENT_OSS,

/** New client has connected; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_CLIENT_START = 60,
/** Client has left the system; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_CLIENT_EXIT,
/** Client status/info has changed; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_CLIENT_CHANGE,
/** New port was created; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_PORT_START,
/** Port was deleted from system; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_PORT_EXIT,
/** Port status/info has changed; event data type = #snd_seq_addr_t */
SND_SEQ_EVENT_PORT_CHANGE,

/** Ports connected; event data type = #snd_seq_connect_t */
SND_SEQ_EVENT_PORT_SUBSCRIBED,
/** Ports disconnected; event data type = #snd_seq_connect_t */
SND_SEQ_EVENT_PORT_UNSUBSCRIBED,

/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR0 = 90,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR1,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR2,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR3,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR4,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR5,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR6,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR7,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR8,
/** user-defined event; event data type = any (fixed size) */
SND_SEQ_EVENT_USR9,

/** system exclusive data (variable length); event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_SYSEX = 130,
/** error event; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_BOUNCE,
/** reserved for user apps; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_USR_VAR0 = 135,
/** reserved for user apps; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_USR_VAR1,
/** reserved for user apps; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_USR_VAR2,
/** reserved for user apps; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_USR_VAR3,
/** reserved for user apps; event data type = #snd_seq_ev_ext_t */
SND_SEQ_EVENT_USR_VAR4,

/** NOP; ignored in any case */
SND_SEQ_EVENT_NONE = 255
};

/** Sequencer event address */
typedef struct snd_seq_addr {
unsigned char client; /**< Client id */
unsigned char port; /**< Port id */
} snd_seq_addr_t;

/** Connection (subscription) between ports */
typedef struct snd_seq_connect {
snd_seq_addr_t sender; /**< sender address */
snd_seq_addr_t dest; /**< destination address */
} snd_seq_connect_t;

/** Real-time data record */
typedef struct snd_seq_real_time {
unsigned int tv_sec; /**< seconds */
unsigned int tv_nsec; /**< nanoseconds */
} snd_seq_real_time_t;

/** (MIDI) Tick-time data record */
typedef unsigned int snd_seq_tick_time_t;

/** unioned time stamp */
typedef union snd_seq_timestamp {
snd_seq_tick_time_t tick; /**< tick-time */
struct snd_seq_real_time time; /**< real-time */
} snd_seq_timestamp_t;

/** Note event */
typedef struct snd_seq_ev_note {
unsigned char channel; /**< channel number */
unsigned char note; /**< note */
unsigned char velocity; /**< velocity */
unsigned char off_velocity; /**< note-off velocity; only for #SND_SEQ_EVENT_NOTE */
unsigned int duration; /**< duration until note-off; only for #SND_SEQ_EVENT_NOTE */
} snd_seq_ev_note_t;

/** Controller event */
typedef struct snd_seq_ev_ctrl {
unsigned char channel; /**< channel number */
unsigned char unused[3]; /**< reserved */
unsigned int param; /**< control parameter */
signed int value; /**< control value */
} snd_seq_ev_ctrl_t;

/** generic set of bytes (12x8 bit) */
typedef struct snd_seq_ev_raw8 {
unsigned char d[12]; /**< 8 bit value */
} snd_seq_ev_raw8_t;

/** generic set of integers (3x32 bit) */
typedef struct snd_seq_ev_raw32 {
unsigned int d[3]; /**< 32 bit value */
} snd_seq_ev_raw32_t;

/** external stored data */
typedef struct snd_seq_ev_ext {
unsigned int len; /**< length of data */
void *ptr; /**< pointer to data (note: can be 64-bit) */
} __attribute__((packed)) snd_seq_ev_ext_t;

/** Result events */
typedef struct snd_seq_result {
int event; /**< processed event type */
int result; /**< status */
} snd_seq_result_t;

/** Queue skew values */
typedef struct snd_seq_queue_skew {
unsigned int value; /**< skew value */
unsigned int base; /**< skew base */
} snd_seq_queue_skew_t;

/** queue timer control */
typedef struct snd_seq_ev_queue_control {
unsigned char queue; /**< affected queue */
unsigned char unused[3]; /**< reserved */
union {
signed int value; /**< affected value (e.g. tempo) */
snd_seq_timestamp_t time; /**< time */
unsigned int position; /**< sync position */
snd_seq_queue_skew_t skew; /**< queue skew */
unsigned int d32[2]; /**< any data */
unsigned char d8[8]; /**< any data */
} param; /**< data value union */
} snd_seq_ev_queue_control_t;

/** Sequencer event */
typedef struct snd_seq_event {
snd_seq_event_type_t type; /**< event type */
unsigned char flags; /**< event flags */
unsigned char tag; /**< tag */

unsigned char queue; /**< schedule queue */
snd_seq_timestamp_t time; /**< schedule time */

snd_seq_addr_t source; /**< source address */
snd_seq_addr_t dest; /**< destination address */

union {
snd_seq_ev_note_t note; /**< note information */
snd_seq_ev_ctrl_t control; /**< MIDI control information */
snd_seq_ev_raw8_t raw8; /**< raw8 data */
snd_seq_ev_raw32_t raw32; /**< raw32 data */
snd_seq_ev_ext_t ext; /**< external data */
snd_seq_ev_queue_control_t queue; /**< queue control */
snd_seq_timestamp_t time; /**< timestamp */
snd_seq_addr_t addr; /**< address */
snd_seq_connect_t connect; /**< connect information */
snd_seq_result_t result; /**< operation result code */
} data; /**< event data... */
} snd_seq_event_t;

#endif /* __ALSA_SEQ_EVENT_COMPAT_H */


+ 603
- 0
src/carla-includes/ladspa/ladspa.h View File

@@ -0,0 +1,603 @@
/* ladspa.h

Linux Audio Developer's Simple Plugin API Version 1.1[LGPL].
Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
Stefan Westerfeld.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA. */

#ifndef LADSPA_INCLUDED
#define LADSPA_INCLUDED

#define LADSPA_VERSION "1.1"
#define LADSPA_VERSION_MAJOR 1
#define LADSPA_VERSION_MINOR 1

#ifdef __cplusplus
extern "C" {
#endif

/*****************************************************************************/

/* Overview:

There is a large number of synthesis packages in use or development
on the Linux platform at this time. This API (`The Linux Audio
Developer's Simple Plugin API') attempts to give programmers the
ability to write simple `plugin' audio processors in C/C++ and link
them dynamically (`plug') into a range of these packages (`hosts').
It should be possible for any host and any plugin to communicate
completely through this interface.

This API is deliberately short and simple. To achieve compatibility
with a range of promising Linux sound synthesis packages it
attempts to find the `greatest common divisor' in their logical
behaviour. Having said this, certain limiting decisions are
implicit, notably the use of a fixed type (LADSPA_Data) for all
data transfer and absence of a parameterised `initialisation'
phase. See below for the LADSPA_Data typedef.

Plugins are expected to distinguish between control and audio
data. Plugins have `ports' that are inputs or outputs for audio or
control data and each plugin is `run' for a `block' corresponding
to a short time interval measured in samples. Audio data is
communicated using arrays of LADSPA_Data, allowing a block of audio
to be processed by the plugin in a single pass. Control data is
communicated using single LADSPA_Data values. Control data has a
single value at the start of a call to the `run()' or `run_adding()'
function, and may be considered to remain this value for its
duration. The plugin may assume that all its input and output ports
have been connected to the relevant data location (see the
`connect_port()' function below) before it is asked to run.

Plugins will reside in shared object files suitable for dynamic
linking by dlopen() and family. The file will provide a number of
`plugin types' that can be used to instantiate actual plugins
(sometimes known as `plugin instances') that can be connected
together to perform tasks.

This API contains very limited error-handling. */

/*****************************************************************************/

/* Fundamental data type passed in and out of plugin. This data type
is used to communicate audio samples and control values. It is
assumed that the plugin will work sensibly given any numeric input
value although it may have a preferred range (see hints below).

For audio it is generally assumed that 1.0f is the `0dB' reference
amplitude and is a `normal' signal level. */

typedef float LADSPA_Data;

/*****************************************************************************/

/* Special Plugin Properties:
Optional features of the plugin type are encapsulated in the
LADSPA_Properties type. This is assembled by ORing individual
properties together. */

typedef int LADSPA_Properties;

/* Property LADSPA_PROPERTY_REALTIME indicates that the plugin has a
real-time dependency (e.g. listens to a MIDI device) and so its
output must not be cached or subject to significant latency. */
#define LADSPA_PROPERTY_REALTIME 0x1

/* Property LADSPA_PROPERTY_INPLACE_BROKEN indicates that the plugin
may cease to work correctly if the host elects to use the same data
location for both input and output (see connect_port()). This
should be avoided as enabling this flag makes it impossible for
hosts to use the plugin to process audio `in-place.' */
#define LADSPA_PROPERTY_INPLACE_BROKEN 0x2

/* Property LADSPA_PROPERTY_HARD_RT_CAPABLE indicates that the plugin
is capable of running not only in a conventional host but also in a
`hard real-time' environment. To qualify for this the plugin must
satisfy all of the following:

(1) The plugin must not use malloc(), free() or other heap memory
management within its run() or run_adding() functions. All new
memory used in run() must be managed via the stack. These
restrictions only apply to the run() function.

(2) The plugin will not attempt to make use of any library
functions with the exceptions of functions in the ANSI standard C
and C maths libraries, which the host is expected to provide.

(3) The plugin will not access files, devices, pipes, sockets, IPC
or any other mechanism that might result in process or thread
blocking.
(4) The plugin will take an amount of time to execute a run() or
run_adding() call approximately of form (A+B*SampleCount) where A
and B depend on the machine and host in use. This amount of time
may not depend on input signals or plugin state. The host is left
the responsibility to perform timings to estimate upper bounds for
A and B. */
#define LADSPA_PROPERTY_HARD_RT_CAPABLE 0x4

#define LADSPA_IS_REALTIME(x) ((x) & LADSPA_PROPERTY_REALTIME)
#define LADSPA_IS_INPLACE_BROKEN(x) ((x) & LADSPA_PROPERTY_INPLACE_BROKEN)
#define LADSPA_IS_HARD_RT_CAPABLE(x) ((x) & LADSPA_PROPERTY_HARD_RT_CAPABLE)

/*****************************************************************************/

/* Plugin Ports:

Plugins have `ports' that are inputs or outputs for audio or
data. Ports can communicate arrays of LADSPA_Data (for audio
inputs/outputs) or single LADSPA_Data values (for control
input/outputs). This information is encapsulated in the
LADSPA_PortDescriptor type which is assembled by ORing individual
properties together.

Note that a port must be an input or an output port but not both
and that a port must be a control or audio port but not both. */

typedef int LADSPA_PortDescriptor;

/* Property LADSPA_PORT_INPUT indicates that the port is an input. */
#define LADSPA_PORT_INPUT 0x1

/* Property LADSPA_PORT_OUTPUT indicates that the port is an output. */
#define LADSPA_PORT_OUTPUT 0x2

/* Property LADSPA_PORT_CONTROL indicates that the port is a control
port. */
#define LADSPA_PORT_CONTROL 0x4

/* Property LADSPA_PORT_AUDIO indicates that the port is a audio
port. */
#define LADSPA_PORT_AUDIO 0x8

#define LADSPA_IS_PORT_INPUT(x) ((x) & LADSPA_PORT_INPUT)
#define LADSPA_IS_PORT_OUTPUT(x) ((x) & LADSPA_PORT_OUTPUT)
#define LADSPA_IS_PORT_CONTROL(x) ((x) & LADSPA_PORT_CONTROL)
#define LADSPA_IS_PORT_AUDIO(x) ((x) & LADSPA_PORT_AUDIO)

/*****************************************************************************/

/* Plugin Port Range Hints:

The host may wish to provide a representation of data entering or
leaving a plugin (e.g. to generate a GUI automatically). To make
this more meaningful, the plugin should provide `hints' to the host
describing the usual values taken by the data.
Note that these are only hints. The host may ignore them and the
plugin must not assume that data supplied to it is meaningful. If
the plugin receives invalid input data it is expected to continue
to run without failure and, where possible, produce a sensible
output (e.g. a high-pass filter given a negative cutoff frequency
might switch to an all-pass mode).
Hints are meaningful for all input and output ports but hints for
input control ports are expected to be particularly useful.
More hint information is encapsulated in the
LADSPA_PortRangeHintDescriptor type which is assembled by ORing
individual hint types together. Hints may require further
LowerBound and UpperBound information.

All the hint information for a particular port is aggregated in the
LADSPA_PortRangeHint structure. */

typedef int LADSPA_PortRangeHintDescriptor;

/* Hint LADSPA_HINT_BOUNDED_BELOW indicates that the LowerBound field
of the LADSPA_PortRangeHint should be considered meaningful. The
value in this field should be considered the (inclusive) lower
bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
specified then the value of LowerBound should be multiplied by the
sample rate. */
#define LADSPA_HINT_BOUNDED_BELOW 0x1

/* Hint LADSPA_HINT_BOUNDED_ABOVE indicates that the UpperBound field
of the LADSPA_PortRangeHint should be considered meaningful. The
value in this field should be considered the (inclusive) upper
bound of the valid range. If LADSPA_HINT_SAMPLE_RATE is also
specified then the value of UpperBound should be multiplied by the
sample rate. */
#define LADSPA_HINT_BOUNDED_ABOVE 0x2

/* Hint LADSPA_HINT_TOGGLED indicates that the data item should be
considered a Boolean toggle. Data less than or equal to zero should
be considered `off' or `false,' and data above zero should be
considered `on' or `true.' LADSPA_HINT_TOGGLED may not be used in
conjunction with any other hint except LADSPA_HINT_DEFAULT_0 or
LADSPA_HINT_DEFAULT_1. */
#define LADSPA_HINT_TOGGLED 0x4

/* Hint LADSPA_HINT_SAMPLE_RATE indicates that any bounds specified
should be interpreted as multiples of the sample rate. For
instance, a frequency range from 0Hz to the Nyquist frequency (half
the sample rate) could be requested by this hint in conjunction
with LowerBound = 0 and UpperBound = 0.5. Hosts that support bounds
at all must support this hint to retain meaning. */
#define LADSPA_HINT_SAMPLE_RATE 0x8

/* Hint LADSPA_HINT_LOGARITHMIC indicates that it is likely that the
user will find it more intuitive to view values using a logarithmic
scale. This is particularly useful for frequencies and gains. */
#define LADSPA_HINT_LOGARITHMIC 0x10

/* Hint LADSPA_HINT_INTEGER indicates that a user interface would
probably wish to provide a stepped control taking only integer
values. Any bounds set should be slightly wider than the actual
integer range required to avoid floating point rounding errors. For
instance, the integer set {0,1,2,3} might be described as [-0.1,
3.1]. */
#define LADSPA_HINT_INTEGER 0x20

/* The various LADSPA_HINT_HAS_DEFAULT_* hints indicate a `normal'
value for the port that is sensible as a default. For instance,
this value is suitable for use as an initial value in a user
interface or as a value the host might assign to a control port
when the user has not provided one. Defaults are encoded using a
mask so only one default may be specified for a port. Some of the
hints make use of lower and upper bounds, in which case the
relevant bound or bounds must be available and
LADSPA_HINT_SAMPLE_RATE must be applied as usual. The resulting
default must be rounded if LADSPA_HINT_INTEGER is present. Default
values were introduced in LADSPA v1.1. */
#define LADSPA_HINT_DEFAULT_MASK 0x3C0

/* This default values indicates that no default is provided. */
#define LADSPA_HINT_DEFAULT_NONE 0x0

/* This default hint indicates that the suggested lower bound for the
port should be used. */
#define LADSPA_HINT_DEFAULT_MINIMUM 0x40

/* This default hint indicates that a low value between the suggested
lower and upper bounds should be chosen. For ports with
LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.75 +
log(upper) * 0.25). Otherwise, this should be (lower * 0.75 + upper
* 0.25). */
#define LADSPA_HINT_DEFAULT_LOW 0x80

/* This default hint indicates that a middle value between the
suggested lower and upper bounds should be chosen. For ports with
LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.5 +
log(upper) * 0.5). Otherwise, this should be (lower * 0.5 + upper *
0.5). */
#define LADSPA_HINT_DEFAULT_MIDDLE 0xC0

/* This default hint indicates that a high value between the suggested
lower and upper bounds should be chosen. For ports with
LADSPA_HINT_LOGARITHMIC, this should be exp(log(lower) * 0.25 +
log(upper) * 0.75). Otherwise, this should be (lower * 0.25 + upper
* 0.75). */
#define LADSPA_HINT_DEFAULT_HIGH 0x100

/* This default hint indicates that the suggested upper bound for the
port should be used. */
#define LADSPA_HINT_DEFAULT_MAXIMUM 0x140

/* This default hint indicates that the number 0 should be used. Note
that this default may be used in conjunction with
LADSPA_HINT_TOGGLED. */
#define LADSPA_HINT_DEFAULT_0 0x200

/* This default hint indicates that the number 1 should be used. Note
that this default may be used in conjunction with
LADSPA_HINT_TOGGLED. */
#define LADSPA_HINT_DEFAULT_1 0x240

/* This default hint indicates that the number 100 should be used. */
#define LADSPA_HINT_DEFAULT_100 0x280

/* This default hint indicates that the Hz frequency of `concert A'
should be used. This will be 440 unless the host uses an unusual
tuning convention, in which case it may be within a few Hz. */
#define LADSPA_HINT_DEFAULT_440 0x2C0

#define LADSPA_IS_HINT_BOUNDED_BELOW(x) ((x) & LADSPA_HINT_BOUNDED_BELOW)
#define LADSPA_IS_HINT_BOUNDED_ABOVE(x) ((x) & LADSPA_HINT_BOUNDED_ABOVE)
#define LADSPA_IS_HINT_TOGGLED(x) ((x) & LADSPA_HINT_TOGGLED)
#define LADSPA_IS_HINT_SAMPLE_RATE(x) ((x) & LADSPA_HINT_SAMPLE_RATE)
#define LADSPA_IS_HINT_LOGARITHMIC(x) ((x) & LADSPA_HINT_LOGARITHMIC)
#define LADSPA_IS_HINT_INTEGER(x) ((x) & LADSPA_HINT_INTEGER)

#define LADSPA_IS_HINT_HAS_DEFAULT(x) ((x) & LADSPA_HINT_DEFAULT_MASK)
#define LADSPA_IS_HINT_DEFAULT_MINIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_MINIMUM)
#define LADSPA_IS_HINT_DEFAULT_LOW(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_LOW)
#define LADSPA_IS_HINT_DEFAULT_MIDDLE(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_MIDDLE)
#define LADSPA_IS_HINT_DEFAULT_HIGH(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_HIGH)
#define LADSPA_IS_HINT_DEFAULT_MAXIMUM(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_MAXIMUM)
#define LADSPA_IS_HINT_DEFAULT_0(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_0)
#define LADSPA_IS_HINT_DEFAULT_1(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_1)
#define LADSPA_IS_HINT_DEFAULT_100(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_100)
#define LADSPA_IS_HINT_DEFAULT_440(x) (((x) & LADSPA_HINT_DEFAULT_MASK) \
== LADSPA_HINT_DEFAULT_440)

typedef struct _LADSPA_PortRangeHint {

/* Hints about the port. */
LADSPA_PortRangeHintDescriptor HintDescriptor;

/* Meaningful when hint LADSPA_HINT_BOUNDED_BELOW is active. When
LADSPA_HINT_SAMPLE_RATE is also active then this value should be
multiplied by the relevant sample rate. */
LADSPA_Data LowerBound;

/* Meaningful when hint LADSPA_HINT_BOUNDED_ABOVE is active. When
LADSPA_HINT_SAMPLE_RATE is also active then this value should be
multiplied by the relevant sample rate. */
LADSPA_Data UpperBound;

} LADSPA_PortRangeHint;

/*****************************************************************************/

/* Plugin Handles:

This plugin handle indicates a particular instance of the plugin
concerned. It is valid to compare this to NULL (0 for C++) but
otherwise the host should not attempt to interpret it. The plugin
may use it to reference internal instance data. */

typedef void * LADSPA_Handle;

/*****************************************************************************/

/* Descriptor for a Type of Plugin:

This structure is used to describe a plugin type. It provides a
number of functions to examine the type, instantiate it, link it to
buffers and workspaces and to run it. */

typedef struct _LADSPA_Descriptor {

/* This numeric identifier indicates the plugin type
uniquely. Plugin programmers may reserve ranges of IDs from a
central body to avoid clashes. Hosts may assume that IDs are
below 0x1000000. */
unsigned long UniqueID;

/* This identifier can be used as a unique, case-sensitive
identifier for the plugin type within the plugin file. Plugin
types should be identified by file and label rather than by index
or plugin name, which may be changed in new plugin
versions. Labels must not contain white-space characters. */
const char * Label;

/* This indicates a number of properties of the plugin. */
LADSPA_Properties Properties;

/* This member points to the null-terminated name of the plugin
(e.g. "Sine Oscillator"). */
const char * Name;

/* This member points to the null-terminated string indicating the
maker of the plugin. This can be an empty string but not NULL. */
const char * Maker;

/* This member points to the null-terminated string indicating any
copyright applying to the plugin. If no Copyright applies the
string "None" should be used. */
const char * Copyright;

/* This indicates the number of ports (input AND output) present on
the plugin. */
unsigned long PortCount;

/* This member indicates an array of port descriptors. Valid indices
vary from 0 to PortCount-1. */
const LADSPA_PortDescriptor * PortDescriptors;

/* This member indicates an array of null-terminated strings
describing ports (e.g. "Frequency (Hz)"). Valid indices vary from
0 to PortCount-1. */
const char * const * PortNames;

/* This member indicates an array of range hints for each port (see
above). Valid indices vary from 0 to PortCount-1. */
const LADSPA_PortRangeHint * PortRangeHints;

/* This may be used by the plugin developer to pass any custom
implementation data into an instantiate call. It must not be used
or interpreted by the host. It is expected that most plugin
writers will not use this facility as LADSPA_Handle should be
used to hold instance data. */
void * ImplementationData;

/* This member is a function pointer that instantiates a plugin. A
handle is returned indicating the new plugin instance. The
instantiation function accepts a sample rate as a parameter. The
plugin descriptor from which this instantiate function was found
must also be passed. This function must return NULL if
instantiation fails.

Note that instance initialisation should generally occur in
activate() rather than here. */
LADSPA_Handle (*instantiate)(const struct _LADSPA_Descriptor * Descriptor,
unsigned long SampleRate);

/* This member is a function pointer that connects a port on an
instantiated plugin to a memory location at which a block of data
for the port will be read/written. The data location is expected
to be an array of LADSPA_Data for audio ports or a single
LADSPA_Data value for control ports. Memory issues will be
managed by the host. The plugin must read/write the data at these
locations every time run() or run_adding() is called and the data
present at the time of this connection call should not be
considered meaningful.

connect_port() may be called more than once for a plugin instance
to allow the host to change the buffers that the plugin is
reading or writing. These calls may be made before or after
activate() or deactivate() calls.

connect_port() must be called at least once for each port before
run() or run_adding() is called. When working with blocks of
LADSPA_Data the plugin should pay careful attention to the block
size passed to the run function as the block allocated may only
just be large enough to contain the block of samples.

Plugin writers should be aware that the host may elect to use the
same buffer for more than one port and even use the same buffer
for both input and output (see LADSPA_PROPERTY_INPLACE_BROKEN).
However, overlapped buffers or use of a single buffer for both
audio and control data may result in unexpected behaviour. */
void (*connect_port)(LADSPA_Handle Instance,
unsigned long Port,
LADSPA_Data * DataLocation);

/* This member is a function pointer that initialises a plugin
instance and activates it for use. This is separated from
instantiate() to aid real-time support and so that hosts can
reinitialise a plugin instance by calling deactivate() and then
activate(). In this case the plugin instance must reset all state
information dependent on the history of the plugin instance
except for any data locations provided by connect_port() and any
gain set by set_run_adding_gain(). If there is nothing for
activate() to do then the plugin writer may provide a NULL rather
than an empty function.

When present, hosts must call this function once before run() (or
run_adding()) is called for the first time. This call should be
made as close to the run() call as possible and indicates to
real-time plugins that they are now live. Plugins should not rely
on a prompt call to run() after activate(). activate() may not be
called again unless deactivate() is called first. Note that
connect_port() may be called before or after a call to
activate(). */
void (*activate)(LADSPA_Handle Instance);

/* This method is a function pointer that runs an instance of a
plugin for a block. Two parameters are required: the first is a
handle to the particular instance to be run and the second
indicates the block size (in samples) for which the plugin
instance may run.

Note that if an activate() function exists then it must be called
before run() or run_adding(). If deactivate() is called for a
plugin instance then the plugin instance may not be reused until
activate() has been called again.

If the plugin has the property LADSPA_PROPERTY_HARD_RT_CAPABLE
then there are various things that the plugin should not do
within the run() or run_adding() functions (see above). */
void (*run)(LADSPA_Handle Instance,
unsigned long SampleCount);

/* This method is a function pointer that runs an instance of a
plugin for a block. This has identical behaviour to run() except
in the way data is output from the plugin. When run() is used,
values are written directly to the memory areas associated with
the output ports. However when run_adding() is called, values
must be added to the values already present in the memory
areas. Furthermore, output values written must be scaled by the
current gain set by set_run_adding_gain() (see below) before
addition.

run_adding() is optional. When it is not provided by a plugin,
this function pointer must be set to NULL. When it is provided,
the function set_run_adding_gain() must be provided also. */
void (*run_adding)(LADSPA_Handle Instance,
unsigned long SampleCount);

/* This method is a function pointer that sets the output gain for
use when run_adding() is called (see above). If this function is
never called the gain is assumed to default to 1. Gain
information should be retained when activate() or deactivate()
are called.

This function should be provided by the plugin if and only if the
run_adding() function is provided. When it is absent this
function pointer must be set to NULL. */
void (*set_run_adding_gain)(LADSPA_Handle Instance,
LADSPA_Data Gain);

/* This is the counterpart to activate() (see above). If there is
nothing for deactivate() to do then the plugin writer may provide
a NULL rather than an empty function.

Hosts must deactivate all activated units after they have been
run() (or run_adding()) for the last time. This call should be
made as close to the last run() call as possible and indicates to
real-time plugins that they are no longer live. Plugins should
not rely on prompt deactivation. Note that connect_port() may be
called before or after a call to deactivate().

Deactivation is not similar to pausing as the plugin instance
will be reinitialised when activate() is called to reuse it. */
void (*deactivate)(LADSPA_Handle Instance);

/* Once an instance of a plugin has been finished with it can be
deleted using the following function. The instance handle passed
ceases to be valid after this call.
If activate() was called for a plugin instance then a
corresponding call to deactivate() must be made before cleanup()
is called. */
void (*cleanup)(LADSPA_Handle Instance);

} LADSPA_Descriptor;

/**********************************************************************/

/* Accessing a Plugin: */

/* The exact mechanism by which plugins are loaded is host-dependent,
however all most hosts will need to know is the name of shared
object file containing the plugin types. To allow multiple hosts to
share plugin types, hosts may wish to check for environment
variable LADSPA_PATH. If present, this should contain a
colon-separated path indicating directories that should be searched
(in order) when loading plugin types.

A plugin programmer must include a function called
"ladspa_descriptor" with the following function prototype within
the shared object file. This function will have C-style linkage (if
you are using C++ this is taken care of by the `extern "C"' clause
at the top of the file).

A host will find the plugin shared object file by one means or
another, find the ladspa_descriptor() function, call it, and
proceed from there.

Plugin types are accessed by index (not ID) using values from 0
upwards. Out of range indexes must result in this function
returning NULL, so the plugin count can be determined by checking
for the least index that results in NULL being returned. */

const LADSPA_Descriptor * ladspa_descriptor(unsigned long Index);

/* Datatype corresponding to the ladspa_descriptor() function. */
typedef const LADSPA_Descriptor *
(*LADSPA_Descriptor_Function)(unsigned long Index);

/**********************************************************************/

#ifdef __cplusplus
}
#endif

#endif /* LADSPA_INCLUDED */

/* EOF */

+ 279
- 0
src/carla-includes/vestige/aeffectx.h View File

@@ -0,0 +1,279 @@
/*
* aeffectx.h - simple header to allow VeSTige compilation and eventually work
*
* Copyright (c) 2006 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include <stdint.h>
#ifndef _AEFFECTX_H
#define _AEFFECTX_H

#define CCONST(a, b, c, d)( ( ( (int) a ) << 24 ) | \
( ( (int) b ) << 16 ) | \
( ( (int) c ) << 8 ) | \
( ( (int) d ) << 0 ) )

#define audioMasterAutomate 0
#define audioMasterVersion 1
#define audioMasterCurrentId 2
#define audioMasterIdle 3
#define audioMasterPinConnected 4
// unsupported? 5
#define audioMasterWantMidi 6
#define audioMasterGetTime 7
#define audioMasterProcessEvents 8
#define audioMasterSetTime 9
#define audioMasterTempoAt 10
#define audioMasterGetNumAutomatableParameters 11
#define audioMasterGetParameterQuantization 12
#define audioMasterIOChanged 13
#define audioMasterNeedIdle 14
#define audioMasterSizeWindow 15
#define audioMasterGetSampleRate 16
#define audioMasterGetBlockSize 17
#define audioMasterGetInputLatency 18
#define audioMasterGetOutputLatency 19
#define audioMasterGetPreviousPlug 20
#define audioMasterGetNextPlug 21
#define audioMasterWillReplaceOrAccumulate 22
#define audioMasterGetCurrentProcessLevel 23
#define audioMasterGetAutomationState 24
#define audioMasterOfflineStart 25
#define audioMasterOfflineRead 26
#define audioMasterOfflineWrite 27
#define audioMasterOfflineGetCurrentPass 28
#define audioMasterOfflineGetCurrentMetaPass 29
#define audioMasterSetOutputSampleRate 30
// unsupported? 31
#define audioMasterGetSpeakerArrangement 31 // deprecated in 2.4?
#define audioMasterGetVendorString 32
#define audioMasterGetProductString 33
#define audioMasterGetVendorVersion 34
#define audioMasterVendorSpecific 35
#define audioMasterSetIcon 36
#define audioMasterCanDo 37
#define audioMasterGetLanguage 38
#define audioMasterOpenWindow 39
#define audioMasterCloseWindow 40
#define audioMasterGetDirectory 41
#define audioMasterUpdateDisplay 42
#define audioMasterBeginEdit 43
#define audioMasterEndEdit 44
#define audioMasterOpenFileSelector 45
#define audioMasterCloseFileSelector 46 // currently unused
#define audioMasterEditFile 47 // currently unused
#define audioMasterGetChunkFile 48 // currently unused
#define audioMasterGetInputSpeakerArrangement 49 // currently unused

#define effFlagsHasEditor 1
#define effFlagsCanReplacing (1 << 4) // very likely
#define effFlagsIsSynth (1 << 8) // currently unused

#define effOpen 0
#define effClose 1 // currently unused
#define effSetProgram 2 // currently unused
#define effGetProgram 3 // currently unused
#define effGetProgramName 5 // currently unused
#define effGetParamName 8 // currently unused
#define effSetSampleRate 10
#define effSetBlockSize 11
#define effMainsChanged 12
#define effEditGetRect 13
#define effEditOpen 14
#define effEditClose 15
#define effEditIdle 19
#define effEditTop 20
#define effProcessEvents 25
#define effGetEffectName 45
#define effGetVendorString 47
#define effGetProductString 48
#define effGetVendorVersion 49
#define effCanDo 51 // currently unused
/* from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
#define effGetParameterProperties 56
#define effGetVstVersion 58 // currently unused

#define kEffectMagic (CCONST( 'V', 's', 't', 'P' ))
#define kVstLangEnglish 1
#define kVstMidiType 1
#define kVstTempoValid (1 << 10)
#define kVstTransportPlaying (1 << 1)


struct RemoteVstPlugin;

#define kVstNanosValid (1 << 8)
#define kVstPpqPosValid (1 << 9)
#define kVstTempoValid (1 << 10)
#define kVstBarsValid (1 << 11)
#define kVstCyclePosValid (1 << 12)
#define kVstTimeSigValid (1 << 13)
#define kVstSmpteValid (1 << 14)
#define kVstClockValid (1 << 15)

struct _VstMidiEvent
{
// 00
int type;
// 04
int byteSize;
// 08
int deltaFrames;
// 0c?
int flags;
// 10?
int noteLength;
// 14?
int noteOffset;
// 18
char midiData[4];
// 1c?
char detune;
// 1d?
char noteOffVelocity;
// 1e?
char reserved1;
// 1f?
char reserved2;
};

typedef struct _VstMidiEvent VstMidiEvent;


struct _VstEvent
{
char dump[sizeof (VstMidiEvent)];

};

typedef struct _VstEvent VstEvent;

struct _VstEvents
{
// 00
int numEvents;
// 04
void *reserved;
// 08
VstEvent * events[];
};

typedef struct _VstEvents VstEvents;

/* this struct taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
struct _VstParameterProperties
{
float stepFloat;
float smallStepFloat;
float largeStepFloat;
char label[64];
int32_t flags;
int32_t minInteger;
int32_t maxInteger;
int32_t stepInteger;
int32_t largeStepInteger;
char shortLabel[8];
};

typedef struct _VstParameterProperties VstParameterProperties;

/* this enum taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
enum VstParameterFlags
{
kVstParameterIsSwitch = 1 << 0, /* parameter is a switch (on/off) */
kVstParameterUsesIntegerMinMax = 1 << 1, /* minInteger, maxInteger valid */
kVstParameterUsesFloatStep = 1 << 2, /* stepFloat, smallStepFloat, largeStepFloat valid */
kVstParameterUsesIntStep = 1 << 3, /* stepInteger, largeStepInteger valid */
kVstParameterSupportsDisplayIndex = 1 << 4, /* displayIndex valid */
kVstParameterSupportsDisplayCategory = 1 << 5, /* category, etc. valid */
kVstParameterCanRamp = 1 << 6 /* set if parameter value can ramp up/down */
};

struct _AEffect
{
// Never use virtual functions!!!
// 00-03
int magic;
// dispatcher 04-07
intptr_t (* dispatcher) (struct _AEffect *, int, int, intptr_t, void *, float);
// process, quite sure 08-0b
void (* process) (struct _AEffect *, float **, float **, int);
// setParameter 0c-0f
void (* setParameter) (struct _AEffect *, int, float);
// getParameter 10-13
float (* getParameter) (struct _AEffect *, int);
// programs 14-17
int numPrograms;
// Params 18-1b
int numParams;
// Input 1c-1f
int numInputs;
// Output 20-23
int numOutputs;
// flags 24-27
int flags;
// Fill somewhere 28-2b
void *ptr1;
void *ptr2;
// Zeroes 2c-2f 30-33 34-37 38-3b
char empty3[4 + 4 + 4];
// 1.0f 3c-3f
float unkown_float;
// An object? pointer 40-43
void *ptr3;
// Zeroes 44-47
void *user;
// Id 48-4b
int32_t uniqueID;
// Don't know 4c-4f
char unknown1[4];
// processReplacing 50-53
void (* processReplacing) (struct _AEffect *, float **, float **, int);
};

typedef struct _AEffect AEffect;

struct _VstTimeInfo
{
// 00
double samplePos;
// 08
double sampleRate;
// unconfirmed 10 18
char empty1[8 + 8];
// 20?
double tempo;
// unconfirmed 28 30 38
char empty2[8 + 8 + 8];
// 40?
int timeSigNumerator;
// 44?
int timeSigDenominator;
// unconfirmed 48 4c 50
char empty3[4 + 4 + 4];
// 54
int flags;
};

typedef struct _VstTimeInfo VstTimeInfo;

typedef intptr_t (* audioMasterCallback) (AEffect *, int32_t, int32_t, intptr_t, void *, float);

#endif

+ 0
- 1
src/ladspa_rdf.py View File

@@ -695,7 +695,6 @@ def recheck_all_plugins(qobject=None):
# Parse all RDF files
for i in range(len(rdf_files)):
rdf_file = rdf_files[i]
print(rdf_file)

# Tell GUI we're parsing this bundle
if (qobject):


Loading…
Cancel
Save