//==============================================================================
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);
    }
}
Exemple #3
0
void startStopSeq(bool gui)
{
	clock::isRunning() ? stopSeq(gui) : startSeq(gui);
}