void LoopingControl::slotLoopStartPos(double pos) { if (!m_pTrack) { return; } int newpos = pos; if (newpos != -1 && !even(newpos)) { newpos--; } if (m_iLoopStartSample == newpos) { //nothing to do return; } clearActiveBeatLoop(); if (pos == -1.0) { setLoopingEnabled(false); } m_iLoopStartSample = newpos; m_pCOLoopStartPosition->set(newpos); if (m_iLoopEndSample != -1 && m_iLoopEndSample < m_iLoopStartSample) { m_iLoopEndSample = -1; m_pCOLoopEndPosition->set(kNoTrigger); setLoopingEnabled(false); } }
void LoopingControl::notifySeek(double dNewPlaypos) { if (m_bLoopingEnabled) { if (dNewPlaypos < m_iLoopStartSample || dNewPlaypos > m_iLoopEndSample) { setLoopingEnabled(false); } } }
void LoopingControl::slotLoopEndPos(double pos) { if (!m_pTrack) { return; } int newpos = pos; if (newpos != -1 && !even(newpos)) { newpos--; } if (m_iLoopEndSample == newpos) { //nothing to do return; } // Reject if the loop-in is not set, or if the new position is before the // start point (but not -1). if (m_iLoopStartSample == -1 || (newpos != -1 && newpos < m_iLoopStartSample)) { m_pCOLoopEndPosition->set(m_iLoopEndSample); return; } clearActiveBeatLoop(); if (pos == -1.0) { setLoopingEnabled(false); } m_iLoopEndSample = newpos; m_pCOLoopEndPosition->set(newpos); }
void LoopingControl::slotReloopExit(double val) { if (!m_pTrack) { return; } if (val) { // If we're looping, stop looping if (m_bLoopingEnabled) { setLoopingEnabled(false); //qDebug() << "reloop_exit looping off"; } else { // If we're not looping, jump to the loop-in point and start looping if (m_iLoopStartSample != -1 && m_iLoopEndSample != -1 && m_iLoopStartSample <= m_iLoopEndSample) { setLoopingEnabled(true); } //qDebug() << "reloop_exit looping on"; } } }
void LoopingControl::slotLoopExit(double val) { if (!m_pTrack) { return; } if (val) { // If we're looping, stop looping if (m_bLoopingEnabled) { setLoopingEnabled(false); } } }
void LoopingControl::slotReloopExit(double val) { if (!m_pTrack) { return; } if (val) { // If we're looping, stop looping if (m_bLoopingEnabled) { // If loop roll was active, also disable slip. if (m_bLoopRollActive) { m_pSlipEnabled->set(0); m_bLoopRollActive = false; } setLoopingEnabled(false); //qDebug() << "reloop_exit looping off"; } else { // If we're not looping, jump to the loop-in point and start looping if (m_iLoopStartSample != -1 && m_iLoopEndSample != -1 && m_iLoopStartSample <= m_iLoopEndSample) { setLoopingEnabled(true); } //qDebug() << "reloop_exit looping on"; } } }
void LoopingControl::slotLoopOut(double val) { if (!m_pTrack) { return; } if (val) { int pos = (m_pQuantizeEnabled->get() > 0.0 && m_pClosestBeat->get() != -1) ? static_cast<int>(floorf(m_pClosestBeat->get())) : m_iCurrentSample; // If the user is trying to set a loop-out before the loop in or without // having a loop-in, then ignore it. if (m_iLoopStartSample == -1 || pos < m_iLoopStartSample) { return; } // If the loop-in and out points are set so close that the loop would be // inaudible (which can happen easily with quantize-to-beat enabled,) // use the smallest pre-defined beatloop instead (when possible) if (pos - m_iLoopStartSample < MINIMUM_AUDIBLE_LOOP_SIZE) { pos = m_iLoopStartSample; if (m_pQuantizeEnabled->get() > 0.0 && m_pBeats) { // 1 would have just returned loop_in, so give 2 to get the beat // following loop_in int nextbeat = m_pBeats->findNthBeat(m_iLoopStartSample, 2); pos += (nextbeat - pos) * s_dBeatSizes[0]; } else { pos += MINIMUM_AUDIBLE_LOOP_SIZE; } } if (pos != -1 && !even(pos)) { pos++; // Increment to avoid shortening too-short loops } clearActiveBeatLoop(); //set loop out position m_iLoopEndSample = pos; m_pCOLoopEndPosition->set(m_iLoopEndSample); // start looping if (m_iLoopStartSample != -1 && m_iLoopEndSample != -1) { setLoopingEnabled(true); } // qDebug() << "set loop_out to " << m_iLoopEndSample; } }
void LoopingControl::slotBeatLoop(double beats, bool keepStartPoint) { int samples = m_pTrackSamples->get(); if (!m_pTrack || samples == 0) { clearActiveBeatLoop(); return; } if (!m_pBeats) { clearActiveBeatLoop(); return; } // For now we do not handle negative beatloops. if (beats < 0) { clearActiveBeatLoop(); return; } // O(n) search, but there are only ~10-ish beatloop controls so this is // fine. foreach (BeatLoopingControl* pBeatLoopControl, m_beatLoops) { if (pBeatLoopControl->getSize() == beats) { if (m_pActiveBeatLoop != pBeatLoopControl) { if (m_pActiveBeatLoop) { m_pActiveBeatLoop->deactivate(); } m_pActiveBeatLoop = pBeatLoopControl; } pBeatLoopControl->activate(); break; } } // give loop_in and loop_out defaults so we can detect problems int loop_in = -1; int loop_out = -1; // For positive numbers we start from the current position/closest beat and // create the loop around X beats from there. if (beats > 0) { if (keepStartPoint) { loop_in = m_iLoopStartSample; } else { // loop_in is set to the previous beat if quantize is on. The // closest beat might be ahead of play position which would cause a seek. // TODO: If in reverse, should probably choose nextBeat. double cur_pos = getCurrentSample(); double prevBeat = floorf(m_pBeats->findPrevBeat(cur_pos)); if (m_pQuantizeEnabled->get() > 0.0 && prevBeat != -1) { if (beats >= 1.0) { loop_in = prevBeat; } else { // In case of beat length less then 1 beat: // (| - beats, ^ - current track's position): // // ...|...................^........|... // // If we press 1/2 beatloop we want loop from 50% to 100%, // If I press 1/4 beatloop, we want loop from 50% to 75% etc double nextBeat = floorf(m_pBeats->findNextBeat(cur_pos)); double beat_len = nextBeat - prevBeat; double loops_per_beat = 1.0 / beats; double beat_pos = cur_pos - prevBeat; int beat_frac = static_cast<int>(floor((beat_pos / beat_len) * loops_per_beat)); loop_in = prevBeat + beat_len / loops_per_beat * beat_frac; } } else { loop_in = floorf(cur_pos); } if (!even(loop_in)) { loop_in--; } } int fullbeats = static_cast<int>(floorf(beats)); double fracbeats = beats - static_cast<double>(fullbeats); // Now we need to calculate the length of the beatloop. We do this by // taking the current beat and the fullbeats'th beat and measuring the // distance between them. loop_out = loop_in; if (fullbeats > 0) { // Add the length between this beat and the fullbeats'th beat to the // loop_out position; double this_beat = m_pBeats->findNthBeat(loop_in, 1); double nth_beat = m_pBeats->findNthBeat(loop_in, 1 + fullbeats); loop_out += (nth_beat - this_beat); } if (fracbeats > 0) { // Add the fraction of the beat following the current loop_out // position to loop out. double loop_out_beat = m_pBeats->findNthBeat(loop_out, 1); double loop_out_next_beat = m_pBeats->findNthBeat(loop_out, 2); loop_out += (loop_out_next_beat - loop_out_beat) * fracbeats; } } if ((loop_in == -1) || ( loop_out == -1)) return; if (!even(loop_in)) loop_in--; if (!even(loop_out)) loop_out--; if (loop_in == loop_out) { if ((loop_out+2) > samples) { loop_in -= 2; } else { loop_out += 2; } } else if (loop_out > samples) { // Do not allow beat loops to go beyond the end of the track loop_out = samples; } m_iLoopStartSample = loop_in; m_pCOLoopStartPosition->set(loop_in); m_iLoopEndSample = loop_out; m_pCOLoopEndPosition->set(loop_out); setLoopingEnabled(true); }
void LoopingControl::slotBeatLoopDeactivateRoll(BeatLoopingControl* pBeatLoopControl) { Q_UNUSED(pBeatLoopControl); setLoopingEnabled(false); m_pSlipEnabled->set(0); m_bLoopRollActive = false; }
void LoopingControl::slotBeatLoopDeactivate(BeatLoopingControl* pBeatLoopControl) { Q_UNUSED(pBeatLoopControl); setLoopingEnabled(false); }