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

Vectorscope #5328

Merged
merged 18 commits into from
Feb 7, 2020
Merged
Show file tree
Hide file tree
Changes from 17 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
1 change: 1 addition & 0 deletions cmake/modules/PluginList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ SET(LMMS_PLUGIN_LIST
VstEffect
watsyn
waveshaper
Vectorscope
vibed
Xpressive
zynaddsubfx
Expand Down
41 changes: 41 additions & 0 deletions include/ColorChooser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* ColorChooser.h - declaration and definition of ColorChooser class.
*
* Copyright (c) 2019 CYBERDEViLNL <cyberdevilnl/at/protonmail/dot/ch>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#include <QColorDialog>
#include <QApplication>
#include <QKeyEvent>

class ColorChooser: public QColorDialog
{
public:
ColorChooser(const QColor &initial, QWidget *parent): QColorDialog(initial, parent) {};
ColorChooser(QWidget *parent): QColorDialog(parent) {};

protected:
// Forward key events to the parent to prevent stuck notes when the dialog gets focus
void keyReleaseEvent(QKeyEvent *event) override
{
QKeyEvent ke(*event);
QApplication::sendEvent(parentWidget(), &ke);
}
};
1 change: 1 addition & 0 deletions include/LocklessRingBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class LocklessRingBufferReader : public ringbuffer_reader_t<T>
void waitForData()
{
QMutex useless_lock;
useless_lock.lock();
m_notifier->wait(&useless_lock);
useless_lock.unlock();
}
Expand Down
3 changes: 3 additions & 0 deletions plugins/Vectorscope/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
INCLUDE(BuildPlugin)
BUILD_PLUGIN(vectorscope Vectorscope.cpp VecControls.cpp VecControlsDialog.cpp VectorView.cpp
MOCFILES VecControls.h VecControlsDialog.h VectorView.h EMBEDDED_RESOURCES logo.png)
14 changes: 14 additions & 0 deletions plugins/Vectorscope/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Vectorscope plugin

## Overview

Vectorscope is a simple stereo field visualizer. Samples are plotted into a graph, with left and right channels providing the coordinates. Previously drawn samples quickly fade away and are continuously replaced by new samples, creating a real-time plot of the most recently played samples.

Similar to other effect plugins, the top-level widget is VecControlDialog. It displays configuration knobs and the main VectorView widget. The back-end configuration class is VecControls, which holds all models and configuration values.

VectorView computes and shows the plot. It gets data for processing from the Vectorscope class, which handles the interface with LMMS. In order to avoid any stalling of the realtime-sensitive audio thread, data are exchanged through a lockless ring buffer.

## Changelog

1.0.0 2019-11-21
- initial release
70 changes: 70 additions & 0 deletions plugins/Vectorscope/VecControls.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* VecControls.cpp - definition of VecControls class.
*
* Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#include "VecControls.h"

#include <QtXml/QDomElement>

#include "VecControlsDialog.h"
#include "Vectorscope.h"


VecControls::VecControls(Vectorscope *effect) :
EffectControls(effect),
m_effect(effect),

// initialize models and set default values
m_persistenceModel(0.5f, 0.0f, 1.0f, 0.05f, this, tr("Display persistence amount")),
m_logarithmicModel(false, this, tr("Logarithmic scale")),
m_highQualityModel(false, this, tr("High quality"))
{
// Colors (percentages include sRGB gamma correction)
m_colorFG = QColor(60, 255, 130, 255); // ~LMMS green
m_colorGrid = QColor(76, 80, 84, 128); // ~60 % gray (slightly cold / blue), 50 % transparent
m_colorLabels = QColor(76, 80, 84, 255); // ~60 % gray (slightly cold / blue)
m_colorOutline = QColor(30, 34, 38, 255); // ~40 % gray (slightly cold / blue)
}


// Create the VecControlDialog widget which handles display of GUI elements.
EffectControlDialog* VecControls::createView()
{
return new VecControlsDialog(this);
}


void VecControls::loadSettings(const QDomElement &element)
{
m_persistenceModel.loadSettings(element, "Persistence");
m_logarithmicModel.loadSettings(element, "Logarithmic");
m_highQualityModel.loadSettings(element, "HighQuality");
}


void VecControls::saveSettings(QDomDocument &document, QDomElement &element)
{
m_persistenceModel.saveSettings(document, element, "Persistence");
m_logarithmicModel.saveSettings(document, element, "Logarithmic");
m_highQualityModel.saveSettings(document, element, "HighQuality");
}
66 changes: 66 additions & 0 deletions plugins/Vectorscope/VecControls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* VecControls.h - declaration of VecControls class.
*
* Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef VECCONTROLS_H
#define VECCONTROLS_H

#include <QColor>

#include "EffectControls.h"


class Vectorscope;

// Holds all the configuration values
class VecControls : public EffectControls
{
Q_OBJECT
public:
explicit VecControls(Vectorscope *effect);
virtual ~VecControls() {}

EffectControlDialog *createView() override;

void saveSettings (QDomDocument &document, QDomElement &element) override;
void loadSettings (const QDomElement &element) override;

QString nodeName() const override {return "Vectorscope";}
int controlCount() override {return 3;}

private:
Vectorscope *m_effect;

FloatModel m_persistenceModel;
BoolModel m_logarithmicModel;
BoolModel m_highQualityModel;

QColor m_colorFG;
QColor m_colorGrid;
QColor m_colorLabels;
QColor m_colorOutline;
Copy link
Member

Choose a reason for hiding this comment

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

Did you use tabs after QColor intentionally?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh; probably not, I'm used to align signal definitions in VHDL so I may have done this without even realizing it. :))
I will fix it here and also in SaControls.h (where it originally came from). Good catch, thanks. :)


friend class VecControlsDialog;
friend class VectorView;
};
#endif // VECCONTROLS_H
94 changes: 94 additions & 0 deletions plugins/Vectorscope/VecControlsDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* VecControlsDialog.cpp - definition of VecControlsDialog class.
*
* Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#include "VecControlsDialog.h"

