summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-11-10 14:30:36 +0000
committerWerner Schweer <ws.seh.de>2006-11-10 14:30:36 +0000
commitc929c5ccee3d955f6ca03877f33b6842f89046aa (patch)
treef59da82bbd3624d4b089fa06cbfa89023c73cc19
parentbdc48d562c8a90536ec9bda17d7722f019da40e9 (diff)
new splitlayer midiplugin
-rw-r--r--muse/ChangeLog1
-rw-r--r--muse/midiplugins/CMakeLists.txt2
-rw-r--r--muse/midiplugins/splitlayer/CMakeLists.txt45
-rw-r--r--muse/midiplugins/splitlayer/splitlayer.cpp172
-rw-r--r--muse/midiplugins/splitlayer/splitlayer.h68
-rw-r--r--muse/midiplugins/splitlayer/splitlayergui.cpp201
-rw-r--r--muse/midiplugins/splitlayer/splitlayergui.h58
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
+