summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/muse/song.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse_qt4_evolution/muse/song.cpp')
-rw-r--r--muse_qt4_evolution/muse/song.cpp1552
1 files changed, 0 insertions, 1552 deletions
diff --git a/muse_qt4_evolution/muse/song.cpp b/muse_qt4_evolution/muse/song.cpp
deleted file mode 100644
index a1f3bff0..00000000
--- a/muse_qt4_evolution/muse/song.cpp
+++ /dev/null
@@ -1,1552 +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 "muse.h"
-#include "song.h"
-#include "track.h"
-#include "undo.h"
-#include "globals.h"
-#include "event.h"
-#include "midiedit/drummap.h"
-#include "audio.h"
-#include "mixer.h"
-#include "audiodev.h"
-#include "gconfig.h"
-#include "al/marker.h"
-#include "al/sig.h"
-#include "al/tempo.h"
-#include "midi.h"
-#include "plugin.h"
-#include "pipeline.h"
-#include "synth.h"
-#include "midiplugin.h"
-#include "midirc.h"
-#include "part.h"
-#include "conf.h"
-#include "midioutport.h"
-#include "midiinport.h"
-#include "instruments/minstrument.h"
-
-Song* song;
-
-//---------------------------------------------------------
-// Song
-//---------------------------------------------------------
-
-Song::Song()
- :QObject(0)
- {
- undoList = new UndoList;
- redoList = new UndoList;
- _markerList = new AL::MarkerList;
- _globalPitchShift = 0;
- clear(false);
- }
-
-//---------------------------------------------------------
-// Song
-//---------------------------------------------------------
-
-Song::~Song()
- {
- delete undoList;
- delete redoList;
- delete _markerList;
-// delete esettingsList;
- }
-
-//---------------------------------------------------------
-// putEvent
-//---------------------------------------------------------
-
-void Song::putEvent(const MidiEvent& event)
- {
- eventFifo.put(event);
- }
-
-//---------------------------------------------------------
-// setTempo
-// public slot
-//---------------------------------------------------------
-
-void Song::setTempo(int newTempo)
- {
- audio->msgSetTempo(pos[0].tick(), newTempo, true);
- }
-
-//---------------------------------------------------------
-// setSig
-// called from transport window
-//---------------------------------------------------------
-
-void Song::setSig(const AL::TimeSignature& sig)
- {
- if (_masterFlag) {
- audio->msgAddSig(pos[0].tick(), sig);
- }
- }
-
-//---------------------------------------------------------
-// addEvent
-// return true if event was added
-//---------------------------------------------------------
-
-bool Song::addEvent(const Event& event, Part* part)
- {
- if (event.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int tick = event.tick() + part->tick();
- int cntrl = event.dataA();
- CVal val;
- val.i = event.dataB();
- if (!track->addControllerVal(cntrl, tick, val)) {
- track->addMidiController(track->instrument(), cntrl);
- if (!track->addControllerVal(cntrl, tick, val)) {
- return false;
- }
- }
- }
- else {
- part->events()->add(event);
- }
- return true;
- }
-
-//---------------------------------------------------------
-// changeEvent
-//---------------------------------------------------------
-
-void Song::changeEvent(const Event& oldEvent, const Event& newEvent, Part* part)
- {
- iEvent i = part->events()->find(oldEvent);
- if (i == part->events()->end()) {
- printf("Song::changeEvent(): EVENT not found !! %ld\n", long(part->events()->size()));
- // abort();
- return;
- }
- part->events()->erase(i);
- part->events()->add(newEvent);
-
- if (newEvent.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int tick = newEvent.tick() + part->tick();
- int cntrl = newEvent.dataA();
- CVal val;
- val.i = newEvent.dataB();
- track->addControllerVal(cntrl, tick, val);
- }
- }
-
-//---------------------------------------------------------
-// deleteEvent
-//---------------------------------------------------------
-
-void Song::deleteEvent(const Event& event, Part* part)
- {
-#if 0 //TODO3
- if (event.type() == Controller) {
- MidiTrack* track = (MidiTrack*)part->track();
- int ch = track->outChannel();
- int tick = event.tick() + part->tick();
- int cntrl = event.dataA();
- midiPorts[track->outPort()].deleteController(ch, tick, cntrl);
- }
-#endif
- iEvent ev = part->events()->find(event);
- if (ev == part->events()->end()) {
- printf("event not found in part\n");
- return;
- }
- part->events()->erase(ev);
- }
-
-//---------------------------------------------------------
-// setLoop
-// set transport loop flag
-//---------------------------------------------------------
-
-void Song::setLoop(bool f)
- {
- if (loopFlag != f) {
- loopFlag = f;
- loopAction->setChecked(loopFlag);
- emit loopChanged(loopFlag);
- }
- }
-
-//---------------------------------------------------------
-// setRecord
-// set record flag
-//---------------------------------------------------------
-
-void Song::setRecord(bool f)
- {
- if (recordFlag == f)
- return;
- if (muse->playAction->isChecked()) {
- //
- // dont allow record state changes when rolling
- //
- recordAction->setChecked(!f);
- return;
- }
-
- if (f) {
- bool alreadyRecEnabled = false;
- Track *selectedTrack = 0;
-
- // loop through list and check if any track is rec enabled
- // if not then rec enable the selected track
-
- WaveTrackList* wtl = waves();
- for (iWaveTrack i = wtl->begin(); i != wtl->end(); ++i) {
- if ((*i)->recordFlag()) {
- alreadyRecEnabled = true;
- break;
- }
- if ((*i)->selected())
- selectedTrack = (*i);
- }
- if (!alreadyRecEnabled) {
- MidiTrackList* mtl = midis();
- for (iMidiTrack it = mtl->begin(); it != mtl->end(); ++it) {
- if ((*it)->recordFlag()) {
- alreadyRecEnabled = true;
- break;
- }
- if ((*it)->selected())
- selectedTrack = (*it);
- }
- }
- if (!alreadyRecEnabled && selectedTrack) {
- // enable recording on selected track:
- setRecordFlag(selectedTrack, true);
- }
- else {
- if (!alreadyRecEnabled) {
- // If there are no tracks, do not enable record.
- // TODO: This forces the user to first enable record on a track
- // which probably is a bad thing. Maybe we should warn
- // only when the user actually starts recording by pressing
- // play.
-
- QMessageBox::critical(0, "MusE: Record",
- "No track(s) enabled for recording");
- f = false;
- }
- }
- }
- if (!f)
- bounceTrack = 0;
- recordAction->setChecked(f);
- if (f != recordFlag) {
- recordFlag = f;
- emit recordChanged(recordFlag);
- }
- }
-
-//---------------------------------------------------------
-// setPunchin
-// set punchin flag
-//---------------------------------------------------------
-
-void Song::setPunchin(bool f)
- {
- if (punchinFlag != f) {
- punchinFlag = f;
- punchinAction->setChecked(punchinFlag);
- emit punchinChanged(punchinFlag);
- }
- }
-
-//---------------------------------------------------------
-// setPunchout
-// set punchout flag
-//---------------------------------------------------------
-
-void Song::setPunchout(bool f)
- {
- if (punchoutFlag != f) {
- punchoutFlag = f;
- punchoutAction->setChecked(punchoutFlag);
- emit punchoutChanged(punchoutFlag);
- }
- }
-
-//---------------------------------------------------------
-// setClick
-//---------------------------------------------------------
-
-void Song::setClick(bool val)
- {
- if (_click != val) {
- _click = val;
- emit clickChanged(_click);
- }
- }
-
-//---------------------------------------------------------
-// setQuantize
-//---------------------------------------------------------
-
-void Song::setQuantize(bool val)
- {
- if (_quantize != val) {
- _quantize = val;
- emit quantizeChanged(_quantize);
- }
- }
-
-//---------------------------------------------------------
-// setMasterFlag
-//---------------------------------------------------------
-
-void Song::setMasterFlag(bool val)
- {
- _masterFlag = val;
- if (AL::tempomap.setMasterFlag(cpos(), val)) {
- emit songChanged(SC_MASTER);
- emit tempoChanged();
- }
- }
-
-//---------------------------------------------------------
-// setPlay
-// set transport play flag
-//---------------------------------------------------------
-
-void Song::setPlay(bool f)
- {
- // only allow the user to set the button "on"
- if (!f) {
- printf(" setPlay checked\n");
- muse->playAction->setChecked(true);
- }
- else {
- if (recordAction->isChecked()) {
- startUndo();
- MidiTrackList* ml = midis();
- for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
- if ((*it)->recordFlag())
- (*it)->startRecording();
- }
- WaveTrackList* wl = waves();
- for (iWaveTrack wt = wl->begin(); wt != wl->end(); ++wt) {
- if ((*wt)->recordFlag())
- (*wt)->startRecording();
- }
- OutputList* ol = outputs();
- for (iAudioOutput o = ol->begin(); o != ol->end(); ++o) {
- if ((*o)->recordFlag())
- (*o)->startRecording();
- }
- }
- audio->msgPlay(true);
- }
- }
-
-//---------------------------------------------------------
-// setStop
-//---------------------------------------------------------
-
-void Song::setStop(bool f)
- {
- // only allow the user to set the button "on"
- if (f)
- audio->msgPlay(false);
- else
- muse->stopAction->setChecked(true);
- }
-
-//---------------------------------------------------------
-// setStopPlay
-//---------------------------------------------------------
-
-void Song::setStopPlay(bool f)
- {
- emit playChanged(f); // signal transport window
- muse->playAction->setChecked(f);
- muse->stopAction->setChecked(!f);
- }
-
-//---------------------------------------------------------
-// swapTracks
-//---------------------------------------------------------
-
-void Song::swapTracks(int i1, int i2)
- {
- undoOp(UndoOp::SwapTrack, i1, i2);
- Track* track = _tracks[i1];
- _tracks[i1] = _tracks[i2];
- _tracks[i2] = track;
- }
-
-//---------------------------------------------------------
-// setTickPos
-//---------------------------------------------------------
-/*
-void Song::setTickPos(int idx, unsigned int tick)
- {
- Pos pos(tick);
- setPos(idx, pos);
- }
-*/
-//---------------------------------------------------------
-// setPos
-// song->setPos(Song::CPOS, pos, true, true, true);
-//---------------------------------------------------------
-
-void Song::setPos(int idx, const AL::Pos& val)
- {
- setPos(idx, val, true, true, false);
- }
-
-void Song::setPos(int idx, const Pos& val, bool sig, bool isSeek, bool follow)
- {
-// printf("setPos %d sig=%d,seek=%d,scroll=%d\n",
-// idx, sig, isSeek, follow);
-// val.dump(0);
-// printf("\n");
-
- if (pos[idx] == val)
- return;
- if (idx == CPOS) {
-// _vcpos = val;
- if (isSeek) {
- seekInProgress = true;
- audio->msgSeek(val);
- return;
- }
- }
- pos[idx] = val;
- bool swap = pos[LPOS] > pos[RPOS];
- if (swap) { // swap lpos/rpos if lpos > rpos
- Pos tmp = pos[LPOS];
- pos[LPOS] = pos[RPOS];
- pos[RPOS] = tmp;
- }
- if (sig) {
- if (swap) {
- emit posChanged(LPOS, pos[LPOS], follow);
- emit posChanged(RPOS, pos[RPOS], follow);
- if (idx != LPOS && idx != RPOS)
- emit posChanged(idx, pos[idx], follow);
- }
- else
- emit posChanged(idx, pos[idx], follow);
- }
-
- if (idx == CPOS)
- updateCurrentMarker();
- }
-
-//---------------------------------------------------------
-// updateCurrentMarker
-//---------------------------------------------------------
-
-void Song::updateCurrentMarker()
- {
- AL::iMarker i1 = _markerList->begin();
- AL::iMarker i2 = i1;
- bool currentChanged = false;
- Pos& val = pos[CPOS];
- for (; i1 != _markerList->end(); ++i1) {
- ++i2;
- if (val.tick() >= i1->first && (i2==_markerList->end() || val.tick() < i2->first)) {
- if (i1->second.current())
- return;
- i1->second.setCurrent(true);
- if (currentChanged) {
- emit markerChanged(MARKER_CUR);
- return;
- }
- ++i1;
- for (; i1 != _markerList->end(); ++i1) {
- if (i1->second.current())
- i1->second.setCurrent(false);
- }
- emit markerChanged(MARKER_CUR);
- return;
- }
- else {
- if (i1->second.current()) {
- currentChanged = true;
- i1->second.setCurrent(false);
- }
- }
- }
- if (currentChanged)
- emit markerChanged(MARKER_CUR);
- }
-
-//---------------------------------------------------------
-// forward
-// roll forward config.division ticks
-//---------------------------------------------------------
-
-void Song::forward()
- {
- unsigned newPos = pos[0].tick() + config.division;
- audio->msgSeek(Pos(newPos, AL::TICKS));
- }
-
-//---------------------------------------------------------
-// rewind
-// roll back config.division ticks
-//---------------------------------------------------------
-
-void Song::rewind()
- {
- unsigned newPos;
- if (unsigned(config.division) > pos[0].tick())
- newPos = 0;
- else
- newPos = pos[0].tick() - config.division;
- audio->msgSeek(Pos(newPos, AL::TICKS));
- }
-
-//---------------------------------------------------------
-// rewindStart
-//---------------------------------------------------------
-
-void Song::rewindStart()
- {
- audio->msgSeek(Pos(0, AL::TICKS));
- }
-
-//---------------------------------------------------------
-// update
-//---------------------------------------------------------
-
-void Song::update(int flags)
- {
- if (flags == 0)
- return;
- emit songChanged(flags);
- if (flags & SC_TEMPO)
- emit tempoChanged();
- }
-
-//---------------------------------------------------------
-// updatePos
-//---------------------------------------------------------
-
-void Song::updatePos()
- {
- emit posChanged(0, pos[0], false);
- emit posChanged(1, pos[1], false);
- emit posChanged(2, pos[2], false);
- }
-
-//---------------------------------------------------------
-// roundUpBar
-//---------------------------------------------------------
-
-int Song::roundUpBar(int t) const
- {
- int bar, beat;
- unsigned tick;
- AL::sigmap.tickValues(t, &bar, &beat, &tick);
- if (beat || tick)
- return AL::sigmap.bar2tick(bar+1, 0, 0);
- return t;
- }
-
-//---------------------------------------------------------
-// roundUpBeat
-//---------------------------------------------------------
-
-int Song::roundUpBeat(int t) const
- {
- int bar, beat;
- unsigned tick;
- AL::sigmap.tickValues(t, &bar, &beat, &tick);
- if (tick)
- return AL::sigmap.bar2tick(bar, beat+1, 0);
- return t;
- }
-
-//---------------------------------------------------------
-// roundDownBar
-//---------------------------------------------------------
-
-int Song::roundDownBar(int t) const
- {
- int bar, beat;
- unsigned tick;
- AL::sigmap.tickValues(t, &bar, &beat, &tick);
- return AL::sigmap.bar2tick(bar, 0, 0);
- }
-
-//---------------------------------------------------------
-// dumpMaster
-//---------------------------------------------------------
-
-void Song::dumpMaster()
- {
- AL::tempomap.dump();
- AL::sigmap.dump();
- }
-
-//---------------------------------------------------------
-// getSelectedParts
-//---------------------------------------------------------
-
-PartList* Song::getSelectedMidiParts() const
- {
- PartList* parts = new PartList();
-
- //------------------------------------------------------
- // wenn ein Part selektiert ist, diesen editieren
- // wenn ein Track selektiert ist, den Ersten
- // Part des Tracks editieren, die restlichen sind
- // 'ghostparts'
- // wenn mehrere Parts selektiert sind, dann Ersten
- // editieren, die restlichen sind 'ghostparts'
- //
-
- // collect marked parts
- for (ciMidiTrack t = _midis.begin(); t != _midis.end(); ++t) {
- MidiTrack* track = *t;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- if (p->second->selected()) {
- parts->add(p->second);
- }
- }
- }
- // if no part is selected, then search for selected track
- // and collect all parts of this track
-
- if (parts->empty()) {
- for (ciMidiTrack t = _midis.begin(); t != _midis.end(); ++t) {
- if ((*t)->selected()) {
- MidiTrack* track = *t;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p)
- parts->add(p->second);
- break;
- }
- }
- }
- return parts;
- }
-
-PartList* Song::getSelectedWaveParts() const
- {
- PartList* parts = new PartList();
-
- //------------------------------------------------------
- // wenn ein Part selektiert ist, diesen editieren
- // wenn ein Track selektiert ist, den Ersten
- // Part des Tracks editieren, die restlichen sind
- // 'ghostparts'
- // wenn mehrere Parts selektiert sind, dann Ersten
- // editieren, die restlichen sind 'ghostparts'
- //
-
- // markierte Parts sammeln
- for (ciWaveTrack t = _waves.begin(); t != _waves.end(); ++t) {
- WaveTrack* track = *t;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- if (p->second->selected()) {
- parts->add(p->second);
- }
- }
- }
- // wenn keine Parts selektiert, dann markierten Track suchen
- // und alle Parts dieses Tracks zusammensuchen
-
- if (parts->empty()) {
- for (ciWaveTrack t = _waves.begin(); t != _waves.end(); ++t) {
- if ((*t)->selected()) {
- WaveTrack* track = *t;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p)
- parts->add(p->second);
- break;
- }
- }
- }
- return parts;
- }
-
-//---------------------------------------------------------
-// beat
-// update gui
-//---------------------------------------------------------
-
-void Song::beat()
- {
- updateFlags = 0;
- if (audio->isPlaying()) {
- int tick = audio->seqTime()->curTickPos;
- setPos(0, tick, true, false, true);
- }
- if (audio->isRecording()) {
- MidiTrackList* ml = midis();
- for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
- MidiTrack* mt = *it;
- if (mt->recordFlag())
- mt->recordBeat();
- }
- WaveTrackList* wl = waves();
- for (iWaveTrack wt = wl->begin(); wt != wl->end(); ++wt) {
- WaveTrack* mt = *wt;
- if (mt->recordFlag())
- mt->recordBeat();
- }
- }
- while (!eventFifo.isEmpty()) {
- MidiEvent event(eventFifo.get());
- if (rcEnable)
- midiRCList.doAction(event);
- emit midiEvent(event);
- }
- //
- // update controller guis
- //
- TrackList* tl = tracks();
- for (iTrack it = tl->begin(); it != tl->end(); ++it) {
- Track* track = *it;
- if (!track->autoRead())
- continue;
- track->updateController();
- }
- update(updateFlags);
- }
-
-//---------------------------------------------------------
-// setLen
-//---------------------------------------------------------
-
-void Song::setLen(int l)
- {
- _len = roundUpBar(l);
- AL::Pos pos(_len);
- int bar, beat;
- unsigned tick;
- AL::sigmap.tickValues(_len, &bar, &beat, &tick);
- emit measureLenChanged(bar);
- emit lenChanged(pos);
- }
-
-//---------------------------------------------------------
-// setMeasureLen
-//---------------------------------------------------------
-
-void Song::setMeasureLen(int b)
- {
- setLen(AL::sigmap.bar2tick(b, 0, 0));
- }
-
-//---------------------------------------------------------
-// addMarker
-//---------------------------------------------------------
-
-AL::Marker* Song::addMarker(const QString& s, const AL::Pos& pos)
- {
- AL::Marker* marker = _markerList->add(s, pos);
- updateCurrentMarker();
- emit markerChanged(MARKER_ADD);
- return marker;
- }
-
-//---------------------------------------------------------
-// removeMarker
-//---------------------------------------------------------
-
-void Song::removeMarker(AL::Marker* marker)
- {
- _markerList->remove(marker);
- updateCurrentMarker();
- emit markerChanged(MARKER_REMOVE);
- }
-
-//---------------------------------------------------------
-// setMarkerName
-//---------------------------------------------------------
-
-AL::Marker* Song::setMarkerName(AL::Marker* m, const QString& s)
- {
- m->setName(s);
- emit markerChanged(MARKER_NAME);
- return m;
- }
-
-AL::Marker* Song::setMarkerTick(AL::Marker* m, int t)
- {
- AL::Marker mm(*m);
- _markerList->remove(m);
- mm.setTick(t);
- m = _markerList->add(mm);
- updateCurrentMarker();
- emit markerChanged(MARKER_TICK);
- return m;
- }
-
-AL::Marker* Song::setMarkerLock(AL::Marker* m, bool f)
- {
- m->setType(f ? AL::FRAMES : AL::TICKS);
- updateCurrentMarker();
- emit markerChanged(MARKER_LOCK);
- return m;
- }
-
-//---------------------------------------------------------
-// endMsgCmd
-//---------------------------------------------------------
-
-void Song::endMsgCmd()
- {
- redoList->clear(); // TODO: delete elements in list
- undoAction->setEnabled(true);
- redoAction->setEnabled(false);
- update(updateFlags);
- }
-
-//---------------------------------------------------------
-// undo
-//---------------------------------------------------------
-
-void Song::undo()
- {
- updateFlags = 0;
- if (doUndo1())
- return;
- audio->msgUndo();
- doUndo3();
- redoAction->setEnabled(true);
- undoAction->setEnabled(!undoList->empty());
- if (updateFlags) {
- emit songChanged(updateFlags);
- if (updateFlags & SC_TEMPO)
- emit tempoChanged();
- }
- }
-
-//---------------------------------------------------------
-// redo
-//---------------------------------------------------------
-
-void Song::redo()
- {
- updateFlags = 0;
- if (doRedo1())
- return;
- audio->msgRedo();
- doRedo3();
- undoAction->setEnabled(true);
- redoAction->setEnabled(!redoList->empty());
- if (updateFlags) {
- emit songChanged(updateFlags);
- if (updateFlags & SC_TEMPO)
- emit tempoChanged();
- }
- }
-
-//---------------------------------------------------------
-// processMsg
-// executed in realtime thread context
-//---------------------------------------------------------
-
-void Song::processMsg(AudioMsg* msg)
- {
- switch(msg->id) {
- case SEQM_UNDO:
- doUndo2();
- break;
- case SEQM_REDO:
- doRedo2();
- break;
-
- case SEQM_ADD_EVENT:
- updateFlags = SC_EVENT_INSERTED;
- if (addEvent(msg->ev1, (Part*)(msg->p2))) {
- undoOp(UndoOp::AddEvent, msg->ev1, (Part*)msg->p2);
- }
- else
- updateFlags = 0;
- break;
-
- case SEQM_ADD_EVENTS:
- updateFlags = SC_EVENT_INSERTED;
- for (int i = 0; i < msg->el->size(); ++i) {
- if (addEvent(msg->el->at(i), (Part*)(msg->p2))) {
- undoOp(UndoOp::AddEvent, msg->el->at(i), (Part*)msg->p2);
- }
- }
- break;
-
- case SEQM_REMOVE_EVENT:
- {
- Event event = msg->ev1;
- Part* part = (Part*)(msg->p2);
- Event e;
- undoOp(UndoOp::DeleteEvent, e, event, part);
- deleteEvent(event, part);
- updateFlags = SC_EVENT_REMOVED;
- }
- break;
- case SEQM_CHANGE_EVENT:
- changeEvent(msg->ev1, msg->ev2, (Part*)(msg->p3));
- undoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3);
- updateFlags = SC_EVENT_MODIFIED;
- break;
-
- case SEQM_ADD_TEMPO:
- undoOp(UndoOp::AddTempo, msg->a, msg->b);
- AL::tempomap.addTempo(msg->a, msg->b);
- updateFlags = SC_TEMPO;
- break;
-
- case SEQM_SET_TEMPO:
- undoOp(UndoOp::AddTempo, msg->a, msg->b);
- AL::tempomap.setTempo(msg->a, msg->b);
- updateFlags = SC_TEMPO;
- break;
-
- case SEQM_SET_GLOBAL_TEMPO:
- AL::tempomap.setGlobalTempo(msg->a);
- break;
-
- case SEQM_REMOVE_TEMPO:
- undoOp(UndoOp::DeleteTempo, msg->a, msg->b);
- AL::tempomap.delTempo(msg->a);
- updateFlags = SC_TEMPO;
- break;
-
- case SEQM_ADD_SIG:
- undoOp(UndoOp::AddSig, msg->a, msg->b, msg->c);
- AL::sigmap.add(msg->a, AL::TimeSignature(msg->b, msg->c));
- updateFlags = SC_SIG;
- break;
-
- case SEQM_REMOVE_SIG:
- //printf("processMsg (SEQM_REMOVE_SIG) UndoOp::DeleteSig. Deleting AL::sigmap at: %d with z=%d n=%d\n", msg->a, msg->b, msg->c);
- undoOp(UndoOp::DeleteSig, msg->a, msg->b, msg->c);
- AL::sigmap.del(msg->a);
- updateFlags = SC_SIG;
- break;
-
- case SEQM_ADD_CTRL:
- msg->track->addControllerVal(msg->a, msg->time, msg->cval1);
- break;
-
- case SEQM_REMOVE_CTRL:
- msg->track->removeControllerVal(msg->a, msg->time);
- break;
-
- case SEQM_ADD_TRACK:
- insertTrack2(msg->track);
- break;
-
- case SEQM_REMOVE_TRACK:
- removeTrack2(msg->track);
- break;
-
- case SEQM_ADD_PART:
- {
- Part* part = (Part*)(msg->p1);
- part->track()->addPart(part);
- }
- break;
-
- case SEQM_REMOVE_PART:
- {
- Part* part = (Part*)(msg->p1);
- Track* track = part->track();
- track->parts()->remove(part);
- }
- break;
-
- case SEQM_CHANGE_PART:
- {
- Part* newPart = (Part*)msg->p2;
- Part* oldPart = (Part*)msg->p1;
- Part part = *newPart;
- *newPart = *oldPart;
- *oldPart = part;
- }
- break;
-
- case SEQM_MOVE_TRACK:
- moveTrack((Track*)(msg->p1), (Track*)(msg->p2));
- break;
-
- default:
- printf("unknown seq message %d\n", msg->id);
- break;
- }
- }
-
-//---------------------------------------------------------
-// panic
-//---------------------------------------------------------
-
-void Song::panic()
- {
- audio->msgPanic();
- }
-
-//---------------------------------------------------------
-// clear
-// signal - emit signals for changes if true
-// called from constructor as clear(false) and
-// from MusE::clearSong() as clear(false)
-//---------------------------------------------------------
-
-void Song::clear(bool signal)
- {
- _created = false;
- _backupWritten = false;
- dirty = false;
- _comment = "";
- _createDate = QDateTime::currentDateTime();
-
- seekInProgress = false;
- bounceTrack = 0;
-
-// for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i)
-// (*i)->deactivate();
-
- _selectedTrack = 0;
- _tracks.clear();
-
- qDeleteAll(_midis);
- _midis.clear();
-
- qDeleteAll(_waves);
- _waves.clear();
-
- qDeleteAll(_inputs); // audio input ports
- _inputs.clear();
-
- qDeleteAll(_outputs); // audio output ports
- _outputs.clear();
-
- qDeleteAll(_groups); // mixer groups
- _groups.clear();
-
- qDeleteAll(_synthIs);
- _synthIs.clear();
-
- qDeleteAll(_midiSyntis);
- _midiSyntis.clear();
-
- qDeleteAll(_midiOutPorts);
- _midiOutPorts.clear();
-
- qDeleteAll(_midiInPorts);
- _midiInPorts.clear();
-
- AL::tempomap.clear();
- AL::sigmap.clear();
- undoList->clear();
- redoList->clear();
- _markerList->clear();
- pos[0].setTick(0);
- pos[1].setTick(0);
- pos[2].setTick(0);
-
- _masterFlag = true;
- loopFlag = false;
- loopFlag = false;
- punchinFlag = false;
- punchoutFlag = false;
- recordFlag = false;
- soloFlag = false;
- // seq
- _recMode = REC_OVERDUP;
- _cycleMode = CYCLE_NORMAL;
- _click = false;
- _quantize = false;
- _len = 1; // song len in ticks
- // _tempo = 500000; // default tempo 120
- if (signal) {
- emit loopChanged(false);
- recordChanged(false);
- }
- }
-
-//---------------------------------------------------------
-// seqSignal
-// sequencer message to GUI
-// execution environment: gui thread
-//---------------------------------------------------------
-
-void Song::seqSignal(int fd)
- {
- char buffer[16];
-
- int n = ::read(fd, buffer, 16);
- if (n < 0) {
- printf("Song: seqSignal(): READ PIPE failed: %s\n",
- strerror(errno));
- return;
- }
- bool graphChangedCalled = false;
- bool seekDone = false;
-
-// printf("seqSignal %d\n", n);
- for (int i = 0; i < n; ++i) {
-// printf(" seqSignal to gui:<%c>\n", buffer[i]);
- switch(buffer[i]) {
- case MSG_STOP:
- stopRolling();
- break;
- case MSG_PLAY:
- setStopPlay(true);
- break;
- case MSG_RECORD:
- setRecord(true);
- break;
- case MSG_SEEK:
- if (!seekDone) {
- seekDone = true;
- setPos(0, audio->seqTime()->curTickPos, true, false, !seekInProgress);
- seekInProgress = false;
- beat(); // update controller guis
- }
- break;
- case MSG_JACK_SHUTDOWN:
- restartJack();
- break;
-
- case MSG_START_BOUNCE:
- {
- bool useFreewheel = config.useJackFreewheelMode;
- if (useFreewheel) {
- // check:
- // we cannot use freewheel, if there are active audio input
- // strips
-
- for (iAudioInput ii = _inputs.begin(); ii != _inputs.end(); ++i) {
- AudioInput* ai = *ii;
- if (!(ai->mute() || ai->off())) {
- useFreewheel = false;
- break;
- }
- }
- if (useFreewheel)
- audioDriver->setFreewheel(true);
- }
- }
- break;
-
- case MSG_STOP_BOUNCE:
- if (audio->freewheel())
- audioDriver->setFreewheel(false);
- audio->msgPlay(false);
- break;
-
- case MSG_GRAPH_CHANGED:
- if (!graphChangedCalled) {
- printf(" graph changed\n");
- graphChangedCalled = true;
- audioDriver->graphChanged();
- }
- break;
-
- default:
- printf("unknown Seq Signal <%c>\n", buffer[i]);
- break;
- }
- }
- }
-
-//---------------------------------------------------------
-// stopRolling
-//---------------------------------------------------------
-
-void Song::stopRolling()
- {
- setStopPlay(false);
- if (record()) {
- audio->msgIdle(true); // gain access to all data structures
-
- WaveTrackList* wl = waves();
- for (iWaveTrack it = wl->begin(); it != wl->end(); ++it) {
- WaveTrack* track = *it;
- if (track->recordFlag() || bounceTrack == track) {
- track->stopRecording(audio->getStartRecordPos(), audio->getEndRecordPos());
- }
- }
- MidiTrackList* ml = midis();
- for (iMidiTrack it = ml->begin(); it != ml->end(); ++it) {
- if ((*it)->recordFlag())
- (*it)->stopRecording();
- }
- OutputList* ol = outputs();
- for (iAudioOutput io = ol->begin(); io != ol->end(); ++io) {
- AudioOutput* ao = *io;
- if (ao->recordFlag())
- ao->stopRecording(audio->getStartRecordPos(), audio->getEndRecordPos());
- }
- audio->msgIdle(false);
- updateFlags |= SC_PART_MODIFIED;
- endUndo(updateFlags);
- setRecord(false);
- }
- //
- // process recorded automation events
- //
- for (iTrack it = tracks()->begin(); it != tracks()->end(); ++it) {
- Track* track = *it;
- if (!track->autoWrite())
- continue;
- CtrlRecList* crl = track->recEvents();
- CtrlList* cl = track->controller();
- for (iCtrl icl = cl->begin(); icl != cl->end(); ++icl) {
- Ctrl* cl = icl->second;
- int id = cl->id();
- //
- // remove old events from record region
- //
- bool hasEvents = false;
-// int start = audio->getStartRecordPos().frame();
-// int end = audio->getEndRecordPos().frame();
-// iCtrlVal s = cl->lower_bound(start);
-// iCtrlVal e = cl->lower_bound(end);
-// cl->erase(s, e);
-// }
-
- for (iCtrlRec icr = crl->begin(); icr != crl->end(); ++icr) {
- if (icr->id == id && icr->type == 1) {
- int start = icr->time;
- ++icr;
- for (; icr != crl->end(); ++icr) {
- if (icr->id == id && icr->type == 2) {
- int end = icr->time;
- if (track->timeType() == AL::TICKS) {
- start = AL::tempomap.frame2tick(start);
- end = AL::tempomap.frame2tick(end);
- }
- iCtrlVal s = cl->lowerBound(start);
- iCtrlVal e = cl->lowerBound(end);
- while (s != e)
- cl->erase(s++);
- hasEvents = true;
- break;
- }
- }
- if (icr == crl->end())
- break;
- }
- }
- //
- // extract all recorded events for controller "id"
- // from CtrlRecList and put into cl
- //
- for (iCtrlRec icr = crl->begin(); icr != crl->end(); ++icr) {
- if (icr->id == id && icr->type == 0)
- cl->add(icr->time, icr->val);
- }
- track->emitControllerChanged(id);
- }
- crl->clear();
- track->setAutoWrite(false);
- }
- }
-
-//---------------------------------------------------------
-// addControllerVal
-// GUI context
-//---------------------------------------------------------
-
-void Song::cmdAddControllerVal(Track* t, int id, const Pos& pos, CVal val)
- {
- Ctrl* c = t->getController(id);
- if (c == 0) {
- printf("Song::addControllerVal:: no controller %d found\n", id);
- return;
- }
- cmdAddControllerVal(t, c, pos, val);
- }
-
-void Song::cmdAddControllerVal(Track* t, Ctrl* c, const Pos& p, CVal val)
- {
- unsigned time = t->timeType() == AL::FRAMES ? p.frame() : p.tick();
- iCtrlVal e = c->find(time);
- if (e == c->end()) {
- // add new controller event
- audio->msgAddController(t, c->id(), time, val);
- }
- else {
- //
- // change controller is handled inline:
- //
- CVal oval = c->value(time);
- startUndo();
- undoOp(UndoOp::ModifyCtrl, t, c->id(), time, val, oval);
- c->add(time, val);
- endUndo(0);
- }
- if (!audio->isPlaying() && t->autoRead()) {
- // current value may have changed
- unsigned ctime = t->timeType() == AL::FRAMES ? pos[0].frame() : pos[0].tick();
- CVal cval = c->value(ctime);
- if (c->curVal().i != cval.i) {
- if (t->type() == Track::MIDI) {
- MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), cval.i);
- ((MidiTrack*)t)->playMidiEvent(&ev);
- }
- c->setCurVal(cval);
- }
- }
- t->emitControllerChanged(c->id()); //moved this out here, otherwise canvas is not updated
- }
-
-//---------------------------------------------------------
-// setControllerVal
-// GUI context
-//---------------------------------------------------------
-
-void Song::setControllerVal(Track* t, int id, CVal val)
- {
- Ctrl* c = t->getController(id);
- if (c == 0) {
- printf("Song::addControllerVal:: no controller %d found\n", id);
- return;
- }
- setControllerVal(t, c, val);
- }
-
-void Song::setControllerVal(Track* t, Ctrl* c, CVal val)
- {
- if (t->isMidiTrack()) {
- if (t->type() == Track::MIDI) {
- MidiTrack* mt = (MidiTrack*)t;
- MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), val.i);
- mt->playMidiEvent(&ev);
- }
- else if (t->type() == Track::MIDI_OUT) {
- MidiOutPort* mp = (MidiOutPort*)t;
- MidiEvent ev(0, 0, ME_CONTROLLER, c->id(), val.i);
- mp->playMidiEvent(&ev);
- }
- }
- else {
- c->setCurVal(val);
- if (c->id() & 0x3ffff000) {
- // plugin controller
- AudioTrack* track = (AudioTrack*) t;
- bool prefader;
- int pluginIndex, ctrlIndex;
- getCtrlPlugin(c->id(), &prefader, &pluginIndex, &ctrlIndex);
- Pipeline* pipe = prefader ? track->prePipe() : track->postPipe();
- pipe->plugin(pluginIndex)->setParam(ctrlIndex, val.f);
- }
- }
- c->setCurVal(val);
-
- if (t->autoWrite()) {
- unsigned time = t->timeType() == AL::FRAMES ? pos[0].frame() : pos[0].tick();
- if (audio->isPlaying())
- t->recEvents()->push_back(CtrlRecVal(time, c->id(), val));
- else {
- iCtrlVal e = c->find(time);
- if (e == c->end()) {
- // add new controller event
- audio->msgAddController(t, c->id(), time, val);
- }
- else {
- CVal oval = c->value(time);
- startUndo();
- undoOp(UndoOp::ModifyCtrl, t, c->id(), time, val, oval);
- c->add(time, val);
- endUndo(0);
- }
- }
- }
- t->emitControllerChanged(c->id());
- }
-
-//---------------------------------------------------------
-// cmdRemoveControllerVal
-//---------------------------------------------------------
-
-void Song::cmdRemoveControllerVal(Track* t, int id, unsigned time)
- {
- audio->msgRemoveController(t, id, time);
- t->emitControllerChanged(id);
- }
-
-//---------------------------------------------------------
-// absoluteProjectPath
-//---------------------------------------------------------
-
-QString Song::absoluteProjectPath() const
- {
- return QDir::homePath() + "/" + config.projectPath + "/" + _projectPath;
- }
-
-//---------------------------------------------------------
-// projectPath
-//---------------------------------------------------------
-
-QString Song::projectPath() const
- {
- return _projectPath;
- }
-
-//---------------------------------------------------------
-// projectName
-//---------------------------------------------------------
-
-QString Song::projectName() const
- {
- QString name = _projectPath.split("/").last();
- return name;
- }
-
-//---------------------------------------------------------
-// setProjectPath
-//---------------------------------------------------------
-
-void Song::setProjectPath(const QString& s)
- {
- _projectPath = s;
- }
-
-//---------------------------------------------------------
-// read
-// return false on error
-//---------------------------------------------------------
-
-bool Song::read(QFile* qf)
- {
- QDomDocument doc;
-
- int line, column;
- QString err;
- if (!doc.setContent(qf, false, &err, &line, &column)) {
- QString col, ln, error;
- col.setNum(column);
- ln.setNum(line);
- error = err + "\n at line: " + ln + " col: " + col;
- printf("error reading med file: %s\n", error.toLatin1().data());
- return false;
- }
- for (QDomNode node = doc.documentElement(); !node.isNull(); node = node.nextSibling()) {
- QDomElement e = node.toElement();
- if (e.isNull())
- continue;
- if (e.tagName() == "muse") {
- QString sversion = e.attribute("version", "1.0");
- int major=0, minor=0;
- sscanf(sversion.toLatin1().data(), "%d.%d", &major, &minor);
- int version = major << 8 + minor;
- if (version >= 0x201)
- read30(node.firstChild());
- else if (version >= 0x200)
- read20(node);
- else if (version == 0x100)
- read10(node.firstChild());
- else
- printf("unsupported *.med file version %s\n", sversion.toLatin1().data());
- }
- else
- printf("MusE: %s not supported\n", e.tagName().toLatin1().data());
- }
- dirty = false;
- return true;
- }
-
-//---------------------------------------------------------
-// read10
-//---------------------------------------------------------
-
-void Song::read10(QDomNode)
- {
- printf("reading type 1.0 *.med files not implemented\n");
- }
-
-//---------------------------------------------------------
-// read30
-//---------------------------------------------------------
-
-void Song::read30(QDomNode node)
- {
- for (; !node.isNull(); node = node.nextSibling()) {
- QDomElement e = node.toElement();
- if (e.isNull())
- continue;
- if (e.tagName() == "configuration")
- readConfiguration(node.firstChild());
- else if (e.tagName() == "song")
- read(node.firstChild());
- else if (e.tagName() == "toplevels")
- muse->readToplevels(node.firstChild());
- else
- printf("MusE:read30(): unknown tag %s\n", e.tagName().toLatin1().data());
- }
- }
-
-//---------------------------------------------------------
-// restartJack
-//---------------------------------------------------------
-
-void Song::restartJack()
- {
- muse->seqStop();
- audioState = AUDIO_STOP;
- for (;;) {
- // give the user a sensible explanation
- int btn = QMessageBox::critical( muse, tr("Jack shutdown!"),
- tr("Jack has detected a performance problem which has lead to\n"
- "MusE being disconnected.\n"
- "This could happen due to a number of reasons:\n"
- "- a performance issue with your particular setup.\n"
- "- a bug in MusE (or possibly in another connected software).\n"
- "- a random hiccup which might never occur again.\n"
- "- jack was voluntary stopped by you or someone else\n"
- "- jack crashed\n"
- "If there is a persisting problem you are much welcome to discuss it\n"
- "on the MusE mailinglist.\n"
- "(there is information about joining the mailinglist on the MusE\n"
- " homepage which is available through the help menu)\n"
- "\n"
- "To proceed check the status of Jack and try to restart it and then .\n"
- "click on the Restart button."),
- "restart", "cancel", "save project"
- );
- if (btn == 0) {
- if (!audioDriver->restart())
- break;
- }
- else if (btn == 2)
- muse->save();
- else if (btn == 1)
- exit(-1);
- }
- muse->seqRestart();
- }
-
-//---------------------------------------------------------
-// routeChanged
-//---------------------------------------------------------
-
-void Song::routeChanged(QAction* a)
- {
- audio->msgRoute(a->isChecked(), a->data().value<Route>());
- }
-