Beispiel #1
0
void WTrackProperty::slotTrackLoaded(TrackPointer track) {
    if (track) {
        m_pCurrentTrack = track;
        connect(track.data(), SIGNAL(changed(Track*)),
                this, SLOT(updateLabel(Track*)));
        updateLabel(track.data());
    }
}
SoundSourceProxy::SoundSourceProxy(const TrackPointer& pTrack)
    : m_pTrack(pTrack),
      m_url(getCanonicalUrlForTrack(pTrack.data())),
      m_soundSourceProviderRegistrations(findSoundSourceProviderRegistrations(m_url)),
      m_soundSourceProviderRegistrationIndex(0) {
    initSoundSource();
}
Beispiel #3
0
//static
CoverArt CoverArtUtils::guessCoverArt(TrackPointer pTrack) {
    CoverArt art;
    art.info.source = CoverInfo::GUESSED;

    if (pTrack.isNull()) {
        return art;
    }

    const QFileInfo fileInfo(pTrack->getFileInfo());
    art.image = extractEmbeddedCover(fileInfo, pTrack->getSecurityToken());
    if (!art.image.isNull()) {
        // TODO() here we my introduce a duplicate hash code
        art.info.hash = calculateHash(art.image);
        art.info.coverLocation = QString();
        art.info.type = CoverInfo::METADATA;
        qDebug() << "CoverArtUtils::guessCoverArt found metadata art" << art;
        return art;
    }

    QLinkedList<QFileInfo> possibleCovers = findPossibleCoversInFolder(
            fileInfo.absolutePath());
    art = selectCoverArtForTrack(pTrack.data(), possibleCovers);
    if (art.info.type == CoverInfo::FILE) {
        qDebug() << "CoverArtUtils::guessCoverArt found file art" << art;
    } else {
        qDebug() << "CoverArtUtils::guessCoverArt didn't find art" << art;
    }
    return art;
}
Beispiel #4
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();
}
Beispiel #5
0
BeatsPointer BeatFactory::makePreferredBeats(
    TrackPointer pTrack, QVector<double> beats,
    const QHash<QString, QString> extraVersionInfo,
    const bool bEnableFixedTempoCorrection, const bool bEnableOffsetCorrection,
    const int iSampleRate, const int iTotalSamples,
    const int iMinBpm, const int iMaxBpm) {
    const QString version = getPreferredVersion(bEnableFixedTempoCorrection);
    const QString subVersion = getPreferredSubVersion(bEnableFixedTempoCorrection,
                               bEnableOffsetCorrection,
                               iMinBpm, iMaxBpm,
                               extraVersionInfo);

    BeatUtils::printBeatStatistics(beats, iSampleRate);
    if (version == BEAT_GRID_2_VERSION) {
        double globalBpm = BeatUtils::calculateBpm(beats, iSampleRate, iMinBpm, iMaxBpm);
        double firstBeat = BeatUtils::calculateFixedTempoFirstBeat(
                               bEnableOffsetCorrection,
                               beats, iSampleRate, iTotalSamples, globalBpm);
        BeatGrid* pGrid = new BeatGrid(pTrack.data(), iSampleRate);
        // firstBeat is in frames here and setGrid() takes samples.
        pGrid->setGrid(globalBpm, firstBeat * 2);
        pGrid->setSubVersion(subVersion);
        return BeatsPointer(pGrid, &BeatFactory::deleteBeats);
    } else if (version == BEAT_MAP_VERSION) {
        BeatMap* pBeatMap = new BeatMap(pTrack, iSampleRate, beats);
        pBeatMap->setSubVersion(subVersion);
        return BeatsPointer(pBeatMap, &BeatFactory::deleteBeats);
    } else {
        qDebug() << "ERROR: Could not determine what type of beatgrid to create.";
        return BeatsPointer();
    }
}
void PlaylistItemDelegate::paintTrack(QPainter *painter,
                                      const QStyleOptionViewItem &option,
                                      const QModelIndex &index) const {

    // get the data object
    const TrackPointer trackPointer = index.data(Playlist::DataObjectRole).value<TrackPointer>();
    Track *track = trackPointer.data();

    // const PlaylistModel* playlistModel = dynamic_cast<const PlaylistModel*>(index.model());

    const bool isActive = index.data(Playlist::ActiveItemRole).toBool();
    // const bool isHovered = index.data(Playlist::HoveredItemRole).toBool();
    const bool isSelected = option.state & QStyle::State_Selected;

    if (isSelected)
        QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter);

    painter->save();

    painter->translate(option.rect.topLeft());
    QRect line(0, 0, option.rect.width(), option.rect.height());

    // text color
    if (isSelected)
        painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0));
    else
        painter->setPen(QPen(option.palette.brush(QPalette::Text), 0));

    if (line.height() > ITEM_HEIGHT) {
        // qDebug() << "header at index" << index.row();
        line.setHeight(ITEM_HEIGHT);
        paintAlbumHeader(painter, option, line, track);

        // now modify our rect and painter
        // to make them similar to "headerless" items
        line.moveBottom(ITEM_HEIGHT);
        painter->translate(0, ITEM_HEIGHT);
    }

    if (isActive) {
        if (!isSelected) paintActiveOverlay(painter, option, line);
        QFont boldFont = painter->font();
        boldFont.setBold(true);
        painter->setFont(boldFont);
        // play icon
        painter->drawPixmap(PADDING*2, (ITEM_HEIGHT - 16) / 2, 16, 16, getPlayIcon());
    } else {
        paintTrackNumber(painter, option, line, track);
    }

    paintTrackTitle(painter, option, line, track);
    paintTrackLength(painter, option, line, track);

    // separator
    painter->setPen(option.palette.color(QPalette::Midlight));
    painter->drawLine(0, line.height()-1, line.width(), line.height()-1);

    painter->restore();
}
Beispiel #7
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);
    }
}
Beispiel #8
0
/** Do a non-recursive import of all the songs in a directory. Does NOT decend into subdirectories.
    @param trackDao The track data access object which provides a connection to the database. We use this parameter in order to make this function callable from separate threads. You need to use a different DB connection for each thread.
    @return true if the scan completed without being cancelled. False if the scan was cancelled part-way through.
*/
bool TrackCollection::importDirectory(const QString& directory, TrackDAO& trackDao,
                                      const QStringList& nameFilters,
                                      volatile bool* cancel) {
    //qDebug() << "TrackCollection::importDirectory(" << directory<< ")";

    emit(startedLoading());
    // QFileInfoList files;

    //get a list of the contents of the directory and go through it.
    QDirIterator it(directory, nameFilters, QDir::Files | QDir::NoDotAndDotDot);
    while (it.hasNext()) {

        //If a flag was raised telling us to cancel the library scan then stop.
        if (*cancel) {
            return false;
        }

        QString absoluteFilePath = it.next();

        // If the track is in the database, mark it as existing. This code gets exectuted
        // when other files in the same directory have changed (the directory hash has changed).
        trackDao.markTrackLocationAsVerified(absoluteFilePath);

        // If the file already exists in the database, continue and go on to
        // the next file.

        // If the file doesn't already exist in the database, then add
        // it. If it does exist in the database, then it is either in the
        // user's library OR the user has "removed" the track via
        // "Right-Click -> Remove". These tracks stay in the library, but
        // their mixxx_deleted column is 1.
        if (!trackDao.trackExistsInDatabase(absoluteFilePath)) {
            //qDebug() << "Loading" << it.fileName();
            emit(progressLoading(it.fileName()));

            TrackPointer pTrack = TrackPointer(new TrackInfoObject(
                                                   absoluteFilePath), &QObject::deleteLater);

            if (trackDao.addTracksAdd(pTrack.data(), false)) {
                // Successful added
                // signal the main instance of TrackDao, that there is a
                // new Track in the database
                m_trackDao->databaseTrackAdded(pTrack);
            } else {
                qDebug() << "Track ("+absoluteFilePath+") could not be added";
            }
        }
    }
    emit(finishedLoading());
    return true;
}
Beispiel #9
0
void SearchModel::itemActivated(const QModelIndex &index) {
    int itemType = index.data(Finder::ItemTypeRole).toInt();
    if (itemType == Finder::ItemTypeArtist) {
        const ArtistPointer pointer = index.data(Finder::DataObjectRole).value<ArtistPointer>();
        finder->artistActivated(pointer.data());
    } else if (itemType == Finder::ItemTypeAlbum) {
        const AlbumPointer pointer = index.data(Finder::DataObjectRole).value<AlbumPointer>();
        finder->albumActivated(pointer.data());
    } else if (itemType == Finder::ItemTypeFolder) {
    } else if (itemType == Finder::ItemTypeTrack) {
        const TrackPointer pointer = index.data(Finder::DataObjectRole).value<TrackPointer>();
        finder->trackActivated(pointer.data());
    }
}
QSize PlaylistItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {

    // determine item height based on font metrics
    if (ITEM_HEIGHT == 0) {
        ITEM_HEIGHT = option.fontMetrics.height() * 2;
    }

    QModelIndex previousIndex = index.sibling(index.row()-1, index.column());
    if (previousIndex.isValid()) {
        const TrackPointer previousTrackPointer = previousIndex.data(Playlist::DataObjectRole).value<TrackPointer>();
        Track *previousTrack = previousTrackPointer.data();
        if (previousTrack) {
            const TrackPointer trackPointer = index.data(Playlist::DataObjectRole).value<TrackPointer>();
            Track *track = trackPointer.data();
            if (previousTrack->getAlbum() != track->getAlbum()) {
                return QSize(ITEM_HEIGHT*2, ITEM_HEIGHT*2);
            }
        }
    } else {
        return QSize(ITEM_HEIGHT*2, ITEM_HEIGHT*2);
    }

    return QSize(ITEM_HEIGHT, ITEM_HEIGHT);
}
Beispiel #11
0
void DlgTagFetcher::loadTrack(const TrackPointer track) {
    if (track == NULL) {
        return;
    }
    results->clear();
    m_track = track;
    m_data = Data();
    m_TagFetcher.startFetch(m_track);

    disconnect(this, SLOT(updateTrackMetadata(TrackPointer)));
    connect(track.data(), SIGNAL(changed(TrackInfoObject*)),
            this, SLOT(updateTrackMetadata(TrackInfoObject*)));

    updateStack();
}
Beispiel #12
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 (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);
}
Beispiel #13
0
Item *SearchModel::itemAt(const QModelIndex &index) const {
    Item *item = nullptr;

    int itemType = index.data(Finder::ItemTypeRole).toInt();
    if (itemType == Finder::ItemTypeArtist) {
        const ArtistPointer pointer = index.data(Finder::DataObjectRole).value<ArtistPointer>();
        item = qobject_cast<Item *>(pointer.data());
    } else if (itemType == Finder::ItemTypeAlbum) {
        const AlbumPointer pointer = index.data(Finder::DataObjectRole).value<AlbumPointer>();
        item = qobject_cast<Item *>(pointer.data());
    } else if (itemType == Finder::ItemTypeFolder) {
    } else if (itemType == Finder::ItemTypeTrack) {
        const TrackPointer pointer = index.data(Finder::DataObjectRole).value<TrackPointer>();
        item = qobject_cast<Item *>(pointer.data());
    }

    return item;
}
Beispiel #14
0
BeatsPointer BeatFactory::loadBeatsFromByteArray(TrackPointer pTrack,
        QString beatsVersion,
        QString beatsSubVersion,
        QByteArray* beatsSerialized) {
    if (beatsVersion == BEAT_GRID_1_VERSION ||
            beatsVersion == BEAT_GRID_2_VERSION) {
        BeatGrid* pGrid = new BeatGrid(pTrack.data(), 0, beatsSerialized);
        pGrid->setSubVersion(beatsSubVersion);
        qDebug() << "Successfully deserialized BeatGrid";
        return BeatsPointer(pGrid, &BeatFactory::deleteBeats);
    } else if (beatsVersion == BEAT_MAP_VERSION) {
        BeatMap* pMap = new BeatMap(pTrack, 0, beatsSerialized);
        pMap->setSubVersion(beatsSubVersion);
        qDebug() << "Successfully deserialized BeatMap";
        return BeatsPointer(pMap, &BeatFactory::deleteBeats);
    }
    qDebug() << "BeatFactory::loadBeatsFromByteArray could not parse serialized beats.";
    return BeatsPointer();
}
Beispiel #15
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);
    }
}