📄 sequencemanager.cpp
字号:
if (result) { // completed successfully m_transportStatus = STARTING_TO_PLAY; } else { m_transportStatus = STOPPED; std::cerr << "ERROR: SequenceManager::play(): Failed to start playback!" << std::endl; } return false;}voidSequenceManager::stopping(){ if (m_countdownTimer) m_countdownTimer->stop(); if (m_countdownDialog) m_countdownDialog->hide(); // Do this here rather than in stop() to avoid any potential // race condition (we use setPointerPosition() during stop()). // if (m_transportStatus == STOPPED) { /*!!! if (m_doc->getComposition().isLooping()) m_doc->slotSetPointerPosition(m_doc->getComposition().getLoopStart()); else m_doc->slotSetPointerPosition(m_doc->getComposition().getStartMarker()); */ m_doc->slotSetPointerPosition(m_lastTransportStartPosition); return ; } // Disarm recording and drop back to STOPPED // if (m_transportStatus == RECORDING_ARMED) { m_transportStatus = STOPPED; m_transport->RecordButton()->setOn(false); m_transport->MetronomeButton()-> setOn(m_doc->getComposition().usePlayMetronome()); return ; } SEQMAN_DEBUG << "SequenceManager::stopping() - preparing to stop\n"; // SEQMAN_DEBUG << kdBacktrace() << endl; stop(); m_shownOverrunWarning = false;}voidSequenceManager::stop(){ // Toggle off the buttons - first record // if (m_transportStatus == RECORDING) { m_transport->RecordButton()->setOn(false); m_transport->MetronomeButton()-> setOn(m_doc->getComposition().usePlayMetronome()); // Remove the countdown dialog and stop the timer // m_countdownDialog->hide(); m_countdownTimer->stop(); } // Now playback m_transport->PlayButton()->setOn(false); // re-enable the record button if it was previously disabled when // going into play mode - DMM // SEQMAN_DEBUG << "SequenceManager::stop() - re-enabling record button\n"; // m_transport->RecordButton()->setEnabled(true); // "call" the sequencer with a stop so we get a synchronous // response - then we can fiddle about with the audio file // without worrying about the sequencer causing problems // with access to the same audio files. // // wait cursor // QApplication::setOverrideCursor(QCursor(Qt::waitCursor)); QCString replyType; QByteArray replyData; bool failed = false; if (!rgapp->sequencerCall("stop()", replyType, replyData)) { failed = true; } // restore QApplication::restoreOverrideCursor(); TransportStatus status = m_transportStatus; // set new transport status first, so that if we're stopping // recording we don't risk the record segment being restored by a // timer while the document is busy trying to do away with it m_transportStatus = STOPPED; // if we're recording MIDI or Audio then tidy up the recording Segment if (status == RECORDING) { m_doc->stopRecordingMidi(); m_doc->stopRecordingAudio(); SEQMAN_DEBUG << "SequenceManager::stop() - stopped recording\n"; } // always untoggle the play button at this stage // m_transport->PlayButton()->setOn(false); SEQMAN_DEBUG << "SequenceManager::stop() - stopped playing\n"; // We don't reset controllers at this point - what happens with static // controllers the next time we play otherwise? [rwb] //resetControllers(); if (failed) { throw(Exception("Failed to contact Rosegarden sequencer with stop command. Please save your composition and restart Rosegarden to continue.")); }}voidSequenceManager::rewind(){ Composition &composition = m_doc->getComposition(); timeT position = composition.getPosition(); std::pair<timeT, timeT> barRange = composition.getBarRangeForTime(position - 1); if (m_transportStatus == PLAYING) { // if we're playing and we had a rewind request less than 200ms // ago and we're some way into the bar but less than half way // through it, rewind two barlines instead of one clock_t now = clock(); int elapsed = (now - m_lastRewoundAt) * 1000 / CLOCKS_PER_SEC; SEQMAN_DEBUG << "That was " << m_lastRewoundAt << ", this is " << now << ", elapsed is " << elapsed << endl; if (elapsed >= 0 && elapsed <= 200) { if (position > barRange.first && position < barRange.second && position <= (barRange.first + (barRange.second - barRange.first) / 2)) { barRange = composition.getBarRangeForTime(barRange.first - 1); } } m_lastRewoundAt = now; } if (barRange.first < composition.getStartMarker()) { m_doc->slotSetPointerPosition(composition.getStartMarker()); } else { m_doc->slotSetPointerPosition(barRange.first); }}voidSequenceManager::fastforward(){ Composition &composition = m_doc->getComposition(); timeT position = composition.getPosition() + 1; timeT newPosition = composition.getBarRangeForTime(position).second; // Don't skip past end marker // if (newPosition > composition.getEndMarker()) newPosition = composition.getEndMarker(); m_doc->slotSetPointerPosition(newPosition);}voidSequenceManager::notifySequencerStatus(TransportStatus status){ // for the moment we don't do anything fancy m_transportStatus = status;}voidSequenceManager::sendSequencerJump(const RealTime &time){ QByteArray data; QDataStream streamOut(data, IO_WriteOnly); streamOut << (long)time.sec; streamOut << (long)time.nsec; rgapp->sequencerSend("jumpTo(long int, long int)", data);}voidSequenceManager::record(bool toggled){ mapSequencer(); SEQMAN_DEBUG << "SequenceManager::record(" << toggled << ")" << endl; Composition &comp = m_doc->getComposition(); Studio &studio = m_doc->getStudio(); KConfig* config = kapp->config(); config->setGroup(GeneralOptionsConfigGroup); bool punchIn = false; // are we punching in? // If we have any audio tracks armed, then we need to check for // a valid audio record path and a working audio subsystem before // we go any further const Composition::recordtrackcontainer &recordTracks = comp.getRecordTracks(); for (Composition::recordtrackcontainer::const_iterator i = recordTracks.begin(); i != recordTracks.end(); ++i) { Track *track = comp.getTrackById(*i); InstrumentId instrId = track->getInstrument(); Instrument *instr = studio.getInstrumentById(instrId); if (instr && instr->getType() == Instrument::Audio) { if (!m_doc || !(m_soundDriverStatus & AUDIO_OK)) { m_transport->RecordButton()->setOn(false); throw(Exception("Audio subsystem is not available - can't record audio")); } // throws BadAudioPathException if path is not valid: m_doc->getAudioFileManager().testAudioPath(); break; } } if (toggled) { // preparing record or punch-in record if (m_transportStatus == RECORDING_ARMED) { SEQMAN_DEBUG << "SequenceManager::record - unarming record\n"; m_transportStatus = STOPPED; // Toggle the buttons m_transport->MetronomeButton()->setOn(comp.usePlayMetronome()); m_transport->RecordButton()->setOn(false); return ; } if (m_transportStatus == STOPPED) { SEQMAN_DEBUG << "SequenceManager::record - armed record\n"; m_transportStatus = RECORDING_ARMED; // Toggle the buttons m_transport->MetronomeButton()->setOn(comp.useRecordMetronome()); m_transport->RecordButton()->setOn(true); return ; } if (m_transportStatus == RECORDING) { SEQMAN_DEBUG << "SequenceManager::record - stop recording and keep playing\n"; QByteArray data; QCString replyType; QByteArray replyData; // Send Record to the Sequencer to signal it to drop out of record mode if (!rgapp->sequencerCall("punchOut()", replyType, replyData, data)) { SEQMAN_DEBUG << "SequenceManager::record - the \"not very plausible\" code executed\n"; // #1797873 - set new transport status first, so that // if we're stopping recording we don't risk the // record segment being restored by a timer while the // document is busy trying to do away with it m_transportStatus = STOPPED; m_doc->stopRecordingMidi(); m_doc->stopRecordingAudio(); return ; } // #1797873 - as above m_transportStatus = PLAYING; m_doc->stopRecordingMidi(); m_doc->stopRecordingAudio(); return ; } if (m_transportStatus == PLAYING) { SEQMAN_DEBUG << "SequenceManager::record - punch in recording\n"; punchIn = true; goto punchin; } } else { m_lastTransportStartPosition = comp.getPosition();punchin: // Get the record tracks and check we have a record instrument bool haveInstrument = false; bool haveAudioInstrument = false; bool haveMIDIInstrument = false; //TrackId recordMIDITrack = 0; for (Composition::recordtrackcontainer::const_iterator i = comp.getRecordTracks().begin(); i != comp.getRecordTracks().end(); ++i) { InstrumentId iid = comp.getTrackById(*i)->getInstrument(); Instrument *inst = studio.getInstrumentById(iid); if (inst) { haveInstrument = true; if (inst->getType() == Instrument::Audio) { haveAudioInstrument = true; break; } else { // soft synths count as MIDI for our purposes here haveMIDIInstrument = true; //recordMIDITrack = *i; } } } if (!haveInstrument) { m_transport->RecordButton()->setDown(false); throw(Exception("No Record instrument selected")); } // may throw an exception checkSoundDriverStatus(false); // toggle the Metronome button if it's in use m_transport->MetronomeButton()->setOn(comp.useRecordMetronome()); // Update record metronome status // m_controlBlockMmapper->updateMetronomeData (m_metronomeMmapper->getMetronomeInstrument()); m_controlBlockMmapper->updateMetronomeForRecord(); // If we are looping then jump to start of loop and start recording, // if we're not take off the number of count-in bars and start // recording. // if (comp.isLooping()) m_doc->slotSetPointerPosition(comp.getLoopStart()); else { if (m_transportStatus != RECORDING_ARMED && punchIn == false) { int startBar = comp.getBarNumber(comp.getPosition()); startBar -= config->readUnsignedNumEntry("countinbars", 0); m_doc->slotSetPointerPosition(comp.getBarRange(startBar).first); } } m_doc->setRecordStartTime(m_doc->getComposition().getPosition()); if (haveAudioInstrument) { // Ask the document to update its record latencies so as to // do latency compensation when we stop m_doc->updateAudioRecordLatency(); } if (haveMIDIInstrument) { // Create the record MIDI segment now, so that the // composition view has a real segment to display. It
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -