diff --git a/src/analyzer/analyzerwaveform.cpp b/src/analyzer/analyzerwaveform.cpp index e837a0ecb652..57af0e2db6f7 100644 --- a/src/analyzer/analyzerwaveform.cpp +++ b/src/analyzer/analyzerwaveform.cpp @@ -104,12 +104,21 @@ bool AnalyzerWaveform::initialize(TrackPointer tio, int sampleRate, int totalSam } bool AnalyzerWaveform::loadStored(TrackPointer tio) const { + TrackId trackId = tio->getId(); + + if (tio->isClearWaveformRequested()) { + bool success = m_pAnalysisDao->deleteAnalysesForTrack(trackId); + qDebug() << (success ? "Successfully deleted" : "Failed to delete") + << "waveform analysis for trackId" << trackId; + tio->setClearWaveformRequested(false); + return false; + } + ConstWaveformPointer pTrackWaveform = tio->getWaveform(); ConstWaveformPointer pTrackWaveformSummary = tio->getWaveformSummary(); ConstWaveformPointer pLoadedTrackWaveform; ConstWaveformPointer pLoadedTrackWaveformSummary; - TrackId trackId = tio->getId(); bool missingWaveform = pTrackWaveform.isNull(); bool missingWavesummary = pTrackWaveformSummary.isNull(); diff --git a/src/library/dao/analysisdao.cpp b/src/library/dao/analysisdao.cpp index 2c1eac8723bd..d6c3ddf207a8 100644 --- a/src/library/dao/analysisdao.cpp +++ b/src/library/dao/analysisdao.cpp @@ -323,14 +323,24 @@ void AnalysisDao::saveTrackAnalyses(TrackInfoObject* pTrack) { ConstWaveformPointer pWaveform = pTrack->getWaveform(); ConstWaveformPointer pWaveSummary = pTrack->getWaveformSummary(); + TrackId trackId(pTrack->getId()); + + // Delete waveform analysis if track was requested to have its waveform cleared. + if (pTrack->isClearWaveformRequested()) { + bool success = deleteAnalysesForTrack(trackId); + qDebug() << (success ? "Successfully deleted" : "Failed to delete") + << "waveform analysis for trackId" << trackId; + // Clear flag + pTrack->setClearWaveformRequested(false); + return; + } + // Don't try to save invalid or non-dirty waveforms. if (!pWaveform || pWaveform->getDataSize() == 0 || !pWaveform->isDirty() || !pWaveSummary || pWaveSummary->getDataSize() == 0 || !pWaveSummary->isDirty()) { return; } - TrackId trackId(pTrack->getId()); - AnalysisDao::AnalysisInfo analysis; analysis.trackId = trackId; if (pWaveform->getId() != -1) { diff --git a/src/trackinfoobject.cpp b/src/trackinfoobject.cpp index 075f82b8edae..8b3019c4c550 100644 --- a/src/trackinfoobject.cpp +++ b/src/trackinfoobject.cpp @@ -56,6 +56,7 @@ TrackInfoObject::TrackInfoObject( m_dateAdded(QDateTime::currentDateTime()), m_bHeaderParsed(false), m_bBpmLocked(false), + m_bClearWaveformRequested(false), m_analyzerProgress(-1) { } @@ -653,21 +654,45 @@ QString TrackInfoObject::getURL() const { } ConstWaveformPointer TrackInfoObject::getWaveform() { - return m_waveform; + return m_pWaveform; } void TrackInfoObject::setWaveform(ConstWaveformPointer pWaveform) { - m_waveform = pWaveform; - emit(waveformUpdated()); + QMutexLocker lock(&m_qMutex); + if (m_pWaveform != pWaveform) { + m_pWaveform = pWaveform; + markDirtyAndUnlock(&lock); + emit(waveformUpdated()); + } } ConstWaveformPointer TrackInfoObject::getWaveformSummary() const { - return m_waveformSummary; + return m_pWaveformSummary; } void TrackInfoObject::setWaveformSummary(ConstWaveformPointer pWaveform) { - m_waveformSummary = pWaveform; - emit(waveformSummaryUpdated()); + QMutexLocker lock(&m_qMutex); + if (m_pWaveformSummary != pWaveform) { + m_pWaveformSummary = pWaveform; + markDirtyAndUnlock(&lock); + emit(waveformSummaryUpdated()); + } +} + +bool TrackInfoObject::isClearWaveformRequested() const { + QMutexLocker lock(&m_qMutex); + return m_bClearWaveformRequested; +} + +void TrackInfoObject::setClearWaveformRequested(bool requested) { + QMutexLocker lock(&m_qMutex); + m_bClearWaveformRequested = requested; +} + +void TrackInfoObject::clearWaveform() { + setClearWaveformRequested(true); + setWaveform(WaveformPointer()); + setWaveformSummary(WaveformPointer()); } void TrackInfoObject::setAnalyzerProgress(int progress) { diff --git a/src/trackinfoobject.h b/src/trackinfoobject.h index 5bac592c83e2..a8dfdf4bc432 100644 --- a/src/trackinfoobject.h +++ b/src/trackinfoobject.h @@ -222,6 +222,10 @@ class TrackInfoObject : public QObject { ConstWaveformPointer getWaveformSummary() const; void setWaveformSummary(ConstWaveformPointer pWaveform); + bool isClearWaveformRequested() const; + void setClearWaveformRequested(bool); + void clearWaveform(); + void setAnalyzerProgress(int progress); int getAnalyzerProgress() const; @@ -378,9 +382,11 @@ class TrackInfoObject : public QObject { // Storage for the track's beats BeatsPointer m_pBeats; - //Visual waveform data - ConstWaveformPointer m_waveform; - ConstWaveformPointer m_waveformSummary; + // Visual waveform data + ConstWaveformPointer m_pWaveform; + ConstWaveformPointer m_pWaveformSummary; + + bool m_bClearWaveformRequested; QAtomicInt m_analyzerProgress; // in 0.1% diff --git a/src/widget/wtracktableview.cpp b/src/widget/wtracktableview.cpp index b8d1b86b3b80..573c36894ced 100644 --- a/src/widget/wtracktableview.cpp +++ b/src/widget/wtracktableview.cpp @@ -449,6 +449,10 @@ void WTrackTableView::createActions() { connect(m_pClearBeatsAction, SIGNAL(triggered()), this, SLOT(slotClearBeats())); + m_pClearWaveformAction = new QAction(tr("Clear Waveform"), this); + connect(m_pClearWaveformAction, SIGNAL(triggered()), + this, SLOT(slotClearWaveform())); + m_pReplayGainResetAction = new QAction(tr("Reset Replay Gain"), this); connect(m_pReplayGainResetAction, SIGNAL(triggered()), this, SLOT(slotReplayGainReset())); @@ -873,6 +877,8 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) { m_pBPMMenu->addAction(m_pClearBeatsAction); } + m_pMenu->addAction(m_pClearWaveformAction); + m_pMenu->addAction(m_pReplayGainResetAction); m_pMenu->addSeparator(); @@ -1586,6 +1592,21 @@ void WTrackTableView::slotClearBeats() { } } +void WTrackTableView::slotClearWaveform() { + TrackModel* trackModel = getTrackModel(); + if (trackModel == nullptr) { + return; + } + + QModelIndexList selectedIndices = selectionModel()->selectedRows(); + foreach (QModelIndex index, selectedIndices) { + TrackPointer pTrack = trackModel->getTrack(index); + if (pTrack) { + pTrack->clearWaveform(); + } + } +} + void WTrackTableView::slotReplayGainReset() { QModelIndexList indices = selectionModel()->selectedRows(); TrackModel* trackModel = getTrackModel(); diff --git a/src/widget/wtracktableview.h b/src/widget/wtracktableview.h index 1fc7e1928775..252c089eb7fb 100644 --- a/src/widget/wtracktableview.h +++ b/src/widget/wtracktableview.h @@ -66,6 +66,7 @@ class WTrackTableView : public WLibraryTableView { void slotUnlockBpm(); void slotScaleBpm(int); void slotClearBeats(); + void slotClearWaveform(); void slotReplayGainReset(); // Signalled 20 times per second (every 50ms) by GuiTick. void slotGuiTick50ms(double); @@ -150,6 +151,9 @@ class WTrackTableView : public WLibraryTableView { // Clear track beats QAction* m_pClearBeatsAction; + // Clear track waveform + QAction* m_pClearWaveformAction; + // Replay Gain feature QAction *m_pReplayGainResetAction;