//============================================================================== void StepSequencer::runSeq(MidiBuffer & midiMessages, int bufferSize, double sampleRate) { // get GUI params seqStepSpeed = 4.0f / params.seqStepSpeed.get(); // internally working with 1/4 = 1.0f seqStepLength = jmin(4.0f / params.seqStepLength.get(), seqStepSpeed); seqNumSteps = static_cast<int>(params.seqNumSteps.get()); if (params.seqDottedLength.getStep() == eOnOffToggle::eOn) { seqStepSpeed *= 1.5f; seqStepLength *= 1.5f; } if (params.seqTriplets.getStep() == eOnOffToggle::eOn) { seqStepSpeed *= 2.0f / 3.0f; seqStepLength *= 2.0f / 3.0f; } if (params.seqPlaySyncHost.getStep() == eOnOffToggle::eOn) { seqHostSync(midiMessages); } else if (params.seqPlayNoHost.getStep() == eOnOffToggle::eOn) { seqNoHostSync(midiMessages, bufferSize, sampleRate); } else { stopSeq(midiMessages); } }
/** * Called while stepSequencer is synced with host. */ void StepSequencer::seqHostSync(MidiBuffer& midiMessages) { AudioPlayHead::CurrentPositionInfo hostPlayHead = params.positionInfo[params.getAudioIndex()]; double currPos = hostPlayHead.ppqPosition; // if host ist playing // NOTE: in Cubase 5 hostPlayHead.isPlaying even before actual playhead starts playing, // at the beginning currPos can be negative if (hostPlayHead.isPlaying && (currPos >= 0.0)) { // if currPos passes stopNoteTime if (currPos >= stopNoteTime) { if (seqNoteIsPlaying) { sendMidiNoteOffMessage(midiMessages, 0); } } // if currPos passes seqNextStep or (currPos < lastPlayHeadPosition) implies loop or rewind if ((currPos >= seqNextStep) || (currPos < lastPlayHeadPosition)) { // stop note if could not stopped before playing seqNote (important for seqNoteLength == seqStepSpeed) if (seqNoteIsPlaying) { sendMidiNoteOffMessage(midiMessages, 0); } // calculate note to play currSeqNote = jmax(0, static_cast<int>(currPos / static_cast<double>(seqStepSpeed)) % seqNumSteps); currSeqNote = jmin(currSeqNote, 7); // if play upDown -> for all odd periods, play in reverse order (down sequence) if (params.seqPlayMode.getStep() == eSeqPlayModes::eUpDown) { int upDownSeq = jmax(0, static_cast<int>(currPos / static_cast<double>(seqNumSteps) / static_cast<double>(seqStepSpeed)) % 2); if (upDownSeq == 1) { currSeqNote = seqNumSteps - 1 - currSeqNote; } } // if is not playing a note then prepare sending midi noteOn message if (!seqNoteIsPlaying) { // set note to play as random if (params.seqPlayMode.getStep() == eSeqPlayModes::eRandom) { setStepRandom(currSeqNote); } // if any note changed or is muted then send noteOff message to that note midiNoteChanged(midiMessages); // send midimessage into midibuffer sendMidiNoteOnMessage(midiMessages, 0); // calculate next stopNoteTime stopNoteTime = currPos + seqStepLength; } } // calculate next seqNextStep and save lastPlayHeadPosition double offset = static_cast<double>(seqStepSpeed) - fmod(jmax(0.0, currPos), static_cast<double>(seqStepSpeed)); seqNextStep = jmax(0.0, currPos) + offset; lastPlayHeadPosition = currPos; seqStopped = false; } else { // if host is not playing then stop sequencer and reset variables stopSeq(midiMessages); } }
void startStopSeq(bool gui) { clock::isRunning() ? stopSeq(gui) : startSeq(gui); }