#include <QGridLayout>
#include <QLabel>
#include <QResizeEvent>
#include <QSizePolicy>
#include <QWidget>

#include "embed.h"
#include "LedCheckbox.h"
#include "VecControls.h"
#include "Vectorscope.h"
#include "VectorView.h"


// The entire GUI layout is built here.
VecControlsDialog::VecControlsDialog(VecControls *controls) :
EffectControlDialog(controls),
m_controls(controls)
{
QVBoxLayout *master_layout = new QVBoxLayout;
master_layout->setContentsMargins(0, 2, 0, 0);
setLayout(master_layout);

// Visualizer widget
// The size of 768 pixels seems to offer a good balance of speed, accuracy and trace thickness.
VectorView *display = new VectorView(controls, m_controls->m_effect->getBuffer(), 768, this);
master_layout->addWidget(display);

// Config area located inside visualizer
QVBoxLayout *internal_layout = new QVBoxLayout(display);
QHBoxLayout *config_layout = new QHBoxLayout();
QVBoxLayout *switch_layout = new QVBoxLayout();
internal_layout->addStretch();
internal_layout->addLayout(config_layout);
config_layout->addLayout(switch_layout);

// High-quality switch
LedCheckBox *highQualityButton = new LedCheckBox(tr("HQ"), this);
highQualityButton->setToolTip(tr("Double the resolution and simulate continuous analog-like trace."));
highQualityButton->setCheckable(true);
highQualityButton->setMinimumSize(70, 12);
highQualityButton->setModel(&controls->m_highQualityModel);
switch_layout->addWidget(highQualityButton);

// Log. scale switch
LedCheckBox *logarithmicButton = new LedCheckBox(tr("Log. scale"), this);
logarithmicButton->setToolTip(tr("Display amplitude on logarithmic scale to better see small values."));
logarithmicButton->setCheckable(true);
logarithmicButton->setMinimumSize(70, 12);
logarithmicButton->setModel(&controls->m_logarithmicModel);
switch_layout->addWidget(logarithmicButton);

config_layout->addStretch();

// Persistence knob
Knob *persistenceKnob = new Knob(knobSmall_17, this);
persistenceKnob->setModel(&controls->m_persistenceModel);
persistenceKnob->setLabel(tr("Persist."));
persistenceKnob->setToolTip(tr("Trace persistence: higher amount means the trace will stay bright for longer time."));
persistenceKnob->setHintText(tr("Trace persistence"), "");
config_layout->addWidget(persistenceKnob);
}


// Suggest the best widget size.
QSize VecControlsDialog::sizeHint() const
{
return QSize(275, 300);
}
47 changes: 47 additions & 0 deletions plugins/Vectorscope/VecControlsDialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* VecControlsDialog.h - declatation of VecControlsDialog class.
*
* Copyright (c) 2019 Martin Pavelek <he29/dot/HS/at/gmail/dot/com>
*
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/

#ifndef VECCONTROLSDIALOG_H
#define VECCONTROLSDIALOG_H

#include "EffectControlDialog.h"

class VecControls;

//! Top-level widget holding the configuration GUI and vector display
class VecControlsDialog : public EffectControlDialog
{
Q_OBJECT
public:
explicit VecControlsDialog(VecControls *controls);
virtual ~VecControlsDialog() {}

bool isResizable() const override {return true;}
QSize sizeHint() const override;

private:
VecControls *m_controls;
};

#endif // VECCONTROLSDIALOG_H
Loading