Exemplo n.º 1
0
void CueControl::trackCuesUpdated() {
    QMutexLocker lock(&m_mutex);
    QSet<int> active_hotcues;

    if (!m_pLoadedTrack)
        return;

    const QList<CuePointer> cuePoints(m_pLoadedTrack->getCuePoints());
    QListIterator<CuePointer> it(cuePoints);
    while (it.hasNext()) {
        CuePointer pCue(it.next());

        if (pCue->getType() != Cue::CUE && pCue->getType() != Cue::LOAD)
            continue;

        int hotcue = pCue->getHotCue();
        if (hotcue != -1) {
            HotcueControl* pControl = m_hotcueControl.value(hotcue, NULL);

            // Cue's hotcue doesn't have a hotcue control.
            if (pControl == NULL) {
                continue;
            }

            CuePointer pOldCue(pControl->getCue());

            // If the old hotcue is different than this one.
            if (pOldCue != pCue) {
                // If the old hotcue exists, detach it
                if (pOldCue) {
                    detachCue(hotcue);
                }
                attachCue(pCue, hotcue);
            } else {
                // If the old hotcue is the same, then we only need to update
                double dOldPosition = pControl->getPosition()->get();
                double dOldEnabled = pControl->getEnabled()->get();
                double dPosition = pCue->getPosition();
                double dEnabled = dPosition == -1 ? 0.0 : 1.0;
                if (dEnabled != dOldEnabled) {
                    pControl->getEnabled()->set(dEnabled);
                }
                if (dPosition != dOldPosition) {
                    pControl->getPosition()->set(dPosition);
                }
            }
            // Add the hotcue to the list of active hotcues
            active_hotcues.insert(hotcue);
        }
    }

    // Detach all hotcues that are no longer present
    for (int i = 0; i < m_iNumHotCues; ++i) {
        if (!active_hotcues.contains(i)) {
            detachCue(i);
        }
    }
}
Exemplo n.º 2
0
void CueControl::hotcueSet(HotcueControl* pControl, double v) {
    //qDebug() << "CueControl::hotcueSet" << v;

    if (!v)
        return;

    QMutexLocker lock(&m_mutex);
    if (!m_pLoadedTrack)
        return;

    int hotcue = pControl->getHotcueNumber();
    detachCue(hotcue);
    Cue* pCue = m_pLoadedTrack->addCue();
    double cuePosition =
            (m_pQuantizeEnabled->get() > 0.0 && m_pClosestBeat->get() != -1) ?
            floorf(m_pClosestBeat->get()) : floorf(getCurrentSample());
    if (!even(cuePosition))
        cuePosition--;
    pCue->setPosition(cuePosition);
    pCue->setHotCue(hotcue);
    pCue->setLabel("");
    pCue->setType(Cue::CUE);
    // TODO(XXX) deal with spurious signals
    attachCue(pCue, hotcue);

    // If quantize is enabled and we are not playing, jump to the cue point
    // since it's not necessarily where we currently are. TODO(XXX) is this
    // potentially invalid for vinyl control?
    bool playing = m_pPlayButton->get() > 0;
    if (!playing && m_pQuantizeEnabled->get() > 0.0) {
        lock.unlock();  // prevent deadlock.
        // Enginebuffer will quantize more exactly than we can.
        seekAbs(cuePosition);
    }
}
Exemplo n.º 3
0
void CueControl::trackUnloaded(TrackPointer pTrack) {
    QMutexLocker lock(&m_mutex);
    disconnect(pTrack.data(), 0, this, 0);
    for (int i = 0; i < m_iNumHotCues; ++i) {
        detachCue(i);
    }

    // Store the cue point in a load cue.
    double cuePoint = m_pCuePoint->get();

    if (cuePoint != -1 && cuePoint != 0.0) {
        Cue* loadCue = NULL;
        const QList<Cue*>& cuePoints = pTrack->getCuePoints();
        QListIterator<Cue*> it(cuePoints);
        while (it.hasNext()) {
            Cue* pCue = it.next();
            if (pCue->getType() == Cue::LOAD) {
                loadCue = pCue;
                break;
            }
        }
        if (!loadCue) {
            loadCue = pTrack->addCue();
            loadCue->setType(Cue::LOAD);
            loadCue->setLength(0);
        }
        loadCue->setPosition(cuePoint);
    }

    m_pCueIndicator->setBlinkValue(ControlIndicator::OFF);
    m_pCuePoint->set(-1.0);
    m_pLoadedTrack.clear();
}
Exemplo n.º 4
0
void CueControl::hotcueClear(HotcueControl* pControl, double v) {
    if (!v)
        return;

    QMutexLocker lock(&m_mutex);
    if (!m_pLoadedTrack) {
        return;
    }

    CuePointer pCue(pControl->getCue());
    detachCue(pControl->getHotcueNumber());
    m_pLoadedTrack->removeCue(pCue);
}
Exemplo n.º 5
0
void CueControl::hotcueClear(HotcueControl* pControl, double v) {
    if (!v)
        return;

    QMutexLocker lock(&m_mutex);
    if (!m_pLoadedTrack)
        return;

    Cue* pCue = pControl->getCue();
    if (pCue) {
        pCue->setHotCue(-1);
    }

    detachCue(pControl->getHotcueNumber());
}
Exemplo n.º 6
0
void CueControl::attachCue(CuePointer pCue, int hotCue) {
    HotcueControl* pControl = m_hotcueControls.value(hotCue, NULL);
    if (pControl == NULL) {
        return;
    }
    if (pControl->getCue() != NULL) {
        detachCue(pControl->getHotcueNumber());
    }
    connect(pCue.get(), SIGNAL(updated()),
            this, SLOT(cueUpdated()),
            Qt::DirectConnection);

    pControl->setCue(pCue);

}
Exemplo n.º 7
0
void CueControl::attachCue(Cue* pCue, int hotCue) {
    if (hotCue < 0 || hotCue >= m_iNumHotCues) {
        return;
    }
    HotcueControl* pControl = m_hotcueControl[hotCue];
    if (pControl->getCue() != NULL) {
        detachCue(pControl->getHotcueNumber());
    }
    pControl->setCue(pCue);
    connect(pCue, SIGNAL(updated()),
            this, SLOT(cueUpdated()),
            Qt::DirectConnection);

    pControl->getPosition()->set(pCue->getPosition());
    pControl->getEnabled()->set(pCue->getPosition() == -1 ? 0.0 : 1.0);
}
Exemplo n.º 8
0
void CueControl::hotcuePositionChanged(HotcueControl* pControl, double newPosition) {
    QMutexLocker lock(&m_mutex);
    if (!m_pLoadedTrack)
        return;

    CuePointer pCue(pControl->getCue());
    if (pCue) {
        // Setting the position to -1 is the same as calling hotcue_x_clear
        if (newPosition == -1) {
            pCue->setHotCue(-1);
            detachCue(pControl->getHotcueNumber());
        } else if (newPosition > 0 && newPosition < m_pTrackSamples->get()) {
            pCue->setPosition(newPosition);
        }
    }
}
Exemplo n.º 9
0
void CueControl::attachCue(Cue* pCue, int hotCue) {
    HotcueControl* pControl = m_hotcueControl.value(hotCue, NULL);
    if (pControl == NULL) {
        return;
    }
    if (pControl->getCue() != NULL) {
        detachCue(pControl->getHotcueNumber());
    }
    connect(pCue, SIGNAL(updated()),
            this, SLOT(cueUpdated()),
            Qt::DirectConnection);

    pControl->getPosition()->set(pCue->getPosition());
    pControl->getEnabled()->set(pCue->getPosition() == -1 ? 0.0 : 1.0);
    // set pCue only if all other data is in place
    // because we have a null check for valid data else where  in the code
    pControl->setCue(pCue);

}
Exemplo n.º 10
0
void CueControl::hotcuePositionChanged(HotcueControl* pControl, double newPosition) {
    QMutexLocker lock(&m_mutex);
    if (!m_pLoadedTrack)
        return;

    Cue* pCue = pControl->getCue();
    if (pCue) {
        // Setting the position to -1 is the same as calling hotcue_x_clear
        if (newPosition == -1) {
            pCue->setHotCue(-1);
            detachCue(pControl->getHotcueNumber());
        } else if (newPosition > 0 && newPosition < m_pTrackSamples->get()) {
            int position = newPosition;
            // People writing from MIDI land, elsewhere might be careless.
            if (position % 2 != 0) {
                position--;
            }
            pCue->setPosition(position);
        }
    }
}
Exemplo n.º 11
0
void CueControl::trackLoaded(TrackPointer pNewTrack, TrackPointer pOldTrack) {
    Q_UNUSED(pOldTrack);
    QMutexLocker lock(&m_mutex);

    if (m_pLoadedTrack) {
        disconnect(m_pLoadedTrack.data(), 0, this, 0);
        for (int i = 0; i < m_iNumHotCues; ++i) {
            detachCue(i);
        }

        // Store the cue point in a load cue.
        double cuePoint = m_pCuePoint->get();

        if (cuePoint != -1 && cuePoint != 0.0) {
            CuePointer loadCue;
            const QList<CuePointer> cuePoints(m_pLoadedTrack->getCuePoints());
            QListIterator<CuePointer> it(cuePoints);
            while (it.hasNext()) {
                CuePointer pCue(it.next());
                if (pCue->getType() == Cue::LOAD) {
                    loadCue = pCue;
                    break;
                }
            }
            if (!loadCue) {
                loadCue = m_pLoadedTrack->addCue();
                loadCue->setType(Cue::LOAD);
                loadCue->setLength(0);
            }
            loadCue->setPosition(cuePoint);
        }

        m_pCueIndicator->setBlinkValue(ControlIndicator::OFF);
        m_pCuePoint->set(-1.0);
        m_pLoadedTrack.clear();
    }


    if (pNewTrack.isNull()) {
        return;
    }

    m_pLoadedTrack = pNewTrack;
    connect(pNewTrack.data(), SIGNAL(cuesUpdated()),
            this, SLOT(trackCuesUpdated()),
            Qt::DirectConnection);

    CuePointer loadCue;
    const QList<CuePointer> cuePoints(pNewTrack->getCuePoints());
    QListIterator<CuePointer> it(cuePoints);
    while (it.hasNext()) {
        CuePointer pCue(it.next());
        if (pCue->getType() == Cue::LOAD) {
            loadCue = pCue;
        } else if (pCue->getType() != Cue::CUE) {
            continue;
        }
        int hotcue = pCue->getHotCue();
        if (hotcue != -1)
            attachCue(pCue, hotcue);
    }

    double loadCuePoint = 0.0;
    // If cue recall is ON in the prefs, then we're supposed to seek to the cue
    // point on song load. Note that [Controls],cueRecall == 0 corresponds to "ON", not OFF.
    bool cueRecall = (getConfig()->getValueString(
                ConfigKey("[Controls]","CueRecall"), "0").toInt() == 0);
    if (loadCue != NULL) {
        m_pCuePoint->set(loadCue->getPosition());
        if (cueRecall) {
            loadCuePoint = loadCue->getPosition();
        }
    } else {
        // If no cue point is stored, set one at track start
        m_pCuePoint->set(0.0);
    }

    // Need to unlock before emitting any signals to prevent deadlock.
    lock.unlock();
    // If cueRecall is on, seek to it even if we didn't find a cue value (we'll
    // seek to 0.
    if (cueRecall) {
        seekExact(loadCuePoint);
    } else if (!(m_pVinylControlEnabled->get() &&
            m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) {
        // If cuerecall is off, seek to zero unless
        // vinylcontrol is on and set to absolute.  This allows users to
        // load tracks and have the needle-drop be maintained.
        seekExact(0.0);
    }
}
Exemplo n.º 12
0
void CueControl::trackLoaded(TrackPointer pNewTrack, TrackPointer pOldTrack) {
    QMutexLocker lock(&m_mutex);

    DEBUG_ASSERT(m_pLoadedTrack == pOldTrack);
    if (m_pLoadedTrack) {
        disconnect(m_pLoadedTrack.get(), 0, this, 0);
        for (int i = 0; i < m_iNumHotCues; ++i) {
            detachCue(i);
        }

        m_pCueIndicator->setBlinkValue(ControlIndicator::OFF);
        m_pCuePoint->set(-1.0);
        m_pLoadedTrack.reset();
    }

    if (!pNewTrack) {
        return;
    }
    m_pLoadedTrack = pNewTrack;

    connect(m_pLoadedTrack.get(), SIGNAL(cuesUpdated()),
            this, SLOT(trackCuesUpdated()),
            Qt::DirectConnection);

    CuePointer pLoadCue;
    for (const CuePointer& pCue: m_pLoadedTrack->getCuePoints()) {
        if (pCue->getType() == Cue::CUE) {
            continue; // skip
        }
        if (pCue->getType() == Cue::LOAD) {
            DEBUG_ASSERT(!pLoadCue);
            pLoadCue = pCue;
        }
        int hotcue = pCue->getHotCue();
        if (hotcue != -1) {
            attachCue(pCue, hotcue);
        }
    }
    double cuePoint;
    if (pLoadCue) {
        cuePoint = pLoadCue->getPosition();
    } else {
        // If no load cue point is stored, read from track
        cuePoint = m_pLoadedTrack->getCuePoint();
    }
    m_pCuePoint->set(cuePoint);

    // Need to unlock before emitting any signals to prevent deadlock.
    lock.unlock();

    // Use pNewTrack here, because m_pLoadedTrack might have been reset
    // immediately after leaving the locking scope!
    pNewTrack->setCuePoint(cuePoint);

    // If cue recall is ON in the prefs, then we're supposed to seek to the cue
    // point on song load. Note that [Controls],cueRecall == 0 corresponds to "ON", not OFF.
    bool cueRecall = (getConfig()->getValueString(
                ConfigKey("[Controls]","CueRecall"), "0").toInt() == 0);
    if (cueRecall && (cuePoint >= 0.0)) {
        seekExact(cuePoint);
    } else if (!(m_pVinylControlEnabled->get() &&
            m_pVinylControlMode->get() == MIXXX_VCMODE_ABSOLUTE)) {
        // If cuerecall is off, seek to zero unless
        // vinylcontrol is on and set to absolute.  This allows users to
        // load tracks and have the needle-drop be maintained.
        seekExact(0.0);
    }

    trackCuesUpdated();
}