Merge pull request #1155 from falkTX/stable-1.1

Initial version of Carla plugin for LMMS
This commit is contained in:
Vesa V
2014-09-28 10:49:23 +03:00
11 changed files with 784 additions and 0 deletions

View File

@@ -29,6 +29,7 @@ INCLUDE(DetectMachine)
OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON)
OPTION(WANT_CALF "Include CALF LADSPA plugins" ON)
OPTION(WANT_CAPS "Include C* Audio Plugin Suite (LADSPA plugins)" ON)
OPTION(WANT_CARLA "Include Carla plugin" ON)
OPTION(WANT_CMT "Include Computer Music Toolkit LADSPA plugins" ON)
OPTION(WANT_JACK "Include JACK (Jack Audio Connection Kit) support" ON)
OPTION(WANT_OGGVORBIS "Include OGG/Vorbis support" ON)
@@ -157,6 +158,18 @@ SET(STATUS_TAP "not built as requested")
ENDIF(WANT_TAP)
# check for CARLA
IF(WANT_CARLA)
PKG_CHECK_MODULES(CARLA carla-standalone>=1.9.5)
IF(CARLA_FOUND)
SET(LMMS_HAVE_CARLA TRUE)
SET(STATUS_CARLA "OK")
ELSE(CARLA_FOUND)
SET(STATUS_CARLA "not found, please install the latest carla")
ENDIF(CARLA_FOUND)
ENDIF(WANT_CARLA)
# check for SDL
IF(WANT_SDL)
SET(SDL_BUILDING_LIBRARY TRUE)
@@ -606,6 +619,7 @@ MESSAGE(
MESSAGE(
"Optional plugins\n"
"----------------\n"
"* Carla Patchbay & Rack : ${STATUS_CARLA}\n"
"* SoundFont2 player : ${STATUS_FLUIDSYNTH}\n"
"* Stk Mallets : ${STATUS_STK}\n"
"* VST-instrument hoster : ${STATUS_VST}\n"

View File

@@ -2,6 +2,9 @@ ADD_SUBDIRECTORY(Amplifier)
ADD_SUBDIRECTORY(audio_file_processor)
ADD_SUBDIRECTORY(BassBooster)
ADD_SUBDIRECTORY(bit_invader)
ADD_SUBDIRECTORY(carlabase)
ADD_SUBDIRECTORY(carlapatchbay)
ADD_SUBDIRECTORY(carlarack)
ADD_SUBDIRECTORY(DualFilter)
ADD_SUBDIRECTORY(dynamics_processor)
ADD_SUBDIRECTORY(flp_import)

View File

@@ -0,0 +1,12 @@
if(LMMS_HAVE_CARLA)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS})
LINK_DIRECTORIES(${CARLA_LIBRARY_DIRS})
LINK_LIBRARIES(${CARLA_LIBRARIES})
BUILD_PLUGIN(carlabase carla.cpp carla.h MOCFILES carla.h)
SET_TARGET_PROPERTIES(carlabase
PROPERTIES SKIP_BUILD_RPATH TRUE
BUILD_WITH_INSTALL_RPATH TRUE
INSTALL_RPATH_USE_LINK_PATH TRUE
INSTALL_RPATH "${CARLA_RPATH}")
endif(LMMS_HAVE_CARLA)

528
plugins/carlabase/carla.cpp Normal file
View File

