pax_global_header 0000666 0000000 0000000 00000000064 13305734127 0014517 g ustar 00root root 0000000 0000000 52 comment=ecc7f131c5530ad517254dd5b24ba9b2742f69ab
csladspa-6.11.1/ 0000775 0000000 0000000 00000000000 13305734127 0013377 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/.gitignore 0000664 0000000 0000000 00000000006 13305734127 0015363 0 ustar 00root root 0000000 0000000 build
csladspa-6.11.1/CMakeLists.txt 0000664 0000000 0000000 00000002325 13305734127 0016141 0 ustar 00root root 0000000 0000000 cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
if(MSVC AND NOT "${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
message(FATAL_ERROR "ERROR: Building with Visual Studio requires
using a 64-bit project generator
(e.g. cmake -G \"Visual Studio 15 2017 Win64\")")
endif()
find_package(Csound)
if(CSOUND_FOUND)
message(STATUS "Building CsLadspa Plugin!")
add_library(csladspa64 MODULE "src/csladspa.cpp")
if(MSVC)
target_include_directories(csladspa64 PRIVATE "${CMAKE_SOURCE_DIR}/include")
target_link_libraries(csladspa64 PRIVATE ${CSOUND_LIBRARY})
else()
target_link_libraries(csladspa64 ${CSOUND_LIBRARY})
target_include_directories(csladspa64 PRIVATE ${CSOUND_INCLUDE_DIRS})
endif()
# We do not want the lib prefix
set_target_properties(csladspa64 PROPERTIES PREFIX "")
if(APPLE)
set(PLUGIN_INSTALL_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/ladspa")
else()
set(PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib")
endif()
install(TARGETS csladspa64
LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}")
else()
message(STATUS "The Csound library is required for CsLadspa")
endif()
csladspa-6.11.1/README.md 0000664 0000000 0000000 00000000403 13305734127 0014653 0 ustar 00root root 0000000 0000000 # Csound LADSPA Plugin
This is the Csound plugin for LADSPA.
Building
==========
CsLasdpa requires Csound to be installed in the system, as well as
CMake. With that in place, to build the plugin you do
```
$ mkdir build
$ cd build
$ cmake ..
$ make
```
csladspa-6.11.1/cmake/ 0000775 0000000 0000000 00000000000 13305734127 0014457 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/cmake/Modules/ 0000775 0000000 0000000 00000000000 13305734127 0016067 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/cmake/Modules/FindCsound.cmake 0000664 0000000 0000000 00000002521 13305734127 0021125 0 ustar 00root root 0000000 0000000 # Try to find the Csound library.
# Once done this will define:
# CSOUND_FOUND - System has the Csound library
# CSOUND_INCLUDE_DIRS - The Csound include directories.
# CSOUND_LIBRARIES - The libraries needed to use the Csound library.
if(APPLE)
find_path(CSOUND_INCLUDE_DIR csound.h HINTS /Library/Frameworks/CsoundLib64.framework/Headers
"$ENV{HOME}/Library/Frameworks/CsoundLib64.framework/Headers")
elseif(WIN32)
find_path(CSOUND_INCLUDE_DIR csound.h PATH_SUFFIXES csound
HINTS "c:\\Program Files\\Csound6_x64\\include")
else()
find_path(CSOUND_INCLUDE_DIR csound.h PATH_SUFFIXES csound)
endif()
if(APPLE)
find_library(CSOUND_LIBRARY NAMES CsoundLib64 HINTS /Library/Frameworks/CsoundLib64.framework/
"$ENV{HOME}/Library/Frameworks/CsoundLib64.framework")
elseif(WIN32)
find_library(CSOUND_LIBRARY NAMES csound64 HINTS "c:\\Program Files\\Csound6_x64\\lib")
else()
find_library(CSOUND_LIBRARY NAMES csound64 csound)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set CSOUND_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(CSOUND
CSOUND_LIBRARY CSOUND_INCLUDE_DIR)
mark_as_advanced(CSOUND_INCLUDE_DIR CSOUND_LIBRARY)
set(CSOUND_INCLUDE_DIRS ${CSOUND_INCLUDE_DIR})
set(CSOUND_LIBRARIES ${CSOUND_LIBRARY} )
csladspa-6.11.1/examples/ 0000775 0000000 0000000 00000000000 13305734127 0015215 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/examples/CSOUNDladspaFlanger.csd 0000664 0000000 0000000 00000001452 13305734127 0021371 0 ustar 00root root 0000000 0000000
Name=Csound-FLANGER
Maker=Victor Lazzarini
UniqueID=1054
Copyright=None
ControlPort=Flange Depth|depth
Range=0|1
ControlPort=Flange Rate|rate
Range=0|10
sr = 44100
ksmps = 10
nchnls = 1
instr 1
kdeltime chnget "depth"
krate chnget "rate"
ain in
a1 oscil kdeltime, 1, 1
ar vdelay3 ain, a1+kdeltime, 1000
out ar+ain
endin
f1 0 1024 10 1
i1 0 3600
100100320240true255255255
csladspa-6.11.1/examples/CSOUNDladspaGain.csd 0000664 0000000 0000000 00000001214 13305734127 0020665 0 ustar 00root root 0000000 0000000
Name=CsoundGain Plugin
Maker=Victor Lazzarini
UniqueID=1049
Copyright=None
ControlPort=Gain|gain
Range=0|2
ControlPort=Test|test
Range=0|2
sr = 44100
ksmps = 10
nchnls = 1
instr 1
kGain chnget "gain"
ain in
out ain*kGain
endin
i1 0 3600
100100320240true255255255
csladspa-6.11.1/examples/CSOUNDladspaPVSblur.csd 0000664 0000000 0000000 00000001544 13305734127 0021352 0 ustar 00root root 0000000 0000000
Name=CsoundPVSblur Plugin
Maker=Lazzarini
UniqueID=1056
Copyright=None
ControlPort=Max Delay|del
Range=0|1
ControlPort=Blur Time|blur
Range=0|10 &log
sr = 44100
ksmps = 10
nchnls = 1
instr 1
imaxdel chnget "del"
iblurtime chnget "blur"
asig in
fsig pvsanal asig, 1024, 256, 1024, 1
ftps pvsblur fsig, 0.2, 0.2
atps pvsynth ftps
out atps
endin
f1 0 1024 10 1
i1 0 3600
100100320240true255255255
csladspa-6.11.1/include/ 0000775 0000000 0000000 00000000000 13305734127 0015022 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/include/dirent.h 0000664 0000000 0000000 00000053154 13305734127 0016470 0 ustar 00root root 0000000 0000000 /*
* Dirent interface for Microsoft Visual Studio
* Version 1.21
*
* Copyright (C) 2006-2012 Toni Ronkko
* This file is part of dirent. Dirent may be freely distributed
* under the MIT license. For all details and documentation, see
* https://github.com/tronkko/dirent
*/
#ifndef DIRENT_H
#define DIRENT_H
/*
* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
* Windows Sockets 2.0.
*/
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* Indicates that d_type field is available in dirent structure */
#define _DIRENT_HAVE_D_TYPE
/* Indicates that d_namlen field is available in dirent structure */
#define _DIRENT_HAVE_D_NAMLEN
/* Entries missing from MSVC 6.0 */
#if !defined(FILE_ATTRIBUTE_DEVICE)
# define FILE_ATTRIBUTE_DEVICE 0x40
#endif
/* File type and permission flags for stat(), general mask */
#if !defined(S_IFMT)
# define S_IFMT _S_IFMT
#endif
/* Directory bit */
#if !defined(S_IFDIR)
# define S_IFDIR _S_IFDIR
#endif
/* Character device bit */
#if !defined(S_IFCHR)
# define S_IFCHR _S_IFCHR
#endif
/* Pipe bit */
#if !defined(S_IFFIFO)
# define S_IFFIFO _S_IFFIFO
#endif
/* Regular file bit */
#if !defined(S_IFREG)
# define S_IFREG _S_IFREG
#endif
/* Read permission */
#if !defined(S_IREAD)
# define S_IREAD _S_IREAD
#endif
/* Write permission */
#if !defined(S_IWRITE)
# define S_IWRITE _S_IWRITE
#endif
/* Execute permission */
#if !defined(S_IEXEC)
# define S_IEXEC _S_IEXEC
#endif
/* Pipe */
#if !defined(S_IFIFO)
# define S_IFIFO _S_IFIFO
#endif
/* Block device */
#if !defined(S_IFBLK)
# define S_IFBLK 0
#endif
/* Link */
#if !defined(S_IFLNK)
# define S_IFLNK 0
#endif
/* Socket */
#if !defined(S_IFSOCK)
# define S_IFSOCK 0
#endif
/* Read user permission */
#if !defined(S_IRUSR)
# define S_IRUSR S_IREAD
#endif
/* Write user permission */
#if !defined(S_IWUSR)
# define S_IWUSR S_IWRITE
#endif
/* Execute user permission */
#if !defined(S_IXUSR)
# define S_IXUSR 0
#endif
/* Read group permission */
#if !defined(S_IRGRP)
# define S_IRGRP 0
#endif
/* Write group permission */
#if !defined(S_IWGRP)
# define S_IWGRP 0
#endif
/* Execute group permission */
#if !defined(S_IXGRP)
# define S_IXGRP 0
#endif
/* Read others permission */
#if !defined(S_IROTH)
# define S_IROTH 0
#endif
/* Write others permission */
#if !defined(S_IWOTH)
# define S_IWOTH 0
#endif
/* Execute others permission */
#if !defined(S_IXOTH)
# define S_IXOTH 0
#endif
/* Maximum length of file name */
#if !defined(PATH_MAX)
# define PATH_MAX MAX_PATH
#endif
#if !defined(FILENAME_MAX)
# define FILENAME_MAX MAX_PATH
#endif
#if !defined(NAME_MAX)
# define NAME_MAX FILENAME_MAX
#endif
/* File type flags for d_type */
#define DT_UNKNOWN 0
#define DT_REG S_IFREG
#define DT_DIR S_IFDIR
#define DT_FIFO S_IFIFO
#define DT_SOCK S_IFSOCK
#define DT_CHR S_IFCHR
#define DT_BLK S_IFBLK
#define DT_LNK S_IFLNK
/* Macros for converting between st_mode and d_type */
#define IFTODT(mode) ((mode) & S_IFMT)
#define DTTOIF(type) (type)
/*
* File type macros. Note that block devices, sockets and links cannot be
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
* only defined for compatibility. These macros should always return false
* on Windows.
*/
#if !defined(S_ISFIFO)
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISDIR)
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG)
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISLNK)
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK)
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISCHR)
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISBLK)
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
#endif
/* Return the exact length of d_namlen without zero terminator */
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
/* Return number of bytes needed to store d_namlen */
#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
#ifdef __cplusplus
extern "C" {
#endif
/* Wide-character version */
struct _wdirent {
/* Always zero */
long d_ino;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
wchar_t d_name[PATH_MAX];
};
typedef struct _wdirent _wdirent;
struct _WDIR {
/* Current directory entry */
struct _wdirent ent;
/* Private file data */
WIN32_FIND_DATAW data;
/* True if data is valid */
int cached;
/* Win32 search handle */
HANDLE handle;
/* Initial directory name */
wchar_t *patt;
};
typedef struct _WDIR _WDIR;
static _WDIR *_wopendir (const wchar_t *dirname);
static struct _wdirent *_wreaddir (_WDIR *dirp);
static int _wclosedir (_WDIR *dirp);
static void _wrewinddir (_WDIR* dirp);
/* For compatibility with Symbian */
#define wdirent _wdirent
#define WDIR _WDIR
#define wopendir _wopendir
#define wreaddir _wreaddir
#define wclosedir _wclosedir
#define wrewinddir _wrewinddir
/* Multi-byte character versions */
struct dirent {
/* Always zero */
long d_ino;
/* Structure size */
unsigned short d_reclen;
/* Length of name without \0 */
size_t d_namlen;
/* File type */
int d_type;
/* File name */
char d_name[PATH_MAX];
};
typedef struct dirent dirent;
struct DIR {
struct dirent ent;
struct _WDIR *wdirp;
};
typedef struct DIR DIR;
static DIR *opendir (const char *dirname);
static struct dirent *readdir (DIR *dirp);
static int closedir (DIR *dirp);
static void rewinddir (DIR* dirp);
/* Internal utility functions */
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
static int dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count);
static int dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes,
const wchar_t *wcstr,
size_t count);
static void dirent_set_errno (int error);
/*
* Open directory stream DIRNAME for read and return a pointer to the
* internal working area that is used to retrieve individual directory
* entries.
*/
static _WDIR*
_wopendir(
const wchar_t *dirname)
{
_WDIR *dirp = NULL;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate new _WDIR structure */
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
if (dirp != NULL) {
DWORD n;
/* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL;
dirp->cached = 0;
/* Compute the length of full path plus zero terminator
*
* Note that on WinRT there's no way to convert relative paths
* into absolute paths, so just assume its an absolute path.
*/
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
n = wcslen(dirname);
# else
n = GetFullPathNameW (dirname, 0, NULL, NULL);
# endif
/* Allocate room for absolute directory name and search pattern */
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
if (dirp->patt) {
/*
* Convert relative directory name to an absolute one. This
* allows rewinddir() to function correctly even when current
* working directory is changed between opendir() and rewinddir().
*
* Note that on WinRT there's no way to convert relative paths
* into absolute paths, so just assume its an absolute path.
*/
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
wcsncpy_s(dirp->patt, n+1, dirname, n);
# else
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
# endif
if (n > 0) {
wchar_t *p;
/* Append search pattern \* to the directory name */
p = dirp->patt + n;
if (dirp->patt < p) {
switch (p[-1]) {
case '\\':
case '/':
case ':':
/* Directory ends in path separator, e.g. c:\temp\ */
/*NOP*/;
break;
default:
/* Directory name doesn't end in path separator */
*p++ = '\\';
}
}
*p++ = '*';
*p = '\0';
/* Open directory stream and retrieve the first entry */
if (dirent_first (dirp)) {
/* Directory stream opened successfully */
error = 0;
} else {
/* Cannot retrieve first entry */
error = 1;
dirent_set_errno (ENOENT);
}
} else {
/* Cannot retrieve full path name */
dirent_set_errno (ENOENT);
error = 1;
}
} else {
/* Cannot allocate memory for search pattern */
error = 1;
}
} else {
/* Cannot allocate _WDIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
_wclosedir (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Read next directory entry. The directory entry is returned in dirent
* structure in the d_name field. Individual directory entries returned by
* this function include regular files, sub-directories, pseudo-directories
* "." and ".." as well as volume labels, hidden files and system files.
*/
static struct _wdirent*
_wreaddir(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
struct _wdirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp);
if (datap) {
size_t n;
DWORD attr;
/* Pointer to directory entry to return */
entp = &dirp->ent;
/*
* Copy file name as wide-character string. If the file name is too
* long to fit in to the destination buffer, then truncate file name
* to PATH_MAX characters and zero-terminate the buffer.
*/
n = 0;
while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
entp->d_name[n] = datap->cFileName[n];
n++;
}
dirp->ent.d_name[n] = 0;
/* Length of file name excluding zero terminator */
entp->d_namlen = n;
/* File type */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
entp->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
entp->d_type = DT_DIR;
} else {
entp->d_type = DT_REG;
}
/* Reset dummy fields */
entp->d_ino = 0;
entp->d_reclen = sizeof (struct _wdirent);
} else {
/* Last directory entry read */
entp = NULL;
}
return entp;
}
/*
* Close directory stream opened by opendir() function. This invalidates the
* DIR structure as well as any directory entry read previously by
* _wreaddir().
*/
static int
_wclosedir(
_WDIR *dirp)
{
int ok;
if (dirp) {
/* Release search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
}
/* Release search pattern */
if (dirp->patt) {
free (dirp->patt);
dirp->patt = NULL;
}
/* Release directory structure */
free (dirp);
ok = /*success*/0;
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/*
* Rewind directory stream such that _wreaddir() returns the very first
* file name again.
*/
static void
_wrewinddir(
_WDIR* dirp)
{
if (dirp) {
/* Release existing search handle */
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose (dirp->handle);
}
/* Open new search handle */
dirent_first (dirp);
}
}
/* Get first directory entry (internal) */
static WIN32_FIND_DATAW*
dirent_first(
_WDIR *dirp)
{
WIN32_FIND_DATAW *datap;
/* Open directory and retrieve the first entry */
dirp->handle = FindFirstFileExW(
dirp->patt, FindExInfoStandard, &dirp->data,
FindExSearchNameMatch, NULL, 0);
if (dirp->handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */
datap = &dirp->data;
dirp->cached = 1;
} else {
/* Failed to re-open directory: no directory entry in memory */
dirp->cached = 0;
datap = NULL;
}
return datap;
}
/* Get next directory entry (internal) */
static WIN32_FIND_DATAW*
dirent_next(
_WDIR *dirp)
{
WIN32_FIND_DATAW *p;
/* Get next directory entry */
if (dirp->cached != 0) {
/* A valid directory entry already in memory */
p = &dirp->data;
dirp->cached = 0;
} else if (dirp->handle != INVALID_HANDLE_VALUE) {
/* Get the next directory entry from stream */
if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
/* Got a file */
p = &dirp->data;
} else {
/* The very last entry has been processed or an error occured */
FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
p = NULL;
}
} else {
/* End of directory stream reached */
p = NULL;
}
return p;
}
/*
* Open directory stream using plain old C-string.
*/
static DIR*
opendir(
const char *dirname)
{
struct DIR *dirp;
int error;
/* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') {
dirent_set_errno (ENOENT);
return NULL;
}
/* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR));
if (dirp) {
wchar_t wname[PATH_MAX];
size_t n;
/* Convert directory name to wide-character string */
error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
if (!error) {
/* Open directory stream using wide-character name */
dirp->wdirp = _wopendir (wname);
if (dirp->wdirp) {
/* Directory stream opened */
error = 0;
} else {
/* Failed to open directory stream */
error = 1;
}
} else {
/*
* Cannot convert file name to wide-character string. This
* occurs if the string contains invalid multi-byte sequences or
* the output buffer is too small to contain the resulting
* string.
*/
error = 1;
}
} else {
/* Cannot allocate DIR structure */
error = 1;
}
/* Clean up in case of error */
if (error && dirp) {
free (dirp);
dirp = NULL;
}
return dirp;
}
/*
* Read next directory entry.
*
* When working with text consoles, please note that file names returned by
* readdir() are represented in the default ANSI code page while any output to
* console is typically formatted on another code page. Thus, non-ASCII
* characters in file names will not usually display correctly on console. The
* problem can be fixed in two ways: (1) change the character set of console
* to 1252 using chcp utility and use Lucida Console font, or (2) use
* _cprintf function when writing to console. The _cprinf() will re-encode
* ANSI strings to the console code page so many non-ASCII characters will
* display correcly.
*/
static struct dirent*
readdir(
DIR *dirp)
{
WIN32_FIND_DATAW *datap;
struct dirent *entp;
/* Read next directory entry */
datap = dirent_next (dirp->wdirp);
if (datap) {
size_t n;
int error;
/* Attempt to convert file name to multi-byte string */
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
/*
* If the file name cannot be represented by a multi-byte string,
* then attempt to use old 8+3 file name. This allows traditional
* Unix-code to access some file names despite of unicode
* characters, although file names may seem unfamiliar to the user.
*
* Be ware that the code below cannot come up with a short file
* name unless the file system provides one. At least
* VirtualBox shared folders fail to do this.
*/
if (error && datap->cAlternateFileName[0] != '\0') {
error = dirent_wcstombs_s(
&n, dirp->ent.d_name, PATH_MAX,
datap->cAlternateFileName, PATH_MAX);
}
if (!error) {
DWORD attr;
/* Initialize directory entry for return */
entp = &dirp->ent;
/* Length of file name excluding zero terminator */
entp->d_namlen = n - 1;
/* File attributes */
attr = datap->dwFileAttributes;
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
entp->d_type = DT_CHR;
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
entp->d_type = DT_DIR;
} else {
entp->d_type = DT_REG;
}
/* Reset dummy fields */
entp->d_ino = 0;
entp->d_reclen = sizeof (struct dirent);
} else {
/*
* Cannot convert file name to multi-byte string so construct
* an errornous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing
* of directory entries completely.
*/
entp = &dirp->ent;
entp->d_name[0] = '?';
entp->d_name[1] = '\0';
entp->d_namlen = 1;
entp->d_type = DT_UNKNOWN;
entp->d_ino = 0;
entp->d_reclen = 0;
}
} else {
/* No more directory entries */
entp = NULL;
}
return entp;
}
/*
* Close directory stream.
*/
static int
closedir(
DIR *dirp)
{
int ok;
if (dirp) {
/* Close wide-character directory stream */
ok = _wclosedir (dirp->wdirp);
dirp->wdirp = NULL;
/* Release multi-byte character version */
free (dirp);
} else {
/* Invalid directory stream */
dirent_set_errno (EBADF);
ok = /*failure*/-1;
}
return ok;
}
/*
* Rewind directory stream to beginning.
*/
static void
rewinddir(
DIR* dirp)
{
/* Rewind wide-character string directory stream */
_wrewinddir (dirp->wdirp);
}
/* Convert multi-byte string to wide character string */
static int
dirent_mbstowcs_s(
size_t *pReturnValue,
wchar_t *wcstr,
size_t sizeInWords,
const char *mbstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to wide-character string (or count characters) */
n = mbstowcs (wcstr, mbstr, sizeInWords);
if (!wcstr || n < count) {
/* Zero-terminate output buffer */
if (wcstr && sizeInWords) {
if (n >= sizeInWords) {
n = sizeInWords - 1;
}
wcstr[n] = 0;
}
/* Length of resuting multi-byte string WITH zero terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Could not convert string */
error = 1;
}
#endif
return error;
}
/* Convert wide-character string to multi-byte string */
static int
dirent_wcstombs_s(
size_t *pReturnValue,
char *mbstr,
size_t sizeInBytes, /* max size of mbstr */
const wchar_t *wcstr,
size_t count)
{
int error;
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 or later */
error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
#else
/* Older Visual Studio or non-Microsoft compiler */
size_t n;
/* Convert to multi-byte string (or count the number of bytes needed) */
n = wcstombs (mbstr, wcstr, sizeInBytes);
if (!mbstr || n < count) {
/* Zero-terminate output buffer */
if (mbstr && sizeInBytes) {
if (n >= sizeInBytes) {
n = sizeInBytes - 1;
}
mbstr[n] = '\0';
}
/* Length of resulting multi-bytes string WITH zero-terminator */
if (pReturnValue) {
*pReturnValue = n + 1;
}
/* Success */
error = 0;
} else {
/* Cannot convert string */
error = 1;
}
#endif
return error;
}
/* Set errno variable */
static void
dirent_set_errno(
int error)
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Microsoft Visual Studio 2005 and later */
_set_errno (error);
#else
/* Non-Microsoft compiler or older Microsoft compiler */
errno = error;
#endif
}
#ifdef __cplusplus
}
#endif
#endif /*DIRENT_H*/
csladspa-6.11.1/src/ 0000775 0000000 0000000 00000000000 13305734127 0014166 5 ustar 00root root 0000000 0000000 csladspa-6.11.1/src/csladspa.cpp 0000664 0000000 0000000 00000036220 13305734127 0016467 0 ustar 00root root 0000000 0000000 /*
Copyright (C) 2007-16 Rory Walsh, Victor Lazzarini
csLADSPA 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.
csLADSPA 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 Csound; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#include
#include
#include
#include
#include
#include
#include
#if defined(__APPLE__)
#include
#else
#include
#endif
#include "ladspa.h"
using namespace std;
#define MAXLINESIZE 4098
#define MAXPORTS 64
#define MAXPLUGINS 512
// plugin aux information
static struct AuxData {
string portnames[MAXPORTS];
int ksmps;
} aux[MAXPLUGINS];
//to remove leading and trailing spaces
string trim(string s)
{
//trim spaces at start
s.erase( 0, s.find_first_not_of( " \t\n" ) );
//trim spaces at end
s.erase( s.find_last_not_of( " \t\n" ) + 1);
return s;
}
// Csound plugin class
// holds the Csound instancec
// and audio/control port pointers
struct CsoundPlugin {
LADSPA_Data *ctl[MAXPORTS];
LADSPA_Data **inp;
LADSPA_Data **outp;
string *ctlchn;
int ctlports;
Csound* csound;
int result;
MYFLT *spout, *spin;
int chans;
int frames;
CsoundPlugin(const char *csd, int chns, int ports, AuxData* paux,
unsigned long rate);
~CsoundPlugin();
void Process(unsigned long cnt);
};
// constructor
CsoundPlugin::CsoundPlugin(const char *csd,
int chns, int ports, AuxData *paux,
unsigned long rate){
char** cmdl;
string sr_override, kr_override;
char *sr, *kr;
int ksmps = paux->ksmps;
ctlchn = paux->portnames;
ctlports = ports;
chans = chns;
frames = ksmps;
inp = new LADSPA_Data*[chans];
outp = new LADSPA_Data*[chans];
// csound parameters
cmdl = new char*[5];
cmdl[0] = (char*)"csound";
cmdl[1] = (char *)csd;
cmdl[2] = (char*)"-n";
// sampling-rate override
sr = new char[32];
sprintf(sr,"%d", (int)rate);
sr_override.append("--sample-rate= ");
sr_override.append(sr);
printf("SR=%s\n", sr_override.c_str());
cmdl[3] = (char *) sr_override.c_str();
// ksmps override
kr = new char[32];
sprintf(kr,"%f",(float)rate/ksmps);
kr_override.append("-k ");
kr_override.append(kr);
printf("KR=%s \n", kr_override.c_str());
cmdl[4] = (char*) kr_override.c_str();
csound = new Csound;
result = csound->Compile(5,(const char **)cmdl);
spout = csound->GetSpout();
spin = csound->GetSpin();
memset(ctl, 0, sizeof(LADSPA_Data *)*MAXPORTS);
delete[] cmdl;
delete[] sr;
delete[] kr;
}
CsoundPlugin::~CsoundPlugin(){
delete csound;
delete[] inp;
delete[] outp;
}
// Processing function
void CsoundPlugin::Process(unsigned long cnt){
int pos, i, j, ksmps = csound->GetKsmps(),n = cnt;
MYFLT scale = csound->Get0dBFS();
for(i=0;iSetChannel(ctlchn[i].c_str(),
*(ctl[i]));
if(!result){
for(i=0; i < n; i++, frames++){
if(frames == ksmps){
result = csound->PerformKsmps();
frames = 0;
}
for(j=0; j < chans; j++)
if(!result){
pos = frames*chans;
spin[j+pos] = inp[j][i]*scale;
outp[j][i] = (LADSPA_Data) (spout[j+pos]/scale);
} else outp[j][i] = 0;
}
}
}
// Plugin instantiation
static LADSPA_Handle createplugin(const LADSPA_Descriptor *pdesc,
unsigned long rate)
{
CsoundPlugin* p;
int i, aports=0;
cerr << "instantiating plugin: " << pdesc->Label << "\n";
for(i=0; i < (int)pdesc->PortCount; i++)
if(pdesc->PortDescriptors[i] & LADSPA_PORT_AUDIO) aports++;
#ifdef DEBUG
cerr << "instantiating plugin: " << pdesc->Label << "\n";
#endif
p = new CsoundPlugin(pdesc->Label, aports/2, pdesc->PortCount-aports,
(AuxData *)pdesc->ImplementationData,rate);
#ifdef DEBUG
if(!p->result)
cerr << "plugin instantiated: " << pdesc->Label << "\n";
else
cerr << "plugin not instantiated \n";
#endif
return p;
}
// Plugin cleanup
static void destroyplugin(LADSPA_Handle inst)
{
CsoundPlugin* p = (CsoundPlugin*)inst;
delete p;
}
// Port connections
static void connect(LADSPA_Handle inst, unsigned long port, LADSPA_Data* pdata)
{
CsoundPlugin *p = (CsoundPlugin *) inst;
unsigned int chans = p->chans;
if(port < chans) p->inp[port] = pdata;
else if(port < chans*2) p->outp[port-chans] = pdata;
else p->ctl[port-chans*2] = pdata;
}
// Processing entry point
static void runplugin(LADSPA_Handle inst, unsigned long cnt)
{
((CsoundPlugin *)inst)->Process(cnt);
}
// initialise a descriptor for a given CSD file
static LADSPA_Descriptor *init_descriptor(char *csdname, int plugindex)
{
char *str, *tmp;
string csddata, temp;
int portcnt=2, chans=1,i;
bool plugin_found=false;
string::size_type indx,indx2,equals=0;
fstream csdfile(csdname);
char **PortNames = new char*[MAXPORTS];
float upper, lower;
string *ctlchn = aux[plugindex].portnames;
LADSPA_PortDescriptor *PortDescriptors = new LADSPA_PortDescriptor[MAXPORTS];
LADSPA_PortRangeHint *PortRangeHints = new LADSPA_PortRangeHint[MAXPORTS];
LADSPA_Descriptor *desc = new LADSPA_Descriptor;
// if descriptor was created
// and csdfile was open properly
if (desc && csdfile.is_open())
{
tmp = new char[strlen(csdname)+1];
str = new char[MAXLINESIZE+1];
strcpy(tmp, csdname);
desc->Label = (const char*) tmp;
aux[plugindex].ksmps = 10;
// check channels
while(!csdfile.eof()){
csdfile.getline(str,MAXLINESIZE);
csddata = str;
#ifdef DEBUG
cerr << csddata << "\n";
#endif
// find nchnls header statement
if(csddata.find("nchnls")!=string::npos)
{
indx = csddata.find('=');
temp = csddata.substr(indx+1,100);
chans = (int) atoi((char *) temp.c_str());
portcnt = chans*2;
break;
}
// if we reached the end of header block
else if(csddata.find("instr")!=string::npos) break;
}
csdfile.seekg(0);
// check ksmps, similar to above
while(!csdfile.eof()){
csdfile.getline(str,MAXLINESIZE);
csddata = str;
#ifdef DEBUG
cerr << csddata << "\n";
#endif
if(csddata.find("ksmps")!=string::npos){
indx = csddata.find('=');
temp = csddata.substr(indx+1,100);
aux[plugindex].ksmps = (int) atoi((char *) temp.c_str());
break;
}
else if(csddata.find("instr")!=string::npos) break;
}
csdfile.seekg(0);
while(!csdfile.eof())
{
csdfile.getline(str,MAXLINESIZE);
csddata = str;
// check for csLADSPA section
if(csddata.find("")!=string::npos){
cerr << "cSLADSPA plugin found: \n";
plugin_found = true;
}
// now if we found a plugin header section
// we proceed to read it
if (plugin_found) {
cerr << csddata << "\n";
if(csddata.find("Name")!=string::npos){
equals = csddata.find('=');
temp = csddata.substr(equals+1);
temp = trim(temp);
tmp = new char[temp.length()+1];
strcpy(tmp, (const char*)temp.c_str());
desc->Name = (const char*) tmp;
}
else if(csddata.find("Maker")!=string::npos){
equals = csddata.find('=');
temp = csddata.substr(equals+1) + (sizeof(MYFLT) == 4 ?
" (csLADSPA: Lazzarini, Walsh)" :
" (csLADSPA64: Lazzarini, Walsh)") ;
temp = trim(temp);
tmp = new char[temp.length()+1];
strcpy(tmp, (const char*)temp.c_str());
desc->Maker = (const char*) tmp;
}
else if(csddata.find("UniqueID")!=string::npos){
equals = csddata.find('=');
temp = csddata.substr(equals+1);
temp = trim(temp);
desc->UniqueID = atoi(temp.c_str());
}
else if(csddata.find("Copyright")!=string::npos){
equals = csddata.find('=');
temp = csddata.substr(equals+1, 100);
temp = trim(temp);
tmp = new char[temp.length()+1];
strcpy(tmp, (const char*)temp.c_str());
desc->Copyright = (const char*) tmp;
}
else if(csddata.find("ControlPort")!=string::npos)
{
equals = csddata.find('=');
if(portcnt < MAXPORTS) {
PortDescriptors[portcnt] =
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL;
temp = csddata;
indx = temp.find('|');
string temp2 = trim(temp.substr(equals+1,indx-(equals+1)));
PortNames[portcnt] = new char[temp2.length()+1];
strcpy(PortNames[portcnt], (const char*)temp2.c_str());
temp2 = trim(temp.substr(indx+1));
ctlchn[portcnt-chans*2] = temp2;//temp.substr(indx+1);
csdfile.getline(str,500);
csddata = str;
temp = csddata.substr(6, 200);
indx = temp.find('|');
indx2 = temp.find('&');
// if &log is found in the range spec, then we have a
// LOGARITHMIC response
if(indx2<200 &&
!strcmp(temp.substr(indx2+1,indx2+3).c_str(), "log")){
PortRangeHints[portcnt].HintDescriptor =
(LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE
| LADSPA_HINT_LOGARITHMIC | LADSPA_HINT_DEFAULT_MIDDLE);
lower = atof((char*)temp.substr(0, indx).c_str());
upper = atof((char*)temp.substr(indx+1, indx2).c_str());
}
else {
PortRangeHints[portcnt].HintDescriptor =
(LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE );
lower = atoi((char*)temp.substr(0, indx).c_str());
upper = atoi((char*)temp.substr(indx+1, 200).c_str());
}
PortRangeHints[portcnt].LowerBound =
lower < upper ? lower : upper;
PortRangeHints[portcnt].UpperBound =
upper > lower ? upper : lower;
portcnt++;
indx2 = 0;
}
}
else if(csddata.find("")!=string::npos) break;
}
}
csdfile.close();
// now if a csLADSPA section was found
// we proceed to create the plugin descriptor
if(plugin_found) {
desc->PortCount = portcnt;
for(i=0;iProperties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
desc->PortDescriptors = (const LADSPA_PortDescriptor *) PortDescriptors;
desc->PortNames = (const char **)PortNames;
desc->PortRangeHints = (const LADSPA_PortRangeHint *) PortRangeHints;
desc->instantiate = createplugin;
desc->connect_port = connect;
desc->activate = NULL;
desc->run = runplugin;
desc->run_adding = NULL;
desc->set_run_adding_gain = NULL;
desc->deactivate = NULL;
desc->cleanup = destroyplugin;
// add the channel names to the descriptor
// paux->portnames = ctlchn;
desc->ImplementationData = (void *) &aux[plugindex];
delete[] str;
cerr << "PLUGIN LOADED\n";
return desc;
}
else delete[] str;
}
// otherwise we just delete the empty descriptors
// and return NULL
delete desc;
delete[] PortNames;
delete[] PortDescriptors;
delete[] PortRangeHints;
cerr << "PLUGIN NOT LOADED: probably missing csLADSPA section\n";
return NULL;
}
// count CSDs in the current directory
unsigned int CountCSD(char **csdnames)
{
DIR *dip = NULL;
struct dirent *dit;
string temp, name, path;
int i = 0;
size_t indx = 0;
char ladspa_path[1024] = "";
char *src = NULL;
#ifdef MACOSX
strcpy(ladspa_path, "/Library/Audio/Plug-Ins/LADSPA");
#else
src = getenv("LADSPA_PATH");
if (src)
strncpy(ladspa_path, src, 1023);
ladspa_path[1023] = '\0';
#endif
// if no LADSPA_PATH attempt to open
// current directory
if(strlen(ladspa_path) == 0) dip = opendir(".");
else {
path = ladspa_path;
#ifdef WIN32
indx = path.find(";");
#else
indx = path.find(":");
#endif
if(indx!=string::npos){
dip = opendir(path.substr(0,indx).c_str());
strncpy(ladspa_path, path.substr(0,indx).c_str(), 1023);
ladspa_path[1023] = '\0';
}
else dip = opendir(ladspa_path);
}
if (dip == NULL) {
return 0;
}
while ((dit = readdir(dip))!=NULL)
{
temp = dit->d_name;
indx = temp.find(".csd", 0);
string validExt = trim(temp.substr(indx+1));
if(!validExt.compare("csd"))
{
if(strlen(ladspa_path) != 0) {
name = ladspa_path;
name.append("/");
name.append(temp);
}
else name = temp;
if(i < MAXPLUGINS) {
if (name.length()>1024) {
closedir(dip);
return 0;
}
csdnames[i] = new char[name.length()+1];
strcpy(csdnames[i], (char*)name.c_str());
i++;
}
}
}
closedir(dip);
return i;
}
// plugin lib entry point
PUBLIC
const LADSPA_Descriptor *ladspa_descriptor(unsigned long index)
{
// count CSD files to build the plugin lib
// and fill in the CSD names list
LADSPA_Descriptor *descriptor = NULL;
char **csdnames = new char*[MAXPLUGINS];
unsigned int csds;
csds = CountCSD(csdnames);
// if the requested index is in the range of CSD numbers
if(index < csds)
{
cerr << "attempting to load plugin index: " << index << "\n";
// initialise the descriptor for a given CSD
descriptor = init_descriptor(csdnames[index], index);
}
// delete the CSD list
for(unsigned int i=0; i < csds; i++) delete[] csdnames[i];
delete[] csdnames;
if(descriptor == NULL)
cerr << "no more csLADSPA plugins\n";
return descriptor;
}
csladspa-6.11.1/src/ladspa.h 0000775 0000000 0000000 00000065653 13305734127 0015625 0 ustar 00root root 0000000 0000000 /* 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. */
PUBLIC 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 */