//============================================================================= // 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. //============================================================================= #include "arranger.h" #include "widgets/outportcombo.h" #include "instruments/minstrument.h" #include "midiedit/drummap.h" #include "midictrl.h" #include "song.h" #include "trackinfo.h" #include "synth.h" #include "tllineedit.h" #include "audio.h" #include "gui.h" #include "midioutport.h" #include "midiinport.h" static QColor labelColor(140, 140, 255); //--------------------------------------------------------- // createTrackInfo //--------------------------------------------------------- TrackInfo* Arranger::createTrackInfo() { Track::TrackType t = _curTrack->type(); switch (t) { case Track::MIDI: return new MidiTrackInfo(); case Track::AUDIO_OUTPUT: return new AudioOutputInfo(); case Track::AUDIO_GROUP: return new AudioGroupInfo(); case Track::WAVE: return new WaveTrackInfo(); case Track::AUDIO_INPUT: return new AudioInputInfo(); case Track::AUDIO_SOFTSYNTH: return new SynthIInfo(); case Track::MIDI_OUT: return new MidiOutPortInfo(); case Track::MIDI_IN: return new MidiInPortInfo(); case Track::MIDI_SYNTI: return new MidiSynthIInfo(); default: printf("Arranger::createTrackInfo: type %d\n", t); abort(); } } //--------------------------------------------------------- // TrackInfo //--------------------------------------------------------- TrackInfo::TrackInfo() : QWidget() { track = 0; label = new QLabel; label->setToolTip(tr("Track Type")); label->setLineWidth(2); label->setFrameStyle(QFrame::Panel | QFrame::Raised); label->setAutoFillBackground(true); QPalette p = label->palette(); p.setColor(QPalette::Background, labelColor); label->setPalette(p); name = new TLLineEdit(""); name->setToolTip(tr("Track Name")); name->setMaximumHeight(24); grid = new QGridLayout; grid->setMargin(0); grid->setSpacing(0); setLayout(grid); grid->addWidget(label, 0, 0, 1, 2); grid->addWidget(name, 1, 0, 1, 2); connect(name, SIGNAL(contentChanged(QString)), SLOT(nameChanged(QString))); connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int))); // resize(QSize(infoWidth, height())); } //--------------------------------------------------------- // nameChanged //--------------------------------------------------------- void TrackInfo::nameChanged(QString s) { song->changeTrackName(track, s); name->setCursorPosition(0); } //--------------------------------------------------------- // init //--------------------------------------------------------- void TrackInfo::init(Track* t) { track = t; if (t == 0) return; label->setText(track->clname()); name->setText(track->name()); connect(track, SIGNAL(nameChanged(const QString&)), name, SLOT(setText(const QString&))); } //--------------------------------------------------------- // songChanged //--------------------------------------------------------- void TrackInfo::songChanged(int val) { if ((val & SC_ROUTE) && track) init(track); } //--------------------------------------------------------- // MidiTrackInfo //--------------------------------------------------------- MidiTrackInfo::MidiTrackInfo() : TrackInfo() { QWidget* midiTrackInfo = new QWidget; mt.setupUi(midiTrackInfo); QWidget* midiPortInfo = new QWidget; mp.setupUi(midiPortInfo); grid->addWidget(midiTrackInfo, 2, 0, 1, 2); channel = new QComboBox; channel->setMaximumHeight(24); for (int ch = 0; ch < MIDI_CHANNELS; ++ch) channel->addItem(tr("Channel %1").arg(ch+1), ch); grid->addWidget(channel, 3, 0, 1, 2); QLabel* label = new QLabel; label->setText(tr("Midi Port")); label->setLineWidth(2); label->setFrameStyle(QFrame::Panel | QFrame::Raised); label->setAutoFillBackground(true); QPalette p = label->palette(); p.setColor(QPalette::Background, labelColor); label->setPalette(p); grid->addWidget(label, 4, 0, 1, 2); port = new QComboBox; port->setMaximumHeight(24); grid->addWidget(port, 5, 0, 1, 2); grid->addWidget(midiPortInfo, 6, 0, 1, 2); grid->setRowStretch(grid->rowCount(), 100); pop = new QMenu(mt.patch); connect(mt.transposition, SIGNAL(valueChanged(int)), SLOT(transpositionChanged(int))); connect(mt.velocity, SIGNAL(valueChanged(int)), SLOT(velocityChanged(int))); connect(mt.delay, SIGNAL(valueChanged(int)), SLOT(delayChanged(int))); connect(mt.length, SIGNAL(valueChanged(int)), SLOT(lenChanged(int))); connect(mt.compression, SIGNAL(valueChanged(int)), SLOT(iKomprChanged(int))); connect(mt.patch, SIGNAL(clicked()), SLOT(patchClicked())); connect(port, SIGNAL(activated(int)), SLOT(portSelected(int))); connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); connect(song, SIGNAL(autoReadChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); connect(song, SIGNAL(autoWriteChanged(Track*,bool)), SLOT(autoChanged(Track*,bool))); } //--------------------------------------------------------- // init //--------------------------------------------------------- void MidiTrackInfo::init(Track* t) { MidiTrack* midiTrack = (MidiTrack*)&*t; if (t != track) { if (track) { disconnect(channel, 0, track, 0); disconnect(track, 0, channel, 0); } connect(channel, SIGNAL(activated(int)), midiTrack, SLOT(setChannel(int))); connect(midiTrack,SIGNAL(channelChanged(int)), channel, SLOT(setCurrentIndex(int))); } TrackInfo::init(t); mt.transposition->setValue(midiTrack->transposition()); mt.delay->setValue(midiTrack->delay()); mt.length->setValue(midiTrack->len()); mt.velocity->setValue(midiTrack->velocity()); mt.compression->setValue(midiTrack->compression()); mp.instrument->clear(); foreach(MidiInstrument* mi, midiInstruments) mp.instrument->addItem(mi->iname()); RouteList* rl = track->outRoutes(); Track* outputTrack = 0; if (!rl->isEmpty()) outputTrack = (*rl)[0].dst.track; port->clear(); port->addItem("---", QVariant::fromValue(0)); foreach(MidiOutPort* mp, *(song->midiOutPorts())) port->addItem(mp->name(), QVariant::fromValue(mp)); foreach(SynthI* s, *(song->syntis())) port->addItem(s->name(), QVariant::fromValue(s)); if (outputTrack) { int idx = port->findText(outputTrack->name()); port->setCurrentIndex(idx == -1 ? 0 : idx); } channel->setCurrentIndex(midiTrack->channelNo()); connect(track, SIGNAL(controllerChanged(int)), SLOT(controllerChanged(int))); if (outputTrack && outputTrack->type() == Track::MIDI_OUT) connect(outputTrack, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); instrumentChanged(); // setup instrument // enable instrument selection only for tracks routed to a // midi out port: mp.instrument->setEnabled(outputTrack && (outputTrack->type() == Track::MIDI_OUT)); if (!rl->isEmpty()) { mp.deviceId->setValue(midiTrack->deviceId()); autoChanged(track, false); // update enable int val = midiTrack->ctrlVal(CTRL_PROGRAM).i; int channelno = midiTrack->channelNo(); mt.patch->setText(midiTrack->instrument()->getPatchName(channelno, val)); } else { channel->setCurrentIndex(0); port->setCurrentIndex(0); mp.instrument->addItem("--"); mp.instrument->setCurrentIndex(0); mt.patch->setText("--"); } } //--------------------------------------------------------- // portSelected //--------------------------------------------------------- void MidiTrackInfo::portSelected(int idx) { QVariant v(port->itemData(idx)); Track* outputTrack = (Track*)v.value(); if (outputTrack == 0) return; RouteList* rl = track->outRoutes(); if (rl->isEmpty()) return; Route r = (*rl)[0]; audio->msgRemoveRoute(r); r.dst.track = outputTrack; audio->msgAddRoute(r); song->update(SC_ROUTE); } //--------------------------------------------------------- // controllerChanged //--------------------------------------------------------- void MidiTrackInfo::controllerChanged(int id) { if (id == CTRL_PROGRAM) { MidiInstrument* mi = track->instrument(); int val = track->ctrlVal(id).i; mt.patch->setText(mi->getPatchName(((MidiTrack*)&*track)->channelNo(), val)); } } //--------------------------------------------------------- // instrumentChanged //--------------------------------------------------------- void MidiTrackInfo::instrumentChanged() { MidiInstrument* mi = track->instrument(); mp.instrument->setCurrentIndex(midiInstruments.indexOf(mi)); } //--------------------------------------------------------- // autoChanged //--------------------------------------------------------- void MidiTrackInfo::autoChanged(Track* t, bool) { if (t != track) return; bool ar = t->autoRead(); bool aw = t->autoWrite(); bool en = !ar || (ar && aw); mt.patch->setEnabled(en); } //--------------------------------------------------------- // transpositionChanged //--------------------------------------------------------- void MidiTrackInfo::transpositionChanged(int val) { ((MidiTrack*)&*track)->setTransposition(val); } //--------------------------------------------------------- // patchClicked //--------------------------------------------------------- void MidiTrackInfo::patchClicked() { MidiInstrument* mi = track->instrument(); mi->populatePatchPopup(pop, 0); QAction* rv = pop->exec(mt.patch->mapToGlobal(QPoint(10,5))); if (rv != 0) { CVal cval; cval.i = rv->data().toInt(); song->setControllerVal(track, CTRL_PROGRAM, cval); } } //--------------------------------------------------------- // instrumentSelected //--------------------------------------------------------- void MidiTrackInfo::instrumentSelected(int n) { RouteList* rl = track->outRoutes(); if (rl->isEmpty()) return; Track* outTrack = (*rl)[0].dst.track; if (outTrack->type() == Track::MIDI_OUT) ((MidiOutPort*)outTrack)->setInstrument(midiInstruments[n]); } //--------------------------------------------------------- // velocityChanged //--------------------------------------------------------- void MidiTrackInfo::velocityChanged(int val) { ((MidiTrack*)&*track)->setVelocity(val); } //--------------------------------------------------------- // delayChanged //--------------------------------------------------------- void MidiTrackInfo::delayChanged(int val) { ((MidiTrack*)&*track)->setDelay(val); } //--------------------------------------------------------- // lenChanged //--------------------------------------------------------- void MidiTrackInfo::lenChanged(int val) { ((MidiTrack*)&*track)->setLen(val); } //--------------------------------------------------------- // iKomprChanged //--------------------------------------------------------- void MidiTrackInfo::iKomprChanged(int val) { ((MidiTrack*)&*track)->setCompression(val); } //--------------------------------------------------------- // deviceIdChanged //--------------------------------------------------------- void MidiTrackInfo::deviceIdChanged(int val) { ((MidiTrack*)&*track)->setDeviceId(val); } //--------------------------------------------------------- // AudioOutputInfo //--------------------------------------------------------- AudioOutputInfo::AudioOutputInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // AudioInputInfo //--------------------------------------------------------- AudioInputInfo::AudioInputInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // AudioGroupInfo //--------------------------------------------------------- AudioGroupInfo::AudioGroupInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // AudioAuxInfo //--------------------------------------------------------- AudioAuxInfo::AudioAuxInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // WaveTrackInfo //--------------------------------------------------------- WaveTrackInfo::WaveTrackInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // SynthIInfo //--------------------------------------------------------- SynthIInfo::SynthIInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // MidiSynthIInfo //--------------------------------------------------------- MidiSynthIInfo::MidiSynthIInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); } //--------------------------------------------------------- // MidiOutPortInfo //--------------------------------------------------------- MidiOutPortInfo::MidiOutPortInfo() : TrackInfo() { QWidget* midiPortInfo = new QWidget; mp.setupUi(midiPortInfo); grid->addWidget(midiPortInfo, 2, 0, 1, 2); grid->setRowStretch(grid->rowCount(), 100); connect(mp.instrument, SIGNAL(activated(int)), SLOT(instrumentSelected(int))); connect(mp.deviceId, SIGNAL(valueChanged(int)), SLOT(deviceIdChanged(int))); } //--------------------------------------------------------- // init //--------------------------------------------------------- void MidiOutPortInfo::init(Track* t) { TrackInfo::init(t); MidiOutPort* op = (MidiOutPort*)&*track; MidiInstrument* mi = op->instrument(); int idx = 0; int curIdx = 0; mp.instrument->clear(); for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { mp.instrument->addItem((*i)->iname()); if ((*i)->iname() == mi->iname()) curIdx = idx; } mp.instrument->setCurrentIndex(curIdx); mp.deviceId->setValue(op->deviceId()); connect(t, SIGNAL(instrumentChanged()), SLOT(instrumentChanged())); } //--------------------------------------------------------- // deviceIdChanged //--------------------------------------------------------- void MidiOutPortInfo::deviceIdChanged(int val) { ((MidiOutPort*)&*track)->setDeviceId(val); } //--------------------------------------------------------- // instrumentChanged //--------------------------------------------------------- void MidiOutPortInfo::instrumentChanged() { MidiOutPort* op = (MidiOutPort*)&*track; MidiInstrument* mi = op->instrument(); int idx = 0; for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { if (*i == mi) { mp.instrument->setCurrentIndex(idx); break; } } } //--------------------------------------------------------- // instrumentSelected //--------------------------------------------------------- void MidiOutPortInfo::instrumentSelected(int n) { MidiOutPort* op = (MidiOutPort*)&*track; int idx = 0; for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i, ++idx) { if (idx == n) { op->setInstrument(*i); break; } } } //--------------------------------------------------------- // MidiInPortInfo //--------------------------------------------------------- MidiInPortInfo::MidiInPortInfo() : TrackInfo() { grid->setRowStretch(grid->rowCount(), 100); }