//============================================================================= // 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; data.veloOffset[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; data.veloOffset[i] = 0; } memset(notes, 0, 128 * sizeof(int)); 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); continue; } int pitch = i->dataA(); int velo = i->dataB(); if (learnMode) { if (learnStartPitch) data.startPitch[learnChannel] = pitch; else data.endPitch[learnChannel] = pitch; learnMode = false; gui->sendResetLearnMode(); return; } if (i->type() == ME_NOTEON && velo) { for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { MidiEvent event(*i); if (pitch >= data.startPitch[ch] && pitch <= data.endPitch[ch] && velo >= data.startVelo[ch] && velo <= data.endVelo[ch]) { notes[pitch] |= (1 << ch); event.setChannel(ch); int p = pitch; int v = velo; p += data.pitchOffset[ch]; if (p > 127) p = 127; else if (p < 0) p = 0; v += data.veloOffset[ch]; if (v > 127) v = 127; else if (v < 0) v = 0; event.setA(p); event.setB(v); ol->insert(event); } } } else { for (int ch = 0; ch < MIDI_CHANNELS; ++ch) { if (notes[pitch] & (1 << ch)) { MidiEvent event(*i); event.setChannel(ch); int p = pitch + data.pitchOffset[ch]; if (p < 0) p = 0; else if (p > 127) p = 127; event.setA(p); ol->insert(event); } } notes[pitch] = 0; } } } //--------------------------------------------------------- // 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; } }