@@ -0,0 +1,528 @@
/*
* carla.cpp - Carla for LMMS
*
* Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
*
* 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 "carla.h"
#define REAL_BUILD // FIXME this shouldn't be needed
#include "CarlaHost.h"
#include "engine.h"
#include "song.h"
#include "InstrumentPlayHandle.h"
#include "InstrumentTrack.h"
#include <QApplication>
#include <QFileDialog>
#include <QPushButton>
#include <QTimerEvent>
#include <QVBoxLayout>
#include <cstring>
// this doesn't seem to be defined anywhere
static const double ticksPerBeat = 48.0;
/*
* Current TODO items:
* - get plugin instance name (to use in external window title)
* - offline mode change callback
* - midi output
* - background artwork
*
* All other items are to be done in Carla itself.
*/
// -----------------------------------------------------------------------
#define handlePtr ((CarlaInstrument*)handle)
static uint32_t host_get_buffer_size(NativeHostHandle handle)
{
return handlePtr->handleGetBufferSize();
}
static double host_get_sample_rate(NativeHostHandle handle)
{
return handlePtr->handleGetSampleRate();
}
static bool host_is_offline(NativeHostHandle handle)
{
return handlePtr->handleIsOffline();
}
static const NativeTimeInfo* host_get_time_info(NativeHostHandle handle)
{
return handlePtr->handleGetTimeInfo();
}
static bool host_write_midi_event(NativeHostHandle, const NativeMidiEvent*)
{
return false; // unsupported?
}
static void host_ui_parameter_changed(NativeHostHandle handle, uint32_t index, float value)
{
handlePtr->handleUiParameterChanged(index, value);
}
static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value)
{
// unused
}
static void host_ui_closed(NativeHostHandle handle)
{
handlePtr->handleUiClosed();
}
static intptr_t host_dispatcher(NativeHostHandle handle, NativeHostDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
{
return handlePtr->handleDispatcher(opcode, index, value, ptr, opt);
}
#undef handlePtr
// -----------------------------------------------------------------------
static const char* host_ui_open_file(NativeHostHandle, bool isDir, const char* title, const char* filter)
{
static QByteArray retStr;
const QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);
retStr = QFileDialog::getOpenFileName(QApplication::activeWindow(), title, "", filter, NULL, options).toUtf8();
return retStr.isEmpty() ? NULL : retStr.constData();
}
static const char* host_ui_save_file(NativeHostHandle, bool isDir, const char* title, const char* filter)
{
static QByteArray retStr;
const QFileDialog::Options options(isDir ? QFileDialog::ShowDirsOnly : 0x0);
retStr = QFileDialog::getSaveFileName(QApplication::activeWindow(), title, "", filter, NULL, options).toUtf8();
return retStr.isEmpty() ? NULL : retStr.constData();
}
// -----------------------------------------------------------------------
CARLA_EXPORT
const NativePluginDescriptor* carla_get_native_patchbay_plugin();
CARLA_EXPORT
const NativePluginDescriptor* carla_get_native_rack_plugin();
// -----------------------------------------------------------------------
CarlaInstrument::CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay)
: Instrument(instrumentTrack, descriptor),
kIsPatchbay(isPatchbay),
fHandle(NULL),
fDescriptor(isPatchbay ? carla_get_native_patchbay_plugin() : carla_get_native_rack_plugin()),
fMidiEventCount(0)
{
fHost.handle = this;
fHost.uiName = NULL;
fHost.uiParentId = 0;
// figure out prefix from dll filename
QString dllName(carla_get_library_filename());
#if defined(CARLA_OS_LINUX)
fHost.resourceDir = strdup(QString(dllName.split("/lib/carla")[0] + "/share/carla/resources/").toUtf8().constData());
#else
fHost.resourceDir = NULL;
#endif
fHost.get_buffer_size = host_get_buffer_size;
fHost.get_sample_rate = host_get_sample_rate;
fHost.is_offline = host_is_offline;
fHost.get_time_info = host_get_time_info;
fHost.write_midi_event = host_write_midi_event;
fHost.ui_parameter_changed = host_ui_parameter_changed;
fHost.ui_custom_data_changed = host_ui_custom_data_changed;
fHost.ui_closed = host_ui_closed;
fHost.ui_open_file = host_ui_open_file;
fHost.ui_save_file = host_ui_save_file;
fHost.dispatcher = host_dispatcher;
std::memset(&fTimeInfo, 0, sizeof(NativeTimeInfo));
fTimeInfo.bbt.valid = true; // always valid
fHandle = fDescriptor->instantiate(&fHost);
Q_ASSERT(fHandle != NULL);
if (fHandle != NULL && fDescriptor->activate != NULL)
fDescriptor->activate(fHandle);
// we need a play-handle which cares for calling play()
InstrumentPlayHandle * iph = new InstrumentPlayHandle( this );
engine::mixer()->addPlayHandle( iph );
connect(engine::mixer(), SIGNAL(sampleRateChanged()), this, SLOT(sampleRateChanged()));
}
CarlaInstrument::~CarlaInstrument()
{
engine::mixer()->removePlayHandles( instrumentTrack() );
if (fHost.resourceDir != NULL)
{
std::free((char*)fHost.resourceDir);
fHost.resourceDir = NULL;
}
if (fHost.uiName != NULL)
{
std::free((char*)fHost.uiName);
fHost.uiName = NULL;
}
if (fHandle == NULL)
return;
if (fDescriptor->deactivate != NULL)
fDescriptor->deactivate(fHandle);
if (fDescriptor->cleanup != NULL)
fDescriptor->cleanup(fHandle);
fHandle = NULL;
}
// -------------------------------------------------------------------
uint32_t CarlaInstrument::handleGetBufferSize() const
{
return engine::mixer()->framesPerPeriod();
}
double CarlaInstrument::handleGetSampleRate() const
{
return engine::mixer()->processingSampleRate();
}
bool CarlaInstrument::handleIsOffline() const
{
return false; // TODO
}
const NativeTimeInfo* CarlaInstrument::handleGetTimeInfo() const
{
return &fTimeInfo;
}
void CarlaInstrument::handleUiParameterChanged(const uint32_t /*index*/, const float /*value*/) const
{
}
void CarlaInstrument::handleUiClosed()
{
emit uiClosed();
}
intptr_t CarlaInstrument::handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
{
intptr_t ret = 0;
switch (opcode)
{
case HOST_OPCODE_NULL:
break;
case HOST_OPCODE_UPDATE_PARAMETER:
case HOST_OPCODE_UPDATE_MIDI_PROGRAM:
case HOST_OPCODE_RELOAD_PARAMETERS:
case HOST_OPCODE_RELOAD_MIDI_PROGRAMS:
case HOST_OPCODE_RELOAD_ALL:
// nothing
break;
case HOST_OPCODE_UI_UNAVAILABLE:
handleUiClosed();
break;
}
return ret;
// unused for now
(void)index; (void)value; (void)ptr; (void)opt;
}
// -------------------------------------------------------------------
Instrument::Flags CarlaInstrument::flags() const
{
return IsSingleStreamed|IsMidiBased|IsNotBendable;
}
QString CarlaInstrument::nodeName() const
{
return descriptor()->name;
}
void CarlaInstrument::saveSettings(QDomDocument& doc, QDomElement& parent)
{
if (fHandle == NULL || fDescriptor->get_state == NULL)
return;
char* const state = fDescriptor->get_state(fHandle);
if (state == NULL)
return;
QDomDocument carlaDoc("carla");
if (carlaDoc.setContent(QString(state)))
{
QDomNode n = doc.importNode(carlaDoc.documentElement(), true);
parent.appendChild(n);
}
std::free(state);
}
void CarlaInstrument::loadSettings(const QDomElement& elem)
{
if (fHandle == NULL || fDescriptor->set_state == NULL)
return;
QDomDocument carlaDoc("carla");
carlaDoc.appendChild(carlaDoc.importNode(elem.firstChildElement(), true ));
fDescriptor->set_state(fHandle, carlaDoc.toString(0).toUtf8().constData());
}
void CarlaInstrument::play(sampleFrame* workingBuffer)
{
const uint bufsize = engine::mixer()->framesPerPeriod();
std::memset(workingBuffer, 0, sizeof(sample_t)*bufsize*DEFAULT_CHANNELS);
if (fHandle == NULL)
{
instrumentTrack()->processAudioBuffer(workingBuffer, bufsize, NULL);
return;
}
// set time info
song* const s = engine::getSong();
fTimeInfo.playing = s->isPlaying();
fTimeInfo.frame = s->getPlayPos(s->playMode()).frames(engine::framesPerTick());
fTimeInfo.usecs = s->getMilliseconds()*1000;
fTimeInfo.bbt.bar = s->getTacts() + 1;
fTimeInfo.bbt.beat = s->getBeat() + 1;
fTimeInfo.bbt.tick = s->getBeatTicks();
fTimeInfo.bbt.barStartTick = ticksPerBeat*s->getTimeSigModel().getNumerator()*s->getTacts();
fTimeInfo.bbt.beatsPerBar = s->getTimeSigModel().getNumerator();
fTimeInfo.bbt.beatType = s->getTimeSigModel().getDenominator();
fTimeInfo.bbt.ticksPerBeat = ticksPerBeat;
fTimeInfo.bbt.beatsPerMinute = s->getTempo();
float buf1[bufsize];
float buf2[bufsize];
float* rBuf[] = { buf1, buf2 };
std::memset(buf1, 0, sizeof(float)*bufsize);
std::memset(buf2, 0, sizeof(float)*bufsize);
{
const QMutexLocker ml(&fMutex);
fDescriptor->process(fHandle, rBuf, rBuf, bufsize, fMidiEvents, fMidiEventCount);
fMidiEventCount = 0;
}
for (uint i=0; i < bufsize; ++i)
{
workingBuffer[i][0] = buf1[i];
workingBuffer[i][1] = buf2[i];
}
instrumentTrack()->processAudioBuffer(workingBuffer, bufsize, NULL);
}
bool CarlaInstrument::handleMidiEvent(const MidiEvent& event, const MidiTime&, f_cnt_t offset)
{
const QMutexLocker ml(&fMutex);
if (fMidiEventCount >= kMaxMidiEvents)
return false;
NativeMidiEvent& nEvent(fMidiEvents[fMidiEventCount++]);
std::memset(&nEvent, 0, sizeof(NativeMidiEvent));
nEvent.port = 0;
nEvent.time = offset;
nEvent.data[0] = event.type() | (event.channel() & 0x0F);
switch (event.type())
{
case MidiNoteOn:
if (event.velocity() > 0)
{
if (event.key() < 0 || event.key() > MidiMaxKey)
break;
nEvent.data[1] = event.key();
nEvent.data[2] = event.velocity();
nEvent.size = 3;
break;
}
else
{
nEvent.data[0] = MidiNoteOff | (event.channel() & 0x0F);
// nobreak
}
case MidiNoteOff:
if (event.key() < 0 || event.key() > MidiMaxKey)
break;
nEvent.data[1] = event.key();
nEvent.data[2] = event.velocity();
nEvent.size = 3;
break;
case MidiKeyPressure:
nEvent.data[1] = event.key();
nEvent.data[2] = event.velocity();
nEvent.size = 3;
break;
case MidiControlChange:
nEvent.data[1] = event.controllerNumber();
nEvent.data[2] = event.controllerValue();
nEvent.size = 3;
break;
case MidiProgramChange:
nEvent.data[1] = event.program();
nEvent.size = 2;
break;
case MidiChannelPressure:
nEvent.data[1] = event.channelPressure();
nEvent.size = 2;
break;
case MidiPitchBend:
nEvent.data[1] = event.pitchBend() & 0x7f;
nEvent.data[2] = event.pitchBend() >> 7;
nEvent.size = 3;
break;
default:
// unhandled
--fMidiEventCount;
break;
}
return true;
}
PluginView* CarlaInstrument::instantiateView(QWidget* parent)
{
if (QWidget* const window = parent->window())
fHost.uiParentId = window->winId();
else
fHost.uiParentId = 0;
std::free((char*)fHost.uiName);
// TODO - get plugin instance name
//fHost.uiName = strdup(parent->windowTitle().toUtf8().constData());
fHost.uiName = strdup(kIsPatchbay ? "CarlaPatchbay-LMMS" : "CarlaRack-LMMS");
return new CarlaInstrumentView(this, parent);
}
void CarlaInstrument::sampleRateChanged()
{
fDescriptor->dispatcher(fHandle, PLUGIN_OPCODE_SAMPLE_RATE_CHANGED, 0, 0, nullptr, handleGetSampleRate());
}
// -------------------------------------------------------------------
CarlaInstrumentView::CarlaInstrumentView(CarlaInstrument* const instrument, QWidget* const parent)
: InstrumentView(instrument, parent),
fHandle(instrument->fHandle),
fDescriptor(instrument->fDescriptor),
fTimerId(fHandle != NULL && fDescriptor->ui_idle != NULL ? startTimer(30) : 0)
{
setAutoFillBackground(true);
//QPalette pal;
//pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork"));
//setPalette(pal);
QVBoxLayout * l = new QVBoxLayout( this );
l->setContentsMargins( 20, 80, 10, 10 );
l->setSpacing( 10 );
m_toggleUIButton = new QPushButton( tr( "Show GUI" ), this );
m_toggleUIButton->setCheckable( true );
m_toggleUIButton->setChecked( false );
//m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) );
//m_toggleUIButton->setFont( pointSize<8>( m_toggleUIButton->font() ) );
connect( m_toggleUIButton, SIGNAL( clicked(bool) ), this, SLOT( toggleUI( bool ) ) );
m_toggleUIButton->setWhatsThis(
tr( "Click here to show or hide the graphical user interface (GUI) of Carla." ) );
l->addWidget( m_toggleUIButton );
l->addStretch();
connect(instrument, SIGNAL(uiClosed()), this, SLOT(uiClosed()));
}
CarlaInstrumentView::~CarlaInstrumentView()
{
if (m_toggleUIButton->isChecked())
toggleUI(false);
}
void CarlaInstrumentView::toggleUI(bool visible)
{
if (fHandle != NULL && fDescriptor->ui_show != NULL)
fDescriptor->ui_show(fHandle, visible);
}
void CarlaInstrumentView::uiClosed()
{
m_toggleUIButton->setChecked(false);
}
void CarlaInstrumentView::modelChanged()
{
}
void CarlaInstrumentView::timerEvent(QTimerEvent* event)
{
if (event->timerId() == fTimerId)
fDescriptor->ui_idle(fHandle);
InstrumentView::timerEvent(event);
}
// -------------------------------------------------------------------
#include "moc_carla.cxx"

