예제 #1
0
void WaveformRenderMark::slotCuesUpdated() {
    TrackPointer trackInfo = m_waveformRenderer->getTrackInfo();
    if (!trackInfo){
        return;
    }

    QList<CuePointer> loadedCues = trackInfo->getCuePoints();
    for (const CuePointer pCue: loadedCues) {
        int hotCue = pCue->getHotCue();
        if (hotCue < 0) {
            continue;
        }

        // Here we assume no two cues can have the same hotcue assigned,
        // because WaveformMarkSet stores one mark for each hotcue.
        WaveformMarkPointer pMark = m_marks.getHotCueMark(hotCue);
        if (pMark.isNull()) {
        	continue;
        }

        WaveformMarkProperties markProperties = pMark->getProperties();
        QString newLabel = pCue->getLabel();
        QColor newColor = m_predefinedColorsRepresentation.representationFor(pCue->getColor());
        if (markProperties.m_text.isNull() || newLabel != markProperties.m_text ||
                !markProperties.fillColor().isValid() || newColor != markProperties.fillColor()) {
            markProperties.m_text = newLabel;
            markProperties.setBaseColor(newColor);
            pMark->setProperties(markProperties);
            generateMarkImage(pMark.data());
        }
    }
}
예제 #2
0
파일: cuecontrol.cpp 프로젝트: Gussss/mixxx
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();
}
예제 #3
0
void CueControl::trackLoaded(TrackPointer pTrack) {
    QMutexLocker lock(&m_mutex);
    if (m_pLoadedTrack)
        trackUnloaded(m_pLoadedTrack);

    if (!pTrack) {
        return;
    }

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

    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;
        } 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);
    }
}
예제 #4
0
파일: cuecontrol.cpp 프로젝트: Gussss/mixxx
void CueControl::trackLoaded(TrackPointer pTrack) {
    QMutexLocker lock(&m_mutex);
    if (m_pLoadedTrack)
        trackUnloaded(m_pLoadedTrack);

    if (!pTrack) {
        return;
    }

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

    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;
        } else if (pCue->getType() != Cue::CUE) {
            continue;
        }
        int hotcue = pCue->getHotCue();
        if (hotcue != -1)
            attachCue(pCue, hotcue);
    }

    double loadCuePoint = 0.0;
    if (loadCue != NULL) {
        m_pCuePoint->set(loadCue->getPosition());

        // 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.
        if (!getConfig()->getValueString(
                ConfigKey("[Controls]","CueRecall")).toInt()) {
            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();
    seekExact(loadCuePoint);
}
예제 #5
0
void BaseTrackPlayer::slotFinishLoading(TrackPointer pTrackInfoObject)
{
    // Read the tags if required
    if (!m_pLoadedTrack->getHeaderParsed()) {
        m_pLoadedTrack->parse();
    }

    // m_pLoadedTrack->setPlayedAndUpdatePlaycount(true); // Actually the song is loaded but not played

    // Update the BPM and duration values that are stored in ControlObjects
    m_pDuration->set(m_pLoadedTrack->getDuration());
    m_pBPM->slotSet(m_pLoadedTrack->getBpm());
    m_pKey->slotSet(m_pLoadedTrack->getKey());
    m_pReplayGain->slotSet(m_pLoadedTrack->getReplayGain());

    // Update the PlayerInfo class that is used in EngineShoutcast to replace
    // the metadata of a stream
    PlayerInfo::instance().setTrackInfo(getGroup(), m_pLoadedTrack);

    // Reset the loop points.
    m_pLoopInPoint->slotSet(-1);
    m_pLoopOutPoint->slotSet(-1);

    const QList<Cue*> trackCues = pTrackInfoObject->getCuePoints();
    QListIterator<Cue*> it(trackCues);
    while (it.hasNext()) {
        Cue* pCue = it.next();
        if (pCue->getType() == Cue::LOOP) {
            int loopStart = pCue->getPosition();
            int loopEnd = loopStart + pCue->getLength();
            if (loopStart != -1 && loopEnd != -1 && even(loopStart) && even(loopEnd)) {
                m_pLoopInPoint->slotSet(loopStart);
                m_pLoopOutPoint->slotSet(loopEnd);
                break;
            }
        }
    }

    emit(newTrackLoaded(m_pLoadedTrack));
}
예제 #6
0
void DlgTrackInfo::populateCues(TrackPointer pTrack) {
    int sampleRate = pTrack->getSampleRate();

    QList<Cue*> listPoints;
    const QList<Cue*>& cuePoints = pTrack->getCuePoints();
    QListIterator<Cue*> it(cuePoints);
    while (it.hasNext()) {
        Cue* pCue = it.next();
        if (pCue->getType() == Cue::CUE || pCue->getType() == Cue::LOAD) {
            listPoints.push_back(pCue);
        }
    }
    it = QListIterator<Cue*>(listPoints);
    cueTable->setSortingEnabled(false);
    int row = 0;

    while (it.hasNext()) {
        Cue* pCue = it.next();

        QString rowStr = QString("%1").arg(row);

        // All hotcues are stored in Cue's as 0-indexed, but the GUI presents
        // them to the user as 1-indexex. Add 1 here. rryan 9/2010
        int iHotcue = pCue->getHotCue() + 1;
        QString hotcue = "";
        if (iHotcue != -1) {
            hotcue = QString("%1").arg(iHotcue);
        }

        int position = pCue->getPosition();
        double totalSeconds;
        if (position == -1)
            continue;
        else {
            totalSeconds = float(position) / float(sampleRate) / 2.0;
        }

        int fraction = 100*(totalSeconds - floor(totalSeconds));
        int seconds = int(totalSeconds) % 60;
        int mins = int(totalSeconds) / 60;
        //int hours = mins / 60; //Not going to worry about this for now. :)

        //Construct a nicely formatted duration string now.
        QString duration = QString("%1:%2.%3").arg(
            QString::number(mins),
            QString("%1").arg(seconds, 2, 10, QChar('0')),
            QString("%1").arg(fraction, 2, 10, QChar('0')));

        QTableWidgetItem* durationItem = new QTableWidgetItem(duration);
        // Make the duration read only
        durationItem->setFlags(Qt::NoItemFlags);

        m_cueMap[row] = pCue;
        cueTable->insertRow(row);
        cueTable->setItem(row, 0, new QTableWidgetItem(rowStr));
        cueTable->setItem(row, 1, durationItem);
        cueTable->setItem(row, 2, new QTableWidgetItem(hotcue));
        cueTable->setItem(row, 3, new QTableWidgetItem(pCue->getLabel()));
        row += 1;
    }
    cueTable->setSortingEnabled(true);
}
예제 #7
0
void BaseTrackPlayerImpl::slotFinishLoading(TrackPointer pTrackInfoObject)
{
    m_replaygainPending = false;
    // Read the tags if required
    if (!m_pLoadedTrack->getHeaderParsed()) {
        m_pLoadedTrack->parse(false);
    }

    // m_pLoadedTrack->setPlayedAndUpdatePlaycount(true); // Actually the song is loaded but not played

    // Update the BPM and duration values that are stored in ControlObjects
    m_pDuration->set(m_pLoadedTrack->getDuration());
    m_pBPM->slotSet(m_pLoadedTrack->getBpm());
    m_pKey->slotSet(m_pLoadedTrack->getKey());
    m_pReplayGain->slotSet(m_pLoadedTrack->getReplayGain());

    // Update the PlayerInfo class that is used in EngineShoutcast to replace
    // the metadata of a stream
    PlayerInfo::instance().setTrackInfo(getGroup(), m_pLoadedTrack);

    // Reset the loop points.
    m_pLoopInPoint->slotSet(-1);
    m_pLoopOutPoint->slotSet(-1);

    const QList<Cue*> trackCues = pTrackInfoObject->getCuePoints();
    QListIterator<Cue*> it(trackCues);
    while (it.hasNext()) {
        Cue* pCue = it.next();
        if (pCue->getType() == Cue::LOOP) {
            int loopStart = pCue->getPosition();
            int loopEnd = loopStart + pCue->getLength();
            if (loopStart != -1 && loopEnd != -1 && even(loopStart) && even(loopEnd)) {
                m_pLoopInPoint->slotSet(loopStart);
                m_pLoopOutPoint->slotSet(loopEnd);
                break;
            }
        }
    }
    if(m_pConfig->getValueString(ConfigKey("[Mixer Profile]", "EqAutoReset"), 0).toInt()) {
        if (m_pLowFilter != NULL) {
            m_pLowFilter->set(1.0);
        }
        if (m_pMidFilter != NULL) {
            m_pMidFilter->set(1.0);
        }
        if (m_pHighFilter != NULL) {
            m_pHighFilter->set(1.0);
        }
        if (m_pLowFilterKill != NULL) {
            m_pLowFilterKill->set(0.0);
        }
        if (m_pMidFilterKill != NULL) {
            m_pMidFilterKill->set(0.0);
        }
        if (m_pHighFilterKill != NULL) {
            m_pHighFilterKill->set(0.0);
        }
        m_pPreGain->set(1.0);
    }
    if(m_pConfig->getValueString(ConfigKey("[Controls]", "SpeedAutoReset"), 0).toInt()) {
        if (m_pSpeed != NULL) {
            m_pSpeed->set(0.0);
        }
        // Note: speed may effect pitch
        if (m_pPitch != NULL) {
            m_pPitch->set(0.0);
        }
    }
    emit(newTrackLoaded(m_pLoadedTrack));
}
예제 #8
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);
    }
}
예제 #9
0
void VinylControlControl::slotControlVinylSeek(double fractionalPos) {
    // Prevent NaN's from sneaking into the engine.
    if (isnan(fractionalPos)) {
        return;
    }

    // Do nothing if no track is loaded.
    TrackPointer pTrack = m_pTrack;
    if (!pTrack) {
        return;
    }

    double total_samples = getSampleOfTrack().total;
    double new_playpos = round(fractionalPos * total_samples);

    if (m_pControlVinylEnabled->get() > 0.0 && m_pControlVinylMode->get() == MIXXX_VCMODE_RELATIVE) {
        int cuemode = (int)m_pControlVinylCueing->get();

        //if in preroll, always seek
        if (new_playpos < 0) {
            seekExact(new_playpos);
            return;
        }

        switch (cuemode) {
        case MIXXX_RELATIVE_CUE_OFF:
            return; // If off, do nothing.
        case MIXXX_RELATIVE_CUE_ONECUE:
            //if onecue, just seek to the regular cue
            seekExact(pTrack->getCuePoint().getPosition());
            return;
        case MIXXX_RELATIVE_CUE_HOTCUE:
            // Continue processing in this function.
            break;
        default:
            qWarning() << "Invalid vinyl cue setting";
            return;
        }

        double shortest_distance = 0;
        int nearest_playpos = -1;

        const QList<CuePointer> cuePoints(pTrack->getCuePoints());
        QListIterator<CuePointer> it(cuePoints);
        while (it.hasNext()) {
            CuePointer pCue(it.next());
            if (pCue->getType() != Cue::CUE || pCue->getHotCue() == -1) {
                continue;
            }

            int cue_position = pCue->getPosition();
            // pick cues closest to new_playpos
            if ((nearest_playpos == -1) ||
                (fabs(new_playpos - cue_position) < shortest_distance)) {
                nearest_playpos = cue_position;
                shortest_distance = fabs(new_playpos - cue_position);
            }
        }

        if (nearest_playpos == -1) {
            if (new_playpos >= 0) {
                //never found an appropriate cue, so don't seek?
                return;
            }
            //if negative, allow a seek by falling down to the bottom
        } else {
            m_bSeekRequested = true;
            seekExact(nearest_playpos);
            m_bSeekRequested = false;
            return;
        }
    }

    // Just seek where it wanted to originally.
    m_bSeekRequested = true;
    seekExact(new_playpos);
    m_bSeekRequested = false;
}