Skip to content

Commit

Permalink
Add the vectorscope plugin (#5328)
Browse files Browse the repository at this point in the history
The credit for the `ColorChooser` class goes to CYBERDEViLNL.
  • Loading branch information
he29-net authored Feb 7, 2020
1 parent 8679f79 commit 89d8363
Show file tree
Hide file tree
Showing 14 changed files with 883 additions and 7 deletions.
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);
}
};
14 changes: 7 additions & 7 deletions plugins/SpectrumAnalyzer/SaControls.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ class SaControls : public EffectControls
FloatModel m_zeroPaddingModel;

// colors (hard-coded, values must add up to specific numbers)
QColor m_colorL; //!< color of the left channel
QColor m_colorR; //!< color of the right channel
QColor m_colorMono; //!< mono color for spectrum display
QColor m_colorMonoW; //!< mono color for waterfall display
QColor m_colorBG; //!< spectrum display background color
QColor m_colorGrid; //!< color of grid lines
QColor m_colorLabels; //!< color of axis labels
QColor m_colorL; //!< color of the left channel
QColor m_colorR; //!< color of the right channel
QColor m_colorMono; //!< mono color for spectrum display
QColor m_colorMonoW; //!< mono color for waterfall display
QColor m_colorBG; //!< spectrum display background color
QColor m_colorGrid; //!< color of grid lines
QColor m_colorLabels; //!< color of axis labels

friend class SaControlsDialog;
friend class SaSpectrumView;
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;

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

0 comments on commit 89d8363

Please sign in to comment.