Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command for clearing waveform to track's context menu #1197

Merged
merged 5 commits into from
Mar 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/waveform/renderers/glslwaveformrenderersignal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,29 @@ void GLSLWaveformRendererSignal::onSetup(const QDomNode& node) {
}

void GLSLWaveformRendererSignal::onSetTrack() {
m_loadedWaveform = 0;
loadTexture();
slotWaveformUpdated();

TrackPointer pTrack = m_waveformRenderer->getTrackInfo();
if (!pTrack) {
return;
}

// When the track's waveform has been changed (or cleared), it is necessary
// to update (or delete) the texture containing the waveform which was
// uploaded to GPU. Otherwise, previous waveform will be shown.
connect(pTrack.get(), SIGNAL(waveformUpdated()),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about disconnecting the signal? I think this means clearing a track also reloads the texture for all decks it was loaded in (even if a new track has replaced it).

this, SLOT(slotWaveformUpdated()));
}

void GLSLWaveformRendererSignal::onResize() {
createFrameBuffers();
}

void GLSLWaveformRendererSignal::slotWaveformUpdated() {
m_loadedWaveform = 0;
loadTexture();
}

void GLSLWaveformRendererSignal::draw(QPainter* painter, QPaintEvent* /*event*/) {
if (!m_frameBuffersValid || !m_shadersValid) {
return;
Expand Down
6 changes: 5 additions & 1 deletion src/waveform/renderers/glslwaveformrenderersignal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

#include "waveformrenderersignalbase.h"

class GLSLWaveformRendererSignal : public WaveformRendererSignalBase {
class GLSLWaveformRendererSignal : public QObject, public WaveformRendererSignalBase {
Q_OBJECT
public:
explicit GLSLWaveformRendererSignal(
WaveformWidgetRenderer* waveformWidgetRenderer, bool rgbShader);
Expand All @@ -24,6 +25,9 @@ class GLSLWaveformRendererSignal : public WaveformRendererSignalBase {
bool loadShaders();
bool loadTexture();

public slots:
void slotWaveformUpdated();

private:
void createGeometry();
void createFrameBuffers();
Expand Down
42 changes: 21 additions & 21 deletions src/widget/woverview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

WOverview::WOverview(const char *pGroup, UserSettingsPointer pConfig, QWidget* parent) :
WWidget(parent),
m_pWaveformSourceImage(nullptr),
m_actualCompletion(0),
m_pixmapDone(false),
m_waveformPeak(-1.0),
Expand All @@ -61,12 +60,6 @@ WOverview::WOverview(const char *pGroup, UserSettingsPointer pConfig, QWidget* p
setAcceptDrops(true);
}

WOverview::~WOverview() {
if (m_pWaveformSourceImage) {
delete m_pWaveformSourceImage;
}
}

void WOverview::setup(const QDomNode& node, const SkinContext& context) {
m_signalColors.setup(node, context);

Expand Down Expand Up @@ -169,12 +162,23 @@ void WOverview::slotWaveformSummaryUpdated() {
return;
}
m_pWaveform = pTrack->getWaveformSummary();
// If the waveform is already complete, just draw it.
if (m_pWaveform && m_pWaveform->getCompletion() == m_pWaveform->getDataSize()) {
m_actualCompletion = 0;
if (drawNextPixmapPart()) {
update();
if (m_pWaveform) {
// If the waveform is already complete, just draw it.
if (m_pWaveform->getCompletion() == m_pWaveform->getDataSize()) {
m_actualCompletion = 0;
if (drawNextPixmapPart()) {
update();
}
}
} else {
// Null waveform pointer means waveform was cleared.
m_waveformSourceImage = QImage();
m_dAnalyzerProgress = 1.0;
m_actualCompletion = 0;
m_waveformPeak = -1.0;
m_pixmapDone = false;

update();
}
}

Expand Down Expand Up @@ -211,11 +215,7 @@ void WOverview::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack)
this, SLOT(slotAnalyzerProgress(int)));
}

if (m_pWaveformSourceImage) {
delete m_pWaveformSourceImage;
m_pWaveformSourceImage = nullptr;
}

m_waveformSourceImage = QImage();
m_dAnalyzerProgress = 1.0;
m_actualCompletion = 0;
m_waveformPeak = -1.0;
Expand Down Expand Up @@ -314,7 +314,7 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) {

// Draw waveform pixmap
WaveformWidgetFactory* widgetFactory = WaveformWidgetFactory::instance();
if (m_pWaveformSourceImage) {
if (!m_waveformSourceImage.isNull()) {
int diffGain;
bool normalize = widgetFactory->isOverviewNormalized();
if (normalize && m_pixmapDone && m_waveformPeak > 1) {
Expand All @@ -325,9 +325,9 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) {
}

if (m_diffGain != diffGain || m_waveformImageScaled.isNull()) {
QRect sourceRect(0, diffGain, m_pWaveformSourceImage->width(),
m_pWaveformSourceImage->height() - 2 * diffGain);
QImage croppedImage = m_pWaveformSourceImage->copy(sourceRect);
QRect sourceRect(0, diffGain, m_waveformSourceImage.width(),
m_waveformSourceImage.height() - 2 * diffGain);
QImage croppedImage = m_waveformSourceImage.copy(sourceRect);
if (m_orientation == Qt::Vertical) {
// Rotate pixmap
croppedImage = croppedImage.transformed(QTransform(0, 1, 1, 0, 0, 0));
Expand Down
3 changes: 1 addition & 2 deletions src/widget/woverview.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class WOverview : public WWidget {
Q_OBJECT
public:
WOverview(const char* pGroup, UserSettingsPointer pConfig, QWidget* parent=nullptr);
~WOverview() override;

void setup(const QDomNode& node, const SkinContext& context);

Expand Down Expand Up @@ -67,7 +66,7 @@ class WOverview : public WWidget {
return m_pWaveform;
}

QImage* m_pWaveformSourceImage;
QImage m_waveformSourceImage;
QImage m_waveformImageScaled;

WaveformSignalColors m_signalColors;
Expand Down
10 changes: 5 additions & 5 deletions src/widget/woverviewhsv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ bool WOverviewHSV::drawNextPixmapPart() {
return false;
}

if (!m_pWaveformSourceImage) {
if (m_waveformSourceImage.isNull()) {
// Waveform pixmap twice the height of the viewport to be scalable
// by total_gain
// We keep full range waveform data to scale it on paint
m_pWaveformSourceImage = new QImage(dataSize / 2, 2 * 255,
m_waveformSourceImage = QImage(dataSize / 2, 2 * 255,
QImage::Format_ARGB32_Premultiplied);
m_pWaveformSourceImage->fill(QColor(0,0,0,0).value());
m_waveformSourceImage.fill(QColor(0, 0, 0, 0).value());
}

// Always multiple of 2
Expand All @@ -57,8 +57,8 @@ bool WOverviewHSV::drawNextPixmapPart() {
// << "completionIncrement:" << completionIncrement;


QPainter painter(m_pWaveformSourceImage);
painter.translate(0.0,static_cast<double>(m_pWaveformSourceImage->height())/2.0);
QPainter painter(&m_waveformSourceImage);
painter.translate(0.0, static_cast<double>(m_waveformSourceImage.height()) / 2.0);

// Get HSV of low color. NOTE(rryan): On ARM, qreal is float so it's
// important we use qreal here and not double or float or else we will get
Expand Down
10 changes: 5 additions & 5 deletions src/widget/woverviewlmh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ bool WOverviewLMH::drawNextPixmapPart() {
return false;
}

if (!m_pWaveformSourceImage) {
if (m_waveformSourceImage.isNull()) {
// Waveform pixmap twice the height of the viewport to be scalable
// by total_gain
// We keep full range waveform data to scale it on paint
m_pWaveformSourceImage = new QImage(dataSize / 2, 2 * 255,
m_waveformSourceImage = QImage(dataSize / 2, 2 * 255,
QImage::Format_ARGB32_Premultiplied);
m_pWaveformSourceImage->fill(QColor(0,0,0,0).value());
m_waveformSourceImage.fill(QColor(0, 0, 0, 0).value());
}

// Always multiple of 2
Expand All @@ -59,8 +59,8 @@ bool WOverviewLMH::drawNextPixmapPart() {
// << "completionIncrement:" << completionIncrement;


QPainter painter(m_pWaveformSourceImage);
painter.translate(0.0,static_cast<double>(m_pWaveformSourceImage->height())/2.0);
QPainter painter(&m_waveformSourceImage);
painter.translate(0.0, static_cast<double>(m_waveformSourceImage.height()) / 2.0);

QColor lowColor = m_signalColors.getLowColor();
QPen lowColorPen(QBrush(lowColor), 1);
Expand Down
10 changes: 5 additions & 5 deletions src/widget/woverviewrgb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ bool WOverviewRGB::drawNextPixmapPart() {
return false;
}

if (!m_pWaveformSourceImage) {
if (m_waveformSourceImage.isNull()) {
// Waveform pixmap twice the height of the viewport to be scalable
// by total_gain
// We keep full range waveform data to scale it on paint
m_pWaveformSourceImage = new QImage(dataSize / 2, 2 * 255,
m_waveformSourceImage = QImage(dataSize / 2, 2 * 255,
QImage::Format_ARGB32_Premultiplied);
m_pWaveformSourceImage->fill(QColor(0,0,0,0).value());
m_waveformSourceImage.fill(QColor(0, 0, 0, 0).value());
}

// Always multiple of 2
Expand All @@ -55,8 +55,8 @@ bool WOverviewRGB::drawNextPixmapPart() {
// << "waveformCompletion:" << waveformCompletion
// << "completionIncrement:" << completionIncrement;

QPainter painter(m_pWaveformSourceImage);
painter.translate(0.0,static_cast<double>(m_pWaveformSourceImage->height())/2.0);
QPainter painter(&m_waveformSourceImage);
painter.translate(0.0, static_cast<double>(m_waveformSourceImage.height()) / 2.0);

QColor color;

Expand Down
28 changes: 28 additions & 0 deletions src/widget/wtracktableview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ WTrackTableView::~WTrackTableView() {
delete m_pPropertiesAct;
delete m_pMenu;
delete m_pPlaylistMenu;
delete m_pCoverMenu;
delete m_pCrateMenu;
delete m_pBpmLockAction;
delete m_pBpmUnlockAction;
Expand All @@ -137,6 +138,8 @@ WTrackTableView::~WTrackTableView() {
delete m_pBpmFourThirdsAction;
delete m_pBpmThreeHalvesAction;
delete m_pBPMMenu;
delete m_pClearBeatsAction;
delete m_pClearWaveformAction;
delete m_pReplayGainResetAction;
delete m_pPurgeAct;
delete m_pFileBrowserAct;
Expand Down Expand Up @@ -455,6 +458,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 ReplayGain"), this);
connect(m_pReplayGainResetAction, SIGNAL(triggered()),
this, SLOT(slotReplayGainReset()));
Expand Down Expand Up @@ -929,6 +936,8 @@ void WTrackTableView::contextMenuEvent(QContextMenuEvent* event) {
m_pBPMMenu->addAction(m_pClearBeatsAction);
}

m_pMenu->addAction(m_pClearWaveformAction);

m_pMenu->addAction(m_pReplayGainResetAction);

m_pMenu->addSeparator();
Expand Down Expand Up @@ -1606,6 +1615,25 @@ void WTrackTableView::slotClearBeats() {
}
}

void WTrackTableView::slotClearWaveform() {
TrackModel* trackModel = getTrackModel();
if (trackModel == nullptr) {
return;
}

AnalysisDao& analysisDao = m_pTrackCollection->getAnalysisDAO();
QModelIndexList indices = selectionModel()->selectedRows();
for (const QModelIndex& index : indices) {
TrackPointer pTrack = trackModel->getTrack(index);
if (!pTrack) {
continue;
}
analysisDao.deleteAnalysesForTrack(pTrack->getId());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this delete the all analysis data?
I think we should rethink the use-cases for "ClearWaveform" and name this feature accordingly.
IMHO clearing all analysis makes sense if the use-case is, that the track samples have changed.
In this case all position related data is invalid.
What will happen with cue points?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhm Well, by looking at the AnalysisDao code, AnalysisDao is used just for storing waveforms, so this indeed is only clearing track's waveforms.

pTrack->setWaveform(WaveformPointer());
pTrack->setWaveformSummary(WaveformPointer());
}
}

void WTrackTableView::slotReplayGainReset() {
QModelIndexList indices = selectionModel()->selectedRows();
TrackModel* trackModel = getTrackModel();
Expand Down
4 changes: 4 additions & 0 deletions src/widget/wtracktableview.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,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);
Expand Down Expand Up @@ -162,6 +163,9 @@ class WTrackTableView : public WLibraryTableView {
// Clear track beats
QAction* m_pClearBeatsAction;

// Clear track waveform
QAction* m_pClearWaveformAction;

// Replay Gain feature
QAction *m_pReplayGainResetAction;

Expand Down