109
plugins/carlabase/carla.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* carla.h - Carla for LMMS
*
* Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
*
* 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.
*
*/
#ifndef CARLA_H
#define CARLA_H
#include "CarlaNative.h"
#include "Instrument.h"
#include "InstrumentView.h"
class QPushButton;
class PLUGIN_EXPORT CarlaInstrument : public Instrument
{
Q_OBJECT
public:
static const uint32_t kMaxMidiEvents = 512;
CarlaInstrument(InstrumentTrack* const instrumentTrack, const Descriptor* const descriptor, const bool isPatchbay);
virtual ~CarlaInstrument();
// CarlaNative functions
uint32_t handleGetBufferSize() const;
double handleGetSampleRate() const;
bool handleIsOffline() const;
const NativeTimeInfo* handleGetTimeInfo() const;
void handleUiParameterChanged(const uint32_t index, const float value) const;
void handleUiClosed();
intptr_t handleDispatcher(const NativeHostDispatcherOpcode opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt);
// LMMS functions
virtual Flags flags() const;
virtual QString nodeName() const;
virtual void saveSettings(QDomDocument& doc, QDomElement& parent);
virtual void loadSettings(const QDomElement& elem);
virtual void play(sampleFrame* workingBuffer);
virtual bool handleMidiEvent(const MidiEvent& event, const MidiTime& time, f_cnt_t offset);
virtual PluginView* instantiateView(QWidget* parent);
signals:
void uiClosed();
private slots:
void sampleRateChanged();
private:
const bool kIsPatchbay;
NativePluginHandle fHandle;
NativeHostDescriptor fHost;
const NativePluginDescriptor* fDescriptor;
uint32_t fMidiEventCount;
NativeMidiEvent fMidiEvents[kMaxMidiEvents];
NativeTimeInfo fTimeInfo;
// this is only needed because note-offs are being sent during play
QMutex fMutex;
friend class CarlaInstrumentView;
};
class CarlaInstrumentView : public InstrumentView
{
Q_OBJECT
public:
CarlaInstrumentView(CarlaInstrument* const instrument, QWidget* const parent);
virtual ~CarlaInstrumentView();
private slots:
void toggleUI(bool);
void uiClosed();
private:
virtual void modelChanged();
virtual void timerEvent(QTimerEvent*);
NativePluginHandle fHandle;
const NativePluginDescriptor* fDescriptor;
int fTimerId;
QPushButton * m_toggleUIButton;
};
#endif

