Exemplo n.º 1
0
void SyncControl::notifySyncModeChanged(SyncMode mode) {
    //qDebug() << "SyncControl::notifySyncModeChanged" << getGroup() << mode;
    // SyncControl has absolutely no say in the matter. This is what EngineSync
    // requires. Bypass confirmation by using setAndConfirm.
    m_masterBpmAdjustFactor = kBpmUnity;
    m_pSyncMode->setAndConfirm(mode);
    m_pSyncEnabled->setAndConfirm(mode != SYNC_NONE);
    m_pSyncMasterEnabled->setAndConfirm(mode == SYNC_MASTER);
    if (mode == SYNC_FOLLOWER) {
        if (m_pVCEnabled && m_pVCEnabled->get()) {
            // If follower mode is enabled, disable vinyl control.
            m_pVCEnabled->set(0.0);
        }
    }
    if (mode != SYNC_NONE && m_pPassthroughEnabled->get()) {
        // If any sync mode is enabled and passthrough was on somehow, disable passthrough.
        // This is very unlikely to happen so this deserves a warning.
        qWarning() << "Notified of sync mode change when passthrough was active -- "
                      "must disable passthrough";
        m_pPassthroughEnabled->set(0.0);
    }
    if (mode == SYNC_MASTER) {
        // Make sure all the followers update based on our current rate.
        slotRateChanged();
        double rateRatio = calcRateRatio();
        m_pEngineSync->notifyBeatDistanceChanged(this, getBeatDistance());
        m_pBpm->set(m_pLocalBpm->get() * rateRatio);
    }
}
Exemplo n.º 2
0
void BpmControl::collectFeatures(GroupFeatureState* pGroupFeatures) const {
    // Without a beatgrid we don't know any beat details.
    SampleOfTrack sot = getSampleOfTrack();
    if (!sot.rate || !m_pBeats) {
        return;
    }

    // Get the current position of this deck.
    double dThisPrevBeat = m_pPrevBeat->get();
    double dThisNextBeat = m_pNextBeat->get();
    double dThisBeatLength;
    double dThisBeatFraction;
    if (getBeatContextNoLookup(sot.current,
                       dThisPrevBeat, dThisNextBeat,
                       &dThisBeatLength, &dThisBeatFraction)) {
        pGroupFeatures->has_beat_length_sec = true;

        // Note: dThisBeatLength is fractional frames count * 2 (stereo samples)
        pGroupFeatures->beat_length_sec = dThisBeatLength / kSamplesPerFrame
                / sot.rate / calcRateRatio();

        pGroupFeatures->has_beat_fraction = true;
        pGroupFeatures->beat_fraction = dThisBeatFraction;
    }
}
Exemplo n.º 3
0
void SyncControl::setLocalBpm(double local_bpm) {
    if (local_bpm == m_prevLocalBpm.getValue()) {
        return;
    }
    m_prevLocalBpm.setValue(local_bpm);

    SyncMode syncMode = getSyncMode();
    if (syncMode <= SYNC_NONE) {
        return;
    }

    // FIXME: This recalculating of the rate is duplicated in bpmcontrol.
    const double rateRatio = calcRateRatio();
    double bpm = local_bpm * rateRatio;
    m_pBpm->set(bpm);

    if (syncMode == SYNC_FOLLOWER) {
        // In this case we need an update from the current master to adjust
        // the rate that we continue with the master BPM. If there is no
        // master bpm, our bpm value is adopted.
        m_pEngineSync->requestBpmUpdate(this, bpm);
    } else {
        DEBUG_ASSERT(syncMode == SYNC_MASTER);
        m_pEngineSync->notifyBpmChanged(this, bpm);
    }
}
Exemplo n.º 4
0
void SyncControl::slotRateChanged() {
    // This slot is fired by rate, rate_dir, and rateRange changes.
    const double rateRatio = calcRateRatio();
    double bpm = m_pLocalBpm ? m_pLocalBpm->get() * rateRatio : 0.0;
    //qDebug() << getGroup() << "SyncControl::slotRateChanged" << rate << bpm;
    if (bpm > 0) {
        // When reporting our bpm, remove the multiplier so the masters all
        // think the followers have the same bpm.
        m_pEngineSync->notifyBpmChanged(this, bpm / m_masterBpmAdjustFactor, false);
    }
}
Exemplo n.º 5
0
void RateControl::setRateTemp(double v)
{
    // Do not go backwards
    if ((calcRateRatio() + v) < 0) {
        return;
    }

    m_dRateTemp = v;
    if (m_dRateTemp < -1.0) {
        m_dRateTemp = -1.0;
    } else if (m_dRateTemp > 1.0) {
        m_dRateTemp = 1.0;
    } else if (isnan(m_dRateTemp)) {
        m_dRateTemp = 0;
    }
}
Exemplo n.º 6
0
void SyncControl::slotFileBpmChanged() {
    // This slot is fired by a new file is loaded or if the user
    // has adjusted the beatgrid.
    //qDebug() << "SyncControl::slotFileBpmChanged";

    // Note: bpmcontrol has updated local_bpm just before
    double local_bpm = m_pLocalBpm ? m_pLocalBpm->get() : 0.0;

    if (!isSynchronized()) {
        const double rateRatio = calcRateRatio();
        double bpm = local_bpm * rateRatio;
        m_pBpm->set(bpm);
    } else {
        setLocalBpm(local_bpm);
    }
}
Exemplo n.º 7
0
void BpmControl::slotTapFilter(double averageLength, int numSamples) {
    // averageLength is the average interval in milliseconds tapped over
    // numSamples samples.  Have to convert to BPM now:

    if (averageLength <= 0)
        return;

    if (numSamples < 4)
        return;

    // (60 seconds per minute) * (1000 milliseconds per second) / (X millis per
    // beat) = Y beats/minute
    double averageBpm = 60.0 * 1000.0 / averageLength;
    double dRate = calcRateRatio();
    m_pFileBpm->set(averageBpm / dRate);
    slotUpdateEngineBpm();
}
Exemplo n.º 8
0
void BpmControl::slotTapFilter(double averageLength, int numSamples) {
    // averageLength is the average interval in milliseconds tapped over
    // numSamples samples.  Have to convert to BPM now:

    if (averageLength <= 0)
        return;

    if (numSamples < 4)
        return;

    BeatsPointer pBeats = m_pBeats;
    if (!pBeats)
        return;

    // (60 seconds per minute) * (1000 milliseconds per second) / (X millis per
    // beat) = Y beats/minute
    double averageBpm = 60.0 * 1000.0 / averageLength / calcRateRatio();
    pBeats->setBpm(averageBpm);
}
Exemplo n.º 9
0
void SyncControl::setLocalBpm(double local_bpm) {
    if (getSyncMode() == SYNC_NONE) {
        return;
    }
    if (local_bpm == m_prevLocalBpm) {
        return;
    }
    if (local_bpm == 0 && m_pPlayButton->toBool()) {
        // If the local bpm is suddenly zero and sync was active and we are playing,
        // stick with the previous localbpm.
        // I think this can only happen if the beatgrid is reset.
        qWarning() << getGroup() << "Sync is already enabled on track with empty or zero bpm";
        return;
    }
    m_prevLocalBpm = local_bpm;

    // FIXME: This recalculating of the rate is duplicated in bpmcontrol.
    const double rateRatio = calcRateRatio();
    double bpm = local_bpm * rateRatio;
    m_pBpm->set(bpm);
    m_pEngineSync->notifyBpmChanged(this, bpm, true);
}
Exemplo n.º 10
0
void SyncControl::trackLoaded(TrackPointer pNewTrack) {
    //qDebug() << getGroup() << "SyncControl::trackLoaded";
    if (getSyncMode() == SYNC_MASTER) {
        // If we change or remove a new track while master, hand off.
        m_pChannel->getEngineBuffer()->requestSyncMode(SYNC_NONE);
    }
    if (pNewTrack) {
        m_masterBpmAdjustFactor = kBpmUnity;
        if (getSyncMode() != SYNC_NONE) {
            // Because of the order signals get processed, the file/local_bpm COs and
            // rate slider are not updated as soon as we need them, so do that now.
            m_pFileBpm->set(pNewTrack->getBpm());
            m_pLocalBpm->set(pNewTrack->getBpm());
            double dRate = calcRateRatio();
            // We used to set the m_pBpm here, but that causes a signal loop whereby
            // that was interpretted as a rate slider tweak, and the master bpm
            // was changed.  Instead, now we pass the suggested bpm to enginesync
            // explicitly, and it can decide what to do with it.
            m_pEngineSync->notifyTrackLoaded(this, m_pLocalBpm->get() * dRate);
        }
    }
}
Exemplo n.º 11
0
void BpmControl::slotUpdateEngineBpm() {
    // Adjust playback bpm in response to a change in the rate slider.
    double dRate = calcRateRatio();
    m_pEngineBpm->set(m_pLocalBpm->get() * dRate);
}