diff options
Diffstat (limited to 'muse_qt4_evolution/muse/song.cpp')
-rw-r--r-- | muse_qt4_evolution/muse/song.cpp | 1552 |
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>()); - } - |