Merge remote-tracking branch 'origin/stable-1.1'
Conflicts: README.md
This commit is contained in:
@@ -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)
|
||||
@@ -171,6 +172,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)
|
||||
@@ -628,6 +641,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"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
 Linux MultiMedia Studio (LMMS)
|
||||
=======================
|
||||
 LMMS
|
||||
[](https://travis-ci.org/LMMS/lmms)
|
||||
|
||||
What is LMMS?
|
||||
|
||||
BIN
data/projects/CoolSongs/Popsip-Electric Dancer.mmpz
Normal file
BIN
data/projects/CoolSongs/Popsip-Electric Dancer.mmpz
Normal file
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 989 B After Width: | Height: | Size: 689 B |
@@ -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)
|
||||
|
||||
12
plugins/carlabase/CMakeLists.txt
Normal file
12
plugins/carlabase/CMakeLists.txt
Normal 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
528
plugins/carlabase/carla.cpp
Normal 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
109
plugins/carlabase/carla.h
Normal 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
|
||||
8
plugins/carlapatchbay/CMakeLists.txt
Normal file
8
plugins/carlapatchbay/CMakeLists.txt
Normal 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)
|
||||
51
plugins/carlapatchbay/carlapatchbay.cpp
Normal file
51
plugins/carlapatchbay/carlapatchbay.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
BIN
plugins/carlapatchbay/logo.png
Normal file
BIN
plugins/carlapatchbay/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
8
plugins/carlarack/CMakeLists.txt
Normal file
8
plugins/carlarack/CMakeLists.txt
Normal 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)
|
||||
51
plugins/carlarack/carlarack.cpp
Normal file
51
plugins/carlarack/carlarack.cpp
Normal 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
BIN
plugins/carlarack/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
@@ -38,6 +38,10 @@ IF(MINGW_PREFIX)
|
||||
SET(FLTK_FLUID_EXECUTABLE "${MINGW_PREFIX}/bin/fluid")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT EXISTS ${FLTK_FLUID_EXECUTABLE})
|
||||
MESSAGE(FATAL_ERROR "Please install the fluid binary which is part of FLTK.")
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES("${FLTK_INCLUDE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${FFTW3F_INCLUDE_DIRS}
|
||||
|
||||
Reference in New Issue
Block a user