summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/importmidi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/importmidi.cpp')
-rw-r--r--muse_qt4_evolution/muse/importmidi.cpp589
1 files changed, 0 insertions, 589 deletions
diff --git a/muse_qt4_evolution/muse/importmidi.cpp b/muse_qt4_evolution/muse/importmidi.cpp
deleted file mode 100644
index 0bd33df8..00000000
--- a/muse_qt4_evolution/muse/importmidi.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-//=============================================================================
-// 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 "globals.h"
-#include "muse.h"
-#include "song.h"
-#include "widgets/filedialog.h"
-#include "midi.h"
-#include "midifile.h"
-#include "transport.h"
-#include "midiedit/drummap.h"
-#include "al/sig.h"
-#include "al/tempo.h"
-#include "instruments/minstrument.h"
-#include "gconfig.h"
-#include "part.h"
-#include "importmidi.h"
-#include "projectdialog.h"
-#include "templatedialog.h"
-#include "audio.h"
-#include "mixer.h"
-#include "arranger.h"
-#include "midictrl.h"
-#include "midiinport.h"
-#include "midioutport.h"
-
-//---------------------------------------------------------
-// ImportMidiDialog
-//---------------------------------------------------------
-
-ImportMidiDialog::ImportMidiDialog(QWidget* parent)
- : QDialog(parent)
- {
- setupUi(this);
- bg = new QButtonGroup(this);
- bg->setExclusive(true);
- bg->addButton(addToProject, 0);
- bg->addButton(createNewProject, 1);
- createNewProject->setChecked(true);
- connect(selectTemplate,SIGNAL(clicked()), SLOT(selectTemplateClicked()));
- connect(selectProject, SIGNAL(clicked()), SLOT(selectProjectClicked()));
- }
-
-//---------------------------------------------------------
-// selectTemplateClicked
-//---------------------------------------------------------
-
-void ImportMidiDialog::selectTemplateClicked()
- {
- TemplateDialog templateDialog;
- templateDialog.setTemplatePath(templateName->text());
- int rv = templateDialog.exec();
- if (rv == 0)
- return;
- templateName->setText(templateDialog.templatePath());
- }
-
-//---------------------------------------------------------
-// selectProjectClicked
-//---------------------------------------------------------
-
-void ImportMidiDialog::selectProjectClicked()
- {
- ProjectDialog projectDialog;
- projectDialog.setProjectName(projectName->text());
- int rv = projectDialog.exec();
- if (rv == 0)
- return;
- projectName->setText(projectDialog.projectName());
- }
-
-//---------------------------------------------------------
-// setProjectName
-//---------------------------------------------------------
-
-void ImportMidiDialog::setProjectName(const QString& name)
- {
- projectName->setText(name);
- }
-
-//---------------------------------------------------------
-// setTemplateName
-//---------------------------------------------------------
-
-void ImportMidiDialog::setTemplateName(const QString& name)
- {
- templateName->setText(name);
- }
-
-//---------------------------------------------------------
-// importMidi
-//---------------------------------------------------------
-
-void MusE::importMidi()
- {
- importMidi(QString());
- }
-
-void MusE::importMidi(const QString &file)
- {
- QString fn;
- QStringList pattern;
-
- const char** s = midi_file_pattern;
- while (*s)
- pattern << *s++;
-
- if (file.isEmpty()) {
- fn = getOpenFileName(lastMidiPath, pattern, this,
- tr("MusE: Import Midi"));
- lastMidiPath = fn;
- if (fn.isEmpty())
- return;
- }
- else
- fn = file;
-
- QFileInfo fi(fn);
-
- ImportMidiDialog mid(this);
- mid.setProjectName(fi.baseName());
- mid.setTemplateName("");
-
- if (mid.exec() == 0)
- return;
-
- if (mid.doCreateNewProject()) {
- QString header = tr("MusE: import midi file");
- QString path(mid.projectName->text());
- QDir pd(QDir::homePath() + "/" + config.projectPath + "/" + path);
-
- if (leaveProject())
- return;
- if (!pd.mkdir(pd.path())) {
- QString s(tr("Cannot create project folder <%1>"));
- QMessageBox::critical(this, header, s.arg(pd.path()));
- return;
- }
- if (audio->isPlaying()) {
- audio->msgPlay(false);
- while (audio->isPlaying())
- qApp->processEvents();
- }
- addProject(path); // add to history
- seqStop();
- if (mixer1)
- mixer1->clear();
- if (mixer2)
- mixer2->clear();
- //===========================================================
- //
- // close all toplevel windows
- //
- foreach(QWidget* w, QApplication::topLevelWidgets()) {
- if (!w->isVisible())
- continue;
- if (strcmp("DrumEdit", w->metaObject()->className()) == 0)
- w->close();
- else if (strcmp("PianoRoll", w->metaObject()->className()) == 0)
- w->close();
- else if (strcmp("MasterEdit", w->metaObject()->className()) == 0)
- w->close();
- else if (strcmp("WaveEdit", w->metaObject()->className()) == 0)
- w->close();
- else if (strcmp("ListEdit", w->metaObject()->className()) == 0)
- w->close();
- }
- emit startLoadSong();
- song->setProjectPath(path);
- song->clear(false);
- song->setCreated(true);
-
- QString s = mid.templateName->text();
- bool rv = true;
- if (!s.isEmpty()) {
- QFile f(s);
- if (f.open(QIODevice::ReadOnly)) {
- rv = song->read(&f);
- f.close();
- }
- else {
- QString msg(tr("Cannot open template file\n%1"));
- QMessageBox::critical(this, header, msg.arg(s));
- }
- }
- if (!rv) {
- QString msg(tr("File <%1> read error"));
- QMessageBox::critical(this, header, msg.arg(s));
- }
- addMidiFile(fn);
-
- tr_id->setChecked(config.transportVisible);
- bt_id->setChecked(config.bigTimeVisible);
-
- //
- // dont emit song->update():
- song->blockSignals(true);
-
- showBigtime(config.bigTimeVisible);
- showMixer1(config.mixer1Visible);
- showMixer2(config.mixer2Visible);
- if (mixer1 && config.mixer1Visible)
- mixer1->setUpdateMixer();
- if (mixer2 && config.mixer2Visible)
- mixer2->setUpdateMixer();
-
- if (config.transportVisible)
- transport->show();
- transport->move(config.geometryTransport.topLeft());
- showTransport(config.transportVisible);
-
- song->blockSignals(false);
-
- transport->setMasterFlag(song->masterFlag());
- punchinAction->setChecked(song->punchin());
- punchoutAction->setChecked(song->punchout());
- loopAction->setChecked(song->loop());
- clipboardChanged(); // enable/disable "Paste"
- song->setLen(song->len()); // emit song->lenChanged() signal
-
- //
- // add connected channels
- //
- TrackList* tl = song->tracks();
-#if 0
- MidiChannelList* mcl = song->midiChannel();
- for (iMidiChannel i = mcl->begin(); i != mcl->end(); ++i) {
- MidiChannel* mc = (MidiChannel*)*i;
- if (mc->noInRoute() || song->trackExists(mc))
- continue;
- tl->push_back(mc);
- }
-#endif
-
- selectionChanged(); // enable/disable "Copy" & "Paste"
- arranger->endLoadSong();
- song->updatePos();
- //
- // send "cur" controller values to devices
- //
-
- for (iTrack i = tl->begin(); i != tl->end(); ++i) {
- Track* track = *i;
- track->blockSignals(true);
- CtrlList* cl = track->controller();
- for (iCtrl ic = cl->begin(); ic != cl->end(); ++ic) {
- Ctrl* ctrl = ic->second;
- if (ctrl->type() & Ctrl::INT) {
- CVal val;
- val = ctrl->curVal();
- ctrl->setCurVal(CTRL_VAL_UNKNOWN);
- song->setControllerVal(track, ctrl, val);
- }
- }
- track->blockSignals(false);
- }
- setWindowTitle(QString("MusE: Song: ") + path);
- seqStart();
- audio->msgSeek(song->cPos());
- }
- else {
- // add to project
- addMidiFile(fn);
- song->update(-1);
- }
- }
-
-//---------------------------------------------------------
-// addMidiFile
-//---------------------------------------------------------
-
-void MusE::addMidiFile(const QString name)
- {
- QFile* fp = fileOpen(this, name, QString(".mid"), QIODevice::ReadOnly);
- if (fp == 0)
- return;
- MidiFile mf;
- bool rv = mf.read(fp);
- fp->close();
- delete fp;
-
- if (rv) {
- QString s(tr("reading midifile\n "));
- s += name;
- s += tr("\nfailed: ");
- s += mf.error();
- QMessageBox::critical(this, QString("MusE"), s);
- return;
- }
- MidiFileTrackList* etl = mf.trackList();
- int division = mf.division();
-
- MidiOutPort* outPort = 0;
-
- if (song->midiOutPorts()->empty()) {
- outPort = new MidiOutPort();
- outPort->setDefaultName();
- song->insertTrack0(outPort, -1);
-
- //
- // set preferred instrument
- //
- MidiInstrument* instr = 0; // genericMidiInstrument;
- for (iMidiInstrument mi = midiInstruments.begin(); mi != midiInstruments.end(); ++mi) {
- if ((*mi)->iname() == config.defaultMidiInstrument) {
- instr = *mi;
- break;
- }
- }
-
- //
- // if midi file is GM/GS/XG this overrides the preferred
- // instrument setting
-
- if (mf.midiType() != MT_GENERIC) {
- MidiInstrument* instr2 = 0;
- for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) {
- MidiInstrument* mi = *i;
- switch(mf.midiType()) {
- case MT_GM:
- if (mi->iname() == "GM")
- instr2 = mi;
- break;
- case MT_GS:
- if (mi->iname() == "GS")
- instr2 = mi;
- break;
- case MT_XG:
- if (mi->iname() == "XG")
- instr2 = mi;
- break;
- case MT_GENERIC: // cannot happen
- break;
- }
- if (instr2)
- break;
- }
- if (instr2)
- instr = instr2;
- }
- if (instr == 0)
- instr = genericMidiInstrument;
- outPort->setInstrument(instr);
- }
- else
- outPort = song->midiOutPorts()->front();
-
- //
- // create MidiTrack and copy events to ->events()
- // - combine note on/off events
- // - calculate tick value for internal resolution
- //
-
- foreach(const MidiFileTrack* t, *etl) {
- const MidiEventList& el = t->events;
- if (el.empty())
- continue;
- //
- // if we split the track, SYSEX and META events go into
- // the first target track
-
- bool first = true;
- for (int channel = 0; channel < MIDI_CHANNELS; ++channel) {
- //
- // check if there are any events for channel in track:
- //
- iMidiEvent i;
- for (i = el.begin(); i != el.end(); ++i) {
- MidiEvent ev = *i;
- if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel)
- break;
- }
- if (i == el.end())
- continue;
-
- MidiTrack* track = new MidiTrack();
- if (t->isDrumTrack)
- track->setUseDrumMap(true);
-//TODOB track->outRoutes()->push_back(Route(outPort->channel(channel), -1, Route::TRACK));
-// if (inPort && config.connectToAllMidiTracks) {
-// for (int ch = 0; ch < MIDI_CHANNELS; ++ch) {
-// Route src(inPort, ch, Route::TRACK);
-// track->inRoutes()->push_back(src);
-// }
-// }
-
- EventList* mel = track->events();
- buildMidiEventList(mel, &el, track, channel, division, first);
- first = false;
-
- for (iEvent i = mel->begin(); i != mel->end(); ++i) {
- Event event = i->second;
- if (event.type() == Controller) {
- int ctrl = event.dataA();
- MidiInstrument* instr = outPort->instrument();
- track->addMidiController(instr, ctrl);
- CVal val;
- val.i = event.dataB();
- track->addControllerVal(ctrl, event.tick(), val);
- }
- }
- processTrack(track);
- if (track->name().isEmpty())
- track->setDefaultName();
- song->insertTrack0(track, -1);
- }
- if (first) {
- //
- // track does only contain non-channel messages
- // (SYSEX or META)
- //
- MidiTrack* track = new MidiTrack();
- EventList* mel = track->events();
- buildMidiEventList(mel, &el, track, 0, division, true);
- processTrack(track);
- if (track->name().isEmpty())
- track->setDefaultName();
- song->insertTrack0(track, -1);
- }
- }
-
- TrackList* tl = song->tracks();
- if (!tl->empty()) {
- Track* track = tl->front();
- track->setSelected(true);
- }
- unsigned int l = 1;
- MidiTrackList* mtl = song->midis();
- for (iMidiTrack t = mtl->begin(); t != mtl->end(); ++t) {
- MidiTrack* track = *t;
- PartList* parts = track->parts();
- for (iPart p = parts->begin(); p != parts->end(); ++p) {
- unsigned last = p->second->tick() + p->second->lenTick();
- if (last > l)
- l = last;
- }
- }
- song->setLen(l);
- AL::TimeSignature sig = AL::sigmap.timesig(0);
- int z = sig.z;
- int n = sig.n;
-
- transport->setTimesig(z, n);
-// int tempo = AL::tempomap.tempo(0);
-// transport->setTempo(tempo);
-
- bool masterF = !AL::tempomap.empty();
- song->setMasterFlag(masterF);
- transport->setMasterFlag(masterF);
-
- song->updatePos();
- }
-
-//---------------------------------------------------------
-// processTrack
-// divide events into parts
-//---------------------------------------------------------
-
-void MusE::processTrack(MidiTrack* track)
- {
- EventList* tevents = track->events();
- if (tevents->empty())
- return;
-
- //---------------------------------------------------
- // create parts
- // Break midi tracks into parts.
- // A new part is created when a gap of at least
- // one measure is detected. Part len is aligned
- // to one measure.
- //---------------------------------------------------
-
- PartList* pl = track->parts();
-
- int lastTick = 0;
- for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
- Event event = i->second;
- int epos = event.tick() + event.lenTick();
- if (epos > lastTick)
- lastTick = epos;
- }
-
- int len = song->roundUpBar(lastTick+1);
- int bar2, beat;
- unsigned tick;
- AL::sigmap.tickValues(len, &bar2, &beat, &tick);
-
- QString partname = track->name();
-
- int lastOff = 0;
- int st = -1; // start tick current part
- int x1 = 0; // start tick current measure
- int x2 = 0; // end tick current measure
-
- for (int bar = 0; bar < bar2; ++bar, x1 = x2) {
- x2 = AL::sigmap.bar2tick(bar+1, 0, 0);
- if (lastOff > x2) {
- // this measure is busy!
- continue;
- }
- iEvent i1 = tevents->lower_bound(x1);
- iEvent i2 = tevents->lower_bound(x2);
-
- if (i1 == i2) { // empty?
- if (st != -1) {
- Part* part = new Part(track);
- part->ref();
- part->setType(AL::TICKS);
- part->setTick(st);
- part->setLenTick(x1-st);
- part->setName(partname);
- pl->add(part);
- st = -1;
- }
- }
- else {
- if (st == -1)
- st = x1; // begin new part
- //HACK:
- //lastOff:
- for (iEvent i = i1; i != i2; ++i) {
- Event event = i->second;
- if (event.type() == Note) {
- int off = event.tick() + event.lenTick();
- if (off > lastOff)
- lastOff = off;
- }
- }
- }
- }
- if (st != -1) {
- Part* part = new Part(track);
- part->ref();
- part->setType(AL::TICKS);
- part->setTick(st);
- part->setLenTick(x2-st);
- part->setName(partname);
- pl->add(part);
- }
-
- //-------------------------------------------------------------
- // assign events to parts
- //-------------------------------------------------------------
-
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- Part* part = p->second;
- int stick = part->tick();
- int etick = part->tick() + part->lenTick();
- iEvent r1 = tevents->lower_bound(stick);
- iEvent r2 = tevents->lower_bound(etick);
- int startTick = part->tick();
-
- EventList* el = part->events();
- for (iEvent i = r1; i != r2; ++i) {
- Event ev = i->second;
- int ntick = ev.tick() - startTick;
- ev.setTick(ntick);
- el->add(ev, ntick);
- }
- tevents->erase(r1, r2);
- }
-
- if (tevents->size())
- printf("-----------events left: %zd\n", tevents->size());
- for (iEvent i = tevents->begin(); i != tevents->end(); ++i) {
- printf("%d===\n", i->first);
- i->second.dump();
- }
- // all events should be processed:
- assert(tevents->empty());
- }
-