summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/mstrip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/mstrip.cpp')
-rw-r--r--muse_qt4_evolution/muse/mstrip.cpp1211
1 files changed, 1211 insertions, 0 deletions
diff --git a/muse_qt4_evolution/muse/mstrip.cpp b/muse_qt4_evolution/muse/mstrip.cpp
new file mode 100644
index 00000000..64b8132c
--- /dev/null
+++ b/muse_qt4_evolution/muse/mstrip.cpp
@@ -0,0 +1,1211 @@
+//=============================================================================
+// MusE
+// Linux Music Editor
+// $Id:$
+//
+// Copyright (C) 2002-2008 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.
+//=============================================================================
+
+#include "midictrl.h"
+#include "mstrip.h"
+#include "audio.h"
+#include "song.h"
+#include "mixer.h"
+#include "widgets/simplebutton.h"
+#include "widgets/utils.h"
+#include "audiodev.h"
+#include "synth.h"
+#include "midirack.h"
+#include "midiplugin.h"
+#include "midiinport.h"
+#include "midioutport.h"
+
+#include "awl/midimslider.h"
+#include "awl/midimeter.h"
+#include "awl/midivolentry.h"
+#include "awl/midipanentry.h"
+#include "awl/midipanknob.h"
+#include "awl/knob.h"
+
+enum { KNOB_PAN, KNOB_CHOR_SEND, KNOB_VAR_SEND, KNOB_REV_SEND };
+
+//---------------------------------------------------------
+// addMidiTracks
+// input == true
+// add routes from all possible midi tracks to input
+// route list of track(channel)
+// input == false
+// add routes to all midi tracks to output route
+// list of track(channel)
+//
+// Note: midi tracks do not have channels
+//---------------------------------------------------------
+
+void addMidiTracks(QMenu* menu, Track* track, int channel, bool input)
+ {
+ RouteList* rl = input ? track->inRoutes() : track->outRoutes();
+ RouteNode a(track, channel, RouteNode::TRACK);
+
+ MidiTrackList* tl = song->midis();
+ for (iMidiTrack i = tl->begin();i != tl->end(); ++i) {
+ MidiTrack* track = *i;
+ QAction* action = menu->addAction(track->name());
+ action->setCheckable(true);
+ RouteNode b(track);
+ Route r = input ? Route(b, a) : Route(a, b);
+ action->setData(QVariant::fromValue(r));
+ action->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// addMidiInPorts
+// can only be added to input route lists
+//---------------------------------------------------------
+
+void Strip::addMidiInPorts(QMenu* menu, Track* dtrack, int channel)
+ {
+ RouteList* rl = dtrack->inRoutes();
+ RouteNode dst(dtrack, channel, RouteNode::TRACK);
+
+ MidiInPortList* tl = song->midiInPorts();
+ for (iMidiInPort i = tl->begin();i != tl->end(); ++i) {
+ MidiInPort* track = *i;
+ QMenu* m = menu->addMenu(track->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode src(track, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addMidiOutPorts
+// can only be added to output route lists
+//---------------------------------------------------------
+
+void Strip::addMidiOutPorts(QMenu* menu, Track* strack, int channel)
+ {
+ RouteList* rl = strack->outRoutes();
+ RouteNode src(strack, channel, RouteNode::TRACK);
+
+ MidiOutPortList* tl = song->midiOutPorts();
+ for (iMidiOutPort i = tl->begin();i != tl->end(); ++i) {
+ MidiOutPort* op = *i;
+ QMenu* m = menu->addMenu(op->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode dst(op, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addSyntiPorts
+// can only be added to output route lists
+//---------------------------------------------------------
+
+static void addSyntiPorts(QMenu* menu, Track* strack, int channel)
+ {
+ RouteList* rl = strack->outRoutes();
+ RouteNode src(strack, channel, RouteNode::TRACK);
+
+ SynthIList* sl = song->syntis();
+ for (iSynthI i = sl->begin(); i != sl->end(); ++i) {
+ SynthI* sy = *i;
+ QMenu* m = menu->addMenu(sy->name());
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QAction* a = m->addAction(QString("Channel %1").arg(ch+1));
+ a->setCheckable(true);
+ RouteNode dst(sy, ch, RouteNode::TRACK);
+ Route r = Route(src, dst);
+ a->setData(QVariant::fromValue(r));
+ a->setChecked(rl->indexOf(r) != -1);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// addKnob
+//---------------------------------------------------------
+
+void MidiStrip::addKnob(int ctrl, int idx, const QString& tt, const QString& label,
+ const char* slot, bool enabled, int row)
+ {
+ Awl::FloatEntry* dl;
+ Awl::Knob* knob;
+
+ if (idx == KNOB_PAN) {
+ dl = new Awl::MidiPanEntry(this);
+ knob = new Awl::MidiPanKnob(this);
+ }
+ else {
+ dl = new Awl::MidiVolEntry(this);
+ knob = new Awl::Knob(this);
+ knob->setRange(0.0, 127.0);
+ }
+ knob->setId(ctrl);
+ dl->setId(ctrl);
+ dl->setFrame(true);
+
+ controller[idx].knob = knob;
+ knob->setToolTip(tt);
+ knob->setEnabled(enabled);
+
+ controller[idx].dl = dl;
+ dl->setFixedSize(entrySize);
+ dl->setEnabled(enabled);
+
+ QLabel* lb = new QLabel(label, this);
+ lb->setObjectName("knobLabel");
+ controller[idx].lb = lb;
+ lb->setFixedSize(entrySize);
+ lb->setAlignment(Qt::AlignCenter);
+ lb->setEnabled(enabled);
+
+ grid->addWidget(lb, row, 0);
+ grid->addWidget(dl, row+1, 0);
+ grid->addWidget(knob, row, 1, 2, 1);
+
+ connect(knob, SIGNAL(valueChanged(double,int)), slot);
+ connect(dl, SIGNAL(valueChanged(double,int)), slot);
+ connect(knob, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(knob, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ }
+
+//---------------------------------------------------------
+// MidiStrip
+//---------------------------------------------------------
+
+MidiStrip::MidiStrip(Mixer* m, MidiTrack* t, bool align)
+ : Strip(m, t, align)
+ {
+ volumeTouched = false;
+ panTouched = false;
+ reverbSendTouched = false;
+ variSendTouched = false;
+ chorusSendTouched = false;
+
+ addKnob(CTRL_VARIATION_SEND, KNOB_VAR_SEND, tr("VariationSend"), tr("Var"), SLOT(ctrlChanged(double,int)), true, 1);
+ addKnob(CTRL_REVERB_SEND, KNOB_REV_SEND, tr("ReverbSend"), tr("Rev"), SLOT(ctrlChanged(double,int)), true, 3);
+ addKnob(CTRL_CHORUS_SEND, KNOB_CHOR_SEND, tr("ChorusSend"), tr("Cho"), SLOT(ctrlChanged(double,int)), true, 5);
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_VOLUME);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 7, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_VOLUME);
+ sl->setFixedHeight(entrySize.height());
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 8, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ addKnob(CTRL_PANPOT, KNOB_PAN, tr("Pan/Balance"), tr("Pan"), SLOT(ctrlChanged(double,int)), true, 9);
+
+ //---------------------------------------------------
+ // --- record
+ // mute, solo
+ //---------------------------------------------------
+
+ SimpleButton* monitor = newMonitorButton();
+ monitor->setFixedHeight(BUTTON_HEIGHT);
+ monitor->setChecked(track->monitor());
+ connect(monitor, SIGNAL(clicked(bool)), SLOT(monitorToggled(bool)));
+ connect(t, SIGNAL(monitorChanged(bool)), monitor, SLOT(setChecked(bool)));
+
+ SimpleButton* record = newRecordButton();
+ record->setFixedHeight(BUTTON_HEIGHT);
+ record->setChecked(track->recordFlag());
+ connect(record, SIGNAL(clicked(bool)), SLOT(recordToggled(bool)));
+ connect(t, SIGNAL(recordChanged(bool)), record, SLOT(setChecked(bool)));
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(monitor, 11, 0);
+ grid->addWidget(record, 11, 1);
+ grid->addWidget(mute, 12, 0);
+ grid->addWidget(solo, 12, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(13);
+
+ //---------------------------------------------------
+ // routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 14, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 14, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int)));
+ autoChanged();
+ controllerChanged(CTRL_VOLUME);
+ controllerChanged(CTRL_PANPOT);
+ controllerChanged(CTRL_VARIATION_SEND);
+ controllerChanged(CTRL_REVERB_SEND);
+ controllerChanged(CTRL_CHORUS_SEND);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiStrip::controllerChanged(int id)
+ {
+ CVal cv = track->ctrlVal(id);
+ double val = double(cv.i);
+
+ switch (id) {
+ case CTRL_VOLUME:
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ break;
+ case CTRL_PANPOT:
+ if (!panTouched)
+ controller[KNOB_PAN].knob->setValue(val);
+ controller[KNOB_PAN].dl->setValue(val);
+ break;
+ case CTRL_VARIATION_SEND:
+ if (!variSendTouched)
+ controller[KNOB_VAR_SEND].knob->setValue(val);
+ controller[KNOB_VAR_SEND].dl->setValue(val);
+ break;
+ case CTRL_REVERB_SEND:
+ if (!reverbSendTouched)
+ controller[KNOB_REV_SEND].knob->setValue(val);
+ controller[KNOB_REV_SEND].dl->setValue(val);
+ break;
+ case CTRL_CHORUS_SEND:
+ if (!chorusSendTouched)
+ controller[KNOB_CHOR_SEND].knob->setValue(val);
+ controller[KNOB_CHOR_SEND].dl->setValue(val);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+// called when user changes controller
+//---------------------------------------------------------
+
+void MidiStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_VOLUME: volumeTouched = true; break;
+ case CTRL_PANPOT: panTouched = true; break;
+ case CTRL_VARIATION_SEND: variSendTouched = true; break;
+ case CTRL_REVERB_SEND: reverbSendTouched = true; break;
+ case CTRL_CHORUS_SEND: chorusSendTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_VOLUME: volumeTouched = false; break;
+ case CTRL_PANPOT: panTouched = false; break;
+ case CTRL_VARIATION_SEND: variSendTouched = false; break;
+ case CTRL_REVERB_SEND: reverbSendTouched = false; break;
+ case CTRL_CHORUS_SEND: chorusSendTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ for (unsigned i = 0; i < sizeof(controller)/sizeof(*controller); ++i) {
+ controller[i].knob->setEnabled(ec);
+ controller[i].dl->setEnabled(ec);
+ }
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+ addMidiInPorts(pup, track, -1); // add midi inputs to menu
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ addMidiOutPorts(pup, track, -1);
+ addSyntiPorts(pup, track, -1);
+ }
+
+//---------------------------------------------------------
+// monitorToggled
+//---------------------------------------------------------
+
+void MidiStrip::monitorToggled(bool val)
+ {
+ song->setMonitor(track, val);
+ }
+
+//---------------------------------------------------------
+// recordToggled
+//---------------------------------------------------------
+
+void MidiStrip::recordToggled(bool val)
+ {
+ song->setRecordFlag(track, !val);
+ }
+
+//---------------------------------------------------------
+// MidiOutPortStrip
+//---------------------------------------------------------
+
+MidiOutPortStrip::MidiOutPortStrip(Mixer* m, MidiOutPort* t, bool align)
+ : Strip(m, t, align)
+ {
+ //---------------------------------------------------
+ // plugin rack
+ //---------------------------------------------------
+
+ MidiRack* rack = new MidiRack(this, t);
+ rack->setFixedHeight(rack->sizeHint().height()+2);
+ grid->addWidget(rack, 1, 0, 1, 2);
+
+
+ if (_align)
+ grid->setRowMinimumHeight(2, STRIP_WIDTH/2);
+
+ volumeTouched = false;
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_MASTER_VOLUME);
+ slider->setRange(0.0, 1024*16.0);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 3, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_MASTER_VOLUME);
+ sl->setMax(128 * 128 - 1);
+// sl->setFont(config.fonts[1]);
+ sl->setFixedHeight(entrySize.height());
+
+ controllerChanged(CTRL_MASTER_VOLUME);
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 4, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(5, entrySize.height() * 2);
+
+ //---------------------------------------------------
+ // sync
+ // mute, solo
+ //---------------------------------------------------
+
+ sync = newSyncButton();
+ sync->setFixedHeight(BUTTON_HEIGHT);
+ sync->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ sync->setChecked(((MidiOutPort*)track)->sendSync());
+ grid->addWidget(sync, 6, 0, 1, 2);
+ connect(sync, SIGNAL(clicked(bool)), SLOT(syncToggled(bool)));
+ connect(track, SIGNAL(sendSyncChanged(bool)), sync, SLOT(setChecked(bool)));
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 7, 0);
+ grid->addWidget(solo, 7, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(8);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 9, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 9, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ autoChanged();
+ controllerChanged(CTRL_MASTER_VOLUME);
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiOutPortStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiOutPortStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiOutPortStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiOutPortStrip::controllerChanged(int id)
+ {
+ if (id == CTRL_MASTER_VOLUME) {
+ double val = double(track->ctrlVal(id).i);
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiOutPortStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, track, ch, true);
+ addMidiInPorts(m, track, ch);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiOutPortStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ RouteList* orl = track->outRoutes();
+
+ QList<PortName> ol;
+ //
+ // add JACK midi ports to list
+ //
+ ol = audioDriver->inputPorts(true);
+ foreach (PortName ip, ol) {
+ QAction* oa = pup->addAction(ip.name);
+ oa->setCheckable(true);
+ RouteNode dst(ip.port, RouteNode::JACKMIDIPORT);
+ Route r = Route(RouteNode(track), dst);
+ oa->setData(QVariant::fromValue(r));
+ oa->setChecked(orl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// syncToggled
+//---------------------------------------------------------
+
+void MidiOutPortStrip::syncToggled(bool val) const
+ {
+ ((MidiOutPort*)track)->setSendSync(val);
+ }
+
+//---------------------------------------------------------
+// MidiInPortStrip
+//---------------------------------------------------------
+
+MidiInPortStrip::MidiInPortStrip(Mixer* m, MidiInPort* t, bool align)
+ : Strip(m, t, align)
+ {
+ //---------------------------------------------------
+ // plugin rack
+ //---------------------------------------------------
+
+ MidiRack* rack = new MidiRack(this, t);
+ rack->setFixedHeight(rack->sizeHint().height()+2);
+ grid->addWidget(rack, 1, 0, 1, 2);
+
+ //---------------------------------------------------
+ // input activity
+ //---------------------------------------------------
+
+ grid->setRowStretch(2, 100);
+
+ QGridLayout* ag = new QGridLayout;
+ ag->setMargin(4);
+ ag->setSpacing(1);
+ QSvgRenderer sr;
+ QPainter painter;
+
+ sr.load(QString(":/xpm/activeon.svg"));
+ QSize aSize(sr.defaultSize());
+ activityOn = new QPixmap(aSize);
+ activityOn->fill(Qt::transparent);
+ painter.begin(activityOn);
+ sr.render(&painter);
+ painter.end();
+
+ sr.load(QString(":/xpm/activeoff.svg"));
+ activityOff = new QPixmap(aSize);
+ activityOff->fill(Qt::transparent);
+ painter.begin(activityOff);
+ sr.render(&painter);
+ painter.end();
+
+ for (int ch = MIDI_CHANNELS-1; ch >= 0; --ch) {
+ QLabel* l = new QLabel(QString("%1").arg(ch+1));
+ l->setObjectName("midiChannelLabel");
+ ag->addWidget(l, ch, 0, Qt::AlignCenter);
+ channelActivity[ch] = new QLabel;
+ ag->addWidget(channelActivity[ch], ch, 1, Qt::AlignCenter);
+ channelActivity[ch]->setPixmap(*activityOff);
+ activity[ch] = 0;
+ }
+ grid->addLayout(ag, 3, 0, 2, Qt::AlignHCenter);
+
+ if (_align)
+ grid->setRowMinimumHeight(4, BUTTON_HEIGHT);
+
+ //---------------------------------------------------
+ // mute, solo
+ // or
+ // record, mixdownfile
+ //---------------------------------------------------
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 5, 0);
+ grid->addWidget(solo, 5, 1);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(6, BUTTON_HEIGHT);
+
+ iR = newInRouteButton();
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ grid->addWidget(iR, 7, 0);
+ grid->addWidget(oR, 7, 1);
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiInPortStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiInPortStrip::heartBeat()
+ {
+ for (int i = 0; i < MIDI_CHANNELS; ++i) {
+ bool isActive = inport()->checkActivity(i);
+ if (activity[i] != isActive) {
+ channelActivity[i]->setPixmap(isActive ? *activityOn : *activityOff);
+ activity[i] = isActive;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiInPortStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiInPortStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiInPortStrip::iRouteShow()
+ {
+ QMenu* pup = iR->menu();
+ pup->clear();
+
+ RouteList* irl = track->inRoutes();
+
+ QList<PortName> ol;
+ //
+ // add JACK midi ports to list
+ //
+ ol = audioDriver->outputPorts(true);
+ foreach (PortName ip, ol) {
+ QAction* action = pup->addAction(ip.name);
+ action->setCheckable(true);
+ RouteNode src(ip.port, RouteNode::JACKMIDIPORT);
+ Route r = Route(src, RouteNode(track));
+ action->setData(QVariant::fromValue(r));
+ action->setChecked(irl->indexOf(r) != -1);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiInPortStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, track, ch, false);
+ addSyntiPorts(m, track, ch);
+ addMidiOutPorts(m, track, ch);
+ }
+ }
+
+//---------------------------------------------------------
+// MidiSyntiStrip
+//---------------------------------------------------------
+
+MidiSyntiStrip::MidiSyntiStrip(Mixer* m, MidiSynti* t, bool align)
+ : Strip(m, t, align)
+ {
+ if (_align)
+ grid->setRowMinimumHeight(1, STRIP_WIDTH/2 * 3);
+
+ volumeTouched = false;
+
+ //---------------------------------------------------
+ // slider, label, meter
+ //---------------------------------------------------
+
+ slider = new Awl::MidiMeterSlider(this);
+ slider->setId(CTRL_MASTER_VOLUME);
+ slider->setRange(0.0, 1024*16.0);
+ slider->setFixedWidth(40);
+ grid->addWidget(slider, 2, 0, 1, 2, Qt::AlignRight);
+
+ sl = new Awl::MidiVolEntry(this);
+ sl->setId(CTRL_MASTER_VOLUME);
+// sl->setFont(config.fonts[1]);
+ sl->setFixedHeight(entrySize.height());
+
+ connect(slider, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ connect(slider, SIGNAL(sliderPressed(int)), SLOT(sliderPressed(int)));
+ connect(slider, SIGNAL(sliderReleased(int)), SLOT(sliderReleased(int)));
+ connect(sl, SIGNAL(valueChanged(double,int)), SLOT(ctrlChanged(double, int)));
+ grid->addWidget(sl, 3, 0, 1, 2);
+
+ //---------------------------------------------------
+ // pan, balance
+ //---------------------------------------------------
+
+ if (_align)
+ grid->setRowMinimumHeight(4, STRIP_WIDTH);
+
+ //---------------------------------------------------
+ // sync
+ // mute, solo
+ //---------------------------------------------------
+
+ mute = newMuteButton();
+ mute->setChecked(track->isMute());
+ mute->setFixedHeight(BUTTON_HEIGHT);
+ connect(mute, SIGNAL(clicked(bool)), SLOT(muteToggled(bool)));
+
+ solo = newSoloButton();
+ solo->setFixedHeight(BUTTON_HEIGHT);
+ solo->setChecked(track->solo());
+ connect(solo, SIGNAL(clicked(bool)), SLOT(soloToggled(bool)));
+
+ grid->addWidget(mute, 5, 0);
+ grid->addWidget(solo, 5, 1);
+
+ //---------------------------------------------------
+ // automation mode
+ //---------------------------------------------------
+
+ addAutomationButtons(6);
+
+ //---------------------------------------------------
+ // output routing
+ //---------------------------------------------------
+
+ iR = newInRouteButton();
+ grid->addWidget(iR, 7, 0);
+ connect(iR->menu(), SIGNAL(aboutToShow()), SLOT(iRouteShow()));
+ connect(iR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ oR = newOutRouteButton();
+ grid->addWidget(oR, 7, 1);
+ connect(oR->menu(), SIGNAL(aboutToShow()), SLOT(oRouteShow()));
+ connect(oR->menu(), SIGNAL(triggered(QAction*)), song, SLOT(routeChanged(QAction*)));
+
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ connect(track, SIGNAL(muteChanged(bool)), mute, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(soloChanged(bool)), solo, SLOT(setChecked(bool)));
+ connect(track, SIGNAL(autoReadChanged(bool)), SLOT(autoChanged()));
+ connect(track, SIGNAL(autoWriteChanged(bool)), SLOT(autoChanged()));
+ autoChanged();
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::songChanged(int val)
+ {
+ if (val & SC_TRACK_MODIFIED)
+ updateLabel();
+ }
+
+//---------------------------------------------------------
+// heartBeat
+//---------------------------------------------------------
+
+void MidiSyntiStrip::heartBeat()
+ {
+ double a = track->meter(0); // fast_log10(track->meter(0)) * .2f;
+ slider->setMeterVal(a * 0.008);
+ track->setMeter(0, a * 0.8); // hack
+ }
+
+//---------------------------------------------------------
+// ctrlChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::ctrlChanged(double val, int num)
+ {
+ int ival = int(val);
+ CVal cval;
+ cval.i = ival;
+ song->setControllerVal(track, num, cval);
+ }
+
+//---------------------------------------------------------
+// sliderPressed
+//---------------------------------------------------------
+
+void MidiSyntiStrip::sliderPressed(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = true; break;
+ }
+ track->startAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// sliderReleased
+//---------------------------------------------------------
+
+void MidiSyntiStrip::sliderReleased(int id)
+ {
+ switch (id) {
+ case CTRL_MASTER_VOLUME: volumeTouched = false; break;
+ }
+ track->stopAutoRecord(id);
+ }
+
+//---------------------------------------------------------
+// muteToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::muteToggled(bool val)
+ {
+ song->setMute(track, val);
+ }
+
+//---------------------------------------------------------
+// soloToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::soloToggled(bool val)
+ {
+ song->setSolo(track, val);
+ }
+
+//---------------------------------------------------------
+// autoChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoChanged()
+ {
+ bool ar = track->autoRead();
+ bool aw = track->autoWrite();
+
+ // controller are enabled if
+ // autoRead is off
+ // autoRead and autoWrite are on (touch mode)
+
+ bool ec = !ar || (ar && aw);
+ slider->setEnabled(ec);
+ sl->setEnabled(ec);
+ }
+
+//---------------------------------------------------------
+// autoReadToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoReadToggled(bool val)
+ {
+ song->setAutoRead(track, val);
+ }
+
+//---------------------------------------------------------
+// autoWriteToggled
+//---------------------------------------------------------
+
+void MidiSyntiStrip::autoWriteToggled(bool val)
+ {
+ song->setAutoWrite(track, val);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiSyntiStrip::controllerChanged(int id)
+ {
+ if (id == CTRL_MASTER_VOLUME) {
+ double val = double(track->ctrlVal(id).i);
+ if (!volumeTouched)
+ slider->setValue(val);
+ sl->setValue(val);
+ }
+ }
+
+//---------------------------------------------------------
+// oRouteShow
+//---------------------------------------------------------
+
+void MidiSyntiStrip::oRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+ addMidiOutPorts(pup, track, -1);
+ }
+
+//---------------------------------------------------------
+// iRouteShow
+//---------------------------------------------------------
+
+void MidiSyntiStrip::iRouteShow()
+ {
+ QMenu* pup = oR->menu();
+ pup->clear();
+
+ MidiOutPort* t = (MidiOutPort*)track;
+
+ for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
+ QMenu* m = pup->addMenu(QString("Channel %1").arg(ch+1));
+ addMidiTracks(m, t, ch, false);
+ addMidiInPorts(m, t, ch);
+ }
+ }