View File

@@ -0,0 +1,8 @@
if(LMMS_HAVE_CARLA)
ADD_DEFINITIONS(-DCARLA_PLUGIN_PATCHBAY -DCARLA_PLUGIN_SYNTH)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/../carlabase")
LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../carlabase")
LINK_LIBRARIES(carlabase)
BUILD_PLUGIN(carlapatchbay carlapatchbay.cpp EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
endif(LMMS_HAVE_CARLA)

View File

@@ -0,0 +1,51 @@
/*
* carlapatchbay.cpp - Carla for LMMS (Patchbay)
*
* Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
*
* 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 "carla.h"
#include "embed.cpp"
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Carla Patchbay",
QT_TRANSLATE_NOOP( "pluginBrowser",
"Carla Patchbay Instrument" ),
"falkTX <falktx/at/falktx.com>",
0x0195,
Plugin::Instrument,
new PluginPixmapLoader( "logo" ),
NULL,
NULL
} ;
Plugin* PLUGIN_EXPORT lmms_plugin_main(Model*, void* data)
{
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlapatchbay_plugin_descriptor, true);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1,8 @@
if(LMMS_HAVE_CARLA)
ADD_DEFINITIONS(-DCARLA_PLUGIN_RACK -DCARLA_PLUGIN_SYNTH)
INCLUDE(BuildPlugin)
INCLUDE_DIRECTORIES(${CARLA_INCLUDE_DIRS} "${CMAKE_CURRENT_SOURCE_DIR}/../carlabase")
LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/../carlabase")
LINK_LIBRARIES(carlabase)
BUILD_PLUGIN(carlarack carlarack.cpp EMBEDDED_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.png")
endif(LMMS_HAVE_CARLA)

View File

@@ -0,0 +1,51 @@
/*
* carlarack.cpp - Carla for LMMS (Rack)
*
* Copyright (C) 2014 Filipe Coelho <falktx@falktx.com>
*
* 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 "carla.h"
#include "embed.cpp"
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Carla Rack",
QT_TRANSLATE_NOOP( "pluginBrowser",
"Carla Rack Instrument" ),
"falkTX <falktx/at/falktx.com>",
0x0195,
Plugin::Instrument,
new PluginPixmapLoader( "logo" ),
NULL,
NULL
} ;
Plugin* PLUGIN_EXPORT lmms_plugin_main(Model*, void* data)
{
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlarack_plugin_descriptor, false);
}
}

BIN
plugins/carlarack/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB