diff options
author | Werner Schweer <ws.seh.de> | 2006-11-10 14:30:36 +0000 |
---|---|---|
committer | Werner Schweer <ws.seh.de> | 2006-11-10 14:30:36 +0000 |
commit | c929c5ccee3d955f6ca03877f33b6842f89046aa (patch) | |
tree | f59da82bbd3624d4b089fa06cbfa89023c73cc19 | |
parent | bdc48d562c8a90536ec9bda17d7722f019da40e9 (diff) |
new splitlayer midiplugin
-rw-r--r-- | muse/ChangeLog | 1 | ||||
-rw-r--r-- | muse/midiplugins/CMakeLists.txt | 2 | ||||
-rw-r--r-- | muse/midiplugins/splitlayer/CMakeLists.txt | 45 | ||||
-rw-r--r-- | muse/midiplugins/splitlayer/splitlayer.cpp | 172 | ||||
-rw-r--r-- | muse/midiplugins/splitlayer/splitlayer.h | 68 | ||||
-rw-r--r-- | muse/midiplugins/splitlayer/splitlayergui.cpp | 201 | ||||
-rw-r--r-- | muse/midiplugins/splitlayer/splitlayergui.h | 58 |
7 files changed, 546 insertions, 1 deletions
diff --git a/muse/ChangeLog b/muse/ChangeLog index d330e606..bee89a76 100644 --- a/muse/ChangeLog +++ b/muse/ChangeLog @@ -1,4 +1,5 @@ 10.11 (ws) + - implemented splitlayer midi plugin - replaced meter in midi input strip by activity "leds" for all midi channels 8.11 (ws) diff --git a/muse/midiplugins/CMakeLists.txt b/muse/midiplugins/CMakeLists.txt index dca0bcaa..db19dfa8 100644 --- a/muse/midiplugins/CMakeLists.txt +++ b/muse/midiplugins/CMakeLists.txt @@ -18,7 +18,7 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #============================================================================= -subdirs(libmidiplugin filter metronom transform trigg dump ) +subdirs(libmidiplugin splitlayer filter metronom transform trigg dump ) set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEBUG -DQT_PLUGIN -DQT_SHARED -fPIC" diff --git a/muse/midiplugins/splitlayer/CMakeLists.txt b/muse/midiplugins/splitlayer/CMakeLists.txt new file mode 100644 index 00000000..b6803d8b --- /dev/null +++ b/muse/midiplugins/splitlayer/CMakeLists.txt @@ -0,0 +1,45 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# 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; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +QT4_WRAP_CPP ( splitlayer_mocs splitlayergui.h ) +## QT4_WRAP_UI ( splitlayer_uis splitlayergui.ui ) + +add_library ( splitlayer SHARED + splitlayer.cpp + splitlayergui.cpp + splitlayergui.h + ${splitlayer_mocs} + ) +target_link_libraries( splitlayer + midiplugin + ${QT_LIBRARIES} + ) + +# - tell cmake to name target splitlayer.so instead of +# libsplitlayer.so +# - use precompiled header files +# +set_target_properties ( splitlayer + PROPERTIES PREFIX "" + COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all-pic.h" + ) + +install_targets ( /${CMAKE_INSTALL_LIBDIR}/${MusE_INSTALL_NAME}/midiplugins/ splitlayer ) + diff --git a/muse/midiplugins/splitlayer/splitlayer.cpp b/muse/midiplugins/splitlayer/splitlayer.cpp new file mode 100644 index 00000000..cc0cf53b --- /dev/null +++ b/muse/midiplugins/splitlayer/splitlayer.cpp @@ -0,0 +1,172 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2006 by Werner Schweer +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// 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; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "splitlayergui.h" +#include "splitlayer.h" +#include "midi.h" +#include "midievent.h" + +//--------------------------------------------------------- +// SplitLayer +//--------------------------------------------------------- + +SplitLayer::SplitLayer(const char* name, const MempiHost* h) + : Mempi(name, h) + { + gui = 0; + } + +//--------------------------------------------------------- +// SplitLayer +//--------------------------------------------------------- + +SplitLayer::~SplitLayer() + { + if (gui) + delete gui; + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +bool SplitLayer::init() + { + data.startVelo[0] = 0; + data.endVelo[0] = 128; + data.startPitch[0] = 0; + data.endPitch[0] = 128; + data.pitchOffset[0] = 0; + for (int i = 1; i < MIDI_CHANNELS; ++i) { + data.startVelo[i] = 0; + data.endVelo[i] = 0; + data.startPitch[i] = 0; + data.endPitch[i] = 0; + data.pitchOffset[i] = 0; + } + learnMode = false; + gui = new SplitLayerGui(this, 0); + gui->hide(); + gui->setWindowTitle(QString(name())); + gui->init(); + return false; + } + +//--------------------------------------------------------- +// getGeometry +//--------------------------------------------------------- + +void SplitLayer::getGeometry(int* x, int* y, int* w, int* h) const + { + QPoint pos(gui->pos()); + QSize size(gui->size()); + *x = pos.x(); + *y = pos.y(); + *w = size.width(); + *h = size.height(); + } + +//--------------------------------------------------------- +// setGeometry +//--------------------------------------------------------- + +void SplitLayer::setGeometry(int x, int y, int w, int h) + { + gui->resize(QSize(w, h)); + gui->move(QPoint(x, y)); + } + +//--------------------------------------------------------- +// process +//--------------------------------------------------------- + +void SplitLayer::process(unsigned, unsigned, MidiEventList* il, MidiEventList* ol) + { + for (iMidiEvent i = il->begin(); i != il->end(); ++i) { + if (i->type() != ME_NOTEON && i->type() != ME_NOTEOFF) + ol->insert(*i); + int pitch = i->dataA(); + if (learnMode) { + if (learnStartPitch) + data.startPitch[learnChannel] = pitch; + else + data.endPitch[learnChannel] = pitch; + learnMode = false; + gui->sendResetLearnMode(); + } + for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { + MidiEvent event(*i); + if (pitch >= data.startPitch[ch] && pitch < data.endPitch[ch]) { + event.setChannel(ch); + pitch += data.pitchOffset[ch]; + if (pitch > 127) + pitch = 127; + else if (pitch < 0) + pitch = 0; + event.setA(pitch); + ol->insert(event); + } + } + } + } + +//--------------------------------------------------------- +// getInitData +//--------------------------------------------------------- + +void SplitLayer::getInitData(int* n, const unsigned char** p) const + { + *n = sizeof(data); + *p = (unsigned char*)&data; + } + +//--------------------------------------------------------- +// setInitData +//--------------------------------------------------------- + +void SplitLayer::setInitData(int n, const unsigned char* p) + { + memcpy((void*)&data, p, n); + if (gui) + gui->init(); + } + +//--------------------------------------------------------- +// inst +//--------------------------------------------------------- + +static Mempi* instantiate(const char* name, const MempiHost* h) + { + return new SplitLayer(name, h); + } + +extern "C" { + static MEMPI descriptor = { + "SplitLayer", + "MusE Midi Splits and Layers", + "0.1", // version string + MEMPI_FILTER, + MEMPI_MAJOR_VERSION, MEMPI_MINOR_VERSION, + instantiate + }; + + const MEMPI* mempi_descriptor() { return &descriptor; } + } + diff --git a/muse/midiplugins/splitlayer/splitlayer.h b/muse/midiplugins/splitlayer/splitlayer.h new file mode 100644 index 00000000..cc548a5b --- /dev/null +++ b/muse/midiplugins/splitlayer/splitlayer.h @@ -0,0 +1,68 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2006 by Werner Schweer +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// 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; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __METRONOM_H__ +#define __METRONOM_H__ + +#include "../libmidiplugin/mempi.h" + +static const int MIDI_CHANNELS = 16; + +//--------------------------------------------------------- +// SplitLayer - splits and layers for midi input +//--------------------------------------------------------- + +class SplitLayer : public Mempi { + + protected: + struct InitData { + int startVelo[MIDI_CHANNELS]; + int endVelo[MIDI_CHANNELS]; + int startPitch[MIDI_CHANNELS]; + int endPitch[MIDI_CHANNELS]; + int pitchOffset[MIDI_CHANNELS]; + } data; + + bool learnMode; + int learnChannel; + bool learnStartPitch; + + SplitLayerGui* gui; + friend class SplitLayerGui; + + virtual void process(unsigned, unsigned, MidiEventList*, MidiEventList*); + + public: + SplitLayer(const char* name, const MempiHost*); + ~SplitLayer(); + virtual bool init(); + + virtual bool hasGui() const { return true; } + virtual bool guiVisible() const { return gui->isVisible(); } + virtual void showGui(bool val) { gui->setShown(val); } + virtual void getGeometry(int* x, int* y, int* w, int* h) const; + virtual void setGeometry(int, int, int, int); + + virtual void getInitData(int*, const unsigned char**) const; + virtual void setInitData(int, const unsigned char*); + }; + +#endif + diff --git a/muse/midiplugins/splitlayer/splitlayergui.cpp b/muse/midiplugins/splitlayer/splitlayergui.cpp new file mode 100644 index 00000000..c6578736 --- /dev/null +++ b/muse/midiplugins/splitlayer/splitlayergui.cpp @@ -0,0 +1,201 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2006 by Werner Schweer +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// 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; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "splitlayergui.h" +#include "splitlayer.h" +#include "gui.h" + +//--------------------------------------------------------- +// SplitLayerGui +//--------------------------------------------------------- + +SplitLayerGui::SplitLayerGui(SplitLayer* f, QWidget* parent) + : QWidget(parent) + { + sl = f; + QGridLayout* grid = new QGridLayout; + grid->setSpacing(1); + setLayout(grid); + QSignalMapper* m1 = new QSignalMapper(this); + QSignalMapper* m2 = new QSignalMapper(this); + QSignalMapper* m3 = new QSignalMapper(this); + connect(m1, SIGNAL(mapped(int)), SLOT(startPitchChanged(int))); + connect(m2, SIGNAL(mapped(int)), SLOT(endPitchChanged(int))); + connect(m3, SIGNAL(mapped(int)), SLOT(pitchOffsetChanged(int))); + for (int i = 0; i < MIDI_CHANNELS; ++i) { + QLabel* l = new QLabel(QString("Ch %1").arg(i+1)); + grid->addWidget(l, i, 0); + + p1[i] = new Awl::PitchEdit(0); + p1[i]->setToolTip(tr("start pitch for split")); + connect(p1[i], SIGNAL(valueChanged(int)), m1, SLOT(map())); + m1->setMapping(p1[i], i); + + a1[i] = new QAction(this); + a1[i]->setToolTip(tr("enable learn mode for start pitch")); + a1[i]->setCheckable(true); + QIcon icon; + icon.addFile(":/xpm/recordOn.svg", ICON_SIZE, QIcon::Normal, QIcon::On); + icon.addFile(":/xpm/recordOff.svg", ICON_SIZE, QIcon::Normal, QIcon::Off); + a1[i]->setIcon(icon); + a1[i]->setData(i); + QToolButton* rb1 = new QToolButton; + rb1->setDefaultAction(a1[i]); + connect(rb1, SIGNAL(triggered(QAction*)), SLOT(learnStartPitch(QAction*))); + + p2[i] = new Awl::PitchEdit(0); + p1[i]->setToolTip(tr("end pitch for split")); + connect(p2[i], SIGNAL(valueChanged(int)), m2, SLOT(map())); + m2->setMapping(p2[i], i); + + a2[i] = new QAction(this); + a2[i]->setToolTip(tr("enable learn mode for end pitch")); + a2[i]->setCheckable(true); + a2[i]->setIcon(icon); + a2[i]->setData(i); + QToolButton* rb2 = new QToolButton; + rb2->setDefaultAction(a2[i]); + connect(rb2, SIGNAL(triggered(QAction*)), SLOT(learnEndPitch(QAction*))); + + p3[i] = new Awl::PitchEdit(0); + p1[i]->setToolTip(tr("pitch offset for split")); + p3[i]->setDeltaMode(true); + connect(p3[i], SIGNAL(valueChanged(int)), m3, SLOT(map())); + m3->setMapping(p3[i], i); + + grid->addWidget(p1[i], i, 1); + grid->addWidget(rb1, i, 2); + grid->addWidget(p2[i], i, 3); + grid->addWidget(rb2, i, 4); + grid->addWidget(p3[i], i, 5); + } + int filedes[2]; // 0 - reading 1 - writing + if (pipe(filedes) == -1) { + perror("SplitLayerGui:creating pipe"); + exit(-1); + } + fd2 = filedes[0]; + fd1 = filedes[1]; + + QSocketNotifier* socket = new QSocketNotifier(fd2, + QSocketNotifier::Read, this); + connect(socket, SIGNAL(activated(int)), SLOT(resetLearnMode(int))); + init(); + } + +//--------------------------------------------------------- +// init +//--------------------------------------------------------- + +void SplitLayerGui::init() + { + for (int i = 0; i < MIDI_CHANNELS; ++i) { + p1[i]->setValue(sl->data.startPitch[i]); + p2[i]->setValue(sl->data.endPitch[i]); + p3[i]->setValue(sl->data.pitchOffset[i]); + } + } + +//--------------------------------------------------------- +// learStartPitch +//--------------------------------------------------------- + +void SplitLayerGui::learnStartPitch(QAction* a) + { + sl->learnChannel = a->data().toInt(); + sl->learnStartPitch = false; + sl->learnMode = true; + for (int i = 0; i < MIDI_CHANNELS; ++i) { + if (a != a1[i]) + a1[i]->setChecked(false); + if (a != a2[i]) + a2[i]->setChecked(false); + } + } + +//--------------------------------------------------------- +// learnEndPitch +//--------------------------------------------------------- + +void SplitLayerGui::learnEndPitch(QAction* a) + { + sl->learnChannel = a->data().toInt(); + sl->learnStartPitch = false; + sl->learnMode = true; + for (int i = 0; i < MIDI_CHANNELS; ++i) { + if (a != a1[i]) + a1[i]->setChecked(false); + if (a != a2[i]) + a2[i]->setChecked(false); + } + } + +//--------------------------------------------------------- +// startPitchChanged +//--------------------------------------------------------- + +void SplitLayerGui::startPitchChanged(int n) + { + sl->data.startPitch[n] = p1[n]->value(); + } + +//--------------------------------------------------------- +// endPitchChanged +//--------------------------------------------------------- + +void SplitLayerGui::endPitchChanged(int n) + { + sl->data.endPitch[n] = p2[n]->value(); + } + +//--------------------------------------------------------- +// pitchOffsetChanged +//--------------------------------------------------------- + +void SplitLayerGui::pitchOffsetChanged(int n) + { + sl->data.pitchOffset[n] = p3[n]->value(); + } + +//--------------------------------------------------------- +// resetLearnMode +//--------------------------------------------------------- + +void SplitLayerGui::resetLearnMode(int fd) + { + char buffer[16]; + read(fd, buffer, 16); + + for (int i = 0; i < MIDI_CHANNELS; ++i) { + a1[i]->setChecked(false); + a2[i]->setChecked(false); + } + init(); + } + +//--------------------------------------------------------- +// sendResetLearnMode +//--------------------------------------------------------- + +void SplitLayerGui::sendResetLearnMode() + { + write(fd1, "X", 1); + } + diff --git a/muse/midiplugins/splitlayer/splitlayergui.h b/muse/midiplugins/splitlayer/splitlayergui.h new file mode 100644 index 00000000..2d10ec4b --- /dev/null +++ b/muse/midiplugins/splitlayer/splitlayergui.h @@ -0,0 +1,58 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2006 by Werner Schweer +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// 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; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __SPLITLAYERGUI_H__ +#define __SPLITLAYERGUI_H__ + +#include "awl/pitchedit.h" + +class SplitLayer; + +//--------------------------------------------------------- +// SplitLayerGui +//--------------------------------------------------------- + +class SplitLayerGui : public QWidget { + Q_OBJECT + SplitLayer* sl; + + Awl::PitchEdit* p1[16]; + Awl::PitchEdit* p2[16]; + Awl::PitchEdit* p3[16]; + QAction* a1[16]; + QAction* a2[16]; + int fd1, fd2; + + private slots: + void learnStartPitch(QAction*); + void learnEndPitch(QAction*); + void startPitchChanged(int); + void endPitchChanged(int); + void pitchOffsetChanged(int); + void resetLearnMode(int); + + public: + SplitLayerGui(SplitLayer*, QWidget* parent=0); + void init(); + void sendResetLearnMode(); + }; + +#endif + |