From d424eaa955dbd2514dc70037d0412b02f0c24cb0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 20 Feb 2024 18:06:46 +0100 Subject: [PATCH 001/184] initial_implementation_of_pointgraph_widget --- include/PointGraph.h | 276 ++++++++++ src/gui/CMakeLists.txt | 1 + src/gui/widgets/PointGraph.cpp | 978 +++++++++++++++++++++++++++++++++ 3 files changed, 1255 insertions(+) create mode 100644 include/PointGraph.h create mode 100644 src/gui/widgets/PointGraph.cpp diff --git a/include/PointGraph.h b/include/PointGraph.h new file mode 100644 index 00000000000..751abf107e0 --- /dev/null +++ b/include/PointGraph.h @@ -0,0 +1,276 @@ + +#ifndef LMMS_GUI_POINTGRAPH_H +#define LMMS_GUI_POINTGRAPH_H + +#include +#include +#include +#include + +#include "Model.h" +#include "ModelView.h" +#include "lmms_basics.h" + +namespace lmms +{ + +class PointGraphModel; +class PointGraphDataArray; + +namespace gui +{ + +class LMMS_EXPORT PointGraphView : public QWidget, public ModelView +{ + Q_OBJECT +public: + // fake styles, update setStyle when adding new styles + enum class Style + { + Linear, // just lines + LinearPoints, // linear + draw data/sample points + Curved, // curved lines + CurvedPoints, // curced lines + draw data/sample points + }; + + PointGraphView(QWidget * parentIn, + int widthIn, int heightIn, + unsigned int pointSizeIn, unsigned int maxLengthIn, + Style styleIn); + ~PointGraphView(); + + void setStyle(Style styleIn, unsigned int dataArrayLocationIn); + void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); + void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); + void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); + + inline PointGraphModel* model() + { + return castModel(); + } + + // returns -2.0f at second when nothing is selected + std::pair getSelectedData(); + void setSelectedData(std::pair dataIn); + +signals: + inline void drawn(); +protected: + void paintEvent(QPaintEvent* pe) override; //TODO + //void dropEvent(QDropEvent* de) override; //ignore + //void dragEnterEvent(QDragEnterEvent* dee) override; //ignore + void mousePressEvent(QMouseEvent* me) override; //TODO + void mouseMoveEvent(QMouseEvent* me) override; //TODO + void mouseReleaseEvent(QMouseEvent* me) override; //TODO + void mouseDoubleClickEvent(QMouseEvent* me) override; +protected slots: + void updateGraph(); +private: + void modelChanged() override; + + std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); + std::pair mapDataPos(std::pair posIn, bool nonNegativeIn); + + float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); + + std::pair showInputDialog(); //TODO + void selectData(int mouseXIn, int mouseYIn); + + bool m_mouseDown; + bool m_mouseDrag; + // if the mouse is not moved + bool m_mousePress; + // decides addition or deletion + bool m_addition; + + // radius, rx = ry + unsigned int m_pointSize; + + unsigned int m_selectedLocation; + unsigned int m_selectedArray; + bool m_isSelected; + + std::pair m_lastTrackPoint; + std::pair m_lastScndTrackPoint; + + Style m_defaultStyle; // TODO +}; + +} // namespace gui + +class LMMS_EXPORT PointGraphModel : public Model +{ +Q_OBJECT +public: + PointGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn); + ~PointGraphModel(); + + inline size_t getDataArraySize() + { + return m_dataArrays.size(); + } + inline PointGraphDataArray* getDataArray(unsigned int locationIn) + { + return &m_dataArrays[locationIn]; + } + inline unsigned int getMaxLength() + { + return m_maxLength; + } + inline void setMaxLength(unsigned int maxLengthIn) + { + if (m_maxLength != maxLengthIn) + { + m_maxLength = maxLengthIn; + emit dataChanged(); + } + } + // returns location + unsigned int addArray(std::vector>* arrayIn); + // returns location + unsigned int addArray(); + // preservs the order + void delArray(unsigned int locationIn); // TODO + inline void clearArray() + { + m_dataArrays.clear(); + } + + // save, load + //void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO + //void loadSettings(const QDomElement& element, const QString& name); //TODO +signals: + // data changed inside m_dataArray or m_maxLength changed + void dataChanged(); + // style changed inside m_dataArray + void styleChanged(); + // m_dataArrays length changed + void lengthChanged(); +public slots: + void dataArrayChanged(); + void dataArrayStyleChanged(); +private: + std::vector m_dataArrays; + unsigned int m_maxLength; + + friend class gui::PointGraphView; +}; + +class LMMS_EXPORT PointGraphDataArray +{ + +public: + enum class Style + { + Linear, // just lines + LinearPoints, // linear + draw data/sample points + Curved, // curved lines + CurvedPoints, // curced lines + draw data/sample points + }; + + PointGraphDataArray(); + PointGraphDataArray(unsigned int* maxLengthIn, Style graphStyleIn, + bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, + PointGraphModel* parentIn); + ~PointGraphDataArray(); + + void updateConnections(PointGraphModel* parentIn); + + void setFixedSize(bool valueIn); + void setFixedValue(bool valueIn); + void setFixedPos(bool valueIn); + void setNonNegative(bool valueIn); + void setLineColor(QColor colorIn); + void setActiveColor(QColor colorIn); + void setFillColor(QColor colorIn); + void setStyle(Style graphStyleIn); + void setMaxLength(unsigned int* maxLengthIn); + + bool getFixedSize(); + bool getFixedValue(); + bool getFixedPos(); + bool getNonNegative(); + QColor* getLineColor(); + QColor* getActiveColor(); + QColor* getFillColor(); + Style getStyle(); + + // array: + // returns the location of added/found point, -1 if not found and can not be added + int add(unsigned int posIn); + // deletes the data/sample if m_isFixedSize is disabled + void del(unsigned int locationIn); + // clears data/sample array without any checks + inline void clear() + { + m_dataArray.clear(); + } + inline size_t size() + { + return m_dataArray.size(); + } + // clamps down the values to 0 - m_maxLength, -1 - 1, does not sort + // does check m_isFixedSize, m_isFixedValue, m_isFixedPos, + // sorts array, removes duplicated positions, + // clampIn: should clamp, sortIn: should sort + void formatArray(bool clampIn, bool sortIn); + + // get: + inline std::pair* getData(unsigned int locationIn) + { + return &m_dataArray[locationIn]; + } + // returns -1 when position is not found + int getLocation(unsigned int posIn); + // gets the nearest data location to the position, + // foundOut is true when the nearest position = posIn, + // reurns -1 when search failed + int getNearestLocation(unsigned int posIn, bool* foundOut); + float getValueAtPositon(float posIn); // TODO + + // set: + // sets data array without any checks + inline void setDataArray(std::vector>* dataArrayIn) + { + m_dataArray = *dataArrayIn; + } + // sets value when m_isFixedValue is disabed + void setValue(unsigned int locationIn, float valueIn); + // sets position when m_isFixedPos is disabed, returns final location + unsigned int setPos(unsigned int locationIn, unsigned int posIn); +// signals: // not qt + // m_dataArray + void dataChanged(); + // color and style + void styleChanged(); +private: + // swapping values, slide moves the values ()between) once left or right + void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); + + // can new data be added or removed + bool m_isFixedSize; + // can the values be changed + bool m_isFixedValue; + // can the positions be changed + bool m_isFixedPos; + + // can values be less than 0 + bool m_nonNegative; + + QColor m_lineColor; + QColor m_activeColor; + QColor m_fillColor; + + Style m_graphStyle; + + PointGraphModel* m_parent; + + unsigned int* m_maxLength; + + // ordered array of 0 < position < max_Length, -1(or 0) < value < 1 + std::vector> m_dataArray; +}; + +} // namespace lmms + +#endif // LMMS_POINTGRAPH_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index fe4a2c462b2..09fdcf59263 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -120,6 +120,7 @@ SET(LMMS_SRCS gui/widgets/Oscilloscope.cpp gui/widgets/PeakIndicator.cpp gui/widgets/PixmapButton.cpp + gui/widgets/PointGraph.cpp gui/widgets/SimpleTextFloat.cpp gui/widgets/TabBar.cpp gui/widgets/TabWidget.cpp diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp new file mode 100644 index 00000000000..88989610278 --- /dev/null +++ b/src/gui/widgets/PointGraph.cpp @@ -0,0 +1,978 @@ + + +#include +#include +#include +#include +#include +#include + +#include "PointGraph.h" + + +namespace lmms +{ + +namespace gui +{ + +PointGraphView::PointGraphView(QWidget * parentIn, + int widthIn, int heightIn, + unsigned int pointSizeIn, unsigned int maxLengthIn, + Style styleIn) : + QWidget(parentIn), + ModelView(new PointGraphModel(maxLengthIn, nullptr, false), this) +{ + resize(widthIn, heightIn); + + m_mouseDown = false; + m_mouseDrag = false; + m_mousePress = false; + m_addition = false; + + m_pointSize = pointSizeIn; + + m_selectedLocation = 0; + m_selectedArray = 0; + m_isSelected = false; + + m_lastTrackPoint.first = 0; + m_lastTrackPoint.second = 0; + m_lastScndTrackPoint.first = 0; + m_lastScndTrackPoint.second = 0; + + m_defaultStyle = styleIn; + + setCursor(Qt::CrossCursor); + + auto gModel = model(); + + QObject::connect(gModel, SIGNAL(dataChanged()), + this, SLOT(updateGraph())); + QObject::connect(gModel, SIGNAL(lengthChanged()), + this, SLOT(updateGraph())); +} +PointGraphView::~PointGraphView() +{ + +} + +// update this when adding new styles +void PointGraphView::setStyle(Style styleIn, unsigned int dataArrayLocationIn) +{ + if (model()->getDataArraySize() > dataArrayLocationIn) + { + switch (styleIn) + { + case Style::Linear: + model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::Linear); + break; + case Style::LinearPoints: + model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::LinearPoints); + break; + case Style::Curved: + model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::Curved); + break; + case Style::CurvedPoints: + model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::CurvedPoints); + break; + default: + break; + } + update(); + } +} +void PointGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) +{ + if (model()->getDataArraySize() > dataArrayLocationIn) + { + model()->getDataArray(dataArrayLocationIn)->setLineColor(colorIn); + update(); + } +} +void PointGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn) +{ + if (model()->getDataArraySize() > dataArrayLocationIn) + { + model()->getDataArray(dataArrayLocationIn)->setActiveColor(colorIn); + update(); + } +} +void PointGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocationIn) +{ + if (model()->getDataArraySize() > dataArrayLocationIn) + { + model()->getDataArray(dataArrayLocationIn)->setFillColor(colorIn); + update(); + } +} + +std::pair PointGraphView::getSelectedData() +{ + std::pair output(0, -2.0f); + if (m_isSelected == true) + { + output = *model()->getDataArray(m_selectedArray)->getData(m_selectedLocation); + } + return output; +} +void PointGraphView::setSelectedData(std::pair dataIn) +{ + if (m_isSelected == true) + { + qDebug("setSelectedData"); + model()->getDataArray(m_selectedArray)->setValue(m_selectedLocation, dataIn.second); + qDebug("set value done"); + model()->getDataArray(m_selectedArray)->setPos(m_selectedLocation, dataIn.first); + qDebug("set position done"); + m_isSelected = false; + } +} + +void PointGraphView::mousePressEvent(QMouseEvent* me) +{ + // get position + int x = me->x(); + int y = me->y(); + if (me->button() == Qt::LeftButton) + { + // add + m_addition = true; + // show new inputDialog to change data if control is pressed + if ((me->modifiers() & Qt::ControlModifier) == true) + { + selectData(x, y); + // if selecting was successful + if (m_isSelected == true) + { + // display dialog + std::pair curData = showInputDialog(); + // change data + setSelectedData(curData); + } + } + else + { + m_mousePress = true; + } + } + else if (me->button() == Qt::RightButton) + { + // delete + m_addition = false; + m_mousePress = true; + } + m_mouseDown = true; + qDebug("mousePressEnd ---------"); +} + +void PointGraphView::mouseMoveEvent(QMouseEvent* me) +{ + // get position + int x = me->x(); + int y = me->y(); + m_mousePress = false; +} + +void PointGraphView::mouseReleaseEvent(QMouseEvent* me) +{ + // get position + int x = me->x(); + int y = me->y(); + if (m_mousePress == true) + { + // add/delete point + selectData(x, y); + if (m_isSelected == false && m_addition == true) + { + // if selection failed and addition + // get the first editable daraArray and add value + qDebug("release size: %ld", model()->getDataArraySize()); + for(unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + std::pair curMouseData = mapMousePos(x, y, + model()->getDataArray(i)->getNonNegative()); // TODO optimize + int location = model()->getDataArray(i)->add(curMouseData.first); + // if adding was successful + if (location >= 0) + { + qDebug("mouseRelease added %d", location); + model()->getDataArray(i)->setValue(location, curMouseData.second); + break; + } + } + } + else if (m_isSelected == true && m_addition == false) + { + // if selection was successful and deletion + model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + } + + m_mousePress = false; + } + else + { + // add/set/delete line end + + } + m_addition = false; + m_mouseDown = false; + m_mouseDrag = false; + // triggering paintEvent + qDebug("mouseReleaseEnd"); + update(); + emit drawn(); +} + +void PointGraphView::mouseDoubleClickEvent(QMouseEvent * me) +{ + // if a data/sample is selected then show input dialog to change the data + if (m_isSelected == true && me->button() == Qt::LeftButton) + { + // display dialog + std::pair curData = showInputDialog(); + // change data + setSelectedData(curData); + } +} + +void PointGraphView::paintEvent(QPaintEvent* pe) +{ + QPainter p(this); + //QPainterPath pt(); // TODO + + qDebug("paintEvent"); + + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + PointGraphDataArray* dataArray = model()->getDataArray(i); + p.setPen(QPen(*dataArray->getLineColor(), 1)); + QColor gcolor = QColor(dataArray->getLineColor()->red(), dataArray->getLineColor()->green(), + dataArray->getLineColor()->blue(), 100); + + unsigned int length = dataArray->size(); + + if (m_isSelected == true) + { + p.drawLine(10, 10, 20, 20); + } + + std::pair posB(0, 0); + if (length > 0) + { + std::pair posA = mapDataPos(*dataArray->getData(0), dataArray->getNonNegative()); + + switch (dataArray->getStyle()) + { + case PointGraphDataArray::Style::Linear: + // if first data/sample > 0, draw a line to the first data/sample from 0 + if (posA.first > 0) + { + //p.drawLine(0, posA.second, posA.first, posA.second); + } + // drawing lines + qDebug("paint size: %d", length); + for (unsigned int j = 0; j < length - 1; j++) + { + std::pair posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); + // x1, y1, x2, y2 + //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); + p.drawLine(posA.first, posA.second, posB.first, posB.second); + posA = posB; + } + if (posA.first < width()) + { + //p.drawLine(posA.first, posA.second, width(), posA.second); + } + break; + case PointGraphDataArray::Style::LinearPoints: + break; + case PointGraphDataArray::Style::Curved: + break; + case PointGraphDataArray::Style::CurvedPoints: + break; + default: + break; + } + } + } +} + +void PointGraphView::modelChanged() +{ + auto gModel = model(); + QObject::connect(gModel, SIGNAL(dataChanged()), + this, SLOT(updateGraph())); + QObject::connect(gModel, SIGNAL(lengthChanged()), + this, SLOT(updateGraph())); +} + +void PointGraphView::updateGraph() +{ + update(); +} + +std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) +{ + if (nonNegativeIn == true) + { + // mapping the position to 0 - m_maxLength, 0 - 1 using qWidget width and height + return std::pair( + static_cast(xIn * (model()->getMaxLength() - 1) / width()), + static_cast(yIn / (float)height())); + } + else + { + // mapping the position to 0 - m_maxLength, -1 - 1 using qWidget width and height + return std::pair( + static_cast(xIn * (model()->getMaxLength() - 1) / width()), + static_cast((yIn * 2.0f / (float)height()) - 1.0f)); + } +} +std::pair PointGraphView::mapDataPos(std::pair posIn, + bool nonNegativeIn) +{ + if (nonNegativeIn == true) + { + // mapping the point/sample positon to mouse/view position + return std::pair( + static_cast(posIn.first * width() / model()->getMaxLength()), + static_cast(posIn.second * height())); + } + else + { + // mapping the point/sample positon to mouse/view position + return std::pair( + static_cast(posIn.first * width() / model()->getMaxLength()), + static_cast((posIn.second / 2.0f + 0.5f) * height())); + } +} + +float PointGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) +{ + return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); +} + +std::pair PointGraphView::showInputDialog() +{ + std::pair curData(0, 0.0f); + if (m_isSelected == true) + { + curData = getSelectedData(); + double minValue = model()->getDataArray(m_selectedArray)->getNonNegative() == true ? 0.0 : -1.0; + + // show position input dialog + bool ok; + double changedPos = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between 0 and ") + QString::number(model()->getMaxLength()), + static_cast(curData.first), + 0.0, static_cast(model()->getMaxLength()), 0, &ok); + if (ok == true) + { + curData.first = static_cast(changedPos); + } + + double changedValue = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between") + QString::number(minValue) + tr(" and 1.0"), + static_cast(curData.second), + minValue, 1.0, 2, &ok); + if (ok == true) + { + curData.second = static_cast(changedValue); + } + } + return curData; +} + +void PointGraphView::selectData(int mouseXIn, int mouseYIn) +{ + qDebug("selectData"); + //float minDistance = m_pointSize + 1.0; + m_selectedLocation = 0; + m_selectedArray = 0; + m_isSelected = false; + + std::pair transformedMouseA = mapMousePos(mouseXIn, mouseYIn, false); + std::pair transformedMouseB = mapMousePos(mouseXIn, mouseYIn, true); + std::pair* transformedMouse = &transformedMouseA; + + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + PointGraphDataArray* dataArray = model()->getDataArray(i); + if (dataArray->getNonNegative() == true) + { + transformedMouse = &transformedMouseB; + } + else + { + transformedMouse = &transformedMouseA; + } + if (dataArray->getFixedSize() == false || + dataArray->getFixedValue() == false || + dataArray->getFixedPos() == false) + { + // we dont use this bool + bool found = false; + // get the nearest data to the mouse pos (x) in an optimalized way + int location = dataArray->getNearestLocation(transformedMouse->first, &found); + qDebug("selected location: %d", location); + + // if getNearestLocation was successful + if (location >= 0) + { + std::pair transformedData = mapDataPos(*dataArray->getData(location), + dataArray->getNonNegative()); + // check distance against the pos (x) + qDebug("selected x distance: %d", std::abs(transformedData.first - mouseXIn)); + if (std::abs(static_cast(transformedData.first) - mouseXIn) <= m_pointSize * 2) + { + // calculate real distance (x and y) + qDebug("selected cords: %d, %d, %d, %d", mouseXIn, mouseYIn, + transformedData.first, transformedData.second); + float curDistance = getDistance(mouseXIn, mouseYIn, + transformedData.first, transformedData.second); + + qDebug("selected full distance: %f", curDistance); + if (curDistance <= m_pointSize) + { + qDebug("selection Made!"); + m_selectedLocation = location; + m_selectedArray = i; + m_isSelected = true; + break; + } + } + } +/* + for (unsigned int j = 0; j < dataArray->size(); j++) + { + std::pair* data = dataArray->getData(j); + std::pair transformedData = mapDataPos(*data, dataArray->getNonNegative()) + float curDistance = getDistance(transformedData.first, mouseXIn, + transformedData.second, mouseYIn); + if (curDistance <= m_pointSize)// && curDistance < minDistance) + { + //minDistance = curDistance; + m_selectedLocation = j; + m_selectedArray = i; + m_isSelected = true; + break; + } + } + if (m_isSelected == true) + { + break; + }*/ + } + } + qDebug("selectDataEnd"); +} + +} // namespace gui + +PointGraphModel::PointGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn) : + Model(parentIn, tr("PointGraphModel"), defaultConstructedIn) +{ + m_maxLength = maxLengthIn; + m_dataArrays = {}; +} + +PointGraphModel::~PointGraphModel() +{ + m_dataArrays.clear(); +} + +unsigned int PointGraphModel::addArray(std::vector>* arrayIn) +{ + unsigned int location = addArray(); + m_dataArrays[location].setDataArray(arrayIn); + return location; +} + +unsigned int PointGraphModel::addArray() +{ + PointGraphDataArray tempArray(&m_maxLength, PointGraphDataArray::Style::Linear, + false, false, false, false, this); + m_dataArrays.push_back(tempArray); + return m_dataArrays.size() - 1; +} + +void PointGraphModel::delArray(unsigned int locationIn) +{ + for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) + { + m_dataArrays[i] = m_dataArrays[i + 1]; + } + m_dataArrays.pop_back(); +} + +void PointGraphModel::dataArrayChanged() +{ + emit dataChanged(); +} + +void PointGraphModel::dataArrayStyleChanged() +{ + emit styleChanged(); +} + +// PointGraphDataArray ------ + +PointGraphDataArray::PointGraphDataArray() +{ + m_maxLength = nullptr; + m_graphStyle = Style::Linear; + m_isFixedSize = false; + m_isFixedValue = false; + m_isFixedPos = false; + m_nonNegative = false; + + m_lineColor = QColor(200, 200, 200, 255); + m_activeColor = QColor(255, 255, 255, 255); + // is not enabled by default + m_fillColor = QColor(0, 0, 0, 0); + + m_dataArray = {}; +} + +PointGraphDataArray::PointGraphDataArray(unsigned int* maxLengthIn, Style graphStyleIn, + bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, + PointGraphModel* parentIn) +{ + m_maxLength = maxLengthIn; + m_graphStyle = graphStyleIn; + m_isFixedSize = isFixedSizeIn; + m_isFixedValue = isFixedValueIn; + m_isFixedPos = isFixedPosIn; + m_nonNegative = nonNegativeIn; + + m_lineColor = QColor(200, 200, 200, 255); + m_activeColor = QColor(255, 255, 255, 255); + // is not enabled by default + m_fillColor = QColor(0, 0, 0, 0); + + m_dataArray = {}; + + updateConnections(parentIn); +} + +PointGraphDataArray::~PointGraphDataArray() +{ + m_dataArray.clear(); +} + +void PointGraphDataArray::updateConnections(PointGraphModel* parentIn) +{ + // call PointGraphModel signals without qt + m_parent = parentIn; +} + +void PointGraphDataArray::setFixedSize(bool valueIn) +{ + m_isFixedSize = valueIn; + dataChanged(); +} +void PointGraphDataArray::setFixedValue(bool valueIn) +{ + m_isFixedValue = valueIn; + dataChanged(); +} +void PointGraphDataArray::setFixedPos(bool valueIn) +{ + m_isFixedPos = valueIn; + dataChanged(); +} +void PointGraphDataArray::setNonNegative(bool valueIn) +{ + m_nonNegative = valueIn; + dataChanged(); +} +void PointGraphDataArray::setLineColor(QColor colorIn) +{ + m_lineColor = colorIn; + styleChanged(); +} +void PointGraphDataArray::setActiveColor(QColor colorIn) +{ + m_activeColor = colorIn; + styleChanged(); +} +void PointGraphDataArray::setFillColor(QColor colorIn) +{ + m_fillColor = colorIn; + styleChanged(); +} +void PointGraphDataArray::setStyle(Style styleIn) +{ + m_graphStyle = styleIn; + styleChanged(); +} +void PointGraphDataArray::setMaxLength(unsigned int* maxLengthIn) +{ + m_maxLength = maxLengthIn; +} + +bool PointGraphDataArray::getFixedSize() +{ + return m_isFixedSize; +} +bool PointGraphDataArray::getFixedValue() +{ + return m_isFixedValue; +} +bool PointGraphDataArray::getFixedPos() +{ + return m_isFixedPos; +} +bool PointGraphDataArray::getNonNegative() +{ + return m_nonNegative; +} +QColor* PointGraphDataArray::getLineColor() +{ + return &m_lineColor; +} +QColor* PointGraphDataArray::getActiveColor() +{ + return &m_activeColor; +} +QColor* PointGraphDataArray::getFillColor() +{ + return &m_fillColor; +} +PointGraphDataArray::Style PointGraphDataArray::getStyle() +{ + return m_graphStyle; +} + +// array: + +int PointGraphDataArray::add(unsigned int posIn) +{ + int location = -1; + if (posIn < *m_maxLength) + { + qDebug("add 1. success"); + bool found = false; + location = getNearestLocation(posIn, &found); + if (found == false && m_isFixedSize == false) + { + qDebug("add 2. success, nearest: %d", location); + int targetLocation = -1; + bool dataChangedVal = false; + // if getNearestLocation returned a value + if (location >= 0) + { + qDebug("add 3. success, nearest: %d", location); + targetLocation = location; + // slide the new data if the closest data pos is bigger + if (m_dataArray[location].first < posIn) + { + // we are adding one value, so dataArray.size() will be a valid location + if (targetLocation < m_dataArray.size()) + { + targetLocation++; + } + } + m_dataArray.push_back(std::pair(posIn, 0.0f)); + qDebug("add 4. success, target: %d", targetLocation); + swap(m_dataArray.size() - 1, targetLocation, true); + dataChangedVal = true; + } + else if (m_dataArray.size() <= 0) + { + qDebug("add 5. success"); + m_dataArray.push_back(std::pair(posIn, 0.0f)); + targetLocation = 0; + dataChangedVal = true; + } + qDebug("add size: %ld", m_dataArray.size()); + location = targetLocation; + if (dataChangedVal == true) + { + dataChanged(); + } + } + } + return location; +} + +void PointGraphDataArray::del(unsigned int locationIn) +{ + if (m_isFixedSize == false && locationIn < m_dataArray.size()) + { + swap(locationIn, m_dataArray.size() - 1, true); + m_dataArray.pop_back(); + dataChanged(); + } +} + +void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) +{ + // clamp + if (clampIn == true) + { + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].first > *m_maxLength) + { + m_dataArray[i].first = *m_maxLength; + } + if (m_dataArray[i].second > 1) + { + m_dataArray[i].second = 1; + } + if (m_nonNegative == true) + { + if (m_dataArray[i].second < 0) + { + m_dataArray[i].second = 0; + } + } + else + { + if (m_dataArray[i].second < -1) + { + m_dataArray[i].second = -1; + } + } + } + } + + // sort + if (sortIn == true) + { + std::sort(m_dataArray.begin(), m_dataArray.end(), + [](std::pair a, std::pair b) + { + return a.first > b.first; + }); + } + + // delete duplicates + unsigned int lastPos = 0; + if (m_dataArray.size() > 0) + { + lastPos = m_dataArray[0].first; + } + for (unsigned int i = 1; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].first == lastPos) + { + del(i); + } + else + { + lastPos = m_dataArray[i].first; + } + } +} + +int PointGraphDataArray::getLocation(unsigned int posIn) +{ + bool found = false; + int location = getNearestLocation(posIn, &found); + if (found == false) + { + return -1; + } + return location; +} + +int PointGraphDataArray::getNearestLocation(unsigned int posIn, bool* foundOut) +{ + if (posIn < *m_maxLength && m_dataArray.size() > 0) + { + int start = 0; + int end = m_dataArray.size() - 1; + int mid = 0; + // binary search + while (start < end) + { + mid = start + (end - start) / 2; + qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); + qDebug("getNearestLocation, val: %d, pos: %d", m_dataArray[mid].first, posIn); + if (m_dataArray[mid].first == posIn) + { + *foundOut = true; + return mid; + } + else if (m_dataArray[mid].first < posIn) + { + start = mid + 1; + } + else + { + end = mid - 1; + } + } + int outputDif = 0; + mid = start + (end - start) / 2; + if (m_dataArray[mid].first > posIn && mid > 0) + { + mid = mid - 1; + } + if (mid + 1 < m_dataArray.size() && + std::abs(static_cast(m_dataArray[mid].first) - static_cast(posIn)) > + std::abs(static_cast(m_dataArray[mid + 1].first) - static_cast(posIn))) + { + outputDif = 1; + } + qDebug("getNearestLocation, outputDif: %d", outputDif); + *foundOut = false; + return mid + outputDif; + } + qDebug("getNearestLocation, posIn: %d", posIn); + *foundOut = false; + return -1; +} + +float PointGraphDataArray::getValueAtPositon(float posIn) +{ + float posB = posIn / static_cast(*m_maxLength); + bool found = false; + unsigned int location = getNearestLocation(static_cast(posIn), &found); + if (location >= 0) + { + if (found == true) + { + return m_dataArray[location].second; + } + else if (m_dataArray.size() == 1) + { + return m_dataArray[0].second; + } + else + { + float posC = posB - static_cast(static_cast(posB)); + int slide = 1; + float value = 0.0f; + if (location == m_dataArray.size() - 1) + { + slide = -1; + } + if (m_graphStyle == Style::Linear && m_graphStyle == Style::LinearPoints) + { + // if linear + value = m_dataArray[location].second * posC + m_dataArray[location + slide].second * (1.0f - posC); + } + else + { + // if curved TODO + + } + return value; + } + } +} + +void PointGraphDataArray::setValue(unsigned int locationIn, float valueIn) +{ + if (m_isFixedValue == false) + { + m_dataArray[locationIn].second = valueIn; + dataChanged(); + } +} + +unsigned int PointGraphDataArray::setPos(unsigned int locationIn, unsigned int posIn) +{ + int location = locationIn; + if (posIn < *m_maxLength) + { + bool found = false; + location = getNearestLocation(posIn, &found); + if (found == false && m_isFixedPos == false) + { + int targetLocation = location; + bool dataChangedVal = false; + // if getNearestLocation returned a value + if (location >= 0) + { + // slide the new data if the closest data pos is bigger + qDebug("set 3. success, location: %d", targetLocation); + //if (m_dataArray[location].first < posIn) + //{ + // if (targetLocation + 1 < m_dataArray.size()) + // { + // targetLocation++; + // } + //} + qDebug("set 4. success, target: %d", targetLocation); + m_dataArray[locationIn].first = posIn; + swap(locationIn, targetLocation, true); + location = targetLocation; + dataChanged(); + } + else + { + location = locationIn; + } + } + else + { + location = locationIn; + } + } + return location; +} + +void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) +{ + if (locationAIn != locationBIn) + { + if (slide == true) + { + qDebug("swap: -------"); + qDebug("first.: %d, second.: %d", locationAIn, locationBIn); + + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %d", i, m_dataArray[i].first); + } + + if (locationAIn < locationBIn) + { + std::pair swap = m_dataArray[locationAIn]; + for (unsigned int i = locationAIn; i < locationBIn; i++) + { + m_dataArray[i] = m_dataArray[i + 1]; + } + m_dataArray[locationBIn] = swap; + } + else + { + std::pair swap = m_dataArray[locationAIn]; + for (unsigned int i = locationAIn; i > locationBIn; i--) + { + m_dataArray[i] = m_dataArray[i - 1]; + } + m_dataArray[locationBIn] = swap; + } + + qDebug(" --------- "); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %d", i, m_dataArray[i].first); + } + } + else + { + std::pair swap = m_dataArray[locationAIn]; + m_dataArray[locationAIn] = m_dataArray[locationBIn]; + m_dataArray[locationBIn] = swap; + } + dataChanged(); + } +} + +void PointGraphDataArray::dataChanged() +{ + m_parent->dataArrayChanged(); +} +void PointGraphDataArray::styleChanged() +{ + m_parent->dataArrayStyleChanged(); +} + +} // namespace lmms From 85714441670842163d440948400b4aea3b66a1b5 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 24 Feb 2024 12:14:06 +0100 Subject: [PATCH 002/184] removed_styles_form_pointgraph --- include/PointGraph.h | 47 ++++++++--------- src/gui/widgets/PointGraph.cpp | 94 ++++++++-------------------------- 2 files changed, 42 insertions(+), 99 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 751abf107e0..9e0ef3ee3d7 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -24,22 +24,29 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView { Q_OBJECT public: - // fake styles, update setStyle when adding new styles - enum class Style - { - Linear, // just lines - LinearPoints, // linear + draw data/sample points - Curved, // curved lines - CurvedPoints, // curced lines + draw data/sample points - }; + // TODO: remove styles + // TODO: change x to float + // TODO: revrite comments + // TODO: make a new class inside PointGraphDataArray to store the point data + // TODO: add is selectable + // TODO: add new setting to make the last point cord 1, 1 + // TODO: flip mouse y position + // TODO: function to get multiple values + + // TODO: automation: + // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 3 value long) + // TODO: add automation support + // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, valueA, valueB + // TODO setPointType(unsigned int type) + // TODO: add effector PointDataArray pointer to the PointDataArray class + // TODO: add effector line attreibutes to the nested class + // TODO: add effects PointGraphView(QWidget * parentIn, int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn, - Style styleIn); + unsigned int pointSizeIn, unsigned int maxLengthIn); ~PointGraphView(); - void setStyle(Style styleIn, unsigned int dataArrayLocationIn); void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); @@ -92,8 +99,6 @@ protected slots: std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; - - Style m_defaultStyle; // TODO }; } // namespace gui @@ -160,16 +165,8 @@ class LMMS_EXPORT PointGraphDataArray { public: - enum class Style - { - Linear, // just lines - LinearPoints, // linear + draw data/sample points - Curved, // curved lines - CurvedPoints, // curced lines + draw data/sample points - }; - PointGraphDataArray(); - PointGraphDataArray(unsigned int* maxLengthIn, Style graphStyleIn, + PointGraphDataArray(unsigned int* maxLengthIn, bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, PointGraphModel* parentIn); ~PointGraphDataArray(); @@ -183,7 +180,6 @@ class LMMS_EXPORT PointGraphDataArray void setLineColor(QColor colorIn); void setActiveColor(QColor colorIn); void setFillColor(QColor colorIn); - void setStyle(Style graphStyleIn); void setMaxLength(unsigned int* maxLengthIn); bool getFixedSize(); @@ -193,7 +189,6 @@ class LMMS_EXPORT PointGraphDataArray QColor* getLineColor(); QColor* getActiveColor(); QColor* getFillColor(); - Style getStyle(); // array: // returns the location of added/found point, -1 if not found and can not be added @@ -241,7 +236,7 @@ class LMMS_EXPORT PointGraphDataArray // signals: // not qt // m_dataArray void dataChanged(); - // color and style + // color void styleChanged(); private: // swapping values, slide moves the values ()between) once left or right @@ -261,8 +256,6 @@ class LMMS_EXPORT PointGraphDataArray QColor m_activeColor; QColor m_fillColor; - Style m_graphStyle; - PointGraphModel* m_parent; unsigned int* m_maxLength; diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index 88989610278..e2a0d86e04e 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -18,8 +18,7 @@ namespace gui PointGraphView::PointGraphView(QWidget * parentIn, int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn, - Style styleIn) : + unsigned int pointSizeIn, unsigned int maxLengthIn) : QWidget(parentIn), ModelView(new PointGraphModel(maxLengthIn, nullptr, false), this) { @@ -40,8 +39,6 @@ PointGraphView::PointGraphView(QWidget * parentIn, m_lastTrackPoint.second = 0; m_lastScndTrackPoint.first = 0; m_lastScndTrackPoint.second = 0; - - m_defaultStyle = styleIn; setCursor(Qt::CrossCursor); @@ -57,31 +54,6 @@ PointGraphView::~PointGraphView() } -// update this when adding new styles -void PointGraphView::setStyle(Style styleIn, unsigned int dataArrayLocationIn) -{ - if (model()->getDataArraySize() > dataArrayLocationIn) - { - switch (styleIn) - { - case Style::Linear: - model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::Linear); - break; - case Style::LinearPoints: - model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::LinearPoints); - break; - case Style::Curved: - model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::Curved); - break; - case Style::CurvedPoints: - model()->getDataArray(dataArrayLocationIn)->setStyle(PointGraphDataArray::Style::CurvedPoints); - break; - default: - break; - } - update(); - } -} void PointGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) { if (model()->getDataArraySize() > dataArrayLocationIn) @@ -262,37 +234,24 @@ void PointGraphView::paintEvent(QPaintEvent* pe) { std::pair posA = mapDataPos(*dataArray->getData(0), dataArray->getNonNegative()); - switch (dataArray->getStyle()) + // if first data/sample > 0, draw a line to the first data/sample from 0 + if (posA.first > 0) { - case PointGraphDataArray::Style::Linear: - // if first data/sample > 0, draw a line to the first data/sample from 0 - if (posA.first > 0) - { - //p.drawLine(0, posA.second, posA.first, posA.second); - } - // drawing lines - qDebug("paint size: %d", length); - for (unsigned int j = 0; j < length - 1; j++) - { - std::pair posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); - // x1, y1, x2, y2 - //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - p.drawLine(posA.first, posA.second, posB.first, posB.second); - posA = posB; - } - if (posA.first < width()) - { - //p.drawLine(posA.first, posA.second, width(), posA.second); - } - break; - case PointGraphDataArray::Style::LinearPoints: - break; - case PointGraphDataArray::Style::Curved: - break; - case PointGraphDataArray::Style::CurvedPoints: - break; - default: - break; + //p.drawLine(0, posA.second, posA.first, posA.second); + } + // drawing lines + qDebug("paint size: %d", length); + for (unsigned int j = 0; j < length - 1; j++) + { + std::pair posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); + // x1, y1, x2, y2 + //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); + p.drawLine(posA.first, posA.second, posB.first, posB.second); + posA = posB; + } + if (posA.first < width()) + { + //p.drawLine(posA.first, posA.second, width(), posA.second); } } } @@ -491,7 +450,7 @@ unsigned int PointGraphModel::addArray(std::vector Date: Sat, 24 Feb 2024 12:35:47 +0100 Subject: [PATCH 003/184] added_temp_plugin_for_testing --- cmake/modules/PluginList.cmake | 1 + plugins/FFTFilter/CMakeLists.txt | 3 + plugins/FFTFilter/FFTFilter.cpp | 218 +++++++++++++++++++ plugins/FFTFilter/FFTFilter.h | 93 ++++++++ plugins/FFTFilter/FFTFilterControlDialog.cpp | 130 +++++++++++ plugins/FFTFilter/FFTFilterControlDialog.h | 54 +++++ plugins/FFTFilter/FFTFilterControls.cpp | 74 +++++++ plugins/FFTFilter/FFTFilterControls.h | 88 ++++++++ plugins/FFTFilter/artwork.png | Bin 0 -> 7739 bytes plugins/FFTFilter/logo.png | Bin 0 -> 774 bytes 10 files changed, 661 insertions(+) create mode 100644 plugins/FFTFilter/CMakeLists.txt create mode 100644 plugins/FFTFilter/FFTFilter.cpp create mode 100644 plugins/FFTFilter/FFTFilter.h create mode 100644 plugins/FFTFilter/FFTFilterControlDialog.cpp create mode 100644 plugins/FFTFilter/FFTFilterControlDialog.h create mode 100644 plugins/FFTFilter/FFTFilterControls.cpp create mode 100644 plugins/FFTFilter/FFTFilterControls.h create mode 100644 plugins/FFTFilter/artwork.png create mode 100644 plugins/FFTFilter/logo.png diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake index 009679533ae..6e9b53a7a2d 100644 --- a/cmake/modules/PluginList.cmake +++ b/cmake/modules/PluginList.cmake @@ -38,6 +38,7 @@ SET(LMMS_PLUGIN_LIST DynamicsProcessor Eq Flanger + FFTFilter GranularPitchShifter HydrogenImport LadspaBrowser diff --git a/plugins/FFTFilter/CMakeLists.txt b/plugins/FFTFilter/CMakeLists.txt new file mode 100644 index 00000000000..01d3a4e2984 --- /dev/null +++ b/plugins/FFTFilter/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(FFTFilter FFTFilter.cpp FFTFilterControls.cpp FFTFilterControlDialog.cpp MOCFILES FFTFilterControls.h FFTFilterControlDialog.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp new file mode 100644 index 00000000000..fb808bef6d9 --- /dev/null +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -0,0 +1,218 @@ +/* + * Amplifier.cpp - A native amplifier effect plugin with sample-exact amplification + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2014 Tobias Doerffel + * + * 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 + +#include "FFTFilter.h" + +#include "embed.h" +#include "plugin_export.h" + +namespace lmms +{ + +extern "C" +{ + +Plugin::Descriptor PLUGIN_EXPORT FFTFilter_plugin_descriptor = +{ + LMMS_STRINGIFY(PLUGIN_NAME), + "FFTFilter", + QT_TRANSLATE_NOOP("PluginBrowser", "TEMP"), + "TEMP", + 0x0100, + Plugin::Type::Effect, + new PluginPixmapLoader("logo"), + nullptr, + nullptr, +} ; + +} + + +FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : + Effect(&FFTFilter_plugin_descriptor, parent, key), + m_filterControls(this) +{ +} + + +bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) +{ + if (!isEnabled() || !isRunning()) { return false ; } + + double outSum = 0.0; + const float d = dryLevel(); + const float w = wetLevel(); + + /* + const ValueBuffer* volumeBuf = m_filterControls.m_volumeModel.valueBuffer(); + const ValueBuffer* panBuf = m_filterControls.m_panModel.valueBuffer(); + const ValueBuffer* leftBuf = m_filterControls.m_leftModel.valueBuffer(); + const ValueBuffer* rightBuf = m_filterControls.m_rightModel.valueBuffer(); + + for (fpp_t f = 0; f < frames; ++f) + { + const float volume = (volumeBuf ? volumeBuf->value(f) : m_filterControls.m_volumeModel.value()) * 0.01f; + const float pan = (panBuf ? panBuf->value(f) : m_filterControls.m_panModel.value()) * 0.01f; + const float left = (leftBuf ? leftBuf->value(f) : m_filterControls.m_leftModel.value()) * 0.01f; + const float right = (rightBuf ? rightBuf->value(f) : m_filterControls.m_rightModel.value()) * 0.01f; + + const float panLeft = std::min(1.0f, 1.0f - pan); + const float panRight = std::min(1.0f, 1.0f + pan); + + auto s = std::array{buf[f][0], buf[f][1]}; + + s[0] *= volume * left * panLeft; + s[1] *= volume * right * panRight; + + buf[f][0] = d * buf[f][0] + w * s[0]; + buf[f][1] = d * buf[f][1] + w * s[1]; + outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; + } + */ + + checkGate(outSum / frames); + + return isRunning(); +} +void FFTFilterEffect::runFFTOnBuffer(std::vector* inputReIn, std::vector* inputImIn, std::vector bufferIn) +{ + +} +void FFTFilterEffect::FFT(std::vector* inputReIn, std::vector* inputImIn) +{ + unsigned int target = 0; + for (unsigned int i = 0; i < inputReIn->size(); i++) + { + if (target > i) + { + const sample_t swapRe = inputReIn->operator[](target); + const sample_t swapIm = inputImIn->operator[](target); + inputReIn->operator[](target) = inputReIn->operator[](i); + inputImIn->operator[](target) = inputImIn->operator[](i); + inputReIn->operator[](i) = swapRe; + inputImIn->operator[](i) = swapIm; + + if (target < inputReIn->size() / 2) + // if (target / 2 < inputReIn->size() / 4) + { + const sample_t swapRe = inputReIn->operator[](inputReIn->size() - (i + 1)); + const sample_t swapIm = inputImIn->operator[](inputReIn->size() - (i + 1)); + inputReIn->operator[](inputReIn->size() - (i + 1)) = + inputReIn->operator[](inputReIn->size() - (target + 1)); + inputImIn->operator[](inputReIn->size() - (i + 1)) = + inputImIn->operator[](inputReIn->size() - (target + 1)); + inputReIn->operator[](inputReIn->size() - (target + 1)) = swapRe; + inputImIn->operator[](inputReIn->size() - (target + 1)) = swapIm; + } + } + unsigned int mask = inputReIn->size(); + /* + while (target & (mask <<= 1)) + { + target &= ~mask; + } + target |= mask; + */ + while (mask >= 1 && target >= mask) + { + target = target - mask; + mask = mask / 2; + } + target += mask; + } + + for (unsigned int step = 1; step < inputReIn->size(); step <<=1) + { + const unsigned int jump = step << 1; + const float stepD = (float)step; + sample_t twiddleRe = 1.0f; + sample_t twiddleIm = 0.0f; + + for (unsigned int group = 0; group < step; group++) + { + for (unsigned int pair = group; group < inputReIn->size(); pair+=jump) + { + const unsigned int match = pair + step; + const sample_t productRe = twiddleRe * inputReIn->operator[](match) - + twiddleIm * inputImIn->operator[](match); + const sample_t productIm = twiddleIm * inputReIn->operator[](match) + + twiddleRe * inputImIn->operator[](match); + inputReIn->operator[](match) = inputReIn->operator[](pair) - productRe; + inputImIn->operator[](match) = inputImIn->operator[](pair) - productIm; + inputReIn->operator[](pair) += productRe; + inputImIn->operator[](pair) += productIm; + } + + if (group + 1 == step) + { + continue; + } + + float angle = -3.14159265358979323846f * ((float)group + 1.0f) / stepD; + twiddleRe = (sample_t)std::cosh(angle); + twiddleIm = (sample_t)std::sinh(angle); + } + } +} +void FFTFilterEffect::IFFT(std::vector* inputReIn, std::vector* inputImIn) +{ + // conjugate the complex numbers + for (unsigned int i = 0; i < inputReIn->size(); i++) + { + inputImIn->operator[](i) *= -1; + } + + FFT(inputReIn, inputImIn); + + // conjugate the complex numbers again + for (unsigned int i = 0; i < inputReIn->size(); i++) + { + inputImIn->operator[](i) *= -1; + } + + // scaling the numbers + for (unsigned int i = 0; i < inputReIn->size(); i++) + { + // dividing the current complex number with (size, 0) + inputReIn->operator[](i) = inputReIn->operator[](i) / inputReIn->size(); + inputImIn->operator[](i) = inputImIn->operator[](i) / inputReIn->size(); + inputImIn->operator[](i) = -1; + } +} + +extern "C" +{ + +// necessary for getting instance out of shared lib +PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* parent, void* data) +{ + return new FFTFilterEffect(parent, static_cast(data)); +} + +} + +} // namespace lmms diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h new file mode 100644 index 00000000000..480012737ba --- /dev/null +++ b/plugins/FFTFilter/FFTFilter.h @@ -0,0 +1,93 @@ +/* + * Amplifier.h - amplifier-effect-plugin + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2014 Tobias Doerffel + * + * 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 LMMS_FFTFILTER_H +#define LMMS_FFTFILTER_H + +#include "vector" + +#include "Effect.h" +#include "FFTFilterControls.h" + +namespace lmms +{ + +class FFTFilterEffect : public Effect +{ +public: + FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); + ~FFTFilterEffect() override = default; + bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; + + EffectControls* controls() override + { + return &m_filterControls; + } + +private: + void runFFTOnBuffer(std::vector* inputReIn, std::vector* inputImIn, std::vector bufferIn); + // implementation of fft + void FFT(std::vector* inputReIn, std::vector* inputImIn); + // inverse fft + void IFFT(std::vector* inputReIn, std::vector* inputImIn); + + inline sample_t getCurSample(unsigned int posIn) + { + if (m_useSecondBufferOut == true) + { + return m_bufferB[posIn]; + } + else + { + return m_bufferA[posIn]; + } + } + inline void setCurSample(unsigned int posIn, sample_t sampleIn) + { + if (m_useSecondBufferOut == true) + { + m_bufferA[posIn] = sampleIn; + } + else + { + m_bufferB[posIn] = sampleIn; + } + } + + FFTFilterControls m_filterControls; + + std::vector m_bufferA; + std::vector m_bufferB; + bool m_useSecondBufferOut; + + std::vector m_FFTFilterData; + + + friend class FFTFilterControls; +}; + +} // namespace lmms + +#endif // LMMS_FFTFILTER_H diff --git a/plugins/FFTFilter/FFTFilterControlDialog.cpp b/plugins/FFTFilter/FFTFilterControlDialog.cpp new file mode 100644 index 00000000000..c1067e3d1c3 --- /dev/null +++ b/plugins/FFTFilter/FFTFilterControlDialog.cpp @@ -0,0 +1,130 @@ +/* + * AmplifierControlDialog.cpp - control dialog for amplifier effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2014 Tobias Doerffel + * + * 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 "FFTFilterControlDialog.h" +#include "FFTFilterControls.h" +#include "embed.h" + +#include "AutomatableButton.h" +#include "embed.h" +#include "Knob.h" +#include "LedCheckBox.h" +#include "PixmapButton.h" +#include "LcdSpinBox.h" +#include "PointGraph.h" + +namespace lmms::gui +{ + +FFTFilterControlDialog::FFTFilterControlDialog(FFTFilterControls* controls) : + EffectControlDialog(controls) +{ + setAutoFillBackground(true); + QPalette pal; + pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); + setPalette(pal); + setFixedSize(600, 700); + /* + auto makeKnob = [this](int x, int y, const QString& label, const QString& hintText, const QString& unit, FloatModel* model, bool isVolume) + { + Knob* newKnob = new Knob(KnobType::Bright26, this); + newKnob->move(x, y); + newKnob->setModel(model); + newKnob->setLabel(label); + newKnob->setHintText(hintText, unit); + newKnob->setVolumeKnob(isVolume); + return newKnob; + };*/ + /* + m_volumeModel.loadSettings(parent, "volume"); + m_freqControlModel.loadSettings(parent, "freqcontrol"); + m_effectControlModel.loadSettings(parent, "effectcontrol"); + m_bufferModel.loadSettings(parent, "buffer"); + m_displayFFTModel.loadSettings(parent, "display"); + */ + + auto volumeKnob = new Knob(KnobType::Bright26, this); + volumeKnob->setModel(&controls->m_volumeModel); + volumeKnob->setLabel(tr("VOLUME")); + //->setCheckable(true); + volumeKnob->setHintText(tr("Input gain:"),""); + //->setVolumeKnob(true); + //->setVolumeRatio(1.0); + volumeKnob->move(10, 10); + + auto freqControlKnob = new Knob(KnobType::Bright26, this); + freqControlKnob->setModel(&controls->m_freqControlModel); + freqControlKnob->setLabel(tr("FREQ_A_TODO")); + freqControlKnob->setHintText(tr("Input gain:"),""); + freqControlKnob->move(10, 100); + + auto effectControlKnob = new Knob(KnobType::Bright26, this); + effectControlKnob->setModel(&controls->m_effectControlModel); + effectControlKnob->setLabel(tr("EFFECT_A_TODO")); + effectControlKnob->setHintText(tr("Input gain:"),""); + effectControlKnob->move(10, 150); + + auto bufferInput = new LcdSpinBox(2, this, "BUFFER_A_TODO"); + bufferInput->setModel(&controls->m_bufferModel); + //bufferInput->setLabel(tr("INPUT")); + //bufferInput->setHintText(tr("Input gain:"),""); + bufferInput->move(10, 200); + + auto displayFFTKnob = new LedCheckBox("DISPLAY_A_TODO", this, tr("DISPLAY_A_TODO"), LedCheckBox::LedColor::Green); + displayFFTKnob->setModel(&controls->m_displayFFTModel); + //displayFFTKnob->setLabel(tr("DISPLAY_A_TODO")); + displayFFTKnob->setCheckable(true); + displayFFTKnob->move(300, 10); + + auto resetButton = new PixmapButton(this, tr("RESET_A_TODO")); + resetButton->setCheckable(true); + resetButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("smooth_active")); + resetButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("smooth_inactive")); + resetButton->setToolTip(tr("RESET_A_TODO")); + resetButton->resize(13, 48); + resetButton->move(300, 100); + + auto curGraph = new PointGraphView(this, 300, 200, 10, 1024); + curGraph->setModel(&controls->m_graphModel); + resetButton->move(100, 240); +/* + auto swapInputs = new LedCheckBox("Swap inputs", this, tr("Swap inputs"), LedCheckBox::LedColor::Green); + swapInputs->move( 20, 275 ); + swapInputs->setModel( & controls->m_swapInputs ); + swapInputs->setToolTip(tr("Swap left and right input channels for reflections")); + */ + /* + auto = new Knob(KnobType::Bright26, this); + ->setModel(&_controls->m_volumeModel); + ->setLabel(tr("INPUT")); + ->setCheckable(true); + ->setHintText(tr("Input gain:"),""); + ->setVolumeKnob(true); + ->setVolumeRatio(1.0); + ->move(26, 223); + */ +} + +} // namespace lmms::gui diff --git a/plugins/FFTFilter/FFTFilterControlDialog.h b/plugins/FFTFilter/FFTFilterControlDialog.h new file mode 100644 index 00000000000..aed329186c1 --- /dev/null +++ b/plugins/FFTFilter/FFTFilterControlDialog.h @@ -0,0 +1,54 @@ +/* + * AmplifierControlDialog.h - control dialog for amplifier effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2006-2014 Tobias Doerffel + * + * 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 LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H +#define LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H + +#include "EffectControlDialog.h" + +namespace lmms +{ + +class FFTFilterControls; +class FloatModel; + +namespace gui +{ + +class Knob; + +class FFTFilterControlDialog : public EffectControlDialog +{ + Q_OBJECT +public: + FFTFilterControlDialog(FFTFilterControls* controls); + ~FFTFilterControlDialog() override = default; +}; + +} // namespace gui + +} // namespace lmms + +#endif // LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp new file mode 100644 index 00000000000..c4b1af6ea6a --- /dev/null +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -0,0 +1,74 @@ +/* + * AmplifierControls.cpp - controls for amplifier effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2008-2014 Tobias Doerffel + * + * 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 + +#include "FFTFilterControls.h" +#include "FFTFilter.h" +#include "PointGraph.h" + +namespace lmms +{ + +FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : + EffectControls(effect), + m_effect(effect), + m_volumeModel(100.0f, 0.0f, 200.0f, 0.1f, this, tr("Volume")), + m_freqControlModel(100.0f, 0.0f, 200.0f, 0.1f, this, tr("Freq")), + m_effectControlModel(0.0f, -100.0f, 100.0f, 0.1f, this, tr("Effect")), + m_bufferModel(16, 2, 2048, this, "Quality"), + //m_filterModel(0.0f, 1.0f, 200, this), + m_displayFFTModel( true, this, tr("Display fft")), + m_graphModel(1024, this, false) +{ + m_graphModel.addArray(); +} + + +void FFTFilterControls::loadSettings(const QDomElement& parent) +{ + m_volumeModel.loadSettings(parent, "volume"); + m_freqControlModel.loadSettings(parent, "freqcontrol"); + m_effectControlModel.loadSettings(parent, "effectcontrol"); + m_bufferModel.loadSettings(parent, "buffer"); + m_displayFFTModel.loadSettings(parent, "display"); +} + + +void FFTFilterControls::saveSettings(QDomDocument& doc, QDomElement& parent) +{ + m_volumeModel.saveSettings(doc, parent, "volume"); + m_freqControlModel.saveSettings(doc, parent, "freqcontrol"); + m_effectControlModel.saveSettings(doc, parent, "effectcontrol"); + m_bufferModel.saveSettings(doc, parent, "buffer"); + m_displayFFTModel.saveSettings(doc, parent, "display"); +} + +void FFTFilterControls::resetClicked() +{ + +} + +} // namespace lmms diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h new file mode 100644 index 00000000000..fd5bd1beb04 --- /dev/null +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -0,0 +1,88 @@ +/* + * AmplifierControls.h - controls for bassboosterx -effect + * + * Copyright (c) 2014 Vesa Kivimäki + * Copyright (c) 2008-2014 Tobias Doerffel + * + * 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 LMMS_FFTFILTER_CONTROLS_H +#define LMMS_FFTFILTER_CONTROLS_H + +#include "EffectControls.h" +#include "FFTFilterControlDialog.h" +#include "PointGraph.h" + +namespace lmms +{ + +class FFTFilterEffect; + +namespace gui +{ +class FFTFilterControlDialog; +} + +class FFTFilterControls : public EffectControls +{ + Q_OBJECT +public: + FFTFilterControls(FFTFilterEffect* effect); + ~FFTFilterControls() override = default; + + void saveSettings(QDomDocument& doc, QDomElement& parent) override; + void loadSettings(const QDomElement& parent) override; + inline QString nodeName() const override + { + return "FFTFilterControls"; + } + gui::EffectControlDialog* createView() override + { + return new gui::FFTFilterControlDialog(this); + } + int controlCount() override { return 6; } + +private slots: + void resetClicked(); + +private: + FFTFilterEffect* m_effect; + FloatModel m_volumeModel; + //FloatModel m_panModel; + //FloatModel m_leftModel; + //FloatModel m_rightModel; + FloatModel m_freqControlModel; + FloatModel m_effectControlModel; + IntModel m_bufferModel; + + BoolModel m_displayFFTModel; + BoolModel m_resetModel; + + PointGraphModel m_graphModel; + + //graphModel m_filterModel; + + friend class gui::FFTFilterControlDialog; + friend class FFTFilterEffect; +}; + +} // namespace lmms + +#endif // LMMS_FFTFILTER_CONTROLS_H diff --git a/plugins/FFTFilter/artwork.png b/plugins/FFTFilter/artwork.png new file mode 100644 index 0000000000000000000000000000000000000000..5598b32db47134819b686a2f2e282c297fe78c06 GIT binary patch literal 7739 zcmV-B9>n2^P)0000PbVXQnLvL+uWo~o;Lvm$dbY)~9 zcWHEJAV*0}P*;Ht7XSbqwMj%lRCwC$UCWMT$&C{)YS%M>fdS_Kf6`lX7WYI1NhwaI z#~Ux)Mz<@o?jue-6cR;I_}l;dFY7=5{M-EV(I2?~^RN8#Z@RvmM@Ihk3GUBD{tB7=3&<)|J^%UXv)TT<2gS=PbhYipoIf)^C*I2T-wXpJ=oZ zub%*3b~XBlxCX=V`97>F5(V@}v3Y~e25g|z2m5}|_vQKuoTuUQV%GY9pKbCxdtC43 zdA2o9$T$$Qk6~U&{d?>Yl2sr}MzJ69c@!C+JP-Ao;q#<7hDKKM2u>jORy51c8)_l?}U{dvgeNoeQe zc^INd?(bg{M?Q0kXV*QC$Y&=3-_O7rJbAWe@py~ee(_awod+yV)CGMP65qePf z1MJ`J@zlA*$~18iQ_c`b)1183ahv&AU|Y%E{5 z7uEgt?e2~7)ev6!Jmh=%60E}S@bMpvV_*xaAphojAx9XOG2OyB#tLHyYw;GDbABGM z2ezMLj~3@2yZs+RqaQ&7TwsUaydG0zPM;k87imhXNBQ~icmpMdg=oK{NBh&W@Z}jl z_t`r4z&6~?{ahC#uZx;bx9#q12m8?`#Zws`3AgvM#cCXvr!4Akn=s7>TcqRW0dkcg zM>d&L+6MXD*B@uk0JF)#vUhMGNVh#Wpq6mtfprJKrtelLf$ZfE`nV+JOU5QA}I+Xk;8EzN!Ui*e+^?yNkVVxZ$MZF2ip%#m;2oaV`GZ zsPGtNxsu%AB9CuEQczooB@kBOiN2^4wFga`Z(qsdf0G!j(D!p-cp7Dq*FnafUp(VG zv4gz!pxnL=8}EcqFa#}F*c7^LH7mOAQS5kphtM0Vl8vfC;0m&IzWy*F13hsNn+wW8 zV%aLKpW*SsMx*v;%C20Cq@%$B$4lUqwKzz#7N!C1>Ut*jte(3E3*srcSD?@c16En9+z8$l=&}rGOaAf+!@=K55#P4)Y z%dsHt1cgS_eW9V>r~?FgYllGEG%7%tZr^u>GiVNKn<%{|r&xo1k?a()6C^M!Ucx%BG@u*UmQiU7q@h_m zh0&Lzfflf1V!>RHMMz|e44mlzCoecd=IbkMzLF<&HsLUG;$Q9n(VRbbc(_y7j{h+> z>KBgrq^k=mMn3^?LVZ~mB+|Y0U=oox0c0AfnRy?udM%pmJ9h#`j?>rM8(>el`R!Eh zbTF>Cm3N$iMPa$-8q+}0+BdqFC}W;k@I$I*dtU*5H|sF#1o!`&%x!! z!p=R#d7$ks?1+{FkO#}6@?dNRx_NqaL~N#ffqIX)kj{>$us=It70dDSFkqUi4Avh! z4{dA@vn>uT9)`t*$o2$@P!0h(y9anl91xKb4lHa(>u_vp%4}E;RVYM6H&5h_VYaUi zM4CE3kB()fdqDRZdCSnT>a($y^cOkYT>6Ev!w<|bAgBmRplxd?d@NBldytB1zL8%} zHMk9k_v`V}-JP(%nvFo6(eJ;^rI+AyT+a&xX-*c?;ddo;!BcqZHtDg?)Ej;0mXhxX z2L~w_5RV^Z*p=ll7&p4EiAQqWd@y=I!HArANEPlrR>z?11hNz3u+RoJnyKfaX}{`b z__@@XU(z-ggl&*n;A7HA*aVJwZb`xe5R8g~48t>Tdct_%crFM7ba+RZ5GdnI9hig0 zdZCy~Zb+WtQjS?C4=}-oWHN$30Eey=FZk?>nx0eOCX*dPSAKb#G}sr!)fWCP5djE? z2t}=#F4A%>`2aDUB>0W~nNHaEJqIVNjVGz;z($eLcYI~0Q$B06KRpYGb}cd-x&zIB zEE=+$@NqMNZZW2amY1N-xxnh0=3P6*$~`8c!1%$A9TRq#wsa)cFhC>-j+jxE7@2s+ zXH9XH@Xrt%Wx3rS4gp`=v_B;4`4;V8m>%sqn8?a{b?~H+@H*jrLrf7e8&f8qf#btt zc-_R%xy=zfP-vg@Ii{IcDh($*hBMaH_*5029Y>{|Ja+a5hDe-zsSi?2;=57rV}MgaY$ge#qxbLP$ysrFcdI z8d@f>Vp5It#$k6#Ny1@<4-3dCW7kcOh9IOA$Cxn*vjVgV1pnm3*QH2I=pN1*rOL7B_TCJuz>d1y4d$ z6Gs-*no;P`!H!JfIF1onfbfV;Y(b&IL)rR}T>LX8l0o@gEc_EW!_o^p6KTalzO|8g zG94}`3>snH@RS&k@D#;5A(pze{BE)pA-0=-qXDt%XS5mM+KsPUGpI3Eld)DDcp(@c;utXS-i)<1u_kD7%N3 zELQAo;b<)ncLkvz%OD{rHijvnnGOR4*A!(UUy65VhF0;j;ie|rb7{nXie`dxqo$$P zD)^+Py{Td1Do(ad_(6l`KumA@K!+(NO;+{OU5>n=g8a{l8-g`b&@f~7^TEfPz1EuUad{%C7LFFj*t_b&{C?Z=4jLqHOCmPW$EcSc)f1G?=0T{lM94eyS2|DTd=3K-M zc(FS1Jd^vI01=lZN4SSq0PBV&UAGcz1Sa1mHJ!vs943p3P`^`uS?>9VbaEOm{47M$ zh)nFO*A-fsw33N3`G%F3pt;wbI|aWA#yiC)ify8fU;v3`%Ga|^fZ>Mb(aL>drEWi9jQtv6$vSJ^f{&9dkhC=*%mDTwIU*x zxwSCnN5`Nb|EtCwL%WPyNjNwYR!U-}(roGp8o_l!BG<$~C@t-%*V^`>>3pP!Whk?{ zt9?b|#DE@|NWkmI14EDpjCh3;mx6~c99SIF@j!=5kdB%qx0EjMAa!sn(uglB#SI9D zjrAwFL|+XMC=m0=Qn)vCk~&J9F3(YG(LB}rLC=+}F&I$IXXb zEOb<8VJq}liHa`tnM6V}dYYH7*fb%Xp*9rqT|A$;YmRgy3MsC|J%FG5wd{QE!e{sI zvS&y#Kv?s%BaFxG)eVH6tU0g@t)6qGIE!)QRfee!I;;1OUGWc$z@{n1qd+8RXjZtK z`V4IF(@j*O_)!G~_w<;Tzr_JU2LkOxT4~*$gY#U_@nCjvzThI!DMAe`!RXo&a}@1< zp^L{w6#T_UEs^{&EoWEkL?NIj8OurkC>Dpy;ND8Dqi4^A7AwY+34lX{N2myU)eZ(Lv{X{XM0Y_ z-~ayi!F$N~6Z4OZ_OcUwaNW?j$V9{yGCV&D6b>N6pZ*LK)E7N zikhi%4^7&+ogT;PfFU4BF+ol>^}BQ_XDwu^-1_k*x6M2+EErVe^B(^OAa9Ydp* zSX2m$YR-LEP~EC76|1A@4^m2zCB!$@B2JaIFUgXUI1|5=9rmP}YmO5$EJ_jt_{3QZ zQ;Zgnky<^^^&Rk%2`SB1gGta3>wf=4t{%=0!%{;HTwKexkBDcTj3E!|;lbFR3|a~l zc@?6JVy{)&4T`3s!A@1|xKs%MN5i1VVAIPF(9|%3+y}HGrCr)kdFraPj2jwl^N=_8 z$=SRytsvG-;}_w9TE4&fV-l{4$UZwbFENHLid|SJ+f}VBTC@_CIHZctDG~q#L$Lyh zh6+I++3<|6H@u?TQ;U~Y%_I+71u6(&g`YeDGefPFes_YYY)avf&~rav{b6`4Onuv$ zOM;nSyiHk@w%z#T5oJO>IUMDKy)z}n0|6xMw8&=R7@RWHErboD=>pRH84AtGNEP~X z-b;#c@w`_pgqLb?(STr%kNZ6@X;RR1KCDQkk*^2Eg@F@HKO!@3wq=}PCsfr+n^4dY z7GokUWYE0;%V6eU=<_8UOJ7_mw%5=J%b5G5y`=mB!M%rk_8UmtFcRtSlp6s+vw+bw?V@WhCB& zAVFk~Crm06bDe49E6CSEA+~zQ3GVq^xlU2K&a23BXInLgU;+^_gL90EADZ4eYXn1C z(^Ox;%UHHo!C`jiJ`Ix?OX!vnZd%`WWX58I?M`V26}LWJ(p1d@)KlZ71;M zoWB5bxIojUm*^2Tr`mUOBkRpT8vS+J4l`*z%eB$w;bX2>D^He;en1V>8gLHk459zw z60y8^0T>>(t1GO!bk=W;b=Ob=(SbYFNy)M{hK>_Lf-Wn{xaeGjD z7levNB(^?i7jdsm=A5rkduUvlsc2M-biC7osxx!~HeBQ@y%wHl$3;xpBY60!mb5i0 zNF1p)(U|c5=%029G228_OjVh16`d*9=-rYi=-!)}Lt+rP*=>}hrhC_az@vO6Xe(o6 zB8xNNngEWKL#9GB+Oz^#^>KNyMF_z^a#+IU$0FF13q3DgBV3b#K<@M;Wqku^6VA zUhu+!9Zs3p!+b>UR+uQ*B>JVQ6VO6Vc8>>nYj2E<2b0n93^0k-Q(84v35#88G;!E1 zTZ%nQeP}?OV7DIKUJS_qx;l|J$dbs9t4>eZj*FjEYO8BQ@5b>8ZCfoItWh zStZz5k8YW|#k)=5fn{V-O%zG8qTm*qUI@8k;y)sKXR)O|!FyAgmaDDA_EasK z4QOotkJh`a;c3Qzlm)=e8E5ZZ;>=8E+?NN267UU#ke6V#!qdN`fxUDg9j&QjP1A=C zsg0~VF>+gRgmG>mB8QET&`W-H8#jMKEBd@lDy<(*eLbcV5wHYaSRM?Unli3Qlv|0W zl%B51+az{%7=XVVUs@(D2e;XnOy-YQ?@7AG$vA(U753Vv>rEcI~S4;O`x4?_`NoWb#CepPb!rb z{J}{MZL`VpOhU!O2#c@wrH=Bh2T&RiYb-CuXvlfALl7-xbkYr^ zM8A32iE5^V5bDbgU(?Zo#F2Ord9SETOe_oh;W7x3gzU9dFnyG&VNs;zMmoZ44nGzl zCoDax><^sDw2NciKqx>YVAooci-1d$Rz;V($ii_%)sl%ez)eXoYNX|7@0_W*c=#1f za1=7I^kWKoMvmmeNVGT2UW=2;m+EhRbgczd5R#QViRe}|6GRM+7S@sM_>nxpZ_WL<#nA}JZ2kSzU zVmhq8x}`uC#8V5H>JS1k@Vy;rO^h8wJkDQ~3rda)Wky}ESUWFVR z23s#Hc~J3XOlK9#!8F5^19Z8W^5?BE^{p0tV8wi#f00?g(e2^)#W5 z1KyyxT1uB=Ql7g0u>55h+dl}L&sfq)8|v~3f}X2fa?|EEQ5-{3)Kt(@ zg9wl}mcRh3Fdz#KgolgV|FuVNPY6m=vyoHAIg8uE*^UNam}6X`{!fRUJX>h}9P8fA zMrR9G_C_5Obpf{&ruIceI!fJx<}8k*I}+14tFG;ilpKAb>%qsd#z?DosH}Qop^Cu!`j)JSi&b+rUFg z6PgTNRGC7}7O%i6U-)ZWeGFYUH}p03r1VY)v_MdZ#~GKPArq1|&E6WK0a8c0L)rF6 z!WK=tWZQdszd~yAO-l}lPncdp3Vgu z(~9z5loau|K5|+xEUq5TWkki8%zQ-qQ=(jI0GW;5`Xxt01QI^*M9vhJ$Zj@J=J{~g z%I1rhaIfH8chU1TQR8@Gxr=UqqHM|0^YZ>I8?FGfZR!WKw3mva5~aqC$ER7oIYAx585r^Tf5)LW9dkH7vBc;Olo=Tc5goZ(>Wl zgn>AH-W!Vi{QYN`tN1hTon2~fW*ku0HUB*Z`r~VT2Qr)1U!&=swbXXyg&sFtRYrLG zrnd)RJ0&nouA70+O*8ndprtMw=?y~o36~lU`TS)ZdWQToF?`o^;f1VGJp(b$=WcxhDbli6i(zH_4xf=_VirZ9(c6Q9`V>Q&qhfSh$!tA2lCMi!w-9d*#ic4#uNs(Vg2&sPOqDEwQH4aPvWO0}ABPrWC(j8@7(pZ`UU zQ)0J9i@uvVvA1z)H>>!(q4u zi1rd}*pR^SILf3oq*c}QDcf+z3DQzE6SCGV?Lj5cdVJv2vuKQhxX4+RxkbN^(0K%y zkpxXWlk__EmYUgOz}`BWL2+;LW!JyEln&bo%kl(4C!8o8sH>m81HCKd2=4s|ymA}| zx_I-e^R7uQRHoS-g@9A3hSo}7w-?cGkGRC4&TqYi*th{t(M)WNW!Q`T(}%zM-d2v? zxwncyBNF`98_RU8>SYlspc!#c=r`E})?x_zzd3cz%|`IvG37PdoOTpnG*f;;A4V`Y zs+9X*{;UXkBWv&mK28BG(xYUf+qH*51{CL?{{so%c^XFLhl~IK002ovPDHLkV1mrw Bz%u{< literal 0 HcmV?d00001 diff --git a/plugins/FFTFilter/logo.png b/plugins/FFTFilter/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9340da708dd79ed97111eb535f51b81a91d6a15b GIT binary patch literal 774 zcmV+h1Nr=kP)7WEc)VQ)zLm`B#lSD% z0Wg;#IH?7|3b0p&fj_`2;A{cm@zx+(Ge?s$@EN$6LtMjg>;+(boCbaXw;ja=b6mQ?gRp67Yf18(18niCN0v&eY^{Cr&#;#IcF{ks?!* z&o!_q>9xbSw`QytRI!M?zP_o#K-8ExJaV?vi znPt?~0KhTu23U+Gy8^Tw;^SzWSet9n Date: Sat, 24 Feb 2024 16:37:12 +0100 Subject: [PATCH 004/184] added_new_PointGraphDataArray_settings --- include/PointGraph.h | 38 ++++++++++---- src/gui/widgets/PointGraph.cpp | 94 ++++++++++++++++++++++++++++------ 2 files changed, 106 insertions(+), 26 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 9e0ef3ee3d7..55ae3526bc3 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -24,12 +24,12 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView { Q_OBJECT public: - // TODO: remove styles + // TODO: remove styles Done // TODO: change x to float // TODO: revrite comments // TODO: make a new class inside PointGraphDataArray to store the point data - // TODO: add is selectable - // TODO: add new setting to make the last point cord 1, 1 + // TODO: add is selectable Done + // TODO: add new setting to make the last point cord 1, 1 Done // TODO: flip mouse y position // TODO: function to get multiple values @@ -38,10 +38,13 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: add automation support // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, valueA, valueB // TODO setPointType(unsigned int type) - // TODO: add effector PointDataArray pointer to the PointDataArray class + // TODO: add effector int location to the PointDataArray class // TODO: add effector line attreibutes to the nested class // TODO: add effects + // TODO: clear array when 2. last point is deleted in the widget + // TODO: event when a dataArray's size gets to 0 + PointGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn); @@ -135,7 +138,7 @@ Q_OBJECT // returns location unsigned int addArray(); // preservs the order - void delArray(unsigned int locationIn); // TODO + void delArray(unsigned int locationIn); inline void clearArray() { m_dataArrays.clear(); @@ -167,8 +170,8 @@ class LMMS_EXPORT PointGraphDataArray public: PointGraphDataArray(); PointGraphDataArray(unsigned int* maxLengthIn, - bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, - PointGraphModel* parentIn); + bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, + bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, PointGraphModel* parentIn); ~PointGraphDataArray(); void updateConnections(PointGraphModel* parentIn); @@ -176,6 +179,9 @@ class LMMS_EXPORT PointGraphDataArray void setFixedSize(bool valueIn); void setFixedValue(bool valueIn); void setFixedPos(bool valueIn); + void setFixedEndPoints(bool valueIn); + void setSelectable(bool valueIn); + void setEditableAttrib(bool valueIn); void setNonNegative(bool valueIn); void setLineColor(QColor colorIn); void setActiveColor(QColor colorIn); @@ -185,6 +191,9 @@ class LMMS_EXPORT PointGraphDataArray bool getFixedSize(); bool getFixedValue(); bool getFixedPos(); + bool getFixedEndPoints(); + bool getSelectable(); + bool getEditableAttrib(); bool getNonNegative(); QColor* getLineColor(); QColor* getActiveColor(); @@ -204,7 +213,7 @@ class LMMS_EXPORT PointGraphDataArray { return m_dataArray.size(); } - // clamps down the values to 0 - m_maxLength, -1 - 1, does not sort + // clamps down the values to 0 - 1, -1 - 1 // does check m_isFixedSize, m_isFixedValue, m_isFixedPos, // sorts array, removes duplicated positions, // clampIn: should clamp, sortIn: should sort @@ -232,15 +241,18 @@ class LMMS_EXPORT PointGraphDataArray // sets value when m_isFixedValue is disabed void setValue(unsigned int locationIn, float valueIn); // sets position when m_isFixedPos is disabed, returns final location - unsigned int setPos(unsigned int locationIn, unsigned int posIn); + unsigned int setPos(unsigned int locationIn, unsigned int posIn); // TODO // signals: // not qt // m_dataArray void dataChanged(); // color void styleChanged(); private: - // swapping values, slide moves the values ()between) once left or right + // swapping values, "slide" moves the values (between) once left or right + // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); + // checks m_isFixedEndPoints, does not call dataChanged() + void formatDataArrayEndPoints(); // can new data be added or removed bool m_isFixedSize; @@ -248,6 +260,12 @@ class LMMS_EXPORT PointGraphDataArray bool m_isFixedValue; // can the positions be changed bool m_isFixedPos; + // if true then it makes the last position coordinate 1, 1, the first point coordinate to -1 (ot 0), 0 + bool m_isFixedEndPoints; + // can PointGraphView select this + bool m_isSelectable; + // can PointGraphView edit the point attributes + bool m_isEditableAttrib; // can values be less than 0 bool m_nonNegative; diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index e2a0d86e04e..b18677ce306 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -366,9 +366,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) { transformedMouse = &transformedMouseA; } - if (dataArray->getFixedSize() == false || - dataArray->getFixedValue() == false || - dataArray->getFixedPos() == false) + if (dataArray->getSelectable() == true) { // we dont use this bool bool found = false; @@ -451,7 +449,7 @@ unsigned int PointGraphModel::addArray(std::vector 0 || m_isFixedEndPoints == false) + { + m_dataArray[locationIn].second = valueIn; + dataChanged(); + } } } unsigned int PointGraphDataArray::setPos(unsigned int locationIn, unsigned int posIn) { int location = locationIn; - if (posIn < *m_maxLength) + if (m_isFixedPos == false && posIn < *m_maxLength) { bool found = false; location = getNearestLocation(posIn, &found); - if (found == false && m_isFixedPos == false) + // if an other point was not found at posIn + // and if getNearestLocation returned a value + // and if dataArray end points are changeable + if (found == false && m_isFixedEndPoints == true && + locationIn < m_dataArray.size() - 1 && location > 0 || + found == false && m_isFixedEndPoints == false) { int targetLocation = location; bool dataChangedVal = false; @@ -841,13 +893,13 @@ unsigned int PointGraphDataArray::setPos(unsigned int locationIn, unsigned int p { // slide the new data if the closest data pos is bigger qDebug("set 3. success, location: %d", targetLocation); - //if (m_dataArray[location].first < posIn) - //{ - // if (targetLocation + 1 < m_dataArray.size()) - // { - // targetLocation++; - // } - //} + if (m_dataArray[location].first < posIn) + { + if (targetLocation + 1 < m_dataArray.size()) + { + //targetLocation++; + } + } qDebug("set 4. success, target: %d", targetLocation); m_dataArray[locationIn].first = posIn; swap(locationIn, targetLocation, true); @@ -915,6 +967,16 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI dataChanged(); } } +void PointGraphDataArray::formatDataArrayEndPoints() +{ + if (m_isFixedEndPoints == true && m_dataArray.size() > 0) + { + m_dataArray[m_dataArray.size() - 1].first = 1; + m_dataArray[m_dataArray.size() - 1].second = 1.0f; + m_dataArray[0].first = 0; + m_dataArray[0].second = m_nonNegative == true ? 0.0f : -1.0f; + } +} void PointGraphDataArray::dataChanged() { From 2650f5eabbd9b1bb64abb7051993aadb877ccb5c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 24 Feb 2024 17:14:49 +0100 Subject: [PATCH 005/184] changed_x_position_to_float --- include/PointGraph.h | 34 ++++----- src/gui/widgets/PointGraph.cpp | 124 ++++++++++++++++----------------- 2 files changed, 80 insertions(+), 78 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 55ae3526bc3..2b1dedeb42a 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -25,13 +25,14 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView Q_OBJECT public: // TODO: remove styles Done - // TODO: change x to float - // TODO: revrite comments + // TODO: change x unsigned int to float Done // TODO: make a new class inside PointGraphDataArray to store the point data // TODO: add is selectable Done // TODO: add new setting to make the last point cord 1, 1 Done // TODO: flip mouse y position // TODO: function to get multiple values + // TODO: revrite comments + // TODO: rename functions and values // TODO: automation: // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 3 value long) @@ -39,11 +40,12 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, valueA, valueB // TODO setPointType(unsigned int type) // TODO: add effector int location to the PointDataArray class - // TODO: add effector line attreibutes to the nested class + // TODO: add effector line attributes to the nested class // TODO: add effects // TODO: clear array when 2. last point is deleted in the widget // TODO: event when a dataArray's size gets to 0 + // TODO: abiliti to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -60,8 +62,8 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView } // returns -2.0f at second when nothing is selected - std::pair getSelectedData(); - void setSelectedData(std::pair dataIn); + std::pair getSelectedData(); + void setSelectedData(std::pair dataIn); signals: inline void drawn(); @@ -78,12 +80,12 @@ protected slots: private: void modelChanged() override; - std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); - std::pair mapDataPos(std::pair posIn, bool nonNegativeIn); + std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); + std::pair mapDataPos(std::pair posIn, bool nonNegativeIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); - std::pair showInputDialog(); //TODO + std::pair showInputDialog(); //TODO void selectData(int mouseXIn, int mouseYIn); bool m_mouseDown; @@ -134,7 +136,7 @@ Q_OBJECT } } // returns location - unsigned int addArray(std::vector>* arrayIn); + unsigned int addArray(std::vector>* arrayIn); // returns location unsigned int addArray(); // preservs the order @@ -201,7 +203,7 @@ class LMMS_EXPORT PointGraphDataArray // array: // returns the location of added/found point, -1 if not found and can not be added - int add(unsigned int posIn); + int add(float posIn); // deletes the data/sample if m_isFixedSize is disabled void del(unsigned int locationIn); // clears data/sample array without any checks @@ -220,28 +222,28 @@ class LMMS_EXPORT PointGraphDataArray void formatArray(bool clampIn, bool sortIn); // get: - inline std::pair* getData(unsigned int locationIn) + inline std::pair* getData(unsigned int locationIn) { return &m_dataArray[locationIn]; } // returns -1 when position is not found - int getLocation(unsigned int posIn); + int getLocation(float posIn); // gets the nearest data location to the position, // foundOut is true when the nearest position = posIn, // reurns -1 when search failed - int getNearestLocation(unsigned int posIn, bool* foundOut); + int getNearestLocation(float posIn, bool* foundOut); float getValueAtPositon(float posIn); // TODO // set: // sets data array without any checks - inline void setDataArray(std::vector>* dataArrayIn) + inline void setDataArray(std::vector>* dataArrayIn) { m_dataArray = *dataArrayIn; } // sets value when m_isFixedValue is disabed void setValue(unsigned int locationIn, float valueIn); // sets position when m_isFixedPos is disabed, returns final location - unsigned int setPos(unsigned int locationIn, unsigned int posIn); // TODO + unsigned int setPos(unsigned int locationIn, float posIn); // TODO // signals: // not qt // m_dataArray void dataChanged(); @@ -279,7 +281,7 @@ class LMMS_EXPORT PointGraphDataArray unsigned int* m_maxLength; // ordered array of 0 < position < max_Length, -1(or 0) < value < 1 - std::vector> m_dataArray; + std::vector> m_dataArray; }; } // namespace lmms diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index b18677ce306..08bbf3c9900 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -79,16 +79,16 @@ void PointGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocation } } -std::pair PointGraphView::getSelectedData() +std::pair PointGraphView::getSelectedData() { - std::pair output(0, -2.0f); + std::pair output(0, -2.0f); if (m_isSelected == true) { output = *model()->getDataArray(m_selectedArray)->getData(m_selectedLocation); } return output; } -void PointGraphView::setSelectedData(std::pair dataIn) +void PointGraphView::setSelectedData(std::pair dataIn) { if (m_isSelected == true) { @@ -118,7 +118,7 @@ void PointGraphView::mousePressEvent(QMouseEvent* me) if (m_isSelected == true) { // display dialog - std::pair curData = showInputDialog(); + std::pair curData = showInputDialog(); // change data setSelectedData(curData); } @@ -162,7 +162,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) qDebug("release size: %ld", model()->getDataArraySize()); for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - std::pair curMouseData = mapMousePos(x, y, + std::pair curMouseData = mapMousePos(x, y, model()->getDataArray(i)->getNonNegative()); // TODO optimize int location = model()->getDataArray(i)->add(curMouseData.first); // if adding was successful @@ -202,7 +202,7 @@ void PointGraphView::mouseDoubleClickEvent(QMouseEvent * me) if (m_isSelected == true && me->button() == Qt::LeftButton) { // display dialog - std::pair curData = showInputDialog(); + std::pair curData = showInputDialog(); // change data setSelectedData(curData); } @@ -243,7 +243,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) qDebug("paint size: %d", length); for (unsigned int j = 0; j < length - 1; j++) { - std::pair posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); + posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); p.drawLine(posA.first, posA.second, posB.first, posB.second); @@ -271,38 +271,38 @@ void PointGraphView::updateGraph() update(); } -std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) +std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) { if (nonNegativeIn == true) { - // mapping the position to 0 - m_maxLength, 0 - 1 using qWidget width and height - return std::pair( - static_cast(xIn * (model()->getMaxLength() - 1) / width()), + // mapping the position to 0 - 1, 0 - 1 using qWidget width and height + return std::pair( + static_cast(xIn / (float)width()), static_cast(yIn / (float)height())); } else { - // mapping the position to 0 - m_maxLength, -1 - 1 using qWidget width and height - return std::pair( - static_cast(xIn * (model()->getMaxLength() - 1) / width()), + // mapping the position to 0 - 1, -1 - 1 using qWidget width and height + return std::pair( + static_cast(xIn / (float)width()), static_cast((yIn * 2.0f / (float)height()) - 1.0f)); } } -std::pair PointGraphView::mapDataPos(std::pair posIn, +std::pair PointGraphView::mapDataPos(std::pair posIn, bool nonNegativeIn) { if (nonNegativeIn == true) { // mapping the point/sample positon to mouse/view position return std::pair( - static_cast(posIn.first * width() / model()->getMaxLength()), + static_cast(posIn.first * width()), static_cast(posIn.second * height())); } else { // mapping the point/sample positon to mouse/view position return std::pair( - static_cast(posIn.first * width() / model()->getMaxLength()), + static_cast(posIn.first * width()), static_cast((posIn.second / 2.0f + 0.5f) * height())); } } @@ -312,32 +312,32 @@ float PointGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); } -std::pair PointGraphView::showInputDialog() +std::pair PointGraphView::showInputDialog() { - std::pair curData(0, 0.0f); + std::pair curData(0.0f, 0.0f); if (m_isSelected == true) { curData = getSelectedData(); - double minValue = model()->getDataArray(m_selectedArray)->getNonNegative() == true ? 0.0 : -1.0; + double minValue = model()->getDataArray(m_selectedArray)->getNonNegative() == true ? 0.0 : -100.0; // show position input dialog bool ok; double changedPos = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between 0 and ") + QString::number(model()->getMaxLength()), - static_cast(curData.first), - 0.0, static_cast(model()->getMaxLength()), 0, &ok); + tr("Please enter a new value between 0 and ") + QString::number(100.0), + static_cast(curData.first * 100.0f), + 0.0, 100.0, 0, &ok); if (ok == true) { - curData.first = static_cast(changedPos); + curData.first = static_cast(changedPos) / 100.0f; } double changedValue = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between") + QString::number(minValue) + tr(" and 1.0"), - static_cast(curData.second), - minValue, 1.0, 2, &ok); + tr("Please enter a new value between ") + QString::number(minValue) + tr(" and 100"), + static_cast(curData.second * 100.0f), + minValue, 100.0, 2, &ok); if (ok == true) { - curData.second = static_cast(changedValue); + curData.second = static_cast(changedValue) / 100.0f; } } return curData; @@ -351,9 +351,9 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) m_selectedArray = 0; m_isSelected = false; - std::pair transformedMouseA = mapMousePos(mouseXIn, mouseYIn, false); - std::pair transformedMouseB = mapMousePos(mouseXIn, mouseYIn, true); - std::pair* transformedMouse = &transformedMouseA; + std::pair transformedMouseA = mapMousePos(mouseXIn, mouseYIn, false); + std::pair transformedMouseB = mapMousePos(mouseXIn, mouseYIn, true); + std::pair* transformedMouse = &transformedMouseA; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { @@ -439,7 +439,7 @@ PointGraphModel::~PointGraphModel() m_dataArrays.clear(); } -unsigned int PointGraphModel::addArray(std::vector>* arrayIn) +unsigned int PointGraphModel::addArray(std::vector>* arrayIn) { unsigned int location = addArray(); m_dataArrays[location].setDataArray(arrayIn); @@ -627,10 +627,10 @@ QColor* PointGraphDataArray::getFillColor() // array: -int PointGraphDataArray::add(unsigned int posIn) +int PointGraphDataArray::add(float posIn) { int location = -1; - if (posIn < *m_maxLength) + if (m_dataArray.size() < *m_maxLength) { qDebug("add 1. success"); bool found = false; @@ -654,7 +654,7 @@ int PointGraphDataArray::add(unsigned int posIn) targetLocation++; } } - m_dataArray.push_back(std::pair(posIn, 0.0f)); + m_dataArray.push_back(std::pair(posIn, 0.0f)); qDebug("add 4. success, target: %d", targetLocation); swap(m_dataArray.size() - 1, targetLocation, true); dataChangedVal = true; @@ -662,7 +662,7 @@ int PointGraphDataArray::add(unsigned int posIn) else if (m_dataArray.size() <= 0) { qDebug("add 5. success"); - m_dataArray.push_back(std::pair(posIn, 0.0f)); + m_dataArray.push_back(std::pair(posIn, 0.0f)); targetLocation = 0; dataChangedVal = true; } @@ -704,9 +704,9 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) { for (unsigned int i = 0; i < m_dataArray.size(); i++) { - if (m_dataArray[i].first > *m_maxLength) + if (m_dataArray[i].first > 1) { - m_dataArray[i].first = *m_maxLength; + m_dataArray[i].first = 1; } if (m_dataArray[i].second > 1) { @@ -734,7 +734,7 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) if (sortIn == true) { std::sort(m_dataArray.begin(), m_dataArray.end(), - [](std::pair a, std::pair b) + [](std::pair a, std::pair b) { return a.first > b.first; }); @@ -759,7 +759,7 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) } } -int PointGraphDataArray::getLocation(unsigned int posIn) +int PointGraphDataArray::getLocation(float posIn) { bool found = false; int location = getNearestLocation(posIn, &found); @@ -770,9 +770,9 @@ int PointGraphDataArray::getLocation(unsigned int posIn) return location; } -int PointGraphDataArray::getNearestLocation(unsigned int posIn, bool* foundOut) +int PointGraphDataArray::getNearestLocation(float posIn, bool* foundOut) { - if (posIn < *m_maxLength && m_dataArray.size() > 0) + if (m_dataArray.size() > 0) { int start = 0; int end = m_dataArray.size() - 1; @@ -782,7 +782,7 @@ int PointGraphDataArray::getNearestLocation(unsigned int posIn, bool* foundOut) { mid = start + (end - start) / 2; qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); - qDebug("getNearestLocation, val: %d, pos: %d", m_dataArray[mid].first, posIn); + qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].first, posIn); if (m_dataArray[mid].first == posIn) { *foundOut = true; @@ -804,8 +804,8 @@ int PointGraphDataArray::getNearestLocation(unsigned int posIn, bool* foundOut) mid = mid - 1; } if (mid + 1 < m_dataArray.size() && - std::abs(static_cast(m_dataArray[mid].first) - static_cast(posIn)) > - std::abs(static_cast(m_dataArray[mid + 1].first) - static_cast(posIn))) + std::abs(static_cast(m_dataArray[mid].first) - posIn) > + std::abs(static_cast(m_dataArray[mid + 1].first) - posIn)) { outputDif = 1; } @@ -813,16 +813,16 @@ int PointGraphDataArray::getNearestLocation(unsigned int posIn, bool* foundOut) *foundOut = false; return mid + outputDif; } - qDebug("getNearestLocation, posIn: %d", posIn); + qDebug("getNearestLocation, posIn: %f", posIn); *foundOut = false; return -1; } float PointGraphDataArray::getValueAtPositon(float posIn) { - float posB = posIn / static_cast(*m_maxLength); + float posB = posIn; bool found = false; - unsigned int location = getNearestLocation(static_cast(posIn), &found); + unsigned int location = getNearestLocation(posIn, &found); if (location >= 0) { if (found == true) @@ -863,8 +863,8 @@ void PointGraphDataArray::setValue(unsigned int locationIn, float valueIn) { if (m_isFixedValue == false) { - if (m_isFixedEndPoints == true && locationIn < m_dataArray.size() - 1 - && locationIn > 0 || m_isFixedEndPoints == false) + if ((m_isFixedEndPoints == true && locationIn < m_dataArray.size() - 1 && + locationIn > 0) || m_isFixedEndPoints == false) { m_dataArray[locationIn].second = valueIn; dataChanged(); @@ -872,26 +872,26 @@ void PointGraphDataArray::setValue(unsigned int locationIn, float valueIn) } } -unsigned int PointGraphDataArray::setPos(unsigned int locationIn, unsigned int posIn) +unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) { int location = locationIn; - if (m_isFixedPos == false && posIn < *m_maxLength) + if (m_isFixedPos == false && posIn <= 1.0f) { bool found = false; location = getNearestLocation(posIn, &found); // if an other point was not found at posIn // and if getNearestLocation returned a value // and if dataArray end points are changeable - if (found == false && m_isFixedEndPoints == true && - locationIn < m_dataArray.size() - 1 && location > 0 || - found == false && m_isFixedEndPoints == false) + if (found == false && ((m_isFixedEndPoints == true && + locationIn < m_dataArray.size() - 1 && location > 0) || + m_isFixedEndPoints == false)) { int targetLocation = location; - bool dataChangedVal = false; + // bool dataChangedVal = false; // if getNearestLocation returned a value if (location >= 0) { - // slide the new data if the closest data pos is bigger + // slide the new data if the closest data pos is bigger TODO fix qDebug("set 3. success, location: %d", targetLocation); if (m_dataArray[location].first < posIn) { @@ -930,12 +930,12 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI for (unsigned int i = 0; i < m_dataArray.size(); i++) { - qDebug(" - i: %d - x: %d", i, m_dataArray[i].first); + qDebug(" - i: %d - x: %f", i, m_dataArray[i].first); } if (locationAIn < locationBIn) { - std::pair swap = m_dataArray[locationAIn]; + std::pair swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i < locationBIn; i++) { m_dataArray[i] = m_dataArray[i + 1]; @@ -944,7 +944,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI } else { - std::pair swap = m_dataArray[locationAIn]; + std::pair swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i > locationBIn; i--) { m_dataArray[i] = m_dataArray[i - 1]; @@ -955,12 +955,12 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI qDebug(" --------- "); for (unsigned int i = 0; i < m_dataArray.size(); i++) { - qDebug(" - i: %d - x: %d", i, m_dataArray[i].first); + qDebug(" - i: %d - x: %f", i, m_dataArray[i].first); } } else { - std::pair swap = m_dataArray[locationAIn]; + std::pair swap = m_dataArray[locationAIn]; m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; } From 429023dce5d8db6996b4a71eb94e9ae4fbaf81dc Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 25 Feb 2024 13:55:23 +0100 Subject: [PATCH 006/184] y_axis_flipped --- include/PointGraph.h | 4 ++-- src/gui/widgets/PointGraph.cpp | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 2b1dedeb42a..8cefaeaefca 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -29,7 +29,7 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: make a new class inside PointGraphDataArray to store the point data // TODO: add is selectable Done // TODO: add new setting to make the last point cord 1, 1 Done - // TODO: flip mouse y position + // TODO: flip mouse y position Done // TODO: function to get multiple values // TODO: revrite comments // TODO: rename functions and values @@ -243,7 +243,7 @@ class LMMS_EXPORT PointGraphDataArray // sets value when m_isFixedValue is disabed void setValue(unsigned int locationIn, float valueIn); // sets position when m_isFixedPos is disabed, returns final location - unsigned int setPos(unsigned int locationIn, float posIn); // TODO + unsigned int setPos(unsigned int locationIn, float posIn); // signals: // not qt // m_dataArray void dataChanged(); diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index 08bbf3c9900..5c145353aea 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -113,7 +113,7 @@ void PointGraphView::mousePressEvent(QMouseEvent* me) // show new inputDialog to change data if control is pressed if ((me->modifiers() & Qt::ControlModifier) == true) { - selectData(x, y); + selectData(x, height() - y); // if selecting was successful if (m_isSelected == true) { @@ -154,7 +154,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) if (m_mousePress == true) { // add/delete point - selectData(x, y); + selectData(x, height() - y); if (m_isSelected == false && m_addition == true) { // if selection failed and addition @@ -162,7 +162,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) qDebug("release size: %ld", model()->getDataArraySize()); for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - std::pair curMouseData = mapMousePos(x, y, + std::pair curMouseData = mapMousePos(x, height() - y, model()->getDataArray(i)->getNonNegative()); // TODO optimize int location = model()->getDataArray(i)->add(curMouseData.first); // if adding was successful @@ -246,7 +246,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - p.drawLine(posA.first, posA.second, posB.first, posB.second); + p.drawLine(posA.first, height() - posA.second, posB.first, height() - posB.second); posA = posB; } if (posA.first < width()) @@ -891,13 +891,20 @@ unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) // if getNearestLocation returned a value if (location >= 0) { - // slide the new data if the closest data pos is bigger TODO fix + // slide the new data if the closest data pos is bigger TODO test ifs qDebug("set 3. success, location: %d", targetLocation); - if (m_dataArray[location].first < posIn) + if (location < locationIn && m_dataArray[location].first < posIn) { if (targetLocation + 1 < m_dataArray.size()) { - //targetLocation++; + targetLocation++; + } + } + else if (location > locationIn && m_dataArray[location].first > posIn) + { + if (targetLocation > 0) + { + targetLocation--; } } qDebug("set 4. success, target: %d", targetLocation); From 5c5998608051eed43959bfb3e8d0378e133f4880 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 29 Feb 2024 18:40:13 +0100 Subject: [PATCH 007/184] PointGraph_added_point_attributes --- include/PointGraph.h | 123 +++++++++++++++---- src/gui/widgets/PointGraph.cpp | 218 ++++++++++++++++++++++----------- 2 files changed, 243 insertions(+), 98 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 8cefaeaefca..b22a04c7d15 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -26,26 +26,27 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView public: // TODO: remove styles Done // TODO: change x unsigned int to float Done - // TODO: make a new class inside PointGraphDataArray to store the point data + // TODO: make a new class inside PointGraphDataArray to store the point data Done // TODO: add is selectable Done // TODO: add new setting to make the last point cord 1, 1 Done // TODO: flip mouse y position Done // TODO: function to get multiple values - // TODO: revrite comments + // TODO: rewrite comments // TODO: rename functions and values // TODO: automation: - // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 3 value long) + // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 4 value long) Done // TODO: add automation support - // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, valueA, valueB - // TODO setPointType(unsigned int type) - // TODO: add effector int location to the PointDataArray class + // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, curve, valueA, valueB Done + // TODO setPointType(unsigned int type) Done + // TODO: add effector(PointGraphDataArray) int location to the PointGraphDataArray class // TODO: add effector line attributes to the nested class // TODO: add effects // TODO: clear array when 2. last point is deleted in the widget // TODO: event when a dataArray's size gets to 0 - // TODO: abiliti to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) + // TODO: ability to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) + // TODO: check PointGraphDataArray signals PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -81,7 +82,7 @@ protected slots: void modelChanged() override; std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); - std::pair mapDataPos(std::pair posIn, bool nonNegativeIn); + std::pair mapDataPos(float xIn, float yIn, bool nonNegativeIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); @@ -136,7 +137,9 @@ Q_OBJECT } } // returns location - unsigned int addArray(std::vector>* arrayIn); + unsigned int addArray(std::vector>* arrayIn, bool isCurvedIn); + // returns location + unsigned int addArray(std::vector* arrayIn, bool isCurvedIn); // returns location unsigned int addArray(); // preservs the order @@ -203,13 +206,14 @@ class LMMS_EXPORT PointGraphDataArray // array: // returns the location of added/found point, -1 if not found and can not be added - int add(float posIn); + int add(float xIn); // deletes the data/sample if m_isFixedSize is disabled void del(unsigned int locationIn); // clears data/sample array without any checks inline void clear() { m_dataArray.clear(); + dataChanged(); } inline size_t size() { @@ -222,34 +226,104 @@ class LMMS_EXPORT PointGraphDataArray void formatArray(bool clampIn, bool sortIn); // get: - inline std::pair* getData(unsigned int locationIn) + inline float* getX(unsigned int locationIn) + { + return &m_dataArray[locationIn].m_x; + } + inline float* getY(unsigned int locationIn) + { + return &m_dataArray[locationIn].m_y; + } + inline float* getC(unsigned int locationIn) + { + return &m_dataArray[locationIn].m_c; + } + inline float* getValA(unsigned int locationIn) { - return &m_dataArray[locationIn]; + return &m_dataArray[locationIn].m_valA; } + inline float* getValB(unsigned int locationIn) + { + return &m_dataArray[locationIn].m_valB; + } + unsigned int getType(unsigned int locationIn); + unsigned int getAutomatedAttrib(unsigned int locationIn); + // returns -1 when position is not found - int getLocation(float posIn); + int getLocation(float xIn); // gets the nearest data location to the position, // foundOut is true when the nearest position = posIn, // reurns -1 when search failed - int getNearestLocation(float posIn, bool* foundOut); - float getValueAtPositon(float posIn); // TODO + int getNearestLocation(float xIn, bool* foundOut); + + float getValueAtPositon(float xIn); // TODO // set: // sets data array without any checks - inline void setDataArray(std::vector>* dataArrayIn) - { - m_dataArray = *dataArrayIn; - } - // sets value when m_isFixedValue is disabed - void setValue(unsigned int locationIn, float valueIn); + // inport x and y coords + void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn); + // inport y coords + void setDataArray(std::vector* dataArrayIn, bool isCurvedIn); + // sets position when m_isFixedPos is disabed, returns final location - unsigned int setPos(unsigned int locationIn, float posIn); + unsigned int setX(unsigned int locationIn, float xIn); + // sets value when m_isFixedValue is disabed + void setY(unsigned int locationIn, float yIn); + // sets value when m_isFixedValue is disabed + void setC(unsigned int locationIn, float cIn); //TODO + // sets value when m_isFixedValue is disabed + void setValA(unsigned int locationIn, float valueIn); //TODO + // sets value when m_isFixedValue is disabed + void setValB(unsigned int locationIn, float valueIn); //TODO + // sets value when m_isFixedValue is disabed + void setType(unsigned int locationIn, unsigned int typeIn); //TODO + // sets value when m_isFixedValue is disabed + void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); //TODO + // signals: // not qt // m_dataArray void dataChanged(); // color void styleChanged(); private: + class PointGraphPoint + { + public: + inline PointGraphPoint() + { + m_x = 0.0f; + m_y = 0.0f; + m_c = 0.0f; + m_valA = 0.0f; + m_valB = 0.0f; + m_type = 0; + } + inline PointGraphPoint(float xIn, float yIn) + { + m_x = xIn; + m_y = yIn; + m_c = 0.0f; + m_valA = 0.0f; + m_valB = 0.0f; + m_type = 0; + } + inline ~PointGraphPoint() + { + } + // 0 - 1 + float m_x; + // 0 (or -1) - 1 + float m_y; + // curve, -1 - 1 + float m_c; + // valueA, -1 - 1 + float m_valA; + // valueB, -1 - 1 + float m_valB; + // line type, 0 - + + unsigned int m_type; + }; // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); @@ -271,7 +345,6 @@ class LMMS_EXPORT PointGraphDataArray // can values be less than 0 bool m_nonNegative; - QColor m_lineColor; QColor m_activeColor; QColor m_fillColor; @@ -280,8 +353,8 @@ class LMMS_EXPORT PointGraphDataArray unsigned int* m_maxLength; - // ordered array of 0 < position < max_Length, -1(or 0) < value < 1 - std::vector> m_dataArray; + // ordered array of PointGraphPoints + std::vector m_dataArray; }; } // namespace lmms diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index 5c145353aea..c119abf21e5 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -84,7 +84,8 @@ std::pair PointGraphView::getSelectedData() std::pair output(0, -2.0f); if (m_isSelected == true) { - output = *model()->getDataArray(m_selectedArray)->getData(m_selectedLocation); + output.first = *model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + output.second = *model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); } return output; } @@ -93,9 +94,9 @@ void PointGraphView::setSelectedData(std::pair dataIn) if (m_isSelected == true) { qDebug("setSelectedData"); - model()->getDataArray(m_selectedArray)->setValue(m_selectedLocation, dataIn.second); + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, dataIn.second); qDebug("set value done"); - model()->getDataArray(m_selectedArray)->setPos(m_selectedLocation, dataIn.first); + model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, dataIn.first); qDebug("set position done"); m_isSelected = false; } @@ -169,7 +170,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) if (location >= 0) { qDebug("mouseRelease added %d", location); - model()->getDataArray(i)->setValue(location, curMouseData.second); + model()->getDataArray(i)->setY(location, curMouseData.second); break; } } @@ -232,7 +233,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) std::pair posB(0, 0); if (length > 0) { - std::pair posA = mapDataPos(*dataArray->getData(0), dataArray->getNonNegative()); + std::pair posA = mapDataPos(*dataArray->getX(0), *dataArray->getY(0), dataArray->getNonNegative()); // if first data/sample > 0, draw a line to the first data/sample from 0 if (posA.first > 0) @@ -243,7 +244,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) qDebug("paint size: %d", length); for (unsigned int j = 0; j < length - 1; j++) { - posB = mapDataPos(*dataArray->getData(j + 1), dataArray->getNonNegative()); + posB = mapDataPos(*dataArray->getX(j + 1), *dataArray->getY(j + 1), dataArray->getNonNegative()); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); p.drawLine(posA.first, height() - posA.second, posB.first, height() - posB.second); @@ -288,22 +289,21 @@ std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNe static_cast((yIn * 2.0f / (float)height()) - 1.0f)); } } -std::pair PointGraphView::mapDataPos(std::pair posIn, - bool nonNegativeIn) +std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) { if (nonNegativeIn == true) { // mapping the point/sample positon to mouse/view position return std::pair( - static_cast(posIn.first * width()), - static_cast(posIn.second * height())); + static_cast(xIn * width()), + static_cast(yIn * height())); } else { // mapping the point/sample positon to mouse/view position return std::pair( - static_cast(posIn.first * width()), - static_cast((posIn.second / 2.0f + 0.5f) * height())); + static_cast(xIn * width()), + static_cast((yIn / 2.0f + 0.5f) * height())); } } @@ -377,8 +377,8 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) // if getNearestLocation was successful if (location >= 0) { - std::pair transformedData = mapDataPos(*dataArray->getData(location), - dataArray->getNonNegative()); + std::pair transformedData = mapDataPos(*dataArray->getX(location), + *dataArray->getY(location), dataArray->getNonNegative()); // check distance against the pos (x) qDebug("selected x distance: %d", std::abs(transformedData.first - mouseXIn)); if (std::abs(static_cast(transformedData.first) - mouseXIn) <= m_pointSize * 2) @@ -403,7 +403,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) /* for (unsigned int j = 0; j < dataArray->size(); j++) { - std::pair* data = dataArray->getData(j); + std::pair* data = dataArray->get(j); std::pair transformedData = mapDataPos(*data, dataArray->getNonNegative()) float curDistance = getDistance(transformedData.first, mouseXIn, transformedData.second, mouseYIn); @@ -439,10 +439,17 @@ PointGraphModel::~PointGraphModel() m_dataArrays.clear(); } -unsigned int PointGraphModel::addArray(std::vector>* arrayIn) +unsigned int PointGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn) { unsigned int location = addArray(); - m_dataArrays[location].setDataArray(arrayIn); + m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); + return location; +} + +unsigned int PointGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn) +{ + unsigned int location = addArray(); + m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); return location; } @@ -627,14 +634,14 @@ QColor* PointGraphDataArray::getFillColor() // array: -int PointGraphDataArray::add(float posIn) +int PointGraphDataArray::add(float xIn) { int location = -1; if (m_dataArray.size() < *m_maxLength) { qDebug("add 1. success"); bool found = false; - location = getNearestLocation(posIn, &found); + location = getNearestLocation(xIn, &found); if (found == false && m_isFixedSize == false) { qDebug("add 2. success, nearest: %d", location); @@ -646,7 +653,7 @@ int PointGraphDataArray::add(float posIn) qDebug("add 3. success, nearest: %d", location); targetLocation = location; // slide the new data if the closest data pos is bigger - if (m_dataArray[location].first < posIn) + if (m_dataArray[location].m_x < xIn) { // we are adding one value, so dataArray.size() will be a valid location if (targetLocation < m_dataArray.size()) @@ -654,7 +661,7 @@ int PointGraphDataArray::add(float posIn) targetLocation++; } } - m_dataArray.push_back(std::pair(posIn, 0.0f)); + m_dataArray.push_back(PointGraphPoint(xIn, 0.0f)); qDebug("add 4. success, target: %d", targetLocation); swap(m_dataArray.size() - 1, targetLocation, true); dataChangedVal = true; @@ -662,7 +669,7 @@ int PointGraphDataArray::add(float posIn) else if (m_dataArray.size() <= 0) { qDebug("add 5. success"); - m_dataArray.push_back(std::pair(posIn, 0.0f)); + m_dataArray.push_back(PointGraphPoint(xIn, 0.0f)); targetLocation = 0; dataChangedVal = true; } @@ -704,26 +711,26 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) { for (unsigned int i = 0; i < m_dataArray.size(); i++) { - if (m_dataArray[i].first > 1) + if (m_dataArray[i].m_x > 1) { - m_dataArray[i].first = 1; + m_dataArray[i].m_x = 1; } - if (m_dataArray[i].second > 1) + if (m_dataArray[i].m_y > 1) { - m_dataArray[i].second = 1; + m_dataArray[i].m_y = 1; } if (m_nonNegative == true) { - if (m_dataArray[i].second < 0) + if (m_dataArray[i].m_y < 0) { - m_dataArray[i].second = 0; + m_dataArray[i].m_y = 0; } } else { - if (m_dataArray[i].second < -1) + if (m_dataArray[i].m_y < -1) { - m_dataArray[i].second = -1; + m_dataArray[i].m_y = -1; } } } @@ -734,9 +741,9 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) if (sortIn == true) { std::sort(m_dataArray.begin(), m_dataArray.end(), - [](std::pair a, std::pair b) + [](PointGraphPoint a, PointGraphPoint b) { - return a.first > b.first; + return a.m_x > b.m_x; }); } @@ -744,25 +751,25 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) unsigned int lastPos = 0; if (m_dataArray.size() > 0) { - lastPos = m_dataArray[0].first; + lastPos = m_dataArray[0].m_x; } for (unsigned int i = 1; i < m_dataArray.size(); i++) { - if (m_dataArray[i].first == lastPos) + if (m_dataArray[i].m_x == lastPos) { del(i); } else { - lastPos = m_dataArray[i].first; + lastPos = m_dataArray[i].m_x; } } } -int PointGraphDataArray::getLocation(float posIn) +int PointGraphDataArray::getLocation(float xIn) { bool found = false; - int location = getNearestLocation(posIn, &found); + int location = getNearestLocation(xIn, &found); if (found == false) { return -1; @@ -770,7 +777,7 @@ int PointGraphDataArray::getLocation(float posIn) return location; } -int PointGraphDataArray::getNearestLocation(float posIn, bool* foundOut) +int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut) { if (m_dataArray.size() > 0) { @@ -782,13 +789,13 @@ int PointGraphDataArray::getNearestLocation(float posIn, bool* foundOut) { mid = start + (end - start) / 2; qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); - qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].first, posIn); - if (m_dataArray[mid].first == posIn) + qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, xIn); + if (m_dataArray[mid].m_x == xIn) { *foundOut = true; return mid; } - else if (m_dataArray[mid].first < posIn) + else if (m_dataArray[mid].m_x < xIn) { start = mid + 1; } @@ -799,13 +806,13 @@ int PointGraphDataArray::getNearestLocation(float posIn, bool* foundOut) } int outputDif = 0; mid = start + (end - start) / 2; - if (m_dataArray[mid].first > posIn && mid > 0) + if (m_dataArray[mid].m_x > xIn && mid > 0) { mid = mid - 1; } if (mid + 1 < m_dataArray.size() && - std::abs(static_cast(m_dataArray[mid].first) - posIn) > - std::abs(static_cast(m_dataArray[mid + 1].first) - posIn)) + std::abs(static_cast(m_dataArray[mid].m_x) - xIn) > + std::abs(static_cast(m_dataArray[mid + 1].m_x) - xIn)) { outputDif = 1; } @@ -813,25 +820,25 @@ int PointGraphDataArray::getNearestLocation(float posIn, bool* foundOut) *foundOut = false; return mid + outputDif; } - qDebug("getNearestLocation, posIn: %f", posIn); + qDebug("getNearestLocation, xIn: %f", xIn); *foundOut = false; return -1; } -float PointGraphDataArray::getValueAtPositon(float posIn) +float PointGraphDataArray::getValueAtPositon(float xIn) { - float posB = posIn; + float posB = xIn; bool found = false; - unsigned int location = getNearestLocation(posIn, &found); + unsigned int location = getNearestLocation(xIn, &found); if (location >= 0) { if (found == true) { - return m_dataArray[location].second; + return m_dataArray[location].m_y; } else if (m_dataArray.size() == 1) { - return m_dataArray[0].second; + return m_dataArray[0].m_y; } else { @@ -846,7 +853,7 @@ float PointGraphDataArray::getValueAtPositon(float posIn) if (m_graphStyle == Style::Linear && m_graphStyle == Style::LinearPoints) { // if linear - value = m_dataArray[location].second * posC + m_dataArray[location + slide].second * (1.0f - posC); + value = m_dataArray[location].m_y * posC + m_dataArray[location + slide].m_y * (1.0f - posC); } else { @@ -859,27 +866,39 @@ float PointGraphDataArray::getValueAtPositon(float posIn) } } -void PointGraphDataArray::setValue(unsigned int locationIn, float valueIn) +void PointGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { - if (m_isFixedValue == false) + m_dataArray.clear(); + for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - if ((m_isFixedEndPoints == true && locationIn < m_dataArray.size() - 1 && - locationIn > 0) || m_isFixedEndPoints == false) + m_dataArray.push_back(PointGraphPoint(dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second)); + if (isCurvedIn == true) { - m_dataArray[locationIn].second = valueIn; - dataChanged(); + // TODO + } + } +} +void PointGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) +{ + m_dataArray.clear(); + for (unsigned int i = 0; i < dataArrayIn->size(); i++) + { + m_dataArray.push_back(PointGraphPoint((i / static_cast(dataArrayIn->size())), dataArrayIn->operator[](i))); + if (isCurvedIn == true) + { + // TODO } } } -unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) +unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) { int location = locationIn; - if (m_isFixedPos == false && posIn <= 1.0f) + if (m_isFixedPos == false && xIn <= 1.0f) { bool found = false; - location = getNearestLocation(posIn, &found); - // if an other point was not found at posIn + location = getNearestLocation(xIn, &found); + // if an other point was not found at xIn // and if getNearestLocation returned a value // and if dataArray end points are changeable if (found == false && ((m_isFixedEndPoints == true && @@ -893,14 +912,14 @@ unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) { // slide the new data if the closest data pos is bigger TODO test ifs qDebug("set 3. success, location: %d", targetLocation); - if (location < locationIn && m_dataArray[location].first < posIn) + if (location < locationIn && m_dataArray[location].m_x < xIn) { if (targetLocation + 1 < m_dataArray.size()) { targetLocation++; } } - else if (location > locationIn && m_dataArray[location].first > posIn) + else if (location > locationIn && m_dataArray[location].m_x > xIn) { if (targetLocation > 0) { @@ -908,7 +927,7 @@ unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) } } qDebug("set 4. success, target: %d", targetLocation); - m_dataArray[locationIn].first = posIn; + m_dataArray[locationIn].m_x = xIn; swap(locationIn, targetLocation, true); location = targetLocation; dataChanged(); @@ -926,6 +945,59 @@ unsigned int PointGraphDataArray::setPos(unsigned int locationIn, float posIn) return location; } +void PointGraphDataArray::setY(unsigned int locationIn, float yIn) +{ + if (m_isFixedValue == false) + { + if ((m_isFixedEndPoints == true && locationIn < m_dataArray.size() - 1 && + locationIn > 0) || m_isFixedEndPoints == false) + { + m_dataArray[locationIn].m_y = yIn; + dataChanged(); + } + } +} + +void PointGraphDataArray::setC(unsigned int locationIn, float cIn) +{ + m_dataArray[locationIn].m_c = cIn; + dataChanged(); +} +void PointGraphDataArray::setValA(unsigned int locationIn, float valueIn) +{ + m_dataArray[locationIn].m_valA = valueIn; + dataChanged(); +} +void PointGraphDataArray::setValB(unsigned int locationIn, float valueIn) +{ + m_dataArray[locationIn].m_valB = valueIn; + dataChanged(); +} +void PointGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) +{ + // set the type without changing the automated attribute location + m_dataArray[locationIn].m_type = typeIn + getAutomatedAttrib(locationIn); + dataChanged(); +} +void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) +{ + // only 4 attributes can be automated (y, c, valA, valB) + attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; + // get the type and add the automated location + m_dataArray[locationIn].m_type = getType(locationIn) + attribLocationIn; + dataChanged(); +} +unsigned int PointGraphDataArray::getType(unsigned int locationIn) +{ + return static_cast + (static_cast(m_dataArray[locationIn].m_type) / 4.0f); +} +unsigned int PointGraphDataArray::getAutomatedAttrib(unsigned int locationIn) +{ + return m_dataArray[locationIn].m_type - getType(locationIn); +} + + void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) { if (locationAIn != locationBIn) @@ -937,12 +1009,12 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI for (unsigned int i = 0; i < m_dataArray.size(); i++) { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].first); + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } if (locationAIn < locationBIn) { - std::pair swap = m_dataArray[locationAIn]; + PointGraphPoint swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i < locationBIn; i++) { m_dataArray[i] = m_dataArray[i + 1]; @@ -951,7 +1023,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI } else { - std::pair swap = m_dataArray[locationAIn]; + PointGraphPoint swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i > locationBIn; i--) { m_dataArray[i] = m_dataArray[i - 1]; @@ -962,12 +1034,12 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI qDebug(" --------- "); for (unsigned int i = 0; i < m_dataArray.size(); i++) { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].first); + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } } else { - std::pair swap = m_dataArray[locationAIn]; + PointGraphPoint swap = m_dataArray[locationAIn]; m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; } @@ -978,10 +1050,10 @@ void PointGraphDataArray::formatDataArrayEndPoints() { if (m_isFixedEndPoints == true && m_dataArray.size() > 0) { - m_dataArray[m_dataArray.size() - 1].first = 1; - m_dataArray[m_dataArray.size() - 1].second = 1.0f; - m_dataArray[0].first = 0; - m_dataArray[0].second = m_nonNegative == true ? 0.0f : -1.0f; + m_dataArray[m_dataArray.size() - 1].m_x = 1; + m_dataArray[m_dataArray.size() - 1].m_y = 1.0f; + m_dataArray[0].m_x = 0; + m_dataArray[0].m_y = m_nonNegative == true ? 0.0f : -1.0f; } } From 266e7ee71c888acb04c651f3bc77fdbe845fa1b7 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:57:25 +0100 Subject: [PATCH 008/184] vectorGraph_effects_added --- include/PointGraph.h | 125 ++++++++++++++++++++++++++------- src/gui/widgets/PointGraph.cpp | 108 +++++++++++++++++++++++++--- 2 files changed, 199 insertions(+), 34 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index b22a04c7d15..db659c695b8 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -10,12 +10,14 @@ #include "Model.h" #include "ModelView.h" #include "lmms_basics.h" +#include "AutomatableModel.h" namespace lmms { class PointGraphModel; class PointGraphDataArray; +class FloatModel; namespace gui { @@ -37,16 +39,24 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: automation: // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 4 value long) Done // TODO: add automation support + // TODO: make FloatModel pointer array Done + // TODO: allocate FloatModels with new Done + // TODO: delete FloatModels in destructor Done + // TODO: save FloatModels (run saveSettings) + // TODO: getter for the FloatModels for saving Done + // TODO: connect FloatModels connect with getter // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, curve, valueA, valueB Done - // TODO setPointType(unsigned int type) Done - // TODO: add effector(PointGraphDataArray) int location to the PointGraphDataArray class - // TODO: add effector line attributes to the nested class - // TODO: add effects + // TODO: setPointType(unsigned int type) Done + // TODO: add effector(PointGraphDataArray) int location to the PointGraphDataArray class Done + // TODO: add effector line attributes to the nested class Done + // TODO: add effect implementation - // TODO: clear array when 2. last point is deleted in the widget + // TODO: clear array when 2. last point is deleted in the widget IGNORE // TODO: event when a dataArray's size gets to 0 // TODO: ability to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) // TODO: check PointGraphDataArray signals + // TODO: journalling in PointGraphModel + // TODO: m_maxLenght* should be replaced with m_parent->getMaxLength() Done PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -109,7 +119,7 @@ protected slots: } // namespace gui -class LMMS_EXPORT PointGraphModel : public Model +class LMMS_EXPORT PointGraphModel : public Model//, public JournallingObject { Q_OBJECT public: @@ -148,6 +158,7 @@ Q_OBJECT { m_dataArrays.clear(); } + unsigned int getDataArrayLocation(PointGraphDataArray* dataArrayIn); // save, load //void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO @@ -173,8 +184,9 @@ class LMMS_EXPORT PointGraphDataArray { public: + // avoid using this or run updateConnections() after initialization PointGraphDataArray(); - PointGraphDataArray(unsigned int* maxLengthIn, + PointGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, PointGraphModel* parentIn); ~PointGraphDataArray(); @@ -191,7 +203,8 @@ class LMMS_EXPORT PointGraphDataArray void setLineColor(QColor colorIn); void setActiveColor(QColor colorIn); void setFillColor(QColor colorIn); - void setMaxLength(unsigned int* maxLengthIn); + // returns true if successful + bool setEffectorArrayLocation(unsigned int locationIn); bool getFixedSize(); bool getFixedValue(); @@ -203,8 +216,11 @@ class LMMS_EXPORT PointGraphDataArray QColor* getLineColor(); QColor* getActiveColor(); QColor* getFillColor(); + // returns -1 if it has no effector + int getEffectorArrayLocation(); - // array: + + // array: ------------------- // returns the location of added/found point, -1 if not found and can not be added int add(float xIn); // deletes the data/sample if m_isFixedSize is disabled @@ -225,7 +241,8 @@ class LMMS_EXPORT PointGraphDataArray // clampIn: should clamp, sortIn: should sort void formatArray(bool clampIn, bool sortIn); - // get: + + // get attribute: ------------------- inline float* getX(unsigned int locationIn) { return &m_dataArray[locationIn].m_x; @@ -248,7 +265,18 @@ class LMMS_EXPORT PointGraphDataArray } unsigned int getType(unsigned int locationIn); unsigned int getAutomatedAttrib(unsigned int locationIn); + inline bool getEffectOnlyPoints(unsigned int locationIn) + { + return &m_dataArray[locationIn].m_effectOnlyPoints; + } + bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); + inline FloatModel* getAutomationModel(unsigned int locationIn) + { + return m_dataArray[locationIn].m_automationModel; + } + + // get: ------------------- // returns -1 when position is not found int getLocation(float xIn); // gets the nearest data location to the position, @@ -258,27 +286,36 @@ class LMMS_EXPORT PointGraphDataArray float getValueAtPositon(float xIn); // TODO - // set: + + // set: ------------------- // sets data array without any checks // inport x and y coords void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn); // inport y coords void setDataArray(std::vector* dataArrayIn, bool isCurvedIn); - // sets position when m_isFixedPos is disabed, returns final location + + // set attribute: ------------------- + // sets position when m_isFixedPos is disabled, returns final location unsigned int setX(unsigned int locationIn, float xIn); - // sets value when m_isFixedValue is disabed + // sets value when m_isFixedValue is disabled void setY(unsigned int locationIn, float yIn); - // sets value when m_isFixedValue is disabed - void setC(unsigned int locationIn, float cIn); //TODO - // sets value when m_isFixedValue is disabed - void setValA(unsigned int locationIn, float valueIn); //TODO - // sets value when m_isFixedValue is disabed - void setValB(unsigned int locationIn, float valueIn); //TODO - // sets value when m_isFixedValue is disabed - void setType(unsigned int locationIn, unsigned int typeIn); //TODO - // sets value when m_isFixedValue is disabed - void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); //TODO + // sets value when m_isFixedValue is disabled + void setC(unsigned int locationIn, float cIn); + // sets value when m_isFixedValue is disabled + void setValA(unsigned int locationIn, float valueIn); + // sets value when m_isFixedValue is disabled + void setValB(unsigned int locationIn, float valueIn); + // sets value when m_isFixedValue is disabled + void setType(unsigned int locationIn, unsigned int typeIn); + // sets value when m_isFixedValue is disabled + void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); + void setEffectOnlyPoints(unsigned int locationIn, bool boolIn); + void setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn); + // if isAutomatedIn is true then make a new FloatModel and connect it, else delete + // the currently used FloatModel + void setAutomated(unsigned int locationIn, bool isAutomatedIn); // TODO + // signals: // not qt // m_dataArray @@ -297,6 +334,16 @@ class LMMS_EXPORT PointGraphDataArray m_valA = 0.0f; m_valB = 0.0f; m_type = 0; + + m_effectOnlyPoints = false; + m_effectAdd = true; + m_effectSubtract = false; + m_effectMultiply = false; + m_effectDivide = false; + m_effectPower = false; + m_effectLog = false; + + m_automationModel = nullptr; } inline PointGraphPoint(float xIn, float yIn) { @@ -306,13 +353,27 @@ class LMMS_EXPORT PointGraphDataArray m_valA = 0.0f; m_valB = 0.0f; m_type = 0; + + m_effectOnlyPoints = false; + m_effectAdd = true; + m_effectSubtract = false; + m_effectMultiply = false; + m_effectDivide = false; + m_effectPower = false; + m_effectLog = false; + + m_automationModel = nullptr; } inline ~PointGraphPoint() { + if (m_automationModel != nullptr) + { + delete m_automationModel; + } } // 0 - 1 float m_x; - // 0 (or -1) - 1 + // 0 (or -1) - 1, the automatin value is scaled if needed TODO float m_y; // curve, -1 - 1 float m_c; @@ -321,8 +382,19 @@ class LMMS_EXPORT PointGraphDataArray // valueB, -1 - 1 float m_valB; // line type, 0 - - unsigned int m_type; + + bool m_effectOnlyPoints; + + bool m_effectAdd; + bool m_effectSubtract; + bool m_effectMultiply; + bool m_effectDivide; + bool m_effectPower; + bool m_effectLog; + + // automation: connecting to floatmodels, nullptr when it isn't conntected' + FloatModel* m_automationModel; }; // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this @@ -351,7 +423,8 @@ class LMMS_EXPORT PointGraphDataArray PointGraphModel* m_parent; - unsigned int* m_maxLength; + // which PointGraphDataArray can effect this one, -1 if not effected + int m_effectorLocation; // ordered array of PointGraphPoints std::vector m_dataArray; diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index c119abf21e5..193f354a26f 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -455,7 +455,7 @@ unsigned int PointGraphModel::addArray(std::vector* arrayIn, bool isCurve unsigned int PointGraphModel::addArray() { - PointGraphDataArray tempArray(&m_maxLength, + PointGraphDataArray tempArray( false, false, false, false, false, false, false, this); m_dataArrays.push_back(tempArray); return m_dataArrays.size() - 1; @@ -479,12 +479,16 @@ void PointGraphModel::dataArrayStyleChanged() { emit styleChanged(); } +unsigned int PointGraphModel::getDataArrayLocation(PointGraphDataArray* dataArrayIn) +{ + return reinterpret_cast(&dataArrayIn) - + reinterpret_cast(&m_dataArrays) / sizeof(PointGraphDataArray); +} // PointGraphDataArray ------ PointGraphDataArray::PointGraphDataArray() { - m_maxLength = nullptr; m_isFixedSize = false; m_isFixedValue = false; m_isFixedPos = false; @@ -498,14 +502,15 @@ PointGraphDataArray::PointGraphDataArray() // is not enabled by default m_fillColor = QColor(0, 0, 0, 0); + m_effectorLocation = -1; + m_dataArray = {}; } -PointGraphDataArray::PointGraphDataArray(unsigned int* maxLengthIn, +PointGraphDataArray::PointGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, PointGraphModel* parentIn) { - m_maxLength = maxLengthIn; m_isFixedSize = isFixedSizeIn; m_isFixedValue = isFixedValueIn; m_isFixedPos = isFixedPosIn; @@ -519,6 +524,8 @@ PointGraphDataArray::PointGraphDataArray(unsigned int* maxLengthIn, // is not enabled by default m_fillColor = QColor(0, 0, 0, 0); + m_effectorLocation = -1; + m_dataArray = {}; updateConnections(parentIn); @@ -586,9 +593,30 @@ void PointGraphDataArray::setFillColor(QColor colorIn) m_fillColor = colorIn; styleChanged(); } -void PointGraphDataArray::setMaxLength(unsigned int* maxLengthIn) +bool PointGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) { - m_maxLength = maxLengthIn; + unsigned int curLocation = m_parent->getDataArrayLocation(this); + qDebug("setEffectorArrayLocation cur_loaction %d", curLocation); + int arrayLocation = locationIn; + bool found = false; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + arrayLocation = m_parent->getDataArray(arrayLocation)->getEffectorArrayLocation(); + if (arrayLocation == -1) + { + break; + } + else if(arrayLocation == curLocation) + { + found = true; + break; + } + } + if (found == false) + { + m_effectorLocation = locationIn; + } + return !found; } bool PointGraphDataArray::getFixedSize() @@ -631,13 +659,17 @@ QColor* PointGraphDataArray::getFillColor() { return &m_fillColor; } +int PointGraphDataArray::getEffectorArrayLocation() +{ + return m_effectorLocation; +} // array: int PointGraphDataArray::add(float xIn) { int location = -1; - if (m_dataArray.size() < *m_maxLength) + if (m_dataArray.size() < m_parent->getMaxLength()) { qDebug("add 1. success"); bool found = false; @@ -996,7 +1028,67 @@ unsigned int PointGraphDataArray::getAutomatedAttrib(unsigned int locationIn) { return m_dataArray[locationIn].m_type - getType(locationIn); } - +void PointGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) +{ + m_dataArray[locationIn].m_effectOnlyPoints = boolIn; +} +bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) +{ + switch (effectNumberIn) + { + case 0: + return m_dataArray[locationIn].m_effectAdd; + case 1: + return m_dataArray[locationIn].m_effectSubtract; + case 2: + return m_dataArray[locationIn].m_effectMultiply; + case 3: + return m_dataArray[locationIn].m_effectDivide; + case 4: + return m_dataArray[locationIn].m_effectPower; + case 5: + return m_dataArray[locationIn].m_effectLog; + } +} +void PointGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) +{ + switch (effectNumberIn) + { + case 0: + m_dataArray[locationIn].m_effectAdd = boolIn; + break; + case 1: + m_dataArray[locationIn].m_effectSubtract = boolIn; + break; + case 2: + m_dataArray[locationIn].m_effectMultiply = boolIn; + break; + case 3: + m_dataArray[locationIn].m_effectDivide = boolIn; + break; + case 4: + m_dataArray[locationIn].m_effectPower = boolIn; + break; + case 5: + m_dataArray[locationIn].m_effectLog = boolIn; + break; + } +} +void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) +{ + if (isAutomatedIn == true) + { + if (m_dataArray[locationIn].m_automationModel == nullptr) + { + m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.0f, nullptr, QString(), false); + } + } + else + { + delete m_dataArray[locationIn].m_automationModel; + m_dataArray[locationIn].m_automationModel = nullptr; // is this needed? TODO + } +} void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) { From 2ce57b7d7af9357c58c7472da593f51d8e9f1f66 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 10 Mar 2024 14:35:56 +0100 Subject: [PATCH 009/184] vectorGraph_attribute_implementation_finished --- include/PointGraph.h | 81 +++- src/gui/widgets/PointGraph.cpp | 669 +++++++++++++++++++++++++++------ 2 files changed, 624 insertions(+), 126 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index db659c695b8..12bf7856013 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -57,6 +57,13 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: check PointGraphDataArray signals // TODO: journalling in PointGraphModel // TODO: m_maxLenght* should be replaced with m_parent->getMaxLength() Done + // TODO: setDataArray keep attributes option + // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option + // TODO: baked values in PointGraphPoint + // TODO: rename class to VectorGraph + // TODO: make std::vector last used values + // TODO: make update logic (isChanged and update only automation / effected lines) + // TODO: effector location (same as automation location) PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -92,12 +99,23 @@ protected slots: void modelChanged() override; std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); + // calculate curve position + std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); + std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); std::pair mapDataPos(float xIn, float yIn, bool nonNegativeIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); + float getDistance(float xAIn, float yAIn, float xBIn, float yBIn); std::pair showInputDialog(); //TODO + // searches arrays to select + // clicked datapoint void selectData(int mouseXIn, int mouseYIn); + // searches for data in a given array + // returns found location, when a data + // was found in the given distance + // else it returns -1 + int searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, PointGraphDataArray* arrayIn, bool curvedIn); bool m_mouseDown; bool m_mouseDrag; @@ -112,6 +130,7 @@ protected slots: unsigned int m_selectedLocation; unsigned int m_selectedArray; bool m_isSelected; + bool m_isCurveSelected; std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; @@ -243,32 +262,34 @@ class LMMS_EXPORT PointGraphDataArray // get attribute: ------------------- - inline float* getX(unsigned int locationIn) + inline float getX(unsigned int locationIn) { - return &m_dataArray[locationIn].m_x; + return m_dataArray[locationIn].m_x; } - inline float* getY(unsigned int locationIn) + inline float getY(unsigned int locationIn) { - return &m_dataArray[locationIn].m_y; + return m_dataArray[locationIn].m_y; } - inline float* getC(unsigned int locationIn) + inline float getC(unsigned int locationIn) { - return &m_dataArray[locationIn].m_c; + return m_dataArray[locationIn].m_c; } - inline float* getValA(unsigned int locationIn) + inline float getValA(unsigned int locationIn) { - return &m_dataArray[locationIn].m_valA; + return m_dataArray[locationIn].m_valA; } - inline float* getValB(unsigned int locationIn) + inline float getValB(unsigned int locationIn) { - return &m_dataArray[locationIn].m_valB; + return m_dataArray[locationIn].m_valB; } unsigned int getType(unsigned int locationIn); - unsigned int getAutomatedAttrib(unsigned int locationIn); + // returns attribLocation: 0 = y, 1 = c, 2 = valA, 3 = valB + unsigned int getAutomatedAttribLocation(unsigned int locationIn); inline bool getEffectOnlyPoints(unsigned int locationIn) { - return &m_dataArray[locationIn].m_effectOnlyPoints; + return m_dataArray[locationIn].m_effectOnlyPoints; } + // returns if the [effectNumberIn] effect is active based on effectNumberIn bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); inline FloatModel* getAutomationModel(unsigned int locationIn) { @@ -282,9 +303,9 @@ class LMMS_EXPORT PointGraphDataArray // gets the nearest data location to the position, // foundOut is true when the nearest position = posIn, // reurns -1 when search failed - int getNearestLocation(float xIn, bool* foundOut); + int getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut); - float getValueAtPositon(float xIn); // TODO + float getValueAtPosition(float xIn); // TODO // set: ------------------- @@ -373,15 +394,19 @@ class LMMS_EXPORT PointGraphDataArray } // 0 - 1 float m_x; - // 0 (or -1) - 1, the automatin value is scaled if needed TODO + // 0 (or -1) - 1, getAutomatedAttrib() -> 0 float m_y; - // curve, -1 - 1 + // curve, -1 - 1, getAutomatedAttrib() -> 1 float m_c; - // valueA, -1 - 1 + // valueA, -1 - 1, getAutomatedAttrib() -> 2 float m_valA; - // valueB, -1 - 1 + // valueB, -1 - 1, getAutomatedAttrib() -> 3 float m_valB; - // line type, 0 - + // line type: + // 0 - none + // 1 - sine + // 2 - steps + // 3 - random unsigned int m_type; bool m_effectOnlyPoints; @@ -399,6 +424,24 @@ class LMMS_EXPORT PointGraphDataArray // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); + // applys the effect on a given value, does clamp TODO clamp + float processEffect(float valueIn, float effectValueIn, + PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn, float lowerLimitIn); + // returns the curve value at a given x coord + float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); + // returns a PointGraphPoint with modified attributes + float processAutomation(unsigned int locationIn, unsigned int attribLocationIn); + // line effects / types, m_type is used for this + // valA: amp, valB: freq, fadeOutStartIn: from what xIn value should the line type fade out + float processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeOutStartIn); + //std::vector processLineTypeArraySine(std::vector xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn); + // valA: amp, valB: x coord, curve: width + float processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); + // y: calculate steps from, valA: y count, valB: curve + float processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeOutStartIn); + // valA: amp, valB: random number count, curveIn: seed + float processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); + // checks m_isFixedEndPoints, does not call dataChanged() void formatDataArrayEndPoints(); diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index 193f354a26f..89b36f40e29 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -2,10 +2,11 @@ #include #include +#include +#include #include #include #include -#include #include "PointGraph.h" @@ -34,8 +35,9 @@ PointGraphView::PointGraphView(QWidget * parentIn, m_selectedLocation = 0; m_selectedArray = 0; m_isSelected = false; + m_isCurveSelected = false; - m_lastTrackPoint.first = 0; + m_lastTrackPoint.first = -1; m_lastTrackPoint.second = 0; m_lastScndTrackPoint.first = 0; m_lastScndTrackPoint.second = 0; @@ -84,8 +86,8 @@ std::pair PointGraphView::getSelectedData() std::pair output(0, -2.0f); if (m_isSelected == true) { - output.first = *model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); - output.second = *model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); + output.first = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + output.second = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); } return output; } @@ -96,9 +98,8 @@ void PointGraphView::setSelectedData(std::pair dataIn) qDebug("setSelectedData"); model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, dataIn.second); qDebug("set value done"); - model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, dataIn.first); + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, dataIn.first); qDebug("set position done"); - m_isSelected = false; } } @@ -144,7 +145,53 @@ void PointGraphView::mouseMoveEvent(QMouseEvent* me) // get position int x = me->x(); int y = me->y(); - m_mousePress = false; + + if (m_lastTrackPoint.first < 0) + { + m_lastTrackPoint.first = m_lastScndTrackPoint.first = x; + m_lastTrackPoint.second = m_lastScndTrackPoint.second = height() - y; + m_mousePress = true; + } + else + { + if (m_isSelected == true) + { + if (m_isCurveSelected == false) + { + std::pair convertedCoords = mapMousePos(x, height() - y, model()->getDataArray(m_selectedArray)->getNonNegative()); + convertedCoords.first = convertedCoords.first > 1.0f ? 1.0f : convertedCoords.first < -1.0f ? -1.0f : convertedCoords.first; + convertedCoords.second = convertedCoords.second > 1.0f ? 1.0f : convertedCoords.second < 0.0f ? 0.0f : convertedCoords.second; + setSelectedData(convertedCoords); + } + else + { + std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, height() - y + m_lastTrackPoint.second, + model()->getDataArray(m_selectedArray)->getNonNegative()); + float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; + curveValue = curveValue > 1.0f ? 1.0f : curveValue < -1.0f ? -1.0f : curveValue; + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); + } + m_mousePress = false; + } + else if (m_addition == false) + { + // TODO deletion + } + else + { + float curDistance = getDistance(x, height() - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize * 2) + { + // TODO drawing + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = height() - y; + + m_mousePress = false; + } + // else m_mousePress does not change + } + } } void PointGraphView::mouseReleaseEvent(QMouseEvent* me) @@ -179,6 +226,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) { // if selection was successful and deletion model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + m_isSelected = false; } m_mousePress = false; @@ -191,6 +239,8 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) m_addition = false; m_mouseDown = false; m_mouseDrag = false; + // reset trackpoint + m_lastTrackPoint.first = -1; // triggering paintEvent qDebug("mouseReleaseEnd"); update(); @@ -230,30 +280,49 @@ void PointGraphView::paintEvent(QPaintEvent* pe) p.drawLine(10, 10, 20, 20); } - std::pair posB(0, 0); if (length > 0) { - std::pair posA = mapDataPos(*dataArray->getX(0), *dataArray->getY(0), dataArray->getNonNegative()); + std::pair posA(0, 0); + std::pair posB(0, 0); // if first data/sample > 0, draw a line to the first data/sample from 0 - if (posA.first > 0) - { + //if (posA.first > 0) + //{ //p.drawLine(0, posA.second, posA.first, posA.second); - } + //} // drawing lines qDebug("paint size: %d", length); - for (unsigned int j = 0; j < length - 1; j++) + if (dataArray->getSelectable() == true) { - posB = mapDataPos(*dataArray->getX(j + 1), *dataArray->getY(j + 1), dataArray->getNonNegative()); + for (unsigned int j = 0; j < length; j++) + { + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); + p.drawEllipse(posB.first - m_pointSize, height() - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + if (j > 0) + { + std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + p.drawRect(posC.first - m_pointSize / 2, height() - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + } + posA = posB; + } + } + posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); + for (unsigned int j = 0; j < width(); j++) + { + //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1), dataArray->getNonNegative()); + posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); + //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); + posB.first = j; + //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); p.drawLine(posA.first, height() - posA.second, posB.first, height() - posB.second); posA = posB; } - if (posA.first < width()) - { + //if (posA.first < width()) + //{ //p.drawLine(posA.first, posA.second, width(), posA.second); - } + //} } } } @@ -306,11 +375,27 @@ std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNeg static_cast((yIn / 2.0f + 0.5f) * height())); } } +std::pair PointGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) +{ + return std::pair( + (xAIn + xBIn) / 2.0f, + yAIn + (curveIn / 2.0f + 0.5f) * (yBIn - yAIn)); +} +std::pair PointGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn) +{ + return std::pair( + (xAIn + xBIn) / 2, + yAIn + static_cast((curveIn / 2.0f + 0.5f) * (yBIn - yAIn))); +} float PointGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) { return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); } +float PointGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBIn) +{ + return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); +} std::pair PointGraphView::showInputDialog() { @@ -346,83 +431,170 @@ std::pair PointGraphView::showInputDialog() void PointGraphView::selectData(int mouseXIn, int mouseYIn) { qDebug("selectData"); - //float minDistance = m_pointSize + 1.0; m_selectedLocation = 0; m_selectedArray = 0; m_isSelected = false; - - std::pair transformedMouseA = mapMousePos(mouseXIn, mouseYIn, false); - std::pair transformedMouseB = mapMousePos(mouseXIn, mouseYIn, true); - std::pair* transformedMouse = &transformedMouseA; + m_isCurveSelected = false; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { PointGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getNonNegative() == true) + if (dataArray->getSelectable() == true) { - transformedMouse = &transformedMouseB; + int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); + if (location > -1) + { + qDebug("selected data!"); + m_selectedLocation = location; + m_selectedArray = i; + qDebug("selected data location: %d, %d", location, i); + m_isSelected = true; + m_isCurveSelected = false; + break; + } } - else + } + if (m_isSelected == false) + { + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - transformedMouse = &transformedMouseA; + PointGraphDataArray* dataArray = model()->getDataArray(i); + if (dataArray->getSelectable() == true) + { + int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); + if (location > -1) + { + qDebug("selected data curve!"); + m_selectedLocation = location; + m_selectedArray = i; + qDebug("selected data curve location: %d, %d", location, i); + m_isSelected = true; + m_isCurveSelected = true; + break; + } + } } - if (dataArray->getSelectable() == true) + } + qDebug("selectDataEnd"); +} + +int PointGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, PointGraphDataArray* arrayIn, bool curvedIn) +{ + int output = -1; + float maxDistance = maxDistanceIn * 2.0f; + qDebug("searchData"); + + std::pair transformedMouse = mapMousePos(mouseXIn, mouseYIn, arrayIn->getNonNegative()); + + // we dont use this bool + bool found = false; + bool isBefore = false; + // get the nearest data to the mouse pos (x) in an optimalized way + int location = arrayIn->getNearestLocation(transformedMouse.first, &found, &isBefore); + qDebug("selected location: %d", location); + + // if getNearestLocation was successful + if (location >= 0) + { + float dataX = arrayIn->getX(location); + float dataY = arrayIn->getY(location); + // this is set to one when curveIn == true + // and isBefore == false + int curvedBefore = 0; + // if curved then get the closest curved coord + if (curvedIn == true && arrayIn->size() > 1) { - // we dont use this bool - bool found = false; - // get the nearest data to the mouse pos (x) in an optimalized way - int location = dataArray->getNearestLocation(transformedMouse->first, &found); - qDebug("selected location: %d", location); + if (isBefore == false && 1 < location) + { + curvedBefore = 1; + } + if (location - curvedBefore < arrayIn->size() - 1) + { + std::pair curvedDataCoords = mapDataCurvePos( + arrayIn->getX(location - curvedBefore), arrayIn->getY(location - curvedBefore), + arrayIn->getX(location - curvedBefore + 1), arrayIn->getY(location - curvedBefore + 1), + arrayIn->getC(location - curvedBefore)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; + } + } + // check distance against x coord + qDebug("selected x distance: %f", std::abs(dataX - transformedMouse.first)); + if (std::abs(dataX - transformedMouse.first) <= maxDistance) + { + // calculate real distance (x and y) + float curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); - // if getNearestLocation was successful - if (location >= 0) + qDebug("selected full distance: %f (%d, %d)", curDistance, location, (location - curvedBefore)); + if (curDistance <= maxDistance) { - std::pair transformedData = mapDataPos(*dataArray->getX(location), - *dataArray->getY(location), dataArray->getNonNegative()); - // check distance against the pos (x) - qDebug("selected x distance: %d", std::abs(transformedData.first - mouseXIn)); - if (std::abs(static_cast(transformedData.first) - mouseXIn) <= m_pointSize * 2) + qDebug("search successful"); + output = location - curvedBefore; + } + else + { + // sometimes the mouse x and the nearest point x + // coordinates are close but the y coords are not + // calculating and testing all near by point distances + int searchStart = 0; + int searchEnd = arrayIn->size() - 1; + // from where we need to search the data + for (int i = location - curvedBefore - 1; i > 0; i--) { - // calculate real distance (x and y) - qDebug("selected cords: %d, %d, %d, %d", mouseXIn, mouseYIn, - transformedData.first, transformedData.second); - float curDistance = getDistance(mouseXIn, mouseYIn, - transformedData.first, transformedData.second); - - qDebug("selected full distance: %f", curDistance); - if (curDistance <= m_pointSize) + if (std::abs(arrayIn->getX(i) - transformedMouse.first) > maxDistance) { - qDebug("selection Made!"); - m_selectedLocation = location; - m_selectedArray = i; - m_isSelected = true; + // if it is curved, then subtract 1 + // add 1 to i because [i] > maxDistanceIn + searchStart = i + 1 - (i > 0 && curvedIn == true ? 1 : 0); break; } } - } -/* - for (unsigned int j = 0; j < dataArray->size(); j++) - { - std::pair* data = dataArray->get(j); - std::pair transformedData = mapDataPos(*data, dataArray->getNonNegative()) - float curDistance = getDistance(transformedData.first, mouseXIn, - transformedData.second, mouseYIn); - if (curDistance <= m_pointSize)// && curDistance < minDistance) + qDebug("search V2AAA temp, start: %d, end: %d", searchStart, searchEnd); + // getting where the search needs to end + for (int i = location - curvedBefore + 1; i < arrayIn->size(); i++) { - //minDistance = curDistance; - m_selectedLocation = j; - m_selectedArray = i; - m_isSelected = true; - break; + if (std::abs(arrayIn->getX(i) - transformedMouse.first) > maxDistance) + { + searchEnd = i - 1 - (i > 0 && curvedIn == true ? 1 : 0); + break; + } + } + qDebug("search V2, start: %d, end: %d", searchStart, searchEnd); + // calculating real distances from the point coords + for (int i = searchStart; i <= searchEnd; i++) + { + if (i != location) + { + dataX = arrayIn->getX(i); + dataY = arrayIn->getY(i); + if (curvedIn == true && arrayIn->size() > 1) + { + if (arrayIn->size() - 1 > i) + { + std::pair curvedDataCoords = mapDataCurvePos( + arrayIn->getX(i), arrayIn->getY(i), arrayIn->getX(i + 1), arrayIn->getY(i + 1), + arrayIn->getC(i)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; + } + } + curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); + qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%d", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); + if (curDistance <= maxDistance) + { + qDebug("search successful V2"); + output = i; + break; + } + } } } - if (m_isSelected == true) - { - break; - }*/ } } - qDebug("selectDataEnd"); + qDebug("searchDataEnd"); + return output; } } // namespace gui @@ -673,7 +845,8 @@ int PointGraphDataArray::add(float xIn) { qDebug("add 1. success"); bool found = false; - location = getNearestLocation(xIn, &found); + bool isBefore = false; + location = getNearestLocation(xIn, &found, &isBefore); if (found == false && m_isFixedSize == false) { qDebug("add 2. success, nearest: %d", location); @@ -685,7 +858,7 @@ int PointGraphDataArray::add(float xIn) qDebug("add 3. success, nearest: %d", location); targetLocation = location; // slide the new data if the closest data pos is bigger - if (m_dataArray[location].m_x < xIn) + if (isBefore == true) { // we are adding one value, so dataArray.size() will be a valid location if (targetLocation < m_dataArray.size()) @@ -801,7 +974,8 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) int PointGraphDataArray::getLocation(float xIn) { bool found = false; - int location = getNearestLocation(xIn, &found); + bool isBefore = false; + int location = getNearestLocation(xIn, &found, &isBefore); if (found == false) { return -1; @@ -809,7 +983,7 @@ int PointGraphDataArray::getLocation(float xIn) return location; } -int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut) +int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut) { if (m_dataArray.size() > 0) { @@ -820,11 +994,12 @@ int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut) while (start < end) { mid = start + (end - start) / 2; - qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); - qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, xIn); + //qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); + //qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, xIn); if (m_dataArray[mid].m_x == xIn) { *foundOut = true; + *isBeforeOut = false; return mid; } else if (m_dataArray[mid].m_x < xIn) @@ -843,59 +1018,157 @@ int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut) mid = mid - 1; } if (mid + 1 < m_dataArray.size() && - std::abs(static_cast(m_dataArray[mid].m_x) - xIn) > - std::abs(static_cast(m_dataArray[mid + 1].m_x) - xIn)) + std::abs(m_dataArray[mid].m_x - xIn) > + std::abs(m_dataArray[mid + 1].m_x - xIn)) { outputDif = 1; + //*isBeforeOut = false; } - qDebug("getNearestLocation, outputDif: %d", outputDif); + //qDebug("getNearestLocation, outputDif: %d", outputDif); *foundOut = false; + if (mid + 1 < m_dataArray.size()) + { + bool isBeforeOutB = xIn < m_dataArray[mid].m_x ? true : m_dataArray[mid + 1].m_x < xIn; + if (isBeforeOutB != *isBeforeOut) + { + qDebug("getNearestLocation, BEFOREBUG xIn: %f", xIn); + } + } + *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } - qDebug("getNearestLocation, xIn: %f", xIn); + //qDebug("getNearestLocation, xIn: %f", xIn); *foundOut = false; + *isBeforeOut = false; return -1; } -float PointGraphDataArray::getValueAtPositon(float xIn) +float PointGraphDataArray::getValueAtPosition(float xIn) { - float posB = xIn; + float output = 0.0f; bool found = false; - unsigned int location = getNearestLocation(xIn, &found); - if (location >= 0) + bool isBefore = false; + int locationBefore = getNearestLocation(xIn, &found, &isBefore); + // get values of points (process effect if it effects only points) + // draw line + // process effect (if it effects lines too) + if (locationBefore >= 0) { + // y limit for clamping + float lowerLimit = m_nonNegative == true ? 0.0f : -1.0f; + // location after should be location before + 1 + // or it is equal to locationBefore when it is on an edge + locationBefore = isBefore == true ? locationBefore : locationBefore - 1; + int locationAfter = locationBefore + 1; + if (locationAfter >= m_dataArray.size()) + { + locationAfter = locationBefore; + } + if (locationBefore < 0) + { + locationBefore++; + locationAfter = locationBefore; + } + + float pointEffectYBefore = processAutomation(locationBefore, 0); + float pointEffectYAfter = processAutomation(locationAfter, 0); + + //qDebug("getVALUE, locationBefore1: %d", locationBefore); + //qDebug("getVALUE, locationAfer: %d", locationAfter); + // temp effecor data + PointGraphDataArray* tempEArray = nullptr; + bool tempEFound = false; + bool tempEIsBefore = false; + int tempELocation = -1; + // if this data array has an effector data array + if (m_effectorLocation >= 0) + { + tempEArray = m_parent->getDataArray(m_effectorLocation); + + // do not change order + // locationAfter + tempELocation = tempEArray->getNearestLocation(m_dataArray[locationAfter].m_x, &tempEFound, &tempEIsBefore); + tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; + if (tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + { + float effectValue = tempEArray->getValueAtPosition(m_dataArray[locationAfter].m_x); + // apply effects + pointEffectYAfter = processEffect(pointEffectYAfter, + effectValue, tempEArray, tempELocation, lowerLimit); + } + + // locationBefore + tempELocation = tempEArray->getNearestLocation(m_dataArray[locationBefore].m_x, &tempEFound, &tempEIsBefore); + tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; + // if the effector point can only change points + if (tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + { + float effectValue = tempEArray->getValueAtPosition(m_dataArray[locationBefore].m_x); + // apply effects + pointEffectYBefore = processEffect(pointEffectYBefore, + effectValue, tempEArray, tempELocation, lowerLimit); + } + } + if (found == true) { - return m_dataArray[location].m_y; + output = pointEffectYAfter; } - else if (m_dataArray.size() == 1) + else if (locationAfter == locationBefore) { - return m_dataArray[0].m_y; + // if the nearest point is an edge + output = pointEffectYBefore; } else { - float posC = posB - static_cast(static_cast(posB)); - int slide = 1; - float value = 0.0f; - if (location == m_dataArray.size() - 1) + float transformedX = (xIn - m_dataArray[locationBefore].m_x) / (m_dataArray[locationAfter].m_x - m_dataArray[locationBefore].m_x); + // type effects TODO + unsigned int type = getType(locationBefore); + float fadeOutStart = 0.95f; + if (type == 0) { - slide = -1; + output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationAfter, 1), transformedX); } - /* - if (m_graphStyle == Style::Linear && m_graphStyle == Style::LinearPoints) + else if (type == 1) { - // if linear - value = m_dataArray[location].m_y * posC + m_dataArray[location + slide].m_y * (1.0f - posC); + output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); + output = output + processLineTypeSine(transformedX, processAutomation(locationAfter, 2), + processAutomation(locationAfter, 3), fadeOutStart); } - else + else if (type == 2) { - // if curved TODO - + output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); + output = output + processLineTypePeak(transformedX, processAutomation(locationAfter, 2), + processAutomation(locationAfter, 3), processAutomation(locationAfter, 1), fadeOutStart); + } + else if (type == 3) + { + output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); + output = output + processLineTypeSteps(transformedX, output, processAutomation(locationAfter, 2), + processAutomation(locationAfter, 3), fadeOutStart); } - */ - return value; + else if (type == 4) + { + output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); + output = output + processLineTypeRandom(transformedX, processAutomation(locationAfter, 2), + processAutomation(locationAfter, 3), processAutomation(locationAfter, 1), fadeOutStart); + } + //qDebug("getVALUE, value2: %f %f - %d %d - %f %f", output, xIn, locationBefore, locationAfter, transformedX, pointEffectBefore); + //qDebug("getVALUE, transfrmedX: %f", transformedX); + //qDebug("getVALUE, x: %f", xIn); + } + + // if this data array has an effector data array + // and it does not only effect data points + if (m_effectorLocation >= 0 && tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + { + // TODO use getValueAtPosition + float effectValue = tempEArray->getValueAtPosition(xIn); + output = processEffect(output, + effectValue, tempEArray, tempELocation, lowerLimit); } } + return output; } void PointGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) @@ -929,7 +1202,8 @@ unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) if (m_isFixedPos == false && xIn <= 1.0f) { bool found = false; - location = getNearestLocation(xIn, &found); + bool isBefore = false; + location = getNearestLocation(xIn, &found, &isBefore); // if an other point was not found at xIn // and if getNearestLocation returned a value // and if dataArray end points are changeable @@ -944,14 +1218,14 @@ unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) { // slide the new data if the closest data pos is bigger TODO test ifs qDebug("set 3. success, location: %d", targetLocation); - if (location < locationIn && m_dataArray[location].m_x < xIn) + if (location < locationIn && isBefore == true) { if (targetLocation + 1 < m_dataArray.size()) { targetLocation++; } } - else if (location > locationIn && m_dataArray[location].m_x > xIn) + else if (location > locationIn && isBefore == false) { if (targetLocation > 0) { @@ -1008,7 +1282,7 @@ void PointGraphDataArray::setValB(unsigned int locationIn, float valueIn) void PointGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { // set the type without changing the automated attribute location - m_dataArray[locationIn].m_type = typeIn + getAutomatedAttrib(locationIn); + m_dataArray[locationIn].m_type = typeIn + getAutomatedAttribLocation(locationIn); dataChanged(); } void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) @@ -1024,7 +1298,7 @@ unsigned int PointGraphDataArray::getType(unsigned int locationIn) return static_cast (static_cast(m_dataArray[locationIn].m_type) / 4.0f); } -unsigned int PointGraphDataArray::getAutomatedAttrib(unsigned int locationIn) +unsigned int PointGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) { return m_dataArray[locationIn].m_type - getType(locationIn); } @@ -1138,7 +1412,188 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI dataChanged(); } } -void PointGraphDataArray::formatDataArrayEndPoints() +float PointGraphDataArray::processEffect(float valueIn, float effectValueIn, + PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn, float lowerLimitIn) +{ + float output = valueIn; + if (effectArrayIn->getEffect(effectLocationIn, 4) == true) + { + // power + output = std::pow(output, effectValueIn); + } + else if (effectArrayIn->getEffect(effectLocationIn, 5) == true) + { + // log + output = std::log(output) / std::log(effectValueIn); + } + + if (effectArrayIn->getEffect(effectLocationIn, 2) == true) + { + // multiply + output = output * 5.0f * effectValueIn; + } + else if (effectArrayIn->getEffect(effectLocationIn, 3) == true) + { + output = output / 5.0f / effectValueIn; + // divide + } + + if (effectArrayIn->getEffect(effectLocationIn, 0) == true) + { + // add + output += effectValueIn; + } + else if (effectArrayIn->getEffect(effectLocationIn, 1) == true) + { + // subtract + output -= effectValueIn; + } + // clamp + if (output > 1.0f) + { + output = 1.0f; + } + else if (output < lowerLimitIn) + { + output = lowerLimitIn; + } + return output; +} +float PointGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) +{ + float absCurveIn = std::abs(curveIn); + float pow = curveIn < 0.0f ? 1.0f - xIn : xIn; + // float xVal = curveIn > 0.0f ? xIn + (1.0f - xIn) * absCurveIn : xIn * (1.0f - absCurveIn); + // float xVal = curveIn > 0.0f ? 1.0 - xIn : xIn; + pow = std::pow(pow, 1.0f - absCurveIn) - pow; + + //float output = valueBeforeIn + (valueAfterIn - valueBeforeIn) * xVal + log * (valueAfterIn - valueBeforeIn); + + float output = valueBeforeIn + (valueAfterIn - valueBeforeIn) * xIn; + output = curveIn > 0.0f ? output + pow * (valueAfterIn - valueBeforeIn) : output - pow * (valueAfterIn - valueBeforeIn); + if (valueBeforeIn > valueAfterIn) + { + output = output < valueAfterIn ? valueAfterIn : output > valueBeforeIn ? valueBeforeIn : output; + } + else + { + output = output < valueBeforeIn ? valueBeforeIn : output > valueAfterIn ? valueAfterIn : output; + } + return output; +} + +float PointGraphDataArray::processAutomation(unsigned int locationIn, unsigned int attribLocationIn) +{ + float output = 0.0f; + // if automated + FloatModel* automationModel = getAutomationModel(locationIn); + if (automationModel != nullptr) + { + unsigned int attribLocation = getAutomatedAttribLocation(locationIn); + if (attribLocation = attribLocationIn) + { + output += automationModel->value(); + } + } + if (attribLocationIn == 0) + { + output += m_dataArray[locationIn].m_y; + } + else if (attribLocationIn == 1) + { + output += m_dataArray[locationIn].m_c; + } + else if (attribLocationIn == 2) + { + output += m_dataArray[locationIn].m_valA; + } + else if (attribLocationIn == 3) + { + output += m_dataArray[locationIn].m_valB; + } + + output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; + return output; +} +float PointGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeOutStartIn) +{ + // sine + float output = valAIn * std::sin(xIn * valBIn); + + // fade out + if (xIn > fadeOutStartIn) + { + output = output * (1.0f - xIn) / (1.0f - fadeOutStartIn); + } + return output; +} +float PointGraphDataArray::processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +{ + // peak + float output = std::pow(curveIn * 0.4f + 0.01f, std::abs(xIn - valBIn) * 10.0f) * valAIn; + + // fade in + float fadeInEnd = 1.0f - fadeOutStartIn; + if (xIn < fadeInEnd) + { + output = output * xIn / fadeInEnd; + } + // fade out + if (xIn > fadeOutStartIn) + { + output = output * (1.0f - xIn) / fadeInEnd; + } + return output; +} +float PointGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeOutStartIn) +{ + // TODO opmtimalize + // step + float stepCount = std::floor(valAIn); + float stepSize = 2.0f / stepCount; + float curStep = std::floor(yIn / stepSize); + float diff = curStep * stepSize - yIn; + float output = diff * (valBIn + 1.0f) / 2.0f + stepSize * (2.0f - (valBIn + 1.0f) / 2.0f); + + // fade in + float fadeInEnd = 1.0f - fadeOutStartIn; + if (xIn < fadeInEnd) + { + output = output * xIn / fadeInEnd; + } + // fade out + if (xIn > fadeOutStartIn) + { + output = output * (1.0f - xIn) / fadeInEnd; + } + return output; +} +float PointGraphDataArray::processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +{ + // randomize + float blend = 50.0f + curveIn * 50.0f; + int randomSeed = static_cast(blend); + blend = blend - randomSeed; + std::srand(randomSeed); + int curLocation = static_cast(xIn * (1.0f + valBIn) * 50.0f); + float output = 0.0f; + // getting the current random value + for (unsigned int i = 1; i <= curLocation; i++) + { + if (i == curLocation) + { + output = rand(); + } + else + { + rand(); + } + } + output = output * blend * (blend - 2.0f) * - 1.0f - rand() * (1.0f - blend) * (-1.0f - blend); + return output * valAIn; +} + +void PointGraphDataArray::PointGraphDataArray::formatDataArrayEndPoints() { if (m_isFixedEndPoints == true && m_dataArray.size() > 0) { From ed0c40d9dafa62468e8c603fa37dd7ce7dd9af8b Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:07:46 +0100 Subject: [PATCH 010/184] VectorGraph_updated_gui --- include/PointGraph.h | 133 ++- plugins/FFTFilter/FFTFilterControlDialog.cpp | 2 +- plugins/FFTFilter/FFTFilterControls.cpp | 9 +- src/gui/widgets/PointGraph.cpp | 1042 ++++++++++++++---- 4 files changed, 962 insertions(+), 224 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index 12bf7856013..cf626aae70e 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -44,12 +44,12 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: delete FloatModels in destructor Done // TODO: save FloatModels (run saveSettings) // TODO: getter for the FloatModels for saving Done - // TODO: connect FloatModels connect with getter + // TODO: connect FloatModels connect with getter Done // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, curve, valueA, valueB Done // TODO: setPointType(unsigned int type) Done // TODO: add effector(PointGraphDataArray) int location to the PointGraphDataArray class Done // TODO: add effector line attributes to the nested class Done - // TODO: add effect implementation + // TODO: add effect implementation Done // TODO: clear array when 2. last point is deleted in the widget IGNORE // TODO: event when a dataArray's size gets to 0 @@ -58,12 +58,17 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: journalling in PointGraphModel // TODO: m_maxLenght* should be replaced with m_parent->getMaxLength() Done // TODO: setDataArray keep attributes option - // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option + // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option Done // TODO: baked values in PointGraphPoint // TODO: rename class to VectorGraph - // TODO: make std::vector last used values + // TODO: make std::vector last used values Done // TODO: make update logic (isChanged and update only automation / effected lines) // TODO: effector location (same as automation location) + // TODO: PointGraphView isSimplified Done + // TODO: new automated color Done + // TODO: context menu in gui (clear automation, connect to controller) + // TODO: display hints (full text) in the editing + // TODO: ability to edit multiple graphs using m_isLastSelectedArray PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -73,14 +78,19 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); + void setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn); inline PointGraphModel* model() { return castModel(); } - - // returns -2.0f at second when nothing is selected + + void setIsSimplified(bool isSimplifiedIn); + + // returns -1.0f at first when nothing is selected std::pair getSelectedData(); + // returns -1 it can not return a array location + int getLastSelectedArray(); void setSelectedData(std::pair dataIn); signals: @@ -92,7 +102,7 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView void mousePressEvent(QMouseEvent* me) override; //TODO void mouseMoveEvent(QMouseEvent* me) override; //TODO void mouseReleaseEvent(QMouseEvent* me) override; //TODO - void mouseDoubleClickEvent(QMouseEvent* me) override; + void mouseDoubleClickEvent(QMouseEvent* me) override; //TODO protected slots: void updateGraph(); private: @@ -103,11 +113,27 @@ protected slots: std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); std::pair mapDataPos(float xIn, float yIn, bool nonNegativeIn); + int mapInputPos(float inputValueIn, unsigned int displayLengthIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); float getDistance(float xAIn, float yAIn, float xBIn, float yBIn); - std::pair showInputDialog(); //TODO + // returns true if the graph was clicked + bool isGraphPressed(int mouseYIn); + // returns -1 if no attribute was clicked + int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); + // returns a float attrib value, valueOut = attrib value if it is a bool + float getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut); + // sets the attrib to floatValueIn it it is float, else it sets the attrib to boolValueIn + void setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn); + // calculates the ideal text color + QColor getTextColorFromBaseColor(QColor baseColorIn); + // returns the first x char that fits in the displayedLength(in pixel) + // cuts the string to displayedLength(in px) size + QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); + + std::pair showCoordInputDialog(); + float showInputDialog(float curInputValueIn); // searches arrays to select // clicked datapoint void selectData(int mouseXIn, int mouseYIn); @@ -126,12 +152,26 @@ protected slots: // radius, rx = ry unsigned int m_pointSize; + // draw simplified lines + bool m_isSimplified; unsigned int m_selectedLocation; unsigned int m_selectedArray; bool m_isSelected; bool m_isCurveSelected; - + // if m_selectedArray was the last array selected + bool m_isLastSelectedArray; + + unsigned int m_graphHeight; + unsigned int m_editingHeight; + // displayed attrib count + unsigned int m_editingInputCount; + unsigned int m_editingDisplayPage; + bool m_isEditingActive; + std::vector m_editingText; + std::vector m_editingLineEffectText; + std::vector m_editingInputIsFloat; + std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; }; @@ -207,34 +247,41 @@ class LMMS_EXPORT PointGraphDataArray PointGraphDataArray(); PointGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, - bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, PointGraphModel* parentIn); + bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, + bool isSaveableIn, PointGraphModel* parentIn); ~PointGraphDataArray(); void updateConnections(PointGraphModel* parentIn); - void setFixedSize(bool valueIn); - void setFixedValue(bool valueIn); - void setFixedPos(bool valueIn); - void setFixedEndPoints(bool valueIn); - void setSelectable(bool valueIn); - void setEditableAttrib(bool valueIn); + void setIsFixedSize(bool valueIn); + void setIsFixedValue(bool valueIn); + void setIsFixedPos(bool valueIn); + void setIsFixedEndPoints(bool valueIn); + void setIsSelectable(bool valueIn); + void setIsEditableAttrib(bool valueIn); + void setIsAutomatableEffectable(bool valueIn); + void setIsSaveable(bool valueIn); void setNonNegative(bool valueIn); void setLineColor(QColor colorIn); void setActiveColor(QColor colorIn); void setFillColor(QColor colorIn); + void setAutomatedColor(QColor colorIn); // returns true if successful bool setEffectorArrayLocation(unsigned int locationIn); - bool getFixedSize(); - bool getFixedValue(); - bool getFixedPos(); - bool getFixedEndPoints(); - bool getSelectable(); - bool getEditableAttrib(); + bool getIsFixedSize(); + bool getIsFixedValue(); + bool getIsFixedPos(); + bool getIsFixedEndPoints(); + bool getIsSelectable(); + bool getIsEditableAttrib(); + bool getIsAutomatableEffectable(); + bool getIsSaveable(); bool getNonNegative(); QColor* getLineColor(); QColor* getActiveColor(); QColor* getFillColor(); + QColor* getAutomatedColor(); // returns -1 if it has no effector int getEffectorArrayLocation(); @@ -282,9 +329,13 @@ class LMMS_EXPORT PointGraphDataArray { return m_dataArray[locationIn].m_valB; } - unsigned int getType(unsigned int locationIn); + inline unsigned int getType(unsigned int locationIn) + { + return m_dataArray[locationIn].m_type; + } // returns attribLocation: 0 = y, 1 = c, 2 = valA, 3 = valB unsigned int getAutomatedAttribLocation(unsigned int locationIn); + unsigned int getEffectedAttribLocation(unsigned int locationIn); inline bool getEffectOnlyPoints(unsigned int locationIn) { return m_dataArray[locationIn].m_effectOnlyPoints; @@ -325,12 +376,13 @@ class LMMS_EXPORT PointGraphDataArray void setC(unsigned int locationIn, float cIn); // sets value when m_isFixedValue is disabled void setValA(unsigned int locationIn, float valueIn); - // sets value when m_isFixedValue is disabled + // void setValB(unsigned int locationIn, float valueIn); - // sets value when m_isFixedValue is disabled + // void setType(unsigned int locationIn, unsigned int typeIn); - // sets value when m_isFixedValue is disabled + // void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); + void setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn); void setEffectOnlyPoints(unsigned int locationIn, bool boolIn); void setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn); // if isAutomatedIn is true then make a new FloatModel and connect it, else delete @@ -355,6 +407,7 @@ class LMMS_EXPORT PointGraphDataArray m_valA = 0.0f; m_valB = 0.0f; m_type = 0; + m_automatedEffectedAttribLocations = 0; m_effectOnlyPoints = false; m_effectAdd = true; @@ -363,6 +416,7 @@ class LMMS_EXPORT PointGraphDataArray m_effectDivide = false; m_effectPower = false; m_effectLog = false; + m_effectSine = false; m_automationModel = nullptr; } @@ -374,6 +428,7 @@ class LMMS_EXPORT PointGraphDataArray m_valA = 0.0f; m_valB = 0.0f; m_type = 0; + m_automatedEffectedAttribLocations = 0; m_effectOnlyPoints = false; m_effectAdd = true; @@ -382,6 +437,7 @@ class LMMS_EXPORT PointGraphDataArray m_effectDivide = false; m_effectPower = false; m_effectLog = false; + m_effectSine = false; m_automationModel = nullptr; } @@ -405,9 +461,16 @@ class LMMS_EXPORT PointGraphDataArray // line type: // 0 - none // 1 - sine - // 2 - steps - // 3 - random + // 2 - sineB + // 3 - peak + // 4 - steps + // 5 - random unsigned int m_type; + // the automated attrib location and + // the effected attrib location is + // stored here + // use getAutomatedAttrib or getEffectedAttrib to get it + unsigned int m_automatedEffectedAttribLocations; bool m_effectOnlyPoints; @@ -417,6 +480,7 @@ class LMMS_EXPORT PointGraphDataArray bool m_effectDivide; bool m_effectPower; bool m_effectLog; + bool m_effectSine; // automation: connecting to floatmodels, nullptr when it isn't conntected' FloatModel* m_automationModel; @@ -434,6 +498,8 @@ class LMMS_EXPORT PointGraphDataArray // line effects / types, m_type is used for this // valA: amp, valB: freq, fadeOutStartIn: from what xIn value should the line type fade out float processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeOutStartIn); + // curveIn: phase + float processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); //std::vector processLineTypeArraySine(std::vector xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn); // valA: amp, valB: x coord, curve: width float processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); @@ -456,13 +522,19 @@ class LMMS_EXPORT PointGraphDataArray // can PointGraphView select this bool m_isSelectable; // can PointGraphView edit the point attributes + // every attribute outside of x and y bool m_isEditableAttrib; + // can the points be automated or effected + bool m_isAutomatableEffectable; + // if PointGraphDataArray is allowed to save this + bool m_isSaveable; // can values be less than 0 bool m_nonNegative; QColor m_lineColor; QColor m_activeColor; QColor m_fillColor; + QColor m_automatedColor; PointGraphModel* m_parent; @@ -471,6 +543,11 @@ class LMMS_EXPORT PointGraphDataArray // ordered array of PointGraphPoints std::vector m_dataArray; + + // baking + bool m_isDataChanged; + // array containing output final float values for optimalization + std::vector m_bakedValues; }; } // namespace lmms diff --git a/plugins/FFTFilter/FFTFilterControlDialog.cpp b/plugins/FFTFilter/FFTFilterControlDialog.cpp index c1067e3d1c3..bcee09c4c78 100644 --- a/plugins/FFTFilter/FFTFilterControlDialog.cpp +++ b/plugins/FFTFilter/FFTFilterControlDialog.cpp @@ -108,7 +108,7 @@ FFTFilterControlDialog::FFTFilterControlDialog(FFTFilterControls* controls) : auto curGraph = new PointGraphView(this, 300, 200, 10, 1024); curGraph->setModel(&controls->m_graphModel); - resetButton->move(100, 240); + curGraph->move(100, 240); /* auto swapInputs = new LedCheckBox("Swap inputs", this, tr("Swap inputs"), LedCheckBox::LedColor::Green); swapInputs->move( 20, 275 ); diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index c4b1af6ea6a..308bc54ee2e 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -43,7 +43,14 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_displayFFTModel( true, this, tr("Display fft")), m_graphModel(1024, this, false) { - m_graphModel.addArray(); + unsigned int arrayLocation = m_graphModel.addArray(); + m_graphModel.getDataArray(arrayLocation)->setIsSelectable(true); + m_graphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); + m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); + m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(255, 50, 50, 255)); + m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 0, 0, 255)); + m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(200, 25, 25, 255)); + m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(0, 200, 255, 255)); } diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index 89b36f40e29..db40bc22a06 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -9,6 +9,7 @@ #include #include "PointGraph.h" +#include "StringPairDrag.h" namespace lmms @@ -31,11 +32,41 @@ PointGraphView::PointGraphView(QWidget * parentIn, m_addition = false; m_pointSize = pointSizeIn; + m_isSimplified = false; m_selectedLocation = 0; m_selectedArray = 0; m_isSelected = false; m_isCurveSelected = false; + m_isLastSelectedArray = false; + + m_graphHeight = height(); + m_editingHeight = 30; + m_editingInputCount = 4; + m_editingDisplayPage = 0; + m_isEditingActive = false; + m_editingText = { + tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), + tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), + tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), + tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), + tr("\"sine\" effect") + }; + m_editingLineEffectText = { + tr("none"), + tr("sine"), + tr("phase changable sine"), + tr("peak"), + tr("steps"), + tr("random") + }; + m_editingInputIsFloat = { + true, true, true, true, + true, false, false, + false, false, false, false, + false, false, false, false, + false + }; m_lastTrackPoint.first = -1; m_lastTrackPoint.second = 0; @@ -53,7 +84,9 @@ PointGraphView::PointGraphView(QWidget * parentIn, } PointGraphView::~PointGraphView() { - + m_editingText.clear(); + m_editingInputIsFloat.clear(); + m_editingLineEffectText.clear(); } void PointGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -80,10 +113,23 @@ void PointGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocation update(); } } +void PointGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn) +{ + if (model()->getDataArraySize() > dataArrayLocationIn) + { + model()->getDataArray(dataArrayLocationIn)->setAutomatedColor(colorIn); + update(); + } +} + +void PointGraphView::setIsSimplified(bool isSimplifiedIn) +{ + m_isSimplified = isSimplifiedIn; +} std::pair PointGraphView::getSelectedData() { - std::pair output(0, -2.0f); + std::pair output(-1.0f, 0.00); if (m_isSelected == true) { output.first = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); @@ -91,6 +137,14 @@ std::pair PointGraphView::getSelectedData() } return output; } +int PointGraphView::getLastSelectedArray() +{ + if (m_isLastSelectedArray == true) + { + return m_selectedArray; + } + return -1; +} void PointGraphView::setSelectedData(std::pair dataIn) { if (m_isSelected == true) @@ -108,32 +162,42 @@ void PointGraphView::mousePressEvent(QMouseEvent* me) // get position int x = me->x(); int y = me->y(); - if (me->button() == Qt::LeftButton) + m_addition = false; + + if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) { - // add - m_addition = true; - // show new inputDialog to change data if control is pressed - if ((me->modifiers() & Qt::ControlModifier) == true) + qDebug("mousePress automation started"); + // connect to automation + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + // check if setAutomated is failed (like when isAutomatableEffecable is not enabled) + if (curFloatModel != nullptr) { - selectData(x, height() - y); - // if selecting was successful - if (m_isSelected == true) - { - // display dialog - std::pair curData = showInputDialog(); - // change data - setSelectedData(curData); - } + qDebug("mousePress automation sent"); + new gui::StringPairDrag("automatable_model", QString::number(curFloatModel->id()), QPixmap(), widget()); + me->accept(); } - else + } + else if (isGraphPressed(y) == true) + { + // try selecting the clicked point (if it is near) + selectData(x, m_graphHeight - y); + + if (me->button() == Qt::LeftButton) + { + // add + m_addition = true; + m_mousePress = true; + } + else if (me->button() == Qt::RightButton) { + // delete + m_addition = false; m_mousePress = true; } } - else if (me->button() == Qt::RightButton) + else { - // delete - m_addition = false; m_mousePress = true; } m_mouseDown = true; @@ -143,53 +207,98 @@ void PointGraphView::mousePressEvent(QMouseEvent* me) void PointGraphView::mouseMoveEvent(QMouseEvent* me) { // get position - int x = me->x(); + // the x coord is clamped because + // m_lastTrackPoint.first < 0 is used + int x = me->x() >= 0 ? me->x() : 0; int y = me->y(); + bool startMoving = false; if (m_lastTrackPoint.first < 0) { m_lastTrackPoint.first = m_lastScndTrackPoint.first = x; - m_lastTrackPoint.second = m_lastScndTrackPoint.second = height() - y; + m_lastTrackPoint.second = m_lastScndTrackPoint.second = m_graphHeight - y; m_mousePress = true; } - else + + if (m_mousePress == true) { - if (m_isSelected == true) + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) { - if (m_isCurveSelected == false) + m_mousePress = false; + startMoving = true; + } + } + + // if the mouse was moved a lot + if (m_mousePress == false) + { + if (isGraphPressed(m_graphHeight - m_lastScndTrackPoint.second) == true) + { + if (m_isSelected == true && m_addition == true) + { + if (m_isCurveSelected == false) + { + std::pair convertedCoords = mapMousePos(x, m_graphHeight - y, model()->getDataArray(m_selectedArray)->getNonNegative()); + convertedCoords.first = convertedCoords.first > 1.0f ? 1.0f : convertedCoords.first < 0.0f ? 1.0f : convertedCoords.first; + convertedCoords.second = convertedCoords.second > 1.0f ? 1.0f : convertedCoords.second < -1.0f ? -1.0f : convertedCoords.second; + setSelectedData(convertedCoords); + } + else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) + { + std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second, + model()->getDataArray(m_selectedArray)->getNonNegative()); + float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; + curveValue = curveValue > 1.0f ? 1.0f : curveValue < -1.0f ? -1.0f : curveValue; + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); + } + } + else if (m_addition == false) { - std::pair convertedCoords = mapMousePos(x, height() - y, model()->getDataArray(m_selectedArray)->getNonNegative()); - convertedCoords.first = convertedCoords.first > 1.0f ? 1.0f : convertedCoords.first < -1.0f ? -1.0f : convertedCoords.first; - convertedCoords.second = convertedCoords.second > 1.0f ? 1.0f : convertedCoords.second < 0.0f ? 0.0f : convertedCoords.second; - setSelectedData(convertedCoords); + // TODO deletion } else { - std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, height() - y + m_lastTrackPoint.second, - model()->getDataArray(m_selectedArray)->getNonNegative()); - float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; - curveValue = curveValue > 1.0f ? 1.0f : curveValue < -1.0f ? -1.0f : curveValue; - model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize * 2) + { + // TODO drawing + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + } + // else m_mousePress does not change } - m_mousePress = false; - } - else if (m_addition == false) - { - // TODO deletion } else { - float curDistance = getDistance(x, height() - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize * 2) + // if editing inputs were pressed (not graph) + int pressLocation = getPressedInput(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, m_editingInputCount + 1); + if (pressLocation >= 0 && pressLocation < m_editingInputCount) { - // TODO drawing - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = height() - y; - - m_mousePress = false; + // pressLocation should always be >= 0 + unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; + // if the input type is a float + if (location < m_editingText.size() && m_editingInputIsFloat[location] == true) + { + // if the user just started to move the mouse it is pressed + if (startMoving == true) + { + // unused bool + bool isTrue = false; + // set m_lastScndTrackPoint.first to the current input value + m_lastScndTrackPoint.first = mapInputPos(getInputAttribValue(location, &isTrue), m_graphHeight); + + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, x, (m_graphHeight - y), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); + } + std::pair convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(m_graphHeight - y - m_lastTrackPoint.second) / 2, + model()->getDataArray(m_selectedArray)->getNonNegative()); + setInputAttribValue(location, convertedCoords.second, false); + } } - // else m_mousePress does not change } } } @@ -199,42 +308,101 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) // get position int x = me->x(); int y = me->y(); - if (m_mousePress == true) + if (isGraphPressed(m_graphHeight - y) == true) { - // add/delete point - selectData(x, height() - y); - if (m_isSelected == false && m_addition == true) + qDebug("mouseMove graphPressed: %d", m_lastTrackPoint.first); + if (m_mousePress == true) { - // if selection failed and addition - // get the first editable daraArray and add value - qDebug("release size: %ld", model()->getDataArraySize()); - for(unsigned int i = 0; i < model()->getDataArraySize(); i++) + // add/delete point + if (m_isSelected == false && m_addition == true) { - std::pair curMouseData = mapMousePos(x, height() - y, - model()->getDataArray(i)->getNonNegative()); // TODO optimize - int location = model()->getDataArray(i)->add(curMouseData.first); - // if adding was successful - if (location >= 0) + // if selection failed and addition + // get the first editable daraArray and add value + qDebug("release size: %ld", model()->getDataArraySize()); + for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - qDebug("mouseRelease added %d", location); - model()->getDataArray(i)->setY(location, curMouseData.second); - break; + std::pair curMouseData = mapMousePos(x, m_graphHeight - y, + model()->getDataArray(i)->getNonNegative()); // TODO optimize + int location = model()->getDataArray(i)->add(curMouseData.first); + // if adding was successful + if (location >= 0) + { + qDebug("mouseRelease added %d %f,%d", location, curMouseData.second, m_graphHeight); + model()->getDataArray(i)->setY(location, curMouseData.second); + break; + } } } + else if (m_isSelected == true && m_addition == false) + { + // if selection was successful and deletion + model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + m_isSelected = false; + m_isEditingActive = false; + } + + m_mousePress = false; } - else if (m_isSelected == true && m_addition == false) + else { - // if selection was successful and deletion - model()->getDataArray(m_selectedArray)->del(m_selectedLocation); - m_isSelected = false; - } + // add/set/delete line end - m_mousePress = false; + } } - else + else if (m_mousePress == true) { - // add/set/delete line end + qDebug("mouseMove 7: %d", m_lastTrackPoint.first); + int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); + if (pressLocation == m_editingInputCount) + { + // if the last button was pressed + + // how many inputs are there + int editingTextCount = m_editingText.size(); + if (m_isSelected == true) + { + if (model()->getDataArray(m_selectedLocation)->getIsEditableAttrib() == false) + { + // x, y + editingTextCount = 2; + } + else if (model()->getDataArray(m_selectedLocation)->getIsAutomatableEffectable() == false) + { + // x, y, curve, valA, valB, switch type + editingTextCount = 6; + } + } + m_editingDisplayPage++; + if (m_editingInputCount * m_editingDisplayPage >= editingTextCount) + { + m_editingDisplayPage = 0; + } + qDebug("mouseMove editingPage: %d", m_editingDisplayPage); + } + else if (pressLocation >= 0) + { + // pressLocation should always be >= 0 + unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; + // setting the boolean values + if (location < m_editingText.size() && m_editingInputIsFloat[location] == false) + { + bool curBoolValue = true; + //if (location >= 5 && location <= 7) + //{ + // curBoolValue = true; + //} + //else + // if location is not at "set type" or "set automation location" or "set effect location" + // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) + if (location < 5 || location > 7) + { + getInputAttribValue(location, &curBoolValue); + curBoolValue = !curBoolValue; + } + setInputAttribValue(location, 0.0f, curBoolValue); + } + } } m_addition = false; m_mouseDown = false; @@ -249,13 +417,36 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) void PointGraphView::mouseDoubleClickEvent(QMouseEvent * me) { + // get position + int x = me->x(); + int y = me->y(); + // if a data/sample is selected then show input dialog to change the data - if (m_isSelected == true && me->button() == Qt::LeftButton) + if (isGraphPressed(m_graphHeight - y) == true) { - // display dialog - std::pair curData = showInputDialog(); - // change data - setSelectedData(curData); + if (m_isSelected == true && me->button() == Qt::LeftButton) + { + // display dialog + std::pair curData = showCoordInputDialog(); + // change data + setSelectedData(curData); + } + } + else + { + int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); + if (pressLocation >= 0 && pressLocation != m_editingInputCount) + { + unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; + if (location < m_editingText.size() && m_editingInputIsFloat[location] == true) + { + // unused bool + bool isTrue = false; + // set m_lastScndTrackPoint.first to the current input value + float curValue = getInputAttribValue(location, &isTrue); + setInputAttribValue(location, showInputDialog(curValue), isTrue); + } + } } } @@ -263,12 +454,13 @@ void PointGraphView::paintEvent(QPaintEvent* pe) { QPainter p(this); //QPainterPath pt(); // TODO - qDebug("paintEvent"); + m_graphHeight = m_isEditingActive == true ? height() - m_editingHeight : height(); + PointGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - PointGraphDataArray* dataArray = model()->getDataArray(i); + dataArray = model()->getDataArray(i); p.setPen(QPen(*dataArray->getLineColor(), 1)); QColor gcolor = QColor(dataArray->getLineColor()->red(), dataArray->getLineColor()->green(), dataArray->getLineColor()->blue(), 100); @@ -292,32 +484,43 @@ void PointGraphView::paintEvent(QPaintEvent* pe) //} // drawing lines qDebug("paint size: %d", length); - if (dataArray->getSelectable() == true) + if (dataArray->getIsSelectable() == true) { for (unsigned int j = 0; j < length; j++) { + //qDebug("draw: x: %f, y: %f", dataArray->getX(j), dataArray->getY(j)); posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); - p.drawEllipse(posB.first - m_pointSize, height() - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + p.drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); if (j > 0) { - std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - p.drawRect(posC.first - m_pointSize / 2, height() - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + if (dataArray->getIsEditableAttrib() == true) + { + std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + p.drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + } + if (m_isSimplified == true) + { + p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + } } posA = posB; } } - posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); - for (unsigned int j = 0; j < width(); j++) + if (m_isSimplified == false) { - //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1), dataArray->getNonNegative()); - posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); - //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); - posB.first = j; - //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); - // x1, y1, x2, y2 - //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - p.drawLine(posA.first, height() - posA.second, posB.first, height() - posB.second); - posA = posB; + posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); + for (unsigned int j = 0; j < width(); j++) + { + //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1), dataArray->getNonNegative()); + posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); + //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); + posB.first = j; + //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); + // x1, y1, x2, y2 + //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); + p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + posA = posB; + } } //if (posA.first < width()) //{ @@ -325,6 +528,91 @@ void PointGraphView::paintEvent(QPaintEvent* pe) //} } } + + if (m_isEditingActive == true) + { + dataArray = model()->getDataArray(m_selectedArray); + QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); + // background of float values + QColor backColor(25, 25, 25, 255); + QColor foreColor = *dataArray->getLineColor(); + if (dataArray->getFillColor()->alpha() > 0) + { + backColor = QColor(dataArray->getFillColor()->red() / 2, dataArray->getFillColor()->green() / 2, + dataArray->getFillColor()->blue() / 2, 255); + foreColor = *dataArray->getFillColor(); + } + + int editingTextCount = m_editingText.size(); + if (dataArray->getIsEditableAttrib() == false) + { + // x, y + editingTextCount = 2; + } + else if (dataArray->getIsAutomatableEffectable() == false) + { + // x, y, curve, valA, valB, switch type + editingTextCount = 6; + } + + int segmentLength = width() / (m_editingInputCount + 1); + // draw inputs + p.setPen(textColor); + for (unsigned int i = 0; i < m_editingInputCount; i++) + { + if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount) + { + if (m_editingInputIsFloat[m_editingInputCount * m_editingDisplayPage + i] == true) + { + QColor curForeColor = foreColor; + // unused bool + bool isTrue = false; + float inputValue = getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); + if (dataArray->getAutomationModel(m_selectedLocation) != nullptr && static_cast(getInputAttribValue(6, &isTrue)) == i - 1) + { + curForeColor = *dataArray->getAutomatedColor(); + } + else if (dataArray->getIsAutomatableEffectable() == true && static_cast(getInputAttribValue(7, &isTrue)) == i - 1) + { + curForeColor = *dataArray->getActiveColor(); + } + p.fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, backColor); + p.fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_editingHeight, curForeColor); + p.drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, + getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); + } + else + { + QColor curForeColor = *dataArray->getFillColor(); + bool isTrue = false; + // unused float + float inputValue = getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); + if (isTrue == true) + { + curForeColor = *dataArray->getActiveColor(); + } + p.fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, curForeColor); + p.drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, + getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); + } + } + } + + // draw "next page" button + p.fillRect(m_editingInputCount * segmentLength, m_graphHeight, segmentLength, m_editingHeight, *dataArray->getFillColor()); + p.setPen(textColor); + p.drawText(m_editingInputCount * segmentLength, m_graphHeight + m_editingHeight / 2, ">>"); + // draw outline + p.setPen(*dataArray->getLineColor()); + p.drawLine(0, m_graphHeight, width(), m_graphHeight); + for (unsigned int i = 1; i < m_editingInputCount + 1; i++) + { + if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount || i >= m_editingInputCount) + { + p.drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); + } + } + } } void PointGraphView::modelChanged() @@ -348,14 +636,14 @@ std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNe // mapping the position to 0 - 1, 0 - 1 using qWidget width and height return std::pair( static_cast(xIn / (float)width()), - static_cast(yIn / (float)height())); + static_cast(yIn / (float)m_graphHeight)); } else { // mapping the position to 0 - 1, -1 - 1 using qWidget width and height return std::pair( static_cast(xIn / (float)width()), - static_cast((yIn * 2.0f / (float)height()) - 1.0f)); + static_cast((yIn * 2.0f / (float)m_graphHeight) - 1.0f)); } } std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) @@ -365,14 +653,14 @@ std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNeg // mapping the point/sample positon to mouse/view position return std::pair( static_cast(xIn * width()), - static_cast(yIn * height())); + static_cast(yIn * m_graphHeight)); } else { // mapping the point/sample positon to mouse/view position return std::pair( static_cast(xIn * width()), - static_cast((yIn / 2.0f + 0.5f) * height())); + static_cast((yIn / 2.0f + 0.5f) * m_graphHeight)); } } std::pair PointGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) @@ -387,6 +675,10 @@ std::pair PointGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBIn (xAIn + xBIn) / 2, yAIn + static_cast((curveIn / 2.0f + 0.5f) * (yBIn - yAIn))); } +int PointGraphView::mapInputPos(float inputValueIn, unsigned int displayLengthIn) +{ + return (inputValueIn / 2.0f + 0.5f) * displayLengthIn; +} float PointGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) { @@ -397,7 +689,231 @@ float PointGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBIn return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); } -std::pair PointGraphView::showInputDialog() +bool PointGraphView::isGraphPressed(int mouseYIn) +{ + if (m_isEditingActive == true && mouseYIn > m_graphHeight) + { + return false; + } + return true; +} +int PointGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) +{ + int output = -1; + if (m_isEditingActive == true && mouseYIn > m_graphHeight) + { + output = mouseXIn * inputCountIn / width(); + } + if (output > inputCountIn) + { + output = inputCountIn; +qDebug("getPressedInput x location ERRROR: %d", mouseXIn); + } + return output; +} +float PointGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut) +{ + float output = 0.0f; + if (m_isSelected == true) + { + switch (editingArrayLocationIn) + { + case 0: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + break; + case 1: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); + break; + case 2: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); + break; + case 3: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); + break; + case 4: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); + break; + case 5: + // type + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); + break; + case 6: + // automation location + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); + break; + case 7: + // effect location + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); + break; + case 8: + *valueOut = model()->getDataArray(m_selectedArray)->getEffectOnlyPoints(m_selectedLocation); + break; + case 9: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); + break; + case 10: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); + break; + case 11: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); + break; + case 12: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); + break; + case 13: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); + break; + case 14: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); + break; + case 15: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); + break; + } + } + return output; +} +void PointGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn) +{ + qDebug("setInputAttribValue started"); + if (m_isSelected == true) + { + float clampedValue = floatValueIn < -1.0f ? -1.0f : floatValueIn > 1.0f ? 1.0f : floatValueIn; + unsigned int clampedValueB = 0; + switch (editingArrayLocationIn) + { + case 0: + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, clampedValue < 0.0f ? 0.0f : clampedValue); + break; + case 1: + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); + break; + case 2: + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, clampedValue); + break; + case 3: + model()->getDataArray(m_selectedArray)->setValA(m_selectedLocation, clampedValue); + break; + case 4: + model()->getDataArray(m_selectedArray)->setValB(m_selectedLocation, clampedValue); + break; + case 5: + // type + clampedValueB = 0; + if (boolValueIn == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation) + 1; + if (clampedValueB > 5) + { + clampedValueB = 0; + } + } + else + { + clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 5.0f ? 5.0f : floatValueIn)); + } + model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); + break; + case 6: + // automation location + clampedValueB = 0; + if (boolValueIn == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation) + 1; + if (clampedValueB > 4) + { + clampedValueB = 0; + } + } + else + { + clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 4.0f ? 4.0f : floatValueIn)); + } + model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); + break; + case 7: + // effect location + clampedValueB = 0; + if (boolValueIn == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation) + 1; + if (clampedValueB > 4) + { + clampedValueB = 0; + } + } + else + { + clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 4.0f ? 4.0f : floatValueIn)); + } + model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); + break; + case 8: + model()->getDataArray(m_selectedArray)->setEffectOnlyPoints(m_selectedLocation, boolValueIn); + break; + case 9: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValueIn); + break; + case 10: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValueIn); + break; + case 11: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValueIn); + break; + case 12: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValueIn); + break; + case 13: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValueIn); + break; + case 14: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValueIn); + break; + case 15: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValueIn); + break; + } + } + qDebug("setInputAttribValue finished"); +} +QColor PointGraphView::getTextColorFromBaseColor(QColor baseColorIn) +{ + QColor output(255, 255, 255, 255); + int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); + if (colorSum > 382) + { + output = QColor(0, 0, 0, 255); + } + return output; +} +QString PointGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) +{ + int charLength = 4; + QString output = ""; + int targetSize = displayLengthIn / charLength < textIn.size() ? displayLengthIn / charLength : textIn.size(); + for (unsigned int i = 0; i < targetSize; i++) + { + if (i + 3 < targetSize) + { + output = output + textIn[i]; + } + else + { + output = output + QString("."); + } + } + return output; +} + +std::pair PointGraphView::showCoordInputDialog() { std::pair curData(0.0f, 0.0f); if (m_isSelected == true) @@ -407,26 +923,42 @@ std::pair PointGraphView::showInputDialog() // show position input dialog bool ok; - double changedPos = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between 0 and ") + QString::number(100.0), + double changedX = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between 0 and 100"), static_cast(curData.first * 100.0f), 0.0, 100.0, 0, &ok); if (ok == true) { - curData.first = static_cast(changedPos) / 100.0f; + curData.first = static_cast(changedX) / 100.0f; } - double changedValue = QInputDialog::getDouble(this, tr("Set value"), + double changedY = QInputDialog::getDouble(this, tr("Set value"), tr("Please enter a new value between ") + QString::number(minValue) + tr(" and 100"), static_cast(curData.second * 100.0f), minValue, 100.0, 2, &ok); if (ok == true) { - curData.second = static_cast(changedValue) / 100.0f; + curData.second = static_cast(changedY) / 100.0f; } } return curData; } +float PointGraphView::showInputDialog(float curInputValueIn) +{ + float output = 0.0f; + + bool ok; + double changedPos = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between -100 and 100"), + static_cast(curInputValueIn * 100.0f), + -100.0, 100.0, 0, &ok); + if (ok == true) + { + output = static_cast(changedPos) / 100.0f; + } + + return output; +} void PointGraphView::selectData(int mouseXIn, int mouseYIn) { @@ -435,11 +967,12 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) m_selectedArray = 0; m_isSelected = false; m_isCurveSelected = false; + m_isEditingActive = false; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { PointGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getSelectable() == true) + if (dataArray->getIsSelectable() == true) { int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); if (location > -1) @@ -450,6 +983,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) qDebug("selected data location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = false; + m_isEditingActive = dataArray->getIsEditableAttrib(); break; } } @@ -459,7 +993,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { PointGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getSelectable() == true) + if (dataArray->getIsSelectable() == true) { int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); if (location > -1) @@ -470,6 +1004,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) qDebug("selected data curve location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = true; + m_isEditingActive = dataArray->getIsEditableAttrib(); break; } } @@ -628,7 +1163,7 @@ unsigned int PointGraphModel::addArray(std::vector* arrayIn, bool isCurve unsigned int PointGraphModel::addArray() { PointGraphDataArray tempArray( - false, false, false, false, false, false, false, this); + false, false, false, false, false, false, false, false, true, this); m_dataArrays.push_back(tempArray); return m_dataArrays.size() - 1; } @@ -667,21 +1202,27 @@ PointGraphDataArray::PointGraphDataArray() m_isFixedEndPoints = false; m_isSelectable = false; m_isEditableAttrib = false; + m_isAutomatableEffectable = false; + m_isSaveable = false; m_nonNegative = false; m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); // is not enabled by default m_fillColor = QColor(0, 0, 0, 0); + m_automatedColor = QColor(0, 0, 0, 0); m_effectorLocation = -1; m_dataArray = {}; + m_isDataChanged = true; + m_bakedValues = {}; } PointGraphDataArray::PointGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, - bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, PointGraphModel* parentIn) + bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, + bool isSaveableIn, PointGraphModel* parentIn) { m_isFixedSize = isFixedSizeIn; m_isFixedValue = isFixedValueIn; @@ -689,6 +1230,8 @@ PointGraphDataArray::PointGraphDataArray( m_isFixedEndPoints = isFixedEndPointsIn; m_isSelectable = isSelectableIn; m_isEditableAttrib = isEditableAttribIn; + m_isAutomatableEffectable = isAutomatableEffectableIn; + m_isSaveable = isSaveableIn; m_nonNegative = nonNegativeIn; m_lineColor = QColor(200, 200, 200, 255); @@ -698,7 +1241,9 @@ PointGraphDataArray::PointGraphDataArray( m_effectorLocation = -1; - m_dataArray = {}; + // m_dataArray = {}; + m_isDataChanged = true; + // m_bakedValues = {}; updateConnections(parentIn); } @@ -714,37 +1259,55 @@ void PointGraphDataArray::updateConnections(PointGraphModel* parentIn) m_parent = parentIn; } -void PointGraphDataArray::setFixedSize(bool valueIn) +void PointGraphDataArray::setIsFixedSize(bool valueIn) { m_isFixedSize = valueIn; dataChanged(); } -void PointGraphDataArray::setFixedValue(bool valueIn) +void PointGraphDataArray::setIsFixedValue(bool valueIn) { m_isFixedValue = valueIn; dataChanged(); } -void PointGraphDataArray::setFixedPos(bool valueIn) +void PointGraphDataArray::setIsFixedPos(bool valueIn) { m_isFixedPos = valueIn; dataChanged(); } -void PointGraphDataArray::setFixedEndPoints(bool valueIn) +void PointGraphDataArray::setIsFixedEndPoints(bool valueIn) { m_isFixedEndPoints = valueIn; formatDataArrayEndPoints(); dataChanged(); } -void PointGraphDataArray::setSelectable(bool valueIn) +void PointGraphDataArray::setIsSelectable(bool valueIn) { m_isSelectable = valueIn; dataChanged(); } -void PointGraphDataArray::setEditableAttrib(bool valueIn) +void PointGraphDataArray::setIsEditableAttrib(bool valueIn) { m_isEditableAttrib = valueIn; dataChanged(); } +void PointGraphDataArray::setIsAutomatableEffectable(bool valueIn) +{ + m_isAutomatableEffectable = valueIn; + if (valueIn == false) + { + setEffectorArrayLocation(-1); + } + else + { + // setEffectorArray will call dataChanged() + dataChanged(); + } +} +void PointGraphDataArray::setIsSaveable(bool valueIn) +{ + m_isSaveable = valueIn; + dataChanged(); +} void PointGraphDataArray::setNonNegative(bool valueIn) { m_nonNegative = valueIn; @@ -765,56 +1328,82 @@ void PointGraphDataArray::setFillColor(QColor colorIn) m_fillColor = colorIn; styleChanged(); } +void PointGraphDataArray::setAutomatedColor(QColor colorIn) +{ + m_automatedColor = colorIn; + styleChanged(); +} bool PointGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) { - unsigned int curLocation = m_parent->getDataArrayLocation(this); - qDebug("setEffectorArrayLocation cur_loaction %d", curLocation); - int arrayLocation = locationIn; - bool found = false; - for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + bool found = true; + if (locationIn >= 0) { - arrayLocation = m_parent->getDataArray(arrayLocation)->getEffectorArrayLocation(); - if (arrayLocation == -1) + unsigned int curLocation = m_parent->getDataArrayLocation(this); + qDebug("setEffectorArrayLocation cur_loaction %d", curLocation); + int arrayLocation = locationIn; + found = false; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) { - break; + arrayLocation = m_parent->getDataArray(arrayLocation)->getEffectorArrayLocation(); + if (arrayLocation == -1) + { + break; + } + else if(arrayLocation == curLocation) + { + found = true; + break; + } } - else if(arrayLocation == curLocation) + if (found == false) { - found = true; - break; + m_effectorLocation = locationIn; + dataChanged(); } } - if (found == false) + else { - m_effectorLocation = locationIn; + if (m_effectorLocation != -1) + { + dataChanged(); + } + m_effectorLocation = -1; } return !found; } -bool PointGraphDataArray::getFixedSize() +bool PointGraphDataArray::getIsFixedSize() { return m_isFixedSize; } -bool PointGraphDataArray::getFixedValue() +bool PointGraphDataArray::getIsFixedValue() { return m_isFixedValue; } -bool PointGraphDataArray::getFixedPos() +bool PointGraphDataArray::getIsFixedPos() { return m_isFixedPos; } -bool PointGraphDataArray::getFixedEndPoints() +bool PointGraphDataArray::getIsFixedEndPoints() { return m_isFixedEndPoints; } -bool PointGraphDataArray::getSelectable() +bool PointGraphDataArray::getIsSelectable() { return m_isSelectable; } -bool PointGraphDataArray::getEditableAttrib() +bool PointGraphDataArray::getIsEditableAttrib() { return m_isEditableAttrib; } +bool PointGraphDataArray::getIsAutomatableEffectable() +{ + return m_isAutomatableEffectable; +} +bool PointGraphDataArray::getIsSaveable() +{ + return m_isSaveable; +} bool PointGraphDataArray::getNonNegative() { return m_nonNegative; @@ -831,6 +1420,10 @@ QColor* PointGraphDataArray::getFillColor() { return &m_fillColor; } +QColor* PointGraphDataArray::getAutomatedColor() +{ + return &m_automatedColor; +} int PointGraphDataArray::getEffectorArrayLocation() { return m_effectorLocation; @@ -1026,14 +1619,14 @@ int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isB } //qDebug("getNearestLocation, outputDif: %d", outputDif); *foundOut = false; - if (mid + 1 < m_dataArray.size()) - { - bool isBeforeOutB = xIn < m_dataArray[mid].m_x ? true : m_dataArray[mid + 1].m_x < xIn; - if (isBeforeOutB != *isBeforeOut) - { - qDebug("getNearestLocation, BEFOREBUG xIn: %f", xIn); - } - } + //if (mid + 1 < m_dataArray.size()) + //{ + //bool isBeforeOutB = xIn < m_dataArray[mid].m_x ? true : m_dataArray[mid + 1].m_x < xIn; + // if (isBeforeOutB != *isBeforeOut) + // { + // qDebug("getNearestLocation, BEFOREBUG xIn: %f", xIn); + //} + //} *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } @@ -1122,36 +1715,43 @@ float PointGraphDataArray::getValueAtPosition(float xIn) else { float transformedX = (xIn - m_dataArray[locationBefore].m_x) / (m_dataArray[locationAfter].m_x - m_dataArray[locationBefore].m_x); - // type effects TODO + // type effects unsigned int type = getType(locationBefore); float fadeOutStart = 0.95f; if (type == 0) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationAfter, 1), transformedX); + output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); } else if (type == 1) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); - output = output + processLineTypeSine(transformedX, processAutomation(locationAfter, 2), - processAutomation(locationAfter, 3), fadeOutStart); + output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); + output = output + processLineTypeSine(transformedX, processAutomation(locationBefore, 2), + processAutomation(locationBefore, 3), fadeOutStart); } else if (type == 2) { output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); - output = output + processLineTypePeak(transformedX, processAutomation(locationAfter, 2), - processAutomation(locationAfter, 3), processAutomation(locationAfter, 1), fadeOutStart); + output = output + processLineTypeSineB(transformedX, processAutomation(locationBefore, 2), + processAutomation(locationBefore, 3), processAutomation(locationBefore, 3), fadeOutStart); } else if (type == 3) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); - output = output + processLineTypeSteps(transformedX, output, processAutomation(locationAfter, 2), - processAutomation(locationAfter, 3), fadeOutStart); + output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); + output = output + processLineTypePeak(transformedX, processAutomation(locationBefore, 2), + processAutomation(locationBefore, 3), processAutomation(locationBefore, 1), fadeOutStart); } else if (type == 4) + { + output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); + output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); + output = output + processLineTypeSteps(transformedX, output, processAutomation(locationBefore, 2), + processAutomation(locationBefore, 3), fadeOutStart); + } + else if (type == 5) { output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); - output = output + processLineTypeRandom(transformedX, processAutomation(locationAfter, 2), - processAutomation(locationAfter, 3), processAutomation(locationAfter, 1), fadeOutStart); + output = output + processLineTypeRandom(transformedX, processAutomation(locationBefore, 2), + processAutomation(locationBefore, 3), processAutomation(locationBefore, 1), fadeOutStart); } //qDebug("getVALUE, value2: %f %f - %d %d - %f %f", output, xIn, locationBefore, locationAfter, transformedX, pointEffectBefore); //qDebug("getVALUE, transfrmedX: %f", transformedX); @@ -1162,7 +1762,6 @@ float PointGraphDataArray::getValueAtPosition(float xIn) // and it does not only effect data points if (m_effectorLocation >= 0 && tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) { - // TODO use getValueAtPosition float effectValue = tempEArray->getValueAtPosition(xIn); output = processEffect(output, effectValue, tempEArray, tempELocation, lowerLimit); @@ -1282,29 +1881,47 @@ void PointGraphDataArray::setValB(unsigned int locationIn, float valueIn) void PointGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { // set the type without changing the automated attribute location - m_dataArray[locationIn].m_type = typeIn + getAutomatedAttribLocation(locationIn); + m_dataArray[locationIn].m_type = typeIn; dataChanged(); } void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { - // only 4 attributes can be automated (y, c, valA, valB) - attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; - // get the type and add the automated location - m_dataArray[locationIn].m_type = getType(locationIn) + attribLocationIn; - dataChanged(); + if (m_isAutomatableEffectable == true) + { + // only 4 attributes can be automated (y, c, valA, valB) + attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; + // set automated location correctly (effected_location = automatedEffectedLocation % 4) + m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); + dataChanged(); + } } -unsigned int PointGraphDataArray::getType(unsigned int locationIn) +void PointGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { - return static_cast - (static_cast(m_dataArray[locationIn].m_type) / 4.0f); + if (m_isAutomatableEffectable == true) + { + // only 4 attributes can be effected (y, c, valA, valB) + attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; + // set effected location correctly + m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); + dataChanged(); + } } unsigned int PointGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) { - return m_dataArray[locationIn].m_type - getType(locationIn); + return m_dataArray[locationIn].m_automatedEffectedAttribLocations / 4; +} +unsigned int PointGraphDataArray::getEffectedAttribLocation(unsigned int locationIn) +{ + return m_dataArray[locationIn].m_automatedEffectedAttribLocations % 4; } void PointGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) { - m_dataArray[locationIn].m_effectOnlyPoints = boolIn; + if (m_isAutomatableEffectable == true) + { + m_dataArray[locationIn].m_effectOnlyPoints = boolIn; + // this change does not effect the output values of the dataArray + // so dataChanged() is not called + } } bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) { @@ -1312,55 +1929,74 @@ bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effect { case 0: return m_dataArray[locationIn].m_effectAdd; + break; case 1: return m_dataArray[locationIn].m_effectSubtract; + break; case 2: return m_dataArray[locationIn].m_effectMultiply; + break; case 3: return m_dataArray[locationIn].m_effectDivide; + break; case 4: return m_dataArray[locationIn].m_effectPower; + break; case 5: return m_dataArray[locationIn].m_effectLog; + break; + case 6: + return m_dataArray[locationIn].m_effectSine; + break; } + return false; } void PointGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) { - switch (effectNumberIn) + if (m_isAutomatableEffectable == true) { - case 0: - m_dataArray[locationIn].m_effectAdd = boolIn; - break; - case 1: - m_dataArray[locationIn].m_effectSubtract = boolIn; - break; - case 2: - m_dataArray[locationIn].m_effectMultiply = boolIn; - break; - case 3: - m_dataArray[locationIn].m_effectDivide = boolIn; - break; - case 4: - m_dataArray[locationIn].m_effectPower = boolIn; - break; - case 5: - m_dataArray[locationIn].m_effectLog = boolIn; - break; + switch (effectNumberIn) + { + case 0: + m_dataArray[locationIn].m_effectAdd = boolIn; + break; + case 1: + m_dataArray[locationIn].m_effectSubtract = boolIn; + break; + case 2: + m_dataArray[locationIn].m_effectMultiply = boolIn; + break; + case 3: + m_dataArray[locationIn].m_effectDivide = boolIn; + break; + case 4: + m_dataArray[locationIn].m_effectPower = boolIn; + break; + case 5: + m_dataArray[locationIn].m_effectLog = boolIn; + break; + case 6: + m_dataArray[locationIn].m_effectSine = boolIn; + break; + } } } void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) { - if (isAutomatedIn == true) + if (m_isAutomatableEffectable == true) { - if (m_dataArray[locationIn].m_automationModel == nullptr) + if (isAutomatedIn == true) { - m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.0f, nullptr, QString(), false); + if (m_dataArray[locationIn].m_automationModel == nullptr) + { + m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.05f, nullptr, QString(), false); + } + } + else + { + delete m_dataArray[locationIn].m_automationModel; + m_dataArray[locationIn].m_automationModel = nullptr; // is this needed? TODO } - } - else - { - delete m_dataArray[locationIn].m_automationModel; - m_dataArray[locationIn].m_automationModel = nullptr; // is this needed? TODO } } @@ -1416,6 +2052,11 @@ float PointGraphDataArray::processEffect(float valueIn, float effectValueIn, PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn, float lowerLimitIn) { float output = valueIn; + if (effectArrayIn->getEffect(effectLocationIn, 6) == true) + { + // sine + output = output + std::sin(effectValueIn * 100.0f); + } if (effectArrayIn->getEffect(effectLocationIn, 4) == true) { // power @@ -1493,6 +2134,7 @@ float PointGraphDataArray::processAutomation(unsigned int locationIn, unsigned i if (attribLocation = attribLocationIn) { output += automationModel->value(); + // qDebug("processAutomation -> value: %f", output); } } if (attribLocationIn == 0) @@ -1527,10 +2169,22 @@ float PointGraphDataArray::processLineTypeSine(float xIn, float valAIn, float va } return output; } +float PointGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +{ + // sine + float output = valAIn * std::sin(xIn * valBIn + curveIn * 10.0f); + + // fade out + if (xIn > fadeOutStartIn) + { + output = output * (1.0f - xIn) / (1.0f - fadeOutStartIn); + } + return output; +} float PointGraphDataArray::processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) { // peak - float output = std::pow(curveIn * 0.4f + 0.01f, std::abs(xIn - valBIn) * 10.0f) * valAIn; + float output = std::pow((curveIn + 1.0f) * 0.2f + 0.01f, std::abs(xIn - (valBIn + 1.0f) * 0.5f) * 10.0f) * valAIn; // fade in float fadeInEnd = 1.0f - fadeOutStartIn; From 9f6c0d20894ce0386807d7143cc39b30b12512b5 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 23 Mar 2024 17:27:27 +0100 Subject: [PATCH 011/184] vectorGraph_getValues_base_implemented --- include/PointGraph.h | 103 ++- src/gui/widgets/PointGraph.cpp | 1103 ++++++++++++++++++++++++++------ 2 files changed, 991 insertions(+), 215 deletions(-) diff --git a/include/PointGraph.h b/include/PointGraph.h index cf626aae70e..402dd12bb75 100644 --- a/include/PointGraph.h +++ b/include/PointGraph.h @@ -32,7 +32,7 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: add is selectable Done // TODO: add new setting to make the last point cord 1, 1 Done // TODO: flip mouse y position Done - // TODO: function to get multiple values + // TODO: function to get multiple values Done // TODO: rewrite comments // TODO: rename functions and values @@ -54,21 +54,23 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: clear array when 2. last point is deleted in the widget IGNORE // TODO: event when a dataArray's size gets to 0 // TODO: ability to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) - // TODO: check PointGraphDataArray signals + // TODO: check PointGraphDataArray signals Done // TODO: journalling in PointGraphModel // TODO: m_maxLenght* should be replaced with m_parent->getMaxLength() Done - // TODO: setDataArray keep attributes option + // TODO: setDataArray keep attributes option, formatArray option which runs formatArray // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option Done - // TODO: baked values in PointGraphPoint + // TODO: baked automation values in PointGraphPoint Done // TODO: rename class to VectorGraph // TODO: make std::vector last used values Done - // TODO: make update logic (isChanged and update only automation / effected lines) - // TODO: effector location (same as automation location) + // TODO: make update logic (isChanged and update only automation / effected lines) Done + // TODO: effector location (same as automation location) Done // TODO: PointGraphView isSimplified Done // TODO: new automated color Done // TODO: context menu in gui (clear automation, connect to controller) // TODO: display hints (full text) in the editing // TODO: ability to edit multiple graphs using m_isLastSelectedArray + // TODO: handle effector arrays when deleting VectorGraphDataArray + // TODO: update formatArray PointGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -295,7 +297,7 @@ class LMMS_EXPORT PointGraphDataArray inline void clear() { m_dataArray.clear(); - dataChanged(); + dataChanged(-1); } inline size_t size() { @@ -303,7 +305,7 @@ class LMMS_EXPORT PointGraphDataArray } // clamps down the values to 0 - 1, -1 - 1 // does check m_isFixedSize, m_isFixedValue, m_isFixedPos, - // sorts array, removes duplicated positions, + // sorts array, removes duplicated positions, calls dataChanged() // clampIn: should clamp, sortIn: should sort void formatArray(bool clampIn, bool sortIn); @@ -336,12 +338,12 @@ class LMMS_EXPORT PointGraphDataArray // returns attribLocation: 0 = y, 1 = c, 2 = valA, 3 = valB unsigned int getAutomatedAttribLocation(unsigned int locationIn); unsigned int getEffectedAttribLocation(unsigned int locationIn); - inline bool getEffectOnlyPoints(unsigned int locationIn) - { - return m_dataArray[locationIn].m_effectOnlyPoints; - } + // returns true when m_effectOnlyPoints is true or + // when getEffectedAttribLocation > 0 (y is uneffected) + bool getEffectOnlyPoints(unsigned int locationIn); // returns if the [effectNumberIn] effect is active based on effectNumberIn bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); + bool getIsAutomationValueChanged(unsigned int locationIn); inline FloatModel* getAutomationModel(unsigned int locationIn) { return m_dataArray[locationIn].m_automationModel; @@ -355,13 +357,18 @@ class LMMS_EXPORT PointGraphDataArray // foundOut is true when the nearest position = posIn, // reurns -1 when search failed int getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut); + // get changed locations + // std::vector getUpdatingValues(); - float getValueAtPosition(float xIn); // TODO + std::vector getValues(unsigned int countIn); + std::vector getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut); + //float getValueAtPosition(float xIn); // TODO // set: ------------------- // sets data array without any checks // inport x and y coords + // TODO should call dataChanged void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn); // inport y coords void setDataArray(std::vector* dataArrayIn, bool isCurvedIn); @@ -392,7 +399,8 @@ class LMMS_EXPORT PointGraphDataArray // signals: // not qt // m_dataArray - void dataChanged(); + // if locationIn > 0 -> adds it to the + void dataChanged(int locationIn); // color void styleChanged(); private: @@ -418,6 +426,7 @@ class LMMS_EXPORT PointGraphDataArray m_effectLog = false; m_effectSine = false; + m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; } inline PointGraphPoint(float xIn, float yIn) @@ -439,6 +448,7 @@ class LMMS_EXPORT PointGraphDataArray m_effectLog = false; m_effectSine = false; + m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; } inline ~PointGraphPoint() @@ -472,6 +482,9 @@ class LMMS_EXPORT PointGraphDataArray // use getAutomatedAttrib or getEffectedAttrib to get it unsigned int m_automatedEffectedAttribLocations; + // if the point's line should effect only points + // getEffectOnlyPoints() will return true when + // effected attrib location > 0 bool m_effectOnlyPoints; bool m_effectAdd; @@ -482,31 +495,55 @@ class LMMS_EXPORT PointGraphDataArray bool m_effectLog; bool m_effectSine; + // stores m_automationModel->value(), used in updating + float m_bufferedAutomationValue; // automation: connecting to floatmodels, nullptr when it isn't conntected' FloatModel* m_automationModel; }; // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); - // applys the effect on a given value, does clamp TODO clamp - float processEffect(float valueIn, float effectValueIn, - PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn, float lowerLimitIn); // returns the curve value at a given x coord float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); + // applys the effect on a given value, does clamp + float processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, + PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn); // returns a PointGraphPoint with modified attributes - float processAutomation(unsigned int locationIn, unsigned int attribLocationIn); + float processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn); + // line effects / types, m_type is used for this - // valA: amp, valB: freq, fadeOutStartIn: from what xIn value should the line type fade out - float processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeOutStartIn); + // valA: amp, valB: freq, fadeInStartIn: from what xIn value should the line type fade out + //float processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn); + std::vector processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float fadeInStartIn); // curveIn: phase - float processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); - //std::vector processLineTypeArraySine(std::vector xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn); + //float processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); + std::vector processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn); // valA: amp, valB: x coord, curve: width - float processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); + //float processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); + std::vector processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn); // y: calculate steps from, valA: y count, valB: curve - float processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeOutStartIn); + //float processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeInStartIn); + std::vector processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, + std::vector* yIn, float valAIn, float valBIn, float fadeInStartIn); // valA: amp, valB: random number count, curveIn: seed - float processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn); + //float processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); + std::vector processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn); + + // updating + // adds the points that are + // effected by the effector's values changing + // ONLY WORKS IN SORTED ARRAYS + void getUpdatingFromEffector(std::shared_ptr> updatingValuesIn); + // adds the points that are changed because their + // automation is changed + void getUpdatingFromAuromation(); + // recalculates m_needsUpdating so + // every point is in there only once + void getUpdatingOriginals(); // checks m_isFixedEndPoints, does not call dataChanged() void formatDataArrayEndPoints(); @@ -544,10 +581,26 @@ class LMMS_EXPORT PointGraphDataArray // ordered array of PointGraphPoints std::vector m_dataArray; + // baking + + // getValues() will return m_bakedValues if a line is unchanged + // else it will recalculate the line's values, update m_bakedValues + // getValues() needs to know where did lines change so it updates + // m_needsUpdating by running getUpdatingFromEffector() + // if m_isDataChanged is true, then getValues adds all the points + // to m_needsUpdating before running + // getValues() clears m_needsUpdating after it has run + + // if we want to update all bool m_isDataChanged; + // if m_needsUpdating is up to date + // bool m_isUpdatedNeedsUpdating; // array containing output final float values for optimalization std::vector m_bakedValues; + // unsorted array of locations in m_dataArray + // that need to be updated + std::vector m_needsUpdating; }; } // namespace lmms diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/PointGraph.cpp index db40bc22a06..dcb72c86595 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/PointGraph.cpp @@ -1,9 +1,10 @@ #include -#include -#include +#include // sine +#include // sort #include +#include // smartpointers #include #include #include @@ -509,10 +510,13 @@ void PointGraphView::paintEvent(QPaintEvent* pe) if (m_isSimplified == false) { posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); - for (unsigned int j = 0; j < width(); j++) + std::vector dataArrayValues = dataArray->getValues(width()); + qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); + for (unsigned int j = 0; j < dataArrayValues.size(); j++) { //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1), dataArray->getNonNegative()); - posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); + //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); + posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); posB.first = j; //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); @@ -521,6 +525,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); posA = posB; } + dataArrayValues.clear(); } //if (posA.first < width()) //{ @@ -1116,7 +1121,7 @@ int PointGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceI } curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%d", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); + qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); if (curDistance <= maxDistance) { qDebug("search successful V2"); @@ -1215,8 +1220,10 @@ PointGraphDataArray::PointGraphDataArray() m_effectorLocation = -1; m_dataArray = {}; - m_isDataChanged = true; + m_isDataChanged = false; + //m_isUpdatedNeedsUpdating = false; m_bakedValues = {}; + m_needsUpdating = {}; } PointGraphDataArray::PointGraphDataArray( @@ -1242,8 +1249,10 @@ PointGraphDataArray::PointGraphDataArray( m_effectorLocation = -1; // m_dataArray = {}; - m_isDataChanged = true; + m_isDataChanged = false; + //m_isUpdatedNeedsUpdating = false; // m_bakedValues = {}; + // m_needsUpdating = {}; updateConnections(parentIn); } @@ -1251,6 +1260,8 @@ PointGraphDataArray::PointGraphDataArray( PointGraphDataArray::~PointGraphDataArray() { m_dataArray.clear(); + m_bakedValues.clear(); + m_needsUpdating.clear(); } void PointGraphDataArray::updateConnections(PointGraphModel* parentIn) @@ -1262,33 +1273,33 @@ void PointGraphDataArray::updateConnections(PointGraphModel* parentIn) void PointGraphDataArray::setIsFixedSize(bool valueIn) { m_isFixedSize = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsFixedValue(bool valueIn) { m_isFixedValue = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsFixedPos(bool valueIn) { m_isFixedPos = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsFixedEndPoints(bool valueIn) { m_isFixedEndPoints = valueIn; formatDataArrayEndPoints(); - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsSelectable(bool valueIn) { m_isSelectable = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsEditableAttrib(bool valueIn) { m_isEditableAttrib = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setIsAutomatableEffectable(bool valueIn) { @@ -1300,18 +1311,17 @@ void PointGraphDataArray::setIsAutomatableEffectable(bool valueIn) else { // setEffectorArray will call dataChanged() - dataChanged(); + dataChanged(-1); } } void PointGraphDataArray::setIsSaveable(bool valueIn) { m_isSaveable = valueIn; - dataChanged(); } void PointGraphDataArray::setNonNegative(bool valueIn) { m_nonNegative = valueIn; - dataChanged(); + dataChanged(-1); } void PointGraphDataArray::setLineColor(QColor colorIn) { @@ -1358,16 +1368,16 @@ bool PointGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) if (found == false) { m_effectorLocation = locationIn; - dataChanged(); + dataChanged(-1); } } else { if (m_effectorLocation != -1) { - dataChanged(); + dataChanged(-1); + m_effectorLocation = -1; } - m_effectorLocation = -1; } return !found; } @@ -1480,7 +1490,7 @@ int PointGraphDataArray::add(float xIn) } if (dataChangedVal == true) { - dataChanged(); + dataChanged(-1); } } } @@ -1493,11 +1503,13 @@ void PointGraphDataArray::del(unsigned int locationIn) { swap(locationIn, m_dataArray.size() - 1, true); m_dataArray.pop_back(); - if (locationIn == 0 || locationIn == m_dataArray.size() - 1) + if (locationIn == 0 || locationIn == m_dataArray.size()) { formatDataArrayEndPoints(); + dataChanged(locationIn == 0 ? 0 : locationIn - 1); } - dataChanged(); + // if locationIn - 1 == -1 then update the entire m_bakedValues / m_dataArray + dataChanged(static_cast(locationIn) - 1); } } @@ -1505,6 +1517,11 @@ void PointGraphDataArray::del(unsigned int locationIn) void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) { // clamp + // TODO implement + float minY = 0.0f; + float maxY = 0.0f; + float minX = 0.0f; + float maxX = 0.0f; if (clampIn == true) { for (unsigned int i = 0; i < m_dataArray.size(); i++) @@ -1546,7 +1563,8 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) } // delete duplicates - unsigned int lastPos = 0; + // TODO update name + float lastPos = 0.0f; if (m_dataArray.size() > 0) { lastPos = m_dataArray[0].m_x; @@ -1562,6 +1580,7 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) lastPos = m_dataArray[i].m_x; } } + dataChanged(-1); } int PointGraphDataArray::getLocation(float xIn) @@ -1636,142 +1655,486 @@ int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isB return -1; } +std::vector PointGraphDataArray::getValues(unsigned int countIn) +{ + bool isChanged = false; + std::shared_ptr> updatingValues = std::make_shared>(); + qDebug("getValuesA1"); + std::vector output = getValues(countIn, &isChanged, updatingValues); + qDebug("getValuesA2, size: %ld", output.size()); + updatingValues->clear(); + qDebug("getValuesA3 finished"); + return output; +} +std::vector PointGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) +{ + bool effectorIsChanged = false; + std::shared_ptr> effectorUpdatingValues = std::make_shared>(); + std::vector effectorOutput; + std::vector outputXLocations(countIn); + m_isDataChanged = true; // TODO DEBUG, delete this line + bool isEffected = m_effectorLocation >= 0; + if (isEffected == true) + { + effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, effectorUpdatingValues); + } + else + { + effectorOutput.resize(countIn); + } + qDebug("getValuesB1, size: %ld", outputXLocations.size()); + + // updating m_needsUpdating + if (m_isDataChanged == false && countIn == m_bakedValues.size()) + { + if (isEffected == true && effectorUpdatingValues->size() > 1) + { + // effectorUpdatingValues needs to be sorted + // before use (in this case it is already sorted) + getUpdatingFromEffector(effectorUpdatingValues); + } + qDebug("getValuesB2"); + getUpdatingFromAuromation(); + // sort and select only original + // values + getUpdatingOriginals(); + qDebug("getValuesB3"); + } + else + { + if (countIn != m_bakedValues.size()) + { + // reseting m_bakedValues + m_bakedValues.resize(countIn); + for (unsigned int i = 0; i < m_bakedValues.size(); i++) + { + m_bakedValues[i] = 0.0f; + } + } + m_needsUpdating.resize(m_dataArray.size()); + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + m_needsUpdating[i] = i; + } + qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); + } + + float stepSize = 1.0f / static_cast(countIn); + // calculating point data + if (m_needsUpdating.size() > 0 && m_bakedValues.size() > 0) + { + // calculating relative X locations (in lines) of the output values + // for later use in the line calculations + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + unsigned int start = static_cast + (std::ceil(m_dataArray[i].m_x / stepSize)); + if (i + 1 < m_dataArray.size()) + { + unsigned int end = static_cast + (std::ceil(m_dataArray[i + 1].m_x / stepSize)); + for (unsigned int j = start; j < end; j++) + { + outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); + //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); + } + } + } + + // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, + std::vector> effectorData; + PointGraphDataArray* effector = nullptr; + if (m_effectorLocation >= 0) + { + effector = m_parent->getDataArray(m_effectorLocation); + } + if (effector != nullptr) + { + effectorData.resize(m_needsUpdating.size()); + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + bool found = false; + bool isBefore = false; + int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + if (curLocation >= 0) + { + curLocation = isBefore == false ? (curLocation > 1 ? curLocation - 1 : curLocation) : curLocation; + // location + effectorData[i].first = curLocation; + // next location + effectorData[i].second = curLocation; + // if the location of this is the next location for before this + if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) + { + effectorData[i - 1].second = curLocation; + } + } + } + qDebug("getValuesB5"); + // getting the missing next location values + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + if (i + 1 < m_needsUpdating.size() && m_needsUpdating[i] + 1 < m_dataArray.size() && + m_needsUpdating[i + 1] != m_needsUpdating[i] + 1) + { + bool found = false; + bool isBefore = false; + int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + if (curLocation >= 0) + { + curLocation = isBefore == false ? (curLocation > 1 ? curLocation - 1 : curLocation) : curLocation; + // next location + effectorData[i].second = curLocation; + } + } + } + } + qDebug("getValuesB6"); + // calculate final line + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + unsigned int effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[i]].m_x / stepSize)); + float curEffectY = effectorOutput[effectYLocation]; + float nextEffectY = effectorOutput[effectYLocation]; + + float curY = m_dataArray[m_needsUpdating[i]].m_y; + float curC = m_dataArray[m_needsUpdating[i]].m_c; + float curValA = m_dataArray[m_needsUpdating[i]].m_valA; + float curValB = m_dataArray[m_needsUpdating[i]].m_valB; + // TODO run processAutomation separatly + if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].first) == true) + { + curY = processAutomation( + processEffect(m_dataArray[m_needsUpdating[i]].m_y, 0, curEffectY, effector, effectorData[i].first), + m_needsUpdating[i], 0); + curC = processAutomation( + processEffect(m_dataArray[m_needsUpdating[i]].m_c, 1, curEffectY, effector, effectorData[i].first), + m_needsUpdating[i], 1); + curValA = processAutomation( + processEffect(m_dataArray[m_needsUpdating[i]].m_valA, 2, curEffectY, effector, effectorData[i].first), + m_needsUpdating[i], 2); + curValB = processAutomation( + processEffect(m_dataArray[m_needsUpdating[i]].m_valB, 3, curEffectY, effector, effectorData[i].first), + m_needsUpdating[i], 3); + } + qDebug("getValuesB7"); + int start = effectYLocation; + int end = start; + + float nextY = curY; + + if (m_needsUpdating[i] + 1 < m_dataArray.size()) + { + effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[i] + 1].m_x / stepSize)); + end = effectYLocation; + if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].second) == true) + { + nextEffectY = effectorOutput[effectYLocation]; + nextY = processAutomation( + processEffect(m_dataArray[m_needsUpdating[i] + 1].m_y, 0, nextEffectY, effector, effectorData[i].second), + m_needsUpdating[i] + 1, 0); + } + else + { + nextY = m_dataArray[m_needsUpdating[i] + 1].m_y; + } + } + // calculating line ends + if (m_needsUpdating[i] + 1 >= m_dataArray.size()) + { + // if this point is at the last location in m_dataArray + for (int j = end; j < m_bakedValues.size(); j++) + { + m_bakedValues[j] = curY; + } + } + if (m_needsUpdating[i] == 0) + { + // if this point is at the 0 location in m_dataArray + for (int j = 0; j < start; j++) + { + m_bakedValues[j] = curY; + } + } + + float fadeInStart = 0.05f; + unsigned int type = m_dataArray[m_needsUpdating[i]].m_type; + qDebug("getValuesB8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", i, start, end, type, curY, nextY, curC, curValA, curValB); + // calculate final updated line + if (type == 0) + { + // calculate curve + for (int j = start; j < end; j++) + { + // accessing m_dataArray[m_needsUpdating[i] + 1] should be safe bacause at the endpoint + // start = end (-> end is not bigger than j) + //float transformedX = (outputXLocations[j] - m_dataArray[m_needsUpdating[i]].m_x) / (m_dataArray[m_needsUpdating[i] + 1].m_x - m_dataArray[m_needsUpdating[i]].m_x); + //qDebug("getValuesB8 [%d] %f outputX", j, outputXLocations[j]); + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); + } + } + else if (type == 1) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySine(&outputXLocations, start, end, curValA, curValB, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 2) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySineB(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 3) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); + } + // line type + std::vector lineTypeOutput = processLineTypeArrayPeak(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 4) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySteps(&outputXLocations, start, end, &m_bakedValues, curValA, curValB, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 5) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); + } + // line type + std::vector lineTypeOutput = processLineTypeArrayRandom(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].second) == false) + { + // process line effect + // if it is enabled + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processEffect(m_bakedValues[j], 0, effectorOutput[j], effector, effectorData[i].first); + } + } + for (int j = start; j < end; j++) + { + if (m_bakedValues[j] > 1.0f) + { + m_bakedValues[j] = 1.0f; + } + else if (m_bakedValues[j] < -1.0f) + { + m_bakedValues[j] = -1.0f; + } + } + } + effectorData.clear(); + } + + if (m_needsUpdating.size() > 0) + { + updatingValuesOut = std::make_shared>(); + *updatingValuesOut = m_needsUpdating; + + // clearing the updated values + m_needsUpdating.clear(); + } + + m_isDataChanged = false; + effectorUpdatingValues->clear(); + qDebug("getValuesB9"); + return m_bakedValues; +} + +// this function is hard to maintain so it is inaccessible +/* float PointGraphDataArray::getValueAtPosition(float xIn) { float output = 0.0f; bool found = false; bool isBefore = false; - int locationBefore = getNearestLocation(xIn, &found, &isBefore); + int curLocation = getNearestLocation(xIn, &found, &isBefore); // get values of points (process effect if it effects only points) // draw line // process effect (if it effects lines too) - if (locationBefore >= 0) + if (curLocation >= 0) { - // y limit for clamping - float lowerLimit = m_nonNegative == true ? 0.0f : -1.0f; // location after should be location before + 1 - // or it is equal to locationBefore when it is on an edge - locationBefore = isBefore == true ? locationBefore : locationBefore - 1; - int locationAfter = locationBefore + 1; - if (locationAfter >= m_dataArray.size()) + // or it is equal to curLocation when it is on an edge + curLocation = isBefore == true ? curLocation : curLocation - 1; + int nextLocation = curLocation + 1; + if (nextLocation >= m_dataArray.size()) { - locationAfter = locationBefore; + nextLocation = curLocation; } - if (locationBefore < 0) + if (curLocation < 0) { - locationBefore++; - locationAfter = locationBefore; + curLocation++; + nextLocation = curLocation; } - float pointEffectYBefore = processAutomation(locationBefore, 0); - float pointEffectYAfter = processAutomation(locationAfter, 0); + float curY = m_dataArray[curLocation].m_y; + float curC = m_dataArray[curLocation].m_c; + float curValA = m_dataArray[curLocation].m_valA; + float curValB = m_dataArray[curLocation].m_valB; + + float nextY = curY; - //qDebug("getVALUE, locationBefore1: %d", locationBefore); - //qDebug("getVALUE, locationAfer: %d", locationAfter); + //qDebug("getVALUE, curLocation: %d", curLocation); + //qDebug("getVALUE, locationAfer: %d", nextLocation); // temp effecor data - PointGraphDataArray* tempEArray = nullptr; + PointGraphDataArray* effector = nullptr; bool tempEFound = false; bool tempEIsBefore = false; int tempELocation = -1; // if this data array has an effector data array if (m_effectorLocation >= 0) { - tempEArray = m_parent->getDataArray(m_effectorLocation); + effector = m_parent->getDataArray(m_effectorLocation); // do not change order - // locationAfter - tempELocation = tempEArray->getNearestLocation(m_dataArray[locationAfter].m_x, &tempEFound, &tempEIsBefore); + // because tempELocation is used somewhere else + // nextLocation + tempELocation = effector->getNearestLocation(m_dataArray[nextLocation].m_x, &tempEFound, &tempEIsBefore); tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; - if (tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + if (tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) { - float effectValue = tempEArray->getValueAtPosition(m_dataArray[locationAfter].m_x); + float curEffectY = effector->getValueAtPosition(m_dataArray[nextLocation].m_x); // apply effects - pointEffectYAfter = processEffect(pointEffectYAfter, - effectValue, tempEArray, tempELocation, lowerLimit); + nextY = processAutomation( + processEffect(m_dataArray[nextLocation].m_y, 0, curEffectY, effector, tempELocation), } - // locationBefore - tempELocation = tempEArray->getNearestLocation(m_dataArray[locationBefore].m_x, &tempEFound, &tempEIsBefore); + // curLocation + tempELocation = effector->getNearestLocation(m_dataArray[curLocation].m_x, &tempEFound, &tempEIsBefore); tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; // if the effector point can only change points - if (tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + if (tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) { - float effectValue = tempEArray->getValueAtPosition(m_dataArray[locationBefore].m_x); + float curEffectY = effector->getValueAtPosition(m_dataArray[curLocation].m_x); // apply effects - pointEffectYBefore = processEffect(pointEffectYBefore, - effectValue, tempEArray, tempELocation, lowerLimit); + curY = processAutomation( + processEffect(m_dataArray[curLocation].m_y, 0, curEffectY, effector, tempELocation), + curLocation, 0); + curC = processAutomation( + processEffect(m_dataArray[curLocation].m_c, 1, curEffectY, effector, tempELocation), + curLocation, 1); + curValA = processAutomation( + processEffect(m_dataArray[curLocation].m_valA, 2, curEffectY, effector, tempELocation), + curLocation, 2); + curValB = processAutomation( + processEffect(m_dataArray[curLocation].m_valB, 3, curEffectY, effector, tempELocation), + curLocation, 3); } } if (found == true) { - output = pointEffectYAfter; + output = nextY; } - else if (locationAfter == locationBefore) + else if (nextLocation == curLocation) { // if the nearest point is an edge - output = pointEffectYBefore; + output = curY; } else { - float transformedX = (xIn - m_dataArray[locationBefore].m_x) / (m_dataArray[locationAfter].m_x - m_dataArray[locationBefore].m_x); + float transformedX = (xIn - m_dataArray[curLocation].m_x) / (m_dataArray[nextLocation].m_x - m_dataArray[curLocation].m_x); // type effects - unsigned int type = getType(locationBefore); - float fadeOutStart = 0.95f; + unsigned int type = getType(curLocation); + float fadeOutStart = 0.05f; if (type == 0) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); + output = processCurve(curY, nextY, curC, curLocation, 1), transformedX); } else if (type == 1) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); - output = output + processLineTypeSine(transformedX, processAutomation(locationBefore, 2), - processAutomation(locationBefore, 3), fadeOutStart); + output = processCurve(curY, nextY, curC, transformedX); + output = output + processLineTypeSine(transformedX, curValA, + curValB, fadeOutStart); } else if (type == 2) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); - output = output + processLineTypeSineB(transformedX, processAutomation(locationBefore, 2), - processAutomation(locationBefore, 3), processAutomation(locationBefore, 3), fadeOutStart); + output = processCurve(curY, nextY, 0.0f, transformedX); + output = output + processLineTypeSineB(transformedX, curValA, + curValB, processAutomation(curLocation, 3), fadeOutStart); } else if (type == 3) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); - output = output + processLineTypePeak(transformedX, processAutomation(locationBefore, 2), - processAutomation(locationBefore, 3), processAutomation(locationBefore, 1), fadeOutStart); + output = processCurve(curY, nextY, 0.0f, transformedX); + output = output + processLineTypePeak(transformedX, curValA, + curValB, curC, fadeOutStart); } else if (type == 4) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, processAutomation(locationBefore, 1), transformedX); - output = processCurve(pointEffectYBefore, pointEffectYAfter, m_dataArray[locationBefore].m_c, transformedX); - output = output + processLineTypeSteps(transformedX, output, processAutomation(locationBefore, 2), - processAutomation(locationBefore, 3), fadeOutStart); + output = processCurve(curY, nextY, curC, transformedX); + output = output + processLineTypeSteps(transformedX, output, curValA, + curValB, fadeOutStart); } else if (type == 5) { - output = processCurve(pointEffectYBefore, pointEffectYAfter, 0.0f, transformedX); - output = output + processLineTypeRandom(transformedX, processAutomation(locationBefore, 2), - processAutomation(locationBefore, 3), processAutomation(locationBefore, 1), fadeOutStart); + output = processCurve(curY, nextY, 0.0f, transformedX); + output = output + processLineTypeRandom(transformedX, curValA, + curValB, curC, fadeOutStart); } - //qDebug("getVALUE, value2: %f %f - %d %d - %f %f", output, xIn, locationBefore, locationAfter, transformedX, pointEffectBefore); + //qDebug("getVALUE, value2: %f %f - %d %d - %f %f", output, xIn, curLocation, nextLocation, transformedX, pointEffectBefore); //qDebug("getVALUE, transfrmedX: %f", transformedX); //qDebug("getVALUE, x: %f", xIn); } // if this data array has an effector data array // and it does not only effect data points - if (m_effectorLocation >= 0 && tempELocation >= 0 && tempEArray->getEffectOnlyPoints(tempELocation) == true) + if (m_effectorLocation >= 0 && tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) { - float effectValue = tempEArray->getValueAtPosition(xIn); - output = processEffect(output, - effectValue, tempEArray, tempELocation, lowerLimit); + float curEffectY = effector->getValueAtPosition(xIn); + output = processEffect(output, 0, curEffectY, effector, tempELocation) } } return output; } +*/ void PointGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { + // TODO implement formatArray option m_dataArray.clear(); for (unsigned int i = 0; i < dataArrayIn->size(); i++) { @@ -1835,7 +2198,7 @@ unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) m_dataArray[locationIn].m_x = xIn; swap(locationIn, targetLocation, true); location = targetLocation; - dataChanged(); + dataChanged(location); } else { @@ -1858,7 +2221,7 @@ void PointGraphDataArray::setY(unsigned int locationIn, float yIn) locationIn > 0) || m_isFixedEndPoints == false) { m_dataArray[locationIn].m_y = yIn; - dataChanged(); + dataChanged(locationIn); } } } @@ -1866,23 +2229,23 @@ void PointGraphDataArray::setY(unsigned int locationIn, float yIn) void PointGraphDataArray::setC(unsigned int locationIn, float cIn) { m_dataArray[locationIn].m_c = cIn; - dataChanged(); + dataChanged(locationIn); } void PointGraphDataArray::setValA(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valA = valueIn; - dataChanged(); + dataChanged(locationIn); } void PointGraphDataArray::setValB(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valB = valueIn; - dataChanged(); + dataChanged(locationIn); } void PointGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { // set the type without changing the automated attribute location m_dataArray[locationIn].m_type = typeIn; - dataChanged(); + dataChanged(locationIn); } void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { @@ -1892,7 +2255,7 @@ void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned i attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set automated location correctly (effected_location = automatedEffectedLocation % 4) m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); - dataChanged(); + dataChanged(locationIn); } } void PointGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) @@ -1903,7 +2266,7 @@ void PointGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned in attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set effected location correctly m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); - dataChanged(); + dataChanged(locationIn); } } unsigned int PointGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) @@ -1914,13 +2277,21 @@ unsigned int PointGraphDataArray::getEffectedAttribLocation(unsigned int locatio { return m_dataArray[locationIn].m_automatedEffectedAttribLocations % 4; } +bool PointGraphDataArray::getEffectOnlyPoints(unsigned int locationIn) +{ + return (m_dataArray[locationIn].m_effectOnlyPoints == true || getEffectedAttribLocation(locationIn) > 0); +} void PointGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) { if (m_isAutomatableEffectable == true) { - m_dataArray[locationIn].m_effectOnlyPoints = boolIn; - // this change does not effect the output values of the dataArray - // so dataChanged() is not called + if (m_dataArray[locationIn].m_effectOnlyPoints != boolIn) + { + m_dataArray[locationIn].m_effectOnlyPoints = boolIn; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() is called + dataChanged(locationIn); + } } } bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) @@ -1980,6 +2351,16 @@ void PointGraphDataArray::setEffect(unsigned int locationIn, unsigned int effect break; } } + dataChanged(locationIn); +} +bool PointGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) +{ + if (m_dataArray[locationIn].m_bufferedAutomationValue != m_dataArray[locationIn].m_automationModel->value()) + { + m_dataArray[locationIn].m_bufferedAutomationValue = m_dataArray[locationIn].m_automationModel->value(); + return true; + } + return false; } void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) { @@ -1989,13 +2370,16 @@ void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomated { if (m_dataArray[locationIn].m_automationModel == nullptr) { - m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.05f, nullptr, QString(), false); + m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, nullptr, QString(), false); + dataChanged(locationIn); } } - else + else if (m_dataArray[locationIn].m_automationModel != nullptr) { + // TODO correctly deconstruct delete m_dataArray[locationIn].m_automationModel; - m_dataArray[locationIn].m_automationModel = nullptr; // is this needed? TODO + m_dataArray[locationIn].m_automationModel = nullptr; + dataChanged(locationIn); } } } @@ -2045,60 +2429,10 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; } - dataChanged(); - } -} -float PointGraphDataArray::processEffect(float valueIn, float effectValueIn, - PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn, float lowerLimitIn) -{ - float output = valueIn; - if (effectArrayIn->getEffect(effectLocationIn, 6) == true) - { - // sine - output = output + std::sin(effectValueIn * 100.0f); - } - if (effectArrayIn->getEffect(effectLocationIn, 4) == true) - { - // power - output = std::pow(output, effectValueIn); - } - else if (effectArrayIn->getEffect(effectLocationIn, 5) == true) - { - // log - output = std::log(output) / std::log(effectValueIn); - } - - if (effectArrayIn->getEffect(effectLocationIn, 2) == true) - { - // multiply - output = output * 5.0f * effectValueIn; - } - else if (effectArrayIn->getEffect(effectLocationIn, 3) == true) - { - output = output / 5.0f / effectValueIn; - // divide - } - - if (effectArrayIn->getEffect(effectLocationIn, 0) == true) - { - // add - output += effectValueIn; - } - else if (effectArrayIn->getEffect(effectLocationIn, 1) == true) - { - // subtract - output -= effectValueIn; - } - // clamp - if (output > 1.0f) - { - output = 1.0f; + dataChanged(locationAIn - 1 > 0 ? locationAIn - 1 : 0); + dataChanged(locationBIn - 1 > 0 ? locationBIn - 1 : 0); + dataChanged(locationBIn); } - else if (output < lowerLimitIn) - { - output = lowerLimitIn; - } - return output; } float PointGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) { @@ -2123,7 +2457,58 @@ float PointGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, return output; } -float PointGraphDataArray::processAutomation(unsigned int locationIn, unsigned int attribLocationIn) +float PointGraphDataArray::processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, + PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn) +{ + float output = attribValueIn; + unsigned int attribLocation = effectArrayIn->getEffectedAttribLocation(effectLocationIn); + // effects + if (attribLocationIn == attribLocation) + { + if (effectArrayIn->getEffect(effectLocationIn, 6) == true) + { + // sine + output = output + std::sin(effectValueIn * 100.0f); + } + if (effectArrayIn->getEffect(effectLocationIn, 4) == true) + { + // power + output = std::pow(output, effectValueIn); + } + else if (effectArrayIn->getEffect(effectLocationIn, 5) == true) + { + // log + output = std::log(output) / std::log(effectValueIn); + } + + if (effectArrayIn->getEffect(effectLocationIn, 2) == true) + { + // multiply + output = output * 5.0f * effectValueIn; + } + else if (effectArrayIn->getEffect(effectLocationIn, 3) == true) + { + output = output / 5.0f / effectValueIn; + // divide + } + + if (effectArrayIn->getEffect(effectLocationIn, 0) == true) + { + // add + output += effectValueIn; + } + else if (effectArrayIn->getEffect(effectLocationIn, 1) == true) + { + // subtract + output -= effectValueIn; + } + + // clamp + output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; + } + return output; +} +float PointGraphDataArray::processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn) { float output = 0.0f; // if automated @@ -2131,75 +2516,168 @@ float PointGraphDataArray::processAutomation(unsigned int locationIn, unsigned i if (automationModel != nullptr) { unsigned int attribLocation = getAutomatedAttribLocation(locationIn); - if (attribLocation = attribLocationIn) + if (attribLocation == attribLocationIn) { output += automationModel->value(); // qDebug("processAutomation -> value: %f", output); } } - if (attribLocationIn == 0) - { - output += m_dataArray[locationIn].m_y; - } - else if (attribLocationIn == 1) - { - output += m_dataArray[locationIn].m_c; - } - else if (attribLocationIn == 2) - { - output += m_dataArray[locationIn].m_valA; - } - else if (attribLocationIn == 3) - { - output += m_dataArray[locationIn].m_valB; - } + output += attribValueIn; output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; return output; } -float PointGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeOutStartIn) + +// line type effects: +/* +float PointGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn) +{ + return processLineTypeSineB(xIn, valAIn, valBIn, 0.0f, fadeInStartIn); +} +*/ +// valA: amp, valB: freq, fadeInStartIn: from what xIn value should the line type fade out +std::vector PointGraphDataArray::processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float fadeInStartIn) +{ + return PointGraphDataArray::processLineTypeArraySineB(xIn, startIn, endIn, + valAIn, valBIn, 0.0f, fadeInStartIn); +} +/* +float PointGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { // sine - float output = valAIn * std::sin(xIn * valBIn); + // 628.318530718f = 100.0f * 2.0f * pi + float output = valAIn * std::sin(xIn * 628.318530718f * valBIn + curveIn * 100.0f); + // fade in + if (xIn < fadeInStartIn) + { + output = output * xIn / fadeInStartIn; + } // fade out - if (xIn > fadeOutStartIn) + if (xIn > 1.0f - fadeInStartIn) { - output = output * (1.0f - xIn) / (1.0f - fadeOutStartIn); + output = output * (1.0f - xIn) / fadeInStartIn; } return output; } -float PointGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +*/ +// valA: amp, valB: freq, curveIn: phase +std::vector PointGraphDataArray::processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn) { - // sine - float output = valAIn * std::sin(xIn * valBIn + curveIn * 10.0f); - + int count = static_cast(endIn) - static_cast(startIn); + if (count < 0) + { + count = 0; + } + float valB = 0.001f + ((valBIn + 1.0f) / 2.0f) * 0.999f; + std::vector output(count); + // calculating how many samples are needed to 1 complete wave + // we have "count" amount of samples and "valB * 100.0f" amount of waves + int end = static_cast(std::floor(count / (valB * 100.0f))); + //qDebug("sineB_1, %f, %d", (count / (valB * 100.0f)), end); + end = end > count ? count : end + 1; + + // calculate 1 wave of sine + for (unsigned int i = 0; i < end; i++) + { + // 628.318531f = 100.0f * 2.0f * pi + // (1 sine wave is 2pi long and we have 1 * 100 * valBIn waves) + output[i] = valAIn * std::sin( + xIn->operator[](startIn + i) * 628.318531f * valB + curveIn * 100.0f); + } + //qDebug("sineB_2"); + // copy values + for (unsigned int i = end; i < count; i++) + { + //qDebug("sineB_2.5: i: %d, %d, %d", (i - end), end, i); + output[i] = output[i - end]; + } + //qDebug("sineB_3"); + // fade in + for (unsigned int i = 0; i < count; i++) + { + float x = xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; + } + //qDebug("sineB_4"); // fade out - if (xIn > fadeOutStartIn) + for (unsigned int i = count - 1; i >= 0; i--) { - output = output * (1.0f - xIn) / (1.0f - fadeOutStartIn); + float x = 1.0f - xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; } + //qDebug("sineB_5"); return output; } -float PointGraphDataArray::processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +/* +float PointGraphDataArray::processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { // peak float output = std::pow((curveIn + 1.0f) * 0.2f + 0.01f, std::abs(xIn - (valBIn + 1.0f) * 0.5f) * 10.0f) * valAIn; // fade in - float fadeInEnd = 1.0f - fadeOutStartIn; - if (xIn < fadeInEnd) + if (xIn < fadeInStartIn) { - output = output * xIn / fadeInEnd; + output = output * xIn / fadeInStartIn; } // fade out - if (xIn > fadeOutStartIn) + if (xIn > 1.0f - fadeInStartIn) { - output = output * (1.0f - xIn) / fadeInEnd; + output = output * (1.0f - xIn) / fadeInStartIn; } return output; } -float PointGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeOutStartIn) +*/ + +// valA: amp, valB: x coord, curve: width +std::vector PointGraphDataArray::processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn) +{ + int count = static_cast(endIn) - static_cast(startIn); + if (count < 0) + { + count = 0; + } + std::vector output(count); + for (unsigned int i = 0; i < count; i++) + { + output[i] = std::pow((curveIn + 1.0f) * 0.2f + 0.01f, + std::abs(xIn->operator[](startIn + i) - (valBIn + 1.0f) * 0.5f) * 10.0f) * valAIn; + } + // fade in + for (unsigned int i = 0; i < count; i++) + { + float x = xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; + } + // fade out + for (unsigned int i = count - 1; i >= 0; i--) + { + float x = 1.0f - xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; + } + return output; +} +/* +float PointGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeInStartIn) { // TODO opmtimalize // step @@ -2210,19 +2688,63 @@ float PointGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valA float output = diff * (valBIn + 1.0f) / 2.0f + stepSize * (2.0f - (valBIn + 1.0f) / 2.0f); // fade in - float fadeInEnd = 1.0f - fadeOutStartIn; - if (xIn < fadeInEnd) + if (xIn < fadeInStartIn) + { + output = output * xIn / fadeInStartIn; + } + // fade out + if (xIn > 1.0f - fadeInStartIn) + { + output = output * (1.0f - xIn) / fadeInStartIn; + } + return output; +} +*/ +// y: calculate steps from, valA: y count, valB: curve +std::vector PointGraphDataArray::processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, + std::vector* yIn, float valAIn, float valBIn, float fadeInStartIn) +{ + int count = static_cast(endIn) - static_cast(startIn); + if (count < 0) + { + count = 0; + } + std::vector output(count); + + float stepCount = (1.0f + valAIn) / 2.0f * 19.0f + 1.0f; + //qDebug("stepsA - stepCount = %f", stepCount); + for (unsigned int i = 0; i < count; i++) + { + float y = yIn->operator[](startIn + i) + 1.0f; + float diff = std::round(y * stepCount) - y * stepCount; + float smooth = 1.0f - std::abs(diff) * (1.0f - (valBIn + 1.0f) / 2.0f) * 2.0f; + output[i] = diff / stepCount * smooth; + } + + // fade in + for (unsigned int i = 0; i < count; i++) { - output = output * xIn / fadeInEnd; + float x = xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; } // fade out - if (xIn > fadeOutStartIn) + for (unsigned int i = count - 1; i >= 0; i--) { - output = output * (1.0f - xIn) / fadeInEnd; + float x = 1.0f - xIn->operator[](startIn + i); + if (x > fadeInStartIn) + { + break; + } + output[i] = output[i] * x / fadeInStartIn; } return output; } -float PointGraphDataArray::processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeOutStartIn) +/* +float PointGraphDataArray::processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { // randomize float blend = 50.0f + curveIn * 50.0f; @@ -2246,6 +2768,193 @@ float PointGraphDataArray::processLineTypeRandom(float xIn, float valAIn, float output = output * blend * (blend - 2.0f) * - 1.0f - rand() * (1.0f - blend) * (-1.0f - blend); return output * valAIn; } +*/ +// valA: amp, valB: random number count, curveIn: seed +std::vector PointGraphDataArray::processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, + float valAIn, float valBIn, float curveIn, float fadeInStartIn) +{ + int count = static_cast(endIn) - static_cast(startIn); + if (count < 0) + { + count = 0; + } + std::vector output(count); + std::vector randomValues(static_cast(50.0f * (valBIn + 1.0f)) * 2); + + float blend = 10.0f + curveIn * 10.0f; + int randomSeed = static_cast(blend); + blend = blend - randomSeed; + std::srand(randomSeed); + + // getting the random values + // generating 2 seeds and blending in between them + for (unsigned int i = 0; i < randomValues.size() / 2; i++) + { + randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + std::srand(randomSeed + 1); + for (unsigned int i = randomValues.size() / 2; i < randomValues.size(); i++) + { + randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + + float size = static_cast(randomValues.size() / 2); + for (unsigned int i = 0; i < count; i++) + { + float randomValueX = xIn->operator[](startIn + i) * size; + float randomValueLocation = std::floor(randomValueX); + output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * + valAIn; + } + + return output; +} + +void PointGraphDataArray::getUpdatingFromEffector(std::shared_ptr> updatingValuesIn) +{ + PointGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); + for (unsigned int i = 0; i < updatingValuesIn->size(); i++) + { + if (updatingValuesIn->operator[](i) > 0) + { + // since updatingValuesIn is a sorted list, we can get the end + // values and update everithing between them + // starting value is i, end value is updatingEnd + unsigned int updatingEnd = i; + for (unsigned int j = i + 1; j < updatingValuesIn->size(); j++) + { + // we can skip 1 wide gaps because + // changes in Y can effect the line before j + if (updatingValuesIn->operator[](updatingEnd) + 2 >= + updatingValuesIn->operator[](j)) + { + updatingEnd = j; + } + else + { + break; + } + } + + bool found = false; + bool isBefore = false; + // i - 1 because changes in Y can effect the line before this + int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i) - 1), &found, &isBefore); + if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i) - 1) == true && isBefore == true) + { + // if only points are effected and the nearest point + // is before [i] (so it needs to be uneffected) + // add 1 + locationBefore++; + } + else if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i) - 1) == false && isBefore == false) + { + // if lines are effected and the nearest point + // is after [i] (so the line before this is effected) + // subtract 1 + // remember points control the line after them + locationBefore--; + } + locationBefore = locationBefore < 0 ? 0 : locationBefore > m_dataArray.size() - 1 ? + m_dataArray.size() - 1 : locationBefore; + isBefore = false; + int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd)), &found, &isBefore); + if (isBefore == false) + { + locationAfter--; + } + // if updatingEnd is the last point in effecor, then + // update everithing after i - 1 + if (updatingValuesIn->operator[](updatingEnd) + 1 > effector->size()) + { + locationAfter = m_dataArray.size() - 1; + } + locationAfter = locationAfter < 0 ? 0 : locationAfter > m_dataArray.size() - 1 ? + m_dataArray.size() - 1 : locationAfter; + + // adding the values between locationBefore, locationAfter + for (unsigned int j = i - 1; j <= locationAfter; j++) + { + m_needsUpdating.push_back(j); + } + } + else + { + // if updatingValuesIn[i] == 0 + if (effector->size() > 1) + { + // add every value before getX(1) + for (unsigned int j = 0; j < m_dataArray.size(); j++) + { + if (getX(j) > effector->getX(1)) + { + break; + } + m_needsUpdating.push_back(j); + } + } + else + { + // if there is only 1 point in effector + // add everithing + for (unsigned int j = 0; j < m_dataArray.size(); j++) + { + m_needsUpdating.push_back(j); + } + + } + } + } +} +void PointGraphDataArray::getUpdatingFromAuromation() +{ + // adding points with changed automation values + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (getIsAutomationValueChanged(i) == true) + { + m_needsUpdating.push_back(i); + } + } +} +void PointGraphDataArray::getUpdatingOriginals() +{ + // selecting only original values + // TODO this might be faster if we sort before + std::vector originalValues; + if (m_needsUpdating.size() > 0) + { + originalValues.push_back(m_needsUpdating[0]); + } + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + bool found = false; + for (unsigned int j = 0; j < originalValues.size(); j++) + { + if (m_needsUpdating[i] == originalValues[j]) + { + found = true; + break; + } + } + if (found == false) + { + originalValues.push_back(m_needsUpdating[i]); + } + } + + // sorting the array + // this is done because of optimalization + std::sort(originalValues.begin(), originalValues.end(), + [](unsigned int a, unsigned int b) + { + return a > b; + }); + + m_needsUpdating = originalValues; + originalValues.clear(); +} void PointGraphDataArray::PointGraphDataArray::formatDataArrayEndPoints() { @@ -2255,11 +2964,25 @@ void PointGraphDataArray::PointGraphDataArray::formatDataArrayEndPoints() m_dataArray[m_dataArray.size() - 1].m_y = 1.0f; m_dataArray[0].m_x = 0; m_dataArray[0].m_y = m_nonNegative == true ? 0.0f : -1.0f; + // dataChanged is called in functions using this function + // so this function does not call it } } -void PointGraphDataArray::dataChanged() +void PointGraphDataArray::dataChanged(int locationIn) { + if (m_isDataChanged == false && locationIn >= 0) + { + m_needsUpdating.push_back(locationIn); + if (m_needsUpdating.size() > m_dataArray.size() * 3) + { + m_isDataChanged = true; + } + } + else if (locationIn < 0) + { + m_isDataChanged = true; + } m_parent->dataArrayChanged(); } void PointGraphDataArray::styleChanged() From 96b99cf61b4711899430fdd90c57875ee5cc3b89 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 23 Mar 2024 18:01:52 +0100 Subject: [PATCH 012/184] vectorGraph_class_renamed --- include/{PointGraph.h => VectorGraph.h} | 75 ++--- plugins/FFTFilter/FFTFilterControlDialog.cpp | 4 +- plugins/FFTFilter/FFTFilterControls.cpp | 2 +- plugins/FFTFilter/FFTFilterControls.h | 4 +- src/gui/CMakeLists.txt | 2 +- .../{PointGraph.cpp => VectorGraph.cpp} | 288 +++++++++--------- 6 files changed, 188 insertions(+), 187 deletions(-) rename include/{PointGraph.h => VectorGraph.h} (92%) rename src/gui/widgets/{PointGraph.cpp => VectorGraph.cpp} (88%) diff --git a/include/PointGraph.h b/include/VectorGraph.h similarity index 92% rename from include/PointGraph.h rename to include/VectorGraph.h index 402dd12bb75..1f4c58e4973 100644 --- a/include/PointGraph.h +++ b/include/VectorGraph.h @@ -1,6 +1,6 @@ -#ifndef LMMS_GUI_POINTGRAPH_H -#define LMMS_GUI_POINTGRAPH_H +#ifndef LMMS_GUI_VECTORGRAPH_H +#define LMMS_GUI_VECTORGRAPH_H #include #include @@ -15,14 +15,14 @@ namespace lmms { -class PointGraphModel; -class PointGraphDataArray; +class VectorGraphModel; +class VectorGraphDataArray; class FloatModel; namespace gui { -class LMMS_EXPORT PointGraphView : public QWidget, public ModelView +class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView { Q_OBJECT public: @@ -72,19 +72,19 @@ class LMMS_EXPORT PointGraphView : public QWidget, public ModelView // TODO: handle effector arrays when deleting VectorGraphDataArray // TODO: update formatArray - PointGraphView(QWidget * parentIn, + VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn); - ~PointGraphView(); + ~VectorGraphView(); void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); void setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn); - inline PointGraphModel* model() + inline VectorGraphModel* model() { - return castModel(); + return castModel(); } void setIsSimplified(bool isSimplifiedIn); @@ -143,7 +143,7 @@ protected slots: // returns found location, when a data // was found in the given distance // else it returns -1 - int searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, PointGraphDataArray* arrayIn, bool curvedIn); + int searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn); bool m_mouseDown; bool m_mouseDrag; @@ -180,18 +180,18 @@ protected slots: } // namespace gui -class LMMS_EXPORT PointGraphModel : public Model//, public JournallingObject +class LMMS_EXPORT VectorGraphModel : public Model//, public JournallingObject { Q_OBJECT public: - PointGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn); - ~PointGraphModel(); + VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn); + ~VectorGraphModel(); inline size_t getDataArraySize() { return m_dataArrays.size(); } - inline PointGraphDataArray* getDataArray(unsigned int locationIn) + inline VectorGraphDataArray* getDataArray(unsigned int locationIn) { return &m_dataArrays[locationIn]; } @@ -219,7 +219,7 @@ Q_OBJECT { m_dataArrays.clear(); } - unsigned int getDataArrayLocation(PointGraphDataArray* dataArrayIn); + unsigned int getDataArrayLocation(VectorGraphDataArray* dataArrayIn); // save, load //void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO @@ -235,25 +235,25 @@ public slots: void dataArrayChanged(); void dataArrayStyleChanged(); private: - std::vector m_dataArrays; + std::vector m_dataArrays; unsigned int m_maxLength; - friend class gui::PointGraphView; + //friend class gui::VectorGraphView; }; -class LMMS_EXPORT PointGraphDataArray +class LMMS_EXPORT VectorGraphDataArray { public: // avoid using this or run updateConnections() after initialization - PointGraphDataArray(); - PointGraphDataArray( + VectorGraphDataArray(); + VectorGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, PointGraphModel* parentIn); - ~PointGraphDataArray(); + bool isSaveableIn, VectorGraphModel* parentIn); + ~VectorGraphDataArray(); - void updateConnections(PointGraphModel* parentIn); + void updateConnections(VectorGraphModel* parentIn); void setIsFixedSize(bool valueIn); void setIsFixedValue(bool valueIn); @@ -404,10 +404,10 @@ class LMMS_EXPORT PointGraphDataArray // color void styleChanged(); private: - class PointGraphPoint + class VectorGraphPoint { public: - inline PointGraphPoint() + inline VectorGraphPoint() { m_x = 0.0f; m_y = 0.0f; @@ -429,7 +429,7 @@ class LMMS_EXPORT PointGraphDataArray m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; } - inline PointGraphPoint(float xIn, float yIn) + inline VectorGraphPoint(float xIn, float yIn) { m_x = xIn; m_y = yIn; @@ -451,8 +451,9 @@ class LMMS_EXPORT PointGraphDataArray m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; } - inline ~PointGraphPoint() + inline ~VectorGraphPoint() { + // TODO make safer, delete in automationTrack if (m_automationModel != nullptr) { delete m_automationModel; @@ -507,8 +508,8 @@ class LMMS_EXPORT PointGraphDataArray float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); // applys the effect on a given value, does clamp float processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, - PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn); - // returns a PointGraphPoint with modified attributes + VectorGraphDataArray* effectArrayIn, unsigned int effectLocationIn); + // returns a VectorGraphPoint with modified attributes float processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn); // line effects / types, m_type is used for this @@ -556,14 +557,14 @@ class LMMS_EXPORT PointGraphDataArray bool m_isFixedPos; // if true then it makes the last position coordinate 1, 1, the first point coordinate to -1 (ot 0), 0 bool m_isFixedEndPoints; - // can PointGraphView select this + // can VectorGraphView select this bool m_isSelectable; - // can PointGraphView edit the point attributes + // can VectorGraphView edit the point attributes // every attribute outside of x and y bool m_isEditableAttrib; // can the points be automated or effected bool m_isAutomatableEffectable; - // if PointGraphDataArray is allowed to save this + // if VectorGraphDataArray is allowed to save this bool m_isSaveable; // can values be less than 0 @@ -573,13 +574,13 @@ class LMMS_EXPORT PointGraphDataArray QColor m_fillColor; QColor m_automatedColor; - PointGraphModel* m_parent; + VectorGraphModel* m_parent; - // which PointGraphDataArray can effect this one, -1 if not effected + // which VectorGraphDataArray can effect this one, -1 if not effected int m_effectorLocation; - // ordered array of PointGraphPoints - std::vector m_dataArray; + // ordered array of VectorGraphPoints + std::vector m_dataArray; // baking @@ -605,4 +606,4 @@ class LMMS_EXPORT PointGraphDataArray } // namespace lmms -#endif // LMMS_POINTGRAPH_H +#endif // LMMS_VECTORGRAPH_H diff --git a/plugins/FFTFilter/FFTFilterControlDialog.cpp b/plugins/FFTFilter/FFTFilterControlDialog.cpp index bcee09c4c78..2e5f4b08f7f 100644 --- a/plugins/FFTFilter/FFTFilterControlDialog.cpp +++ b/plugins/FFTFilter/FFTFilterControlDialog.cpp @@ -33,7 +33,7 @@ #include "LedCheckBox.h" #include "PixmapButton.h" #include "LcdSpinBox.h" -#include "PointGraph.h" +#include "VectorGraph.h" namespace lmms::gui { @@ -106,7 +106,7 @@ FFTFilterControlDialog::FFTFilterControlDialog(FFTFilterControls* controls) : resetButton->resize(13, 48); resetButton->move(300, 100); - auto curGraph = new PointGraphView(this, 300, 200, 10, 1024); + auto curGraph = new VectorGraphView(this, 300, 200, 10, 1024); curGraph->setModel(&controls->m_graphModel); curGraph->move(100, 240); /* diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 308bc54ee2e..bd06c279b73 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -27,7 +27,7 @@ #include "FFTFilterControls.h" #include "FFTFilter.h" -#include "PointGraph.h" +#include "VectorGraph.h" namespace lmms { diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h index fd5bd1beb04..97f1e37e52e 100644 --- a/plugins/FFTFilter/FFTFilterControls.h +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -28,7 +28,7 @@ #include "EffectControls.h" #include "FFTFilterControlDialog.h" -#include "PointGraph.h" +#include "VectorGraph.h" namespace lmms { @@ -75,7 +75,7 @@ private slots: BoolModel m_displayFFTModel; BoolModel m_resetModel; - PointGraphModel m_graphModel; + VectorGraphModel m_graphModel; //graphModel m_filterModel; diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 09fdcf59263..feafce25c2d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -120,7 +120,6 @@ SET(LMMS_SRCS gui/widgets/Oscilloscope.cpp gui/widgets/PeakIndicator.cpp gui/widgets/PixmapButton.cpp - gui/widgets/PointGraph.cpp gui/widgets/SimpleTextFloat.cpp gui/widgets/TabBar.cpp gui/widgets/TabWidget.cpp @@ -129,6 +128,7 @@ SET(LMMS_SRCS gui/widgets/TextFloat.cpp gui/widgets/TimeDisplayWidget.cpp gui/widgets/ToolButton.cpp + gui/widgets/VectorGraph.cpp PARENT_SCOPE ) diff --git a/src/gui/widgets/PointGraph.cpp b/src/gui/widgets/VectorGraph.cpp similarity index 88% rename from src/gui/widgets/PointGraph.cpp rename to src/gui/widgets/VectorGraph.cpp index dcb72c86595..6d31fb4d10f 100644 --- a/src/gui/widgets/PointGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -9,7 +9,7 @@ #include #include -#include "PointGraph.h" +#include "VectorGraph.h" #include "StringPairDrag.h" @@ -19,11 +19,11 @@ namespace lmms namespace gui { -PointGraphView::PointGraphView(QWidget * parentIn, +VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn) : QWidget(parentIn), - ModelView(new PointGraphModel(maxLengthIn, nullptr, false), this) + ModelView(new VectorGraphModel(maxLengthIn, nullptr, false), this) { resize(widthIn, heightIn); @@ -83,14 +83,14 @@ PointGraphView::PointGraphView(QWidget * parentIn, QObject::connect(gModel, SIGNAL(lengthChanged()), this, SLOT(updateGraph())); } -PointGraphView::~PointGraphView() +VectorGraphView::~VectorGraphView() { m_editingText.clear(); m_editingInputIsFloat.clear(); m_editingLineEffectText.clear(); } -void PointGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) { if (model()->getDataArraySize() > dataArrayLocationIn) { @@ -98,7 +98,7 @@ void PointGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocation update(); } } -void PointGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn) { if (model()->getDataArraySize() > dataArrayLocationIn) { @@ -106,7 +106,7 @@ void PointGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocati update(); } } -void PointGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocationIn) { if (model()->getDataArraySize() > dataArrayLocationIn) { @@ -114,7 +114,7 @@ void PointGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocation update(); } } -void PointGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn) { if (model()->getDataArraySize() > dataArrayLocationIn) { @@ -123,12 +123,12 @@ void PointGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLoc } } -void PointGraphView::setIsSimplified(bool isSimplifiedIn) +void VectorGraphView::setIsSimplified(bool isSimplifiedIn) { m_isSimplified = isSimplifiedIn; } -std::pair PointGraphView::getSelectedData() +std::pair VectorGraphView::getSelectedData() { std::pair output(-1.0f, 0.00); if (m_isSelected == true) @@ -138,7 +138,7 @@ std::pair PointGraphView::getSelectedData() } return output; } -int PointGraphView::getLastSelectedArray() +int VectorGraphView::getLastSelectedArray() { if (m_isLastSelectedArray == true) { @@ -146,7 +146,7 @@ int PointGraphView::getLastSelectedArray() } return -1; } -void PointGraphView::setSelectedData(std::pair dataIn) +void VectorGraphView::setSelectedData(std::pair dataIn) { if (m_isSelected == true) { @@ -158,7 +158,7 @@ void PointGraphView::setSelectedData(std::pair dataIn) } } -void PointGraphView::mousePressEvent(QMouseEvent* me) +void VectorGraphView::mousePressEvent(QMouseEvent* me) { // get position int x = me->x(); @@ -205,7 +205,7 @@ void PointGraphView::mousePressEvent(QMouseEvent* me) qDebug("mousePressEnd ---------"); } -void PointGraphView::mouseMoveEvent(QMouseEvent* me) +void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { // get position // the x coord is clamped because @@ -304,7 +304,7 @@ void PointGraphView::mouseMoveEvent(QMouseEvent* me) } } -void PointGraphView::mouseReleaseEvent(QMouseEvent* me) +void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) { // get position int x = me->x(); @@ -416,7 +416,7 @@ void PointGraphView::mouseReleaseEvent(QMouseEvent* me) emit drawn(); } -void PointGraphView::mouseDoubleClickEvent(QMouseEvent * me) +void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) { // get position int x = me->x(); @@ -451,14 +451,14 @@ void PointGraphView::mouseDoubleClickEvent(QMouseEvent * me) } } -void PointGraphView::paintEvent(QPaintEvent* pe) +void VectorGraphView::paintEvent(QPaintEvent* pe) { QPainter p(this); //QPainterPath pt(); // TODO qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_editingHeight : height(); - PointGraphDataArray* dataArray = nullptr; + VectorGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { dataArray = model()->getDataArray(i); @@ -620,7 +620,7 @@ void PointGraphView::paintEvent(QPaintEvent* pe) } } -void PointGraphView::modelChanged() +void VectorGraphView::modelChanged() { auto gModel = model(); QObject::connect(gModel, SIGNAL(dataChanged()), @@ -629,12 +629,12 @@ void PointGraphView::modelChanged() this, SLOT(updateGraph())); } -void PointGraphView::updateGraph() +void VectorGraphView::updateGraph() { update(); } -std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) +std::pair VectorGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) { if (nonNegativeIn == true) { @@ -651,7 +651,7 @@ std::pair PointGraphView::mapMousePos(int xIn, int yIn, bool nonNe static_cast((yIn * 2.0f / (float)m_graphHeight) - 1.0f)); } } -std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) +std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) { if (nonNegativeIn == true) { @@ -668,33 +668,33 @@ std::pair PointGraphView::mapDataPos(float xIn, float yIn, bool nonNeg static_cast((yIn / 2.0f + 0.5f) * m_graphHeight)); } } -std::pair PointGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) +std::pair VectorGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) { return std::pair( (xAIn + xBIn) / 2.0f, yAIn + (curveIn / 2.0f + 0.5f) * (yBIn - yAIn)); } -std::pair PointGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn) +std::pair VectorGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn) { return std::pair( (xAIn + xBIn) / 2, yAIn + static_cast((curveIn / 2.0f + 0.5f) * (yBIn - yAIn))); } -int PointGraphView::mapInputPos(float inputValueIn, unsigned int displayLengthIn) +int VectorGraphView::mapInputPos(float inputValueIn, unsigned int displayLengthIn) { return (inputValueIn / 2.0f + 0.5f) * displayLengthIn; } -float PointGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) +float VectorGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) { return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); } -float PointGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBIn) +float VectorGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBIn) { return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); } -bool PointGraphView::isGraphPressed(int mouseYIn) +bool VectorGraphView::isGraphPressed(int mouseYIn) { if (m_isEditingActive == true && mouseYIn > m_graphHeight) { @@ -702,7 +702,7 @@ bool PointGraphView::isGraphPressed(int mouseYIn) } return true; } -int PointGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) +int VectorGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) { int output = -1; if (m_isEditingActive == true && mouseYIn > m_graphHeight) @@ -716,7 +716,7 @@ qDebug("getPressedInput x location ERRROR: %d", mouseXIn); } return output; } -float PointGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut) +float VectorGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut) { float output = 0.0f; if (m_isSelected == true) @@ -786,7 +786,7 @@ float PointGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, b } return output; } -void PointGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn) +void VectorGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn) { qDebug("setInputAttribValue started"); if (m_isSelected == true) @@ -889,7 +889,7 @@ void PointGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, fl } qDebug("setInputAttribValue finished"); } -QColor PointGraphView::getTextColorFromBaseColor(QColor baseColorIn) +QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColorIn) { QColor output(255, 255, 255, 255); int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); @@ -899,7 +899,7 @@ QColor PointGraphView::getTextColorFromBaseColor(QColor baseColorIn) } return output; } -QString PointGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) +QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) { int charLength = 4; QString output = ""; @@ -918,7 +918,7 @@ QString PointGraphView::getTextFromDisplayLength(QString textIn, unsigned int di return output; } -std::pair PointGraphView::showCoordInputDialog() +std::pair VectorGraphView::showCoordInputDialog() { std::pair curData(0.0f, 0.0f); if (m_isSelected == true) @@ -948,7 +948,7 @@ std::pair PointGraphView::showCoordInputDialog() } return curData; } -float PointGraphView::showInputDialog(float curInputValueIn) +float VectorGraphView::showInputDialog(float curInputValueIn) { float output = 0.0f; @@ -965,7 +965,7 @@ float PointGraphView::showInputDialog(float curInputValueIn) return output; } -void PointGraphView::selectData(int mouseXIn, int mouseYIn) +void VectorGraphView::selectData(int mouseXIn, int mouseYIn) { qDebug("selectData"); m_selectedLocation = 0; @@ -976,7 +976,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - PointGraphDataArray* dataArray = model()->getDataArray(i); + VectorGraphDataArray* dataArray = model()->getDataArray(i); if (dataArray->getIsSelectable() == true) { int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); @@ -997,7 +997,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) { for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - PointGraphDataArray* dataArray = model()->getDataArray(i); + VectorGraphDataArray* dataArray = model()->getDataArray(i); if (dataArray->getIsSelectable() == true) { int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); @@ -1018,7 +1018,7 @@ void PointGraphView::selectData(int mouseXIn, int mouseYIn) qDebug("selectDataEnd"); } -int PointGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, PointGraphDataArray* arrayIn, bool curvedIn) +int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn) { int output = -1; float maxDistance = maxDistanceIn * 2.0f; @@ -1139,41 +1139,41 @@ int PointGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceI } // namespace gui -PointGraphModel::PointGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn) : - Model(parentIn, tr("PointGraphModel"), defaultConstructedIn) +VectorGraphModel::VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn) : + Model(parentIn, tr("VectorGraphModel"), defaultConstructedIn) { m_maxLength = maxLengthIn; m_dataArrays = {}; } -PointGraphModel::~PointGraphModel() +VectorGraphModel::~VectorGraphModel() { m_dataArrays.clear(); } -unsigned int PointGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn) +unsigned int VectorGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn) { unsigned int location = addArray(); m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); return location; } -unsigned int PointGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn) +unsigned int VectorGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn) { unsigned int location = addArray(); m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); return location; } -unsigned int PointGraphModel::addArray() +unsigned int VectorGraphModel::addArray() { - PointGraphDataArray tempArray( + VectorGraphDataArray tempArray( false, false, false, false, false, false, false, false, true, this); m_dataArrays.push_back(tempArray); return m_dataArrays.size() - 1; } -void PointGraphModel::delArray(unsigned int locationIn) +void VectorGraphModel::delArray(unsigned int locationIn) { for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) { @@ -1182,24 +1182,24 @@ void PointGraphModel::delArray(unsigned int locationIn) m_dataArrays.pop_back(); } -void PointGraphModel::dataArrayChanged() +void VectorGraphModel::dataArrayChanged() { emit dataChanged(); } -void PointGraphModel::dataArrayStyleChanged() +void VectorGraphModel::dataArrayStyleChanged() { emit styleChanged(); } -unsigned int PointGraphModel::getDataArrayLocation(PointGraphDataArray* dataArrayIn) +unsigned int VectorGraphModel::getDataArrayLocation(VectorGraphDataArray* dataArrayIn) { return reinterpret_cast(&dataArrayIn) - - reinterpret_cast(&m_dataArrays) / sizeof(PointGraphDataArray); + reinterpret_cast(&m_dataArrays) / sizeof(VectorGraphDataArray); } -// PointGraphDataArray ------ +// VectorGraphDataArray ------ -PointGraphDataArray::PointGraphDataArray() +VectorGraphDataArray::VectorGraphDataArray() { m_isFixedSize = false; m_isFixedValue = false; @@ -1226,10 +1226,10 @@ PointGraphDataArray::PointGraphDataArray() m_needsUpdating = {}; } -PointGraphDataArray::PointGraphDataArray( +VectorGraphDataArray::VectorGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, PointGraphModel* parentIn) + bool isSaveableIn, VectorGraphModel* parentIn) { m_isFixedSize = isFixedSizeIn; m_isFixedValue = isFixedValueIn; @@ -1257,51 +1257,51 @@ PointGraphDataArray::PointGraphDataArray( updateConnections(parentIn); } -PointGraphDataArray::~PointGraphDataArray() +VectorGraphDataArray::~VectorGraphDataArray() { m_dataArray.clear(); m_bakedValues.clear(); m_needsUpdating.clear(); } -void PointGraphDataArray::updateConnections(PointGraphModel* parentIn) +void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) { - // call PointGraphModel signals without qt + // call VectorGraphModel signals without qt m_parent = parentIn; } -void PointGraphDataArray::setIsFixedSize(bool valueIn) +void VectorGraphDataArray::setIsFixedSize(bool valueIn) { m_isFixedSize = valueIn; dataChanged(-1); } -void PointGraphDataArray::setIsFixedValue(bool valueIn) +void VectorGraphDataArray::setIsFixedValue(bool valueIn) { m_isFixedValue = valueIn; dataChanged(-1); } -void PointGraphDataArray::setIsFixedPos(bool valueIn) +void VectorGraphDataArray::setIsFixedPos(bool valueIn) { m_isFixedPos = valueIn; dataChanged(-1); } -void PointGraphDataArray::setIsFixedEndPoints(bool valueIn) +void VectorGraphDataArray::setIsFixedEndPoints(bool valueIn) { m_isFixedEndPoints = valueIn; formatDataArrayEndPoints(); dataChanged(-1); } -void PointGraphDataArray::setIsSelectable(bool valueIn) +void VectorGraphDataArray::setIsSelectable(bool valueIn) { m_isSelectable = valueIn; dataChanged(-1); } -void PointGraphDataArray::setIsEditableAttrib(bool valueIn) +void VectorGraphDataArray::setIsEditableAttrib(bool valueIn) { m_isEditableAttrib = valueIn; dataChanged(-1); } -void PointGraphDataArray::setIsAutomatableEffectable(bool valueIn) +void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) { m_isAutomatableEffectable = valueIn; if (valueIn == false) @@ -1314,36 +1314,36 @@ void PointGraphDataArray::setIsAutomatableEffectable(bool valueIn) dataChanged(-1); } } -void PointGraphDataArray::setIsSaveable(bool valueIn) +void VectorGraphDataArray::setIsSaveable(bool valueIn) { m_isSaveable = valueIn; } -void PointGraphDataArray::setNonNegative(bool valueIn) +void VectorGraphDataArray::setNonNegative(bool valueIn) { m_nonNegative = valueIn; dataChanged(-1); } -void PointGraphDataArray::setLineColor(QColor colorIn) +void VectorGraphDataArray::setLineColor(QColor colorIn) { m_lineColor = colorIn; styleChanged(); } -void PointGraphDataArray::setActiveColor(QColor colorIn) +void VectorGraphDataArray::setActiveColor(QColor colorIn) { m_activeColor = colorIn; styleChanged(); } -void PointGraphDataArray::setFillColor(QColor colorIn) +void VectorGraphDataArray::setFillColor(QColor colorIn) { m_fillColor = colorIn; styleChanged(); } -void PointGraphDataArray::setAutomatedColor(QColor colorIn) +void VectorGraphDataArray::setAutomatedColor(QColor colorIn) { m_automatedColor = colorIn; styleChanged(); } -bool PointGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) +bool VectorGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) { bool found = true; if (locationIn >= 0) @@ -1382,66 +1382,66 @@ bool PointGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) return !found; } -bool PointGraphDataArray::getIsFixedSize() +bool VectorGraphDataArray::getIsFixedSize() { return m_isFixedSize; } -bool PointGraphDataArray::getIsFixedValue() +bool VectorGraphDataArray::getIsFixedValue() { return m_isFixedValue; } -bool PointGraphDataArray::getIsFixedPos() +bool VectorGraphDataArray::getIsFixedPos() { return m_isFixedPos; } -bool PointGraphDataArray::getIsFixedEndPoints() +bool VectorGraphDataArray::getIsFixedEndPoints() { return m_isFixedEndPoints; } -bool PointGraphDataArray::getIsSelectable() +bool VectorGraphDataArray::getIsSelectable() { return m_isSelectable; } -bool PointGraphDataArray::getIsEditableAttrib() +bool VectorGraphDataArray::getIsEditableAttrib() { return m_isEditableAttrib; } -bool PointGraphDataArray::getIsAutomatableEffectable() +bool VectorGraphDataArray::getIsAutomatableEffectable() { return m_isAutomatableEffectable; } -bool PointGraphDataArray::getIsSaveable() +bool VectorGraphDataArray::getIsSaveable() { return m_isSaveable; } -bool PointGraphDataArray::getNonNegative() +bool VectorGraphDataArray::getNonNegative() { return m_nonNegative; } -QColor* PointGraphDataArray::getLineColor() +QColor* VectorGraphDataArray::getLineColor() { return &m_lineColor; } -QColor* PointGraphDataArray::getActiveColor() +QColor* VectorGraphDataArray::getActiveColor() { return &m_activeColor; } -QColor* PointGraphDataArray::getFillColor() +QColor* VectorGraphDataArray::getFillColor() { return &m_fillColor; } -QColor* PointGraphDataArray::getAutomatedColor() +QColor* VectorGraphDataArray::getAutomatedColor() { return &m_automatedColor; } -int PointGraphDataArray::getEffectorArrayLocation() +int VectorGraphDataArray::getEffectorArrayLocation() { return m_effectorLocation; } // array: -int PointGraphDataArray::add(float xIn) +int VectorGraphDataArray::add(float xIn) { int location = -1; if (m_dataArray.size() < m_parent->getMaxLength()) @@ -1469,7 +1469,7 @@ int PointGraphDataArray::add(float xIn) targetLocation++; } } - m_dataArray.push_back(PointGraphPoint(xIn, 0.0f)); + m_dataArray.push_back(VectorGraphPoint(xIn, 0.0f)); qDebug("add 4. success, target: %d", targetLocation); swap(m_dataArray.size() - 1, targetLocation, true); dataChangedVal = true; @@ -1477,7 +1477,7 @@ int PointGraphDataArray::add(float xIn) else if (m_dataArray.size() <= 0) { qDebug("add 5. success"); - m_dataArray.push_back(PointGraphPoint(xIn, 0.0f)); + m_dataArray.push_back(VectorGraphPoint(xIn, 0.0f)); targetLocation = 0; dataChangedVal = true; } @@ -1497,7 +1497,7 @@ int PointGraphDataArray::add(float xIn) return location; } -void PointGraphDataArray::del(unsigned int locationIn) +void VectorGraphDataArray::del(unsigned int locationIn) { if (m_isFixedSize == false && locationIn < m_dataArray.size()) { @@ -1514,7 +1514,7 @@ void PointGraphDataArray::del(unsigned int locationIn) } // TODO input scaleing values -void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) +void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) { // clamp // TODO implement @@ -1556,7 +1556,7 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) if (sortIn == true) { std::sort(m_dataArray.begin(), m_dataArray.end(), - [](PointGraphPoint a, PointGraphPoint b) + [](VectorGraphPoint a, VectorGraphPoint b) { return a.m_x > b.m_x; }); @@ -1583,7 +1583,7 @@ void PointGraphDataArray::formatArray(bool clampIn, bool sortIn) dataChanged(-1); } -int PointGraphDataArray::getLocation(float xIn) +int VectorGraphDataArray::getLocation(float xIn) { bool found = false; bool isBefore = false; @@ -1595,7 +1595,7 @@ int PointGraphDataArray::getLocation(float xIn) return location; } -int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut) +int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut) { if (m_dataArray.size() > 0) { @@ -1655,7 +1655,7 @@ int PointGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isB return -1; } -std::vector PointGraphDataArray::getValues(unsigned int countIn) +std::vector VectorGraphDataArray::getValues(unsigned int countIn) { bool isChanged = false; std::shared_ptr> updatingValues = std::make_shared>(); @@ -1666,7 +1666,7 @@ std::vector PointGraphDataArray::getValues(unsigned int countIn) qDebug("getValuesA3 finished"); return output; } -std::vector PointGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) +std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) { bool effectorIsChanged = false; std::shared_ptr> effectorUpdatingValues = std::make_shared>(); @@ -1743,7 +1743,7 @@ std::vector PointGraphDataArray::getValues(unsigned int countIn, bool* is // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, std::vector> effectorData; - PointGraphDataArray* effector = nullptr; + VectorGraphDataArray* effector = nullptr; if (m_effectorLocation >= 0) { effector = m_parent->getDataArray(m_effectorLocation); @@ -2021,7 +2021,7 @@ float PointGraphDataArray::getValueAtPosition(float xIn) //qDebug("getVALUE, curLocation: %d", curLocation); //qDebug("getVALUE, locationAfer: %d", nextLocation); // temp effecor data - PointGraphDataArray* effector = nullptr; + VectorGraphDataArray* effector = nullptr; bool tempEFound = false; bool tempEIsBefore = false; int tempELocation = -1; @@ -2132,25 +2132,25 @@ float PointGraphDataArray::getValueAtPosition(float xIn) } */ -void PointGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) +void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { // TODO implement formatArray option m_dataArray.clear(); for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - m_dataArray.push_back(PointGraphPoint(dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second)); + m_dataArray.push_back(VectorGraphPoint(dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second)); if (isCurvedIn == true) { // TODO } } } -void PointGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) +void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) { m_dataArray.clear(); for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - m_dataArray.push_back(PointGraphPoint((i / static_cast(dataArrayIn->size())), dataArrayIn->operator[](i))); + m_dataArray.push_back(VectorGraphPoint((i / static_cast(dataArrayIn->size())), dataArrayIn->operator[](i))); if (isCurvedIn == true) { // TODO @@ -2158,7 +2158,7 @@ void PointGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isC } } -unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) +unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) { int location = locationIn; if (m_isFixedPos == false && xIn <= 1.0f) @@ -2213,7 +2213,7 @@ unsigned int PointGraphDataArray::setX(unsigned int locationIn, float xIn) return location; } -void PointGraphDataArray::setY(unsigned int locationIn, float yIn) +void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) { if (m_isFixedValue == false) { @@ -2226,28 +2226,28 @@ void PointGraphDataArray::setY(unsigned int locationIn, float yIn) } } -void PointGraphDataArray::setC(unsigned int locationIn, float cIn) +void VectorGraphDataArray::setC(unsigned int locationIn, float cIn) { m_dataArray[locationIn].m_c = cIn; dataChanged(locationIn); } -void PointGraphDataArray::setValA(unsigned int locationIn, float valueIn) +void VectorGraphDataArray::setValA(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valA = valueIn; dataChanged(locationIn); } -void PointGraphDataArray::setValB(unsigned int locationIn, float valueIn) +void VectorGraphDataArray::setValB(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valB = valueIn; dataChanged(locationIn); } -void PointGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) +void VectorGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { // set the type without changing the automated attribute location m_dataArray[locationIn].m_type = typeIn; dataChanged(locationIn); } -void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) +void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { if (m_isAutomatableEffectable == true) { @@ -2258,7 +2258,7 @@ void PointGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned i dataChanged(locationIn); } } -void PointGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) +void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { if (m_isAutomatableEffectable == true) { @@ -2269,19 +2269,19 @@ void PointGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned in dataChanged(locationIn); } } -unsigned int PointGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) +unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) { return m_dataArray[locationIn].m_automatedEffectedAttribLocations / 4; } -unsigned int PointGraphDataArray::getEffectedAttribLocation(unsigned int locationIn) +unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int locationIn) { return m_dataArray[locationIn].m_automatedEffectedAttribLocations % 4; } -bool PointGraphDataArray::getEffectOnlyPoints(unsigned int locationIn) +bool VectorGraphDataArray::getEffectOnlyPoints(unsigned int locationIn) { return (m_dataArray[locationIn].m_effectOnlyPoints == true || getEffectedAttribLocation(locationIn) > 0); } -void PointGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) +void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) { if (m_isAutomatableEffectable == true) { @@ -2294,7 +2294,7 @@ void PointGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool bool } } } -bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) +bool VectorGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) { switch (effectNumberIn) { @@ -2322,7 +2322,7 @@ bool PointGraphDataArray::getEffect(unsigned int locationIn, unsigned int effect } return false; } -void PointGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) +void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) { if (m_isAutomatableEffectable == true) { @@ -2353,7 +2353,7 @@ void PointGraphDataArray::setEffect(unsigned int locationIn, unsigned int effect } dataChanged(locationIn); } -bool PointGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) +bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) { if (m_dataArray[locationIn].m_bufferedAutomationValue != m_dataArray[locationIn].m_automationModel->value()) { @@ -2362,7 +2362,7 @@ bool PointGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) } return false; } -void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) +void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) { if (m_isAutomatableEffectable == true) { @@ -2384,7 +2384,7 @@ void PointGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomated } } -void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) +void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) { if (locationAIn != locationBIn) { @@ -2400,7 +2400,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI if (locationAIn < locationBIn) { - PointGraphPoint swap = m_dataArray[locationAIn]; + VectorGraphPoint swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i < locationBIn; i++) { m_dataArray[i] = m_dataArray[i + 1]; @@ -2409,7 +2409,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI } else { - PointGraphPoint swap = m_dataArray[locationAIn]; + VectorGraphPoint swap = m_dataArray[locationAIn]; for (unsigned int i = locationAIn; i > locationBIn; i--) { m_dataArray[i] = m_dataArray[i - 1]; @@ -2425,7 +2425,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI } else { - PointGraphPoint swap = m_dataArray[locationAIn]; + VectorGraphPoint swap = m_dataArray[locationAIn]; m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; } @@ -2434,7 +2434,7 @@ void PointGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBI dataChanged(locationBIn); } } -float PointGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) +float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) { float absCurveIn = std::abs(curveIn); float pow = curveIn < 0.0f ? 1.0f - xIn : xIn; @@ -2457,8 +2457,8 @@ float PointGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, return output; } -float PointGraphDataArray::processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, - PointGraphDataArray* effectArrayIn, unsigned int effectLocationIn) +float VectorGraphDataArray::processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, + VectorGraphDataArray* effectArrayIn, unsigned int effectLocationIn) { float output = attribValueIn; unsigned int attribLocation = effectArrayIn->getEffectedAttribLocation(effectLocationIn); @@ -2508,7 +2508,7 @@ float PointGraphDataArray::processEffect(float attribValueIn, unsigned int attri } return output; } -float PointGraphDataArray::processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn) +float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn) { float output = 0.0f; // if automated @@ -2530,20 +2530,20 @@ float PointGraphDataArray::processAutomation(float attribValueIn, unsigned int l // line type effects: /* -float PointGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn) { return processLineTypeSineB(xIn, valAIn, valBIn, 0.0f, fadeInStartIn); } */ // valA: amp, valB: freq, fadeInStartIn: from what xIn value should the line type fade out -std::vector PointGraphDataArray::processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, +std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn, float fadeInStartIn) { - return PointGraphDataArray::processLineTypeArraySineB(xIn, startIn, endIn, + return VectorGraphDataArray::processLineTypeArraySineB(xIn, startIn, endIn, valAIn, valBIn, 0.0f, fadeInStartIn); } /* -float PointGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { // sine // 628.318530718f = 100.0f * 2.0f * pi @@ -2563,7 +2563,7 @@ float PointGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float v } */ // valA: amp, valB: freq, curveIn: phase -std::vector PointGraphDataArray::processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, +std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { int count = static_cast(endIn) - static_cast(startIn); @@ -2620,7 +2620,7 @@ std::vector PointGraphDataArray::processLineTypeArraySineB(std::vector PointGraphDataArray::processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, +std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { int count = static_cast(endIn) - static_cast(startIn); @@ -2677,7 +2677,7 @@ std::vector PointGraphDataArray::processLineTypeArrayPeak(std::vector PointGraphDataArray::processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, +std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, std::vector* yIn, float valAIn, float valBIn, float fadeInStartIn) { int count = static_cast(endIn) - static_cast(startIn); @@ -2744,7 +2744,7 @@ std::vector PointGraphDataArray::processLineTypeArraySteps(std::vector PointGraphDataArray::processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, +std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) { int count = static_cast(endIn) - static_cast(startIn); @@ -2811,9 +2811,9 @@ std::vector PointGraphDataArray::processLineTypeArrayRandom(std::vector> updatingValuesIn) +void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr> updatingValuesIn) { - PointGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); + VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); for (unsigned int i = 0; i < updatingValuesIn->size(); i++) { if (updatingValuesIn->operator[](i) > 0) @@ -2907,7 +2907,7 @@ void PointGraphDataArray::getUpdatingFromEffector(std::shared_ptr 0) { @@ -2969,7 +2969,7 @@ void PointGraphDataArray::PointGraphDataArray::formatDataArrayEndPoints() } } -void PointGraphDataArray::dataChanged(int locationIn) +void VectorGraphDataArray::dataChanged(int locationIn) { if (m_isDataChanged == false && locationIn >= 0) { @@ -2985,7 +2985,7 @@ void PointGraphDataArray::dataChanged(int locationIn) } m_parent->dataArrayChanged(); } -void PointGraphDataArray::styleChanged() +void VectorGraphDataArray::styleChanged() { m_parent->dataArrayStyleChanged(); } From f3b7c4a8af215d13adbee8c8463be0d793a84528 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 23 Mar 2024 18:53:00 +0100 Subject: [PATCH 013/184] vectorGraph_reimplemented_nonNegative --- include/VectorGraph.h | 4 +- src/gui/widgets/VectorGraph.cpp | 67 +++++++++++++-------------------- 2 files changed, 29 insertions(+), 42 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 1f4c58e4973..c010875382e 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -60,7 +60,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // TODO: setDataArray keep attributes option, formatArray option which runs formatArray // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option Done // TODO: baked automation values in PointGraphPoint Done - // TODO: rename class to VectorGraph + // TODO: rename class to VectorGraph Done // TODO: make std::vector last used values Done // TODO: make update logic (isChanged and update only automation / effected lines) Done // TODO: effector location (same as automation location) Done @@ -110,7 +110,7 @@ protected slots: private: void modelChanged() override; - std::pair mapMousePos(int xIn, int yIn, bool nonNegativeIn); + std::pair mapMousePos(int xIn, int yIn); // calculate curve position std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 6d31fb4d10f..9d45b21e466 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -241,15 +241,14 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { if (m_isCurveSelected == false) { - std::pair convertedCoords = mapMousePos(x, m_graphHeight - y, model()->getDataArray(m_selectedArray)->getNonNegative()); + std::pair convertedCoords = mapMousePos(x, m_graphHeight - y); convertedCoords.first = convertedCoords.first > 1.0f ? 1.0f : convertedCoords.first < 0.0f ? 1.0f : convertedCoords.first; convertedCoords.second = convertedCoords.second > 1.0f ? 1.0f : convertedCoords.second < -1.0f ? -1.0f : convertedCoords.second; setSelectedData(convertedCoords); } else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { - std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second, - model()->getDataArray(m_selectedArray)->getNonNegative()); + std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; curveValue = curveValue > 1.0f ? 1.0f : curveValue < -1.0f ? -1.0f : curveValue; model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); @@ -295,8 +294,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) m_lastTrackPoint.second = m_graphHeight - y; qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, x, (m_graphHeight - y), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); } - std::pair convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(m_graphHeight - y - m_lastTrackPoint.second) / 2, - model()->getDataArray(m_selectedArray)->getNonNegative()); + std::pair convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(m_graphHeight - y - m_lastTrackPoint.second) / 2); setInputAttribValue(location, convertedCoords.second, false); } } @@ -322,8 +320,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) qDebug("release size: %ld", model()->getDataArraySize()); for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - std::pair curMouseData = mapMousePos(x, m_graphHeight - y, - model()->getDataArray(i)->getNonNegative()); // TODO optimize + std::pair curMouseData = mapMousePos(x, m_graphHeight - y); int location = model()->getDataArray(i)->add(curMouseData.first); // if adding was successful if (location >= 0) @@ -514,8 +511,8 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); for (unsigned int j = 0; j < dataArrayValues.size(); j++) { - //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1), dataArray->getNonNegative()); - //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width())), dataArray->getNonNegative()); + //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1)); + //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width()))); posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); posB.first = j; @@ -634,22 +631,12 @@ void VectorGraphView::updateGraph() update(); } -std::pair VectorGraphView::mapMousePos(int xIn, int yIn, bool nonNegativeIn) +std::pair VectorGraphView::mapMousePos(int xIn, int yIn) { - if (nonNegativeIn == true) - { - // mapping the position to 0 - 1, 0 - 1 using qWidget width and height - return std::pair( - static_cast(xIn / (float)width()), - static_cast(yIn / (float)m_graphHeight)); - } - else - { - // mapping the position to 0 - 1, -1 - 1 using qWidget width and height - return std::pair( - static_cast(xIn / (float)width()), - static_cast((yIn * 2.0f / (float)m_graphHeight) - 1.0f)); - } + // mapping the position to 0 - 1, 0 - 1 using qWidget width and height + return std::pair( + static_cast(xIn / (float)width()), + static_cast(yIn * 2.0f / (float)m_graphHeight) - 1.0f); } std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) { @@ -662,10 +649,9 @@ std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool nonNe } else { - // mapping the point/sample positon to mouse/view position return std::pair( static_cast(xIn * width()), - static_cast((yIn / 2.0f + 0.5f) * m_graphHeight)); + static_cast((yIn + 1.0f) * static_cast(m_graphHeight) / 2.0f)); } } std::pair VectorGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) @@ -1024,7 +1010,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance float maxDistance = maxDistanceIn * 2.0f; qDebug("searchData"); - std::pair transformedMouse = mapMousePos(mouseXIn, mouseYIn, arrayIn->getNonNegative()); + std::pair transformedMouse = mapMousePos(mouseXIn, mouseYIn); // we dont use this bool bool found = false; @@ -1526,6 +1512,10 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) { for (unsigned int i = 0; i < m_dataArray.size(); i++) { + if (m_dataArray[i].m_x < 0) + { + m_dataArray[i].m_x = 0; + } if (m_dataArray[i].m_x > 1) { m_dataArray[i].m_x = 1; @@ -1534,19 +1524,9 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) { m_dataArray[i].m_y = 1; } - if (m_nonNegative == true) - { - if (m_dataArray[i].m_y < 0) - { - m_dataArray[i].m_y = 0; - } - } - else + if (m_dataArray[i].m_y < -1) { - if (m_dataArray[i].m_y < -1) - { - m_dataArray[i].m_y = -1; - } + m_dataArray[i].m_y = -1; } } formatDataArrayEndPoints(); @@ -1965,6 +1945,13 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i m_bakedValues[j] = -1.0f; } } + if (m_nonNegative == true) + { + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; + } + } } effectorData.clear(); } @@ -2963,7 +2950,7 @@ void VectorGraphDataArray::formatDataArrayEndPoints() m_dataArray[m_dataArray.size() - 1].m_x = 1; m_dataArray[m_dataArray.size() - 1].m_y = 1.0f; m_dataArray[0].m_x = 0; - m_dataArray[0].m_y = m_nonNegative == true ? 0.0f : -1.0f; + m_dataArray[0].m_y = -1.0f; // dataChanged is called in functions using this function // so this function does not call it } From cb03af031899769f76706909c8ec501020d92544 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 23 Mar 2024 19:16:37 +0100 Subject: [PATCH 014/184] vectorGraph_before_pr_commit --- include/VectorGraph.h | 24 ++++++++++++++++++++ plugins/FFTFilter/FFTFilter.cpp | 5 ++--- plugins/FFTFilter/FFTFilter.h | 5 ++--- plugins/FFTFilter/FFTFilterControlDialog.h | 5 ++--- plugins/FFTFilter/FFTFilterControls.cpp | 13 +++++------ plugins/FFTFilter/FFTFilterControls.h | 5 ++--- src/gui/widgets/VectorGraph.cpp | 26 ++++++++++++++++++++-- 7 files changed, 62 insertions(+), 21 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index c010875382e..b4300b3b397 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -1,3 +1,26 @@ +/* + * VecorGraph.h - Vector graph widget and model implementation + * + * Copyright (c) 2024 Szeli1 TODO + * + * 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 LMMS_GUI_VECTORGRAPH_H #define LMMS_GUI_VECTORGRAPH_H @@ -71,6 +94,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // TODO: ability to edit multiple graphs using m_isLastSelectedArray // TODO: handle effector arrays when deleting VectorGraphDataArray // TODO: update formatArray + // TODO: licensing email TODO VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index fb808bef6d9..31297cd9ed3 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -1,8 +1,7 @@ /* - * Amplifier.cpp - A native amplifier effect plugin with sample-exact amplification + * FFTFilter.cpp - main FFTFilter class * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2006-2014 Tobias Doerffel + * Copyright (c) 2024 Szeli1 TODO * * This file is part of LMMS - https://lmms.io * diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index 480012737ba..9340792b3c2 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -1,8 +1,7 @@ /* - * Amplifier.h - amplifier-effect-plugin + * FFTFilter.h - FFTFilter effect for lmms * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2006-2014 Tobias Doerffel + * Copyright (c) 2024 Szeli1 TODO * * This file is part of LMMS - https://lmms.io * diff --git a/plugins/FFTFilter/FFTFilterControlDialog.h b/plugins/FFTFilter/FFTFilterControlDialog.h index aed329186c1..1bb14ec4f31 100644 --- a/plugins/FFTFilter/FFTFilterControlDialog.h +++ b/plugins/FFTFilter/FFTFilterControlDialog.h @@ -1,8 +1,7 @@ /* - * AmplifierControlDialog.h - control dialog for amplifier effect + * FFTFilterControlDialog.h - control dialog for FFTFilter effect * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2006-2014 Tobias Doerffel + * Copyright (c) 2024 Szeli1 TODO * * This file is part of LMMS - https://lmms.io * diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index bd06c279b73..18da63d4ef8 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -1,8 +1,7 @@ /* - * AmplifierControls.cpp - controls for amplifier effect + * FFTFilterCotnrols.cpp - controls for FFTFilter effect * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2008-2014 Tobias Doerffel + * Copyright (c) 2024 Szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -47,10 +46,10 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_graphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); - m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(255, 50, 50, 255)); - m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 0, 0, 255)); - m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(200, 25, 25, 255)); - m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(0, 200, 255, 255)); + m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); + m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); + m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 255)); + m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); } diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h index 97f1e37e52e..fba69e9a95e 100644 --- a/plugins/FFTFilter/FFTFilterControls.h +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -1,8 +1,7 @@ /* - * AmplifierControls.h - controls for bassboosterx -effect + * FFTFilterControls.h - FFTFilter controls * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2008-2014 Tobias Doerffel + * Copyright (c) 2024 Szeli1 TODO * * This file is part of LMMS - https://lmms.io * diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 9d45b21e466..06ecd26cd0d 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1,4 +1,26 @@ - +/* + * VectorGraph.cpp - Vector graph widget, model, helper class implementation + * + * Copyright (c) 2024 Szeli1 TODO + * + * 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 #include // sine @@ -2357,7 +2379,7 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate { if (m_dataArray[locationIn].m_automationModel == nullptr) { - m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, nullptr, QString(), false); + m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false); dataChanged(locationIn); } } From 61f974bf9bf0aaa1377c3ae9ce0a18ea30cbd3b4 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 23 Mar 2024 19:41:53 +0100 Subject: [PATCH 015/184] vectorGraph_before_pr_commit2 --- plugins/FFTFilter/FFTFilter.cpp | 105 -------------------------------- plugins/FFTFilter/FFTFilter.h | 5 -- src/gui/widgets/VectorGraph.cpp | 4 +- 3 files changed, 2 insertions(+), 112 deletions(-) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index 31297cd9ed3..fb99d91bb25 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -97,111 +97,6 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) return isRunning(); } -void FFTFilterEffect::runFFTOnBuffer(std::vector* inputReIn, std::vector* inputImIn, std::vector bufferIn) -{ - -} -void FFTFilterEffect::FFT(std::vector* inputReIn, std::vector* inputImIn) -{ - unsigned int target = 0; - for (unsigned int i = 0; i < inputReIn->size(); i++) - { - if (target > i) - { - const sample_t swapRe = inputReIn->operator[](target); - const sample_t swapIm = inputImIn->operator[](target); - inputReIn->operator[](target) = inputReIn->operator[](i); - inputImIn->operator[](target) = inputImIn->operator[](i); - inputReIn->operator[](i) = swapRe; - inputImIn->operator[](i) = swapIm; - - if (target < inputReIn->size() / 2) - // if (target / 2 < inputReIn->size() / 4) - { - const sample_t swapRe = inputReIn->operator[](inputReIn->size() - (i + 1)); - const sample_t swapIm = inputImIn->operator[](inputReIn->size() - (i + 1)); - inputReIn->operator[](inputReIn->size() - (i + 1)) = - inputReIn->operator[](inputReIn->size() - (target + 1)); - inputImIn->operator[](inputReIn->size() - (i + 1)) = - inputImIn->operator[](inputReIn->size() - (target + 1)); - inputReIn->operator[](inputReIn->size() - (target + 1)) = swapRe; - inputImIn->operator[](inputReIn->size() - (target + 1)) = swapIm; - } - } - unsigned int mask = inputReIn->size(); - /* - while (target & (mask <<= 1)) - { - target &= ~mask; - } - target |= mask; - */ - while (mask >= 1 && target >= mask) - { - target = target - mask; - mask = mask / 2; - } - target += mask; - } - - for (unsigned int step = 1; step < inputReIn->size(); step <<=1) - { - const unsigned int jump = step << 1; - const float stepD = (float)step; - sample_t twiddleRe = 1.0f; - sample_t twiddleIm = 0.0f; - - for (unsigned int group = 0; group < step; group++) - { - for (unsigned int pair = group; group < inputReIn->size(); pair+=jump) - { - const unsigned int match = pair + step; - const sample_t productRe = twiddleRe * inputReIn->operator[](match) - - twiddleIm * inputImIn->operator[](match); - const sample_t productIm = twiddleIm * inputReIn->operator[](match) + - twiddleRe * inputImIn->operator[](match); - inputReIn->operator[](match) = inputReIn->operator[](pair) - productRe; - inputImIn->operator[](match) = inputImIn->operator[](pair) - productIm; - inputReIn->operator[](pair) += productRe; - inputImIn->operator[](pair) += productIm; - } - - if (group + 1 == step) - { - continue; - } - - float angle = -3.14159265358979323846f * ((float)group + 1.0f) / stepD; - twiddleRe = (sample_t)std::cosh(angle); - twiddleIm = (sample_t)std::sinh(angle); - } - } -} -void FFTFilterEffect::IFFT(std::vector* inputReIn, std::vector* inputImIn) -{ - // conjugate the complex numbers - for (unsigned int i = 0; i < inputReIn->size(); i++) - { - inputImIn->operator[](i) *= -1; - } - - FFT(inputReIn, inputImIn); - - // conjugate the complex numbers again - for (unsigned int i = 0; i < inputReIn->size(); i++) - { - inputImIn->operator[](i) *= -1; - } - - // scaling the numbers - for (unsigned int i = 0; i < inputReIn->size(); i++) - { - // dividing the current complex number with (size, 0) - inputReIn->operator[](i) = inputReIn->operator[](i) / inputReIn->size(); - inputImIn->operator[](i) = inputImIn->operator[](i) / inputReIn->size(); - inputImIn->operator[](i) = -1; - } -} extern "C" { diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index 9340792b3c2..2dec6b8a71e 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -46,11 +46,6 @@ class FFTFilterEffect : public Effect } private: - void runFFTOnBuffer(std::vector* inputReIn, std::vector* inputImIn, std::vector bufferIn); - // implementation of fft - void FFT(std::vector* inputReIn, std::vector* inputImIn); - // inverse fft - void IFFT(std::vector* inputReIn, std::vector* inputImIn); inline sample_t getCurSample(unsigned int posIn) { diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 06ecd26cd0d..94ad80a2c56 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -381,12 +381,12 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) int editingTextCount = m_editingText.size(); if (m_isSelected == true) { - if (model()->getDataArray(m_selectedLocation)->getIsEditableAttrib() == false) + if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) { // x, y editingTextCount = 2; } - else if (model()->getDataArray(m_selectedLocation)->getIsAutomatableEffectable() == false) + else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) { // x, y, curve, valA, valB, switch type editingTextCount = 6; From aa56b637ca90c4cc4bca007c543edda9da79bcaf Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:13:26 +0100 Subject: [PATCH 016/184] vectorGraph_added_muliple_graph_support --- include/VectorGraph.h | 25 +- plugins/FFTFilter/FFTFilterControls.cpp | 13 + src/gui/widgets/VectorGraph.cpp | 329 ++++++++++++++++++------ 3 files changed, 282 insertions(+), 85 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index b4300b3b397..783ed2216a4 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -96,6 +96,8 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // TODO: update formatArray // TODO: licensing email TODO + // TODO: check selectedLocation, selectedArray, isSelected, isLastSelectedArray usage + VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn); @@ -144,8 +146,12 @@ protected slots: float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); float getDistance(float xAIn, float yAIn, float xBIn, float yBIn); + bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); + // returns true if the graph was clicked - bool isGraphPressed(int mouseYIn); + bool isGraphPressed(int mouseXIn, int mouseYIn); + // returns true if the editing window was clicked while in editing mode + bool isEditingWindowPressed(int mouseYIn); // returns -1 if no attribute was clicked int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); // returns a float attrib value, valueOut = attrib value if it is a bool @@ -181,6 +187,10 @@ protected slots: // draw simplified lines bool m_isSimplified; + // if m_isLastSelectedArray == true then + // m_selectedArray can be used + // else if m_isSelected == false then + // m_selectedLocation amd m_selectedArray should not be used unsigned int m_selectedLocation; unsigned int m_selectedArray; bool m_isSelected; @@ -225,6 +235,7 @@ Q_OBJECT } inline void setMaxLength(unsigned int maxLengthIn) { + // TODO run formatArray on all the dataArrays if (m_maxLength != maxLengthIn) { m_maxLength = maxLengthIn; @@ -243,7 +254,8 @@ Q_OBJECT { m_dataArrays.clear(); } - unsigned int getDataArrayLocation(VectorGraphDataArray* dataArrayIn); + int getDataArrayLocationFromId(int idIn); + int getDataArrayNewId(); // save, load //void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO @@ -274,7 +286,7 @@ class LMMS_EXPORT VectorGraphDataArray VectorGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, VectorGraphModel* parentIn); + bool isSaveableIn, VectorGraphModel* parentIn, int idIn); ~VectorGraphDataArray(); void updateConnections(VectorGraphModel* parentIn); @@ -293,7 +305,8 @@ class LMMS_EXPORT VectorGraphDataArray void setFillColor(QColor colorIn); void setAutomatedColor(QColor colorIn); // returns true if successful - bool setEffectorArrayLocation(unsigned int locationIn); + + bool setEffectorArrayLocation(int locationIn); bool getIsFixedSize(); bool getIsFixedValue(); @@ -309,7 +322,9 @@ class LMMS_EXPORT VectorGraphDataArray QColor* getFillColor(); QColor* getAutomatedColor(); // returns -1 if it has no effector + int getEffectorArrayLocation(); + int getId(); // array: ------------------- @@ -599,6 +614,8 @@ class LMMS_EXPORT VectorGraphDataArray QColor m_automatedColor; VectorGraphModel* m_parent; + // simple id system for setEffectorArrayLocation + int m_id; // which VectorGraphDataArray can effect this one, -1 if not effected int m_effectorLocation; diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 18da63d4ef8..d6335282c60 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -50,6 +50,19 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 255)); m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); + + unsigned int arrayLocationB = m_graphModel.addArray(); + m_graphModel.getDataArray(arrayLocationB)->setIsSelectable(true); + m_graphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); + m_graphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); + m_graphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); + m_graphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); + m_graphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 255)); + m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); + m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); + + // effectors: + m_graphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB); } diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 94ad80a2c56..a913c725fc4 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -25,7 +25,8 @@ #include #include // sine #include // sort -#include +#include // rand +#include // unintptr_t #include // smartpointers #include #include @@ -201,7 +202,7 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) me->accept(); } } - else if (isGraphPressed(y) == true) + else if (isGraphPressed(x, m_graphHeight - y) == true) { // try selecting the clicked point (if it is near) selectData(x, m_graphHeight - y); @@ -257,7 +258,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) // if the mouse was moved a lot if (m_mousePress == false) { - if (isGraphPressed(m_graphHeight - m_lastScndTrackPoint.second) == true) + if (isGraphPressed(x, m_lastScndTrackPoint.second) == true) { if (m_isSelected == true && m_addition == true) { @@ -293,13 +294,14 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) // else m_mousePress does not change } } - else + else if (isEditingWindowPressed(m_lastScndTrackPoint.second) == true) { // if editing inputs were pressed (not graph) int pressLocation = getPressedInput(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, m_editingInputCount + 1); if (pressLocation >= 0 && pressLocation < m_editingInputCount) { - // pressLocation should always be >= 0 + // pressLocation should always be bigger than -1 + // if the editing window was pressed unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; // if the input type is a float if (location < m_editingText.size() && m_editingInputIsFloat[location] == true) @@ -329,7 +331,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) // get position int x = me->x(); int y = me->y(); - if (isGraphPressed(m_graphHeight - y) == true) + if (isGraphPressed(x, m_graphHeight - y) == true) { qDebug("mouseMove graphPressed: %d", m_lastTrackPoint.first); if (m_mousePress == true) @@ -340,16 +342,22 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) // if selection failed and addition // get the first editable daraArray and add value qDebug("release size: %ld", model()->getDataArraySize()); - for(unsigned int i = 0; i < model()->getDataArraySize(); i++) + bool success = false; + if (m_isLastSelectedArray == true && m_isSelected == true) + { + // trying to add to the last selected array + success = addPoint(m_selectedArray, x, m_graphHeight - y); + } + if (success == false) { - std::pair curMouseData = mapMousePos(x, m_graphHeight - y); - int location = model()->getDataArray(i)->add(curMouseData.first); - // if adding was successful - if (location >= 0) + // trying to add to all the selected arrays + for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - qDebug("mouseRelease added %d %f,%d", location, curMouseData.second, m_graphHeight); - model()->getDataArray(i)->setY(location, curMouseData.second); - break; + success = addPoint(m_selectedArray, x, m_graphHeight - y); + if (success == true) + { + break; + } } } } @@ -369,7 +377,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } } - else if (m_mousePress == true) + else if (m_mousePress == true && isEditingWindowPressed(m_graphHeight - y) == true) { qDebug("mouseMove 7: %d", m_lastTrackPoint.first); int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); @@ -402,7 +410,6 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } else if (pressLocation >= 0) { - // pressLocation should always be >= 0 unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; // setting the boolean values if (location < m_editingText.size() && m_editingInputIsFloat[location] == false) @@ -424,6 +431,43 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } } } + else + { +qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray); + // if the "switch graph" button was pressed + unsigned int oldSelectedArray = m_selectedArray; + m_selectedLocation = 0; + m_selectedArray = 0; + m_isLastSelectedArray = false; + m_isSelected = false; + m_isEditingActive = false; + m_isCurveSelected = false; + + // looping throught the data arrays to get a new + // selected data array + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + //qDebug("mouseRelease select new array: [%d], m_selectedArray: %d, old: %d", i, m_selectedArray, oldSelectedArray); + if (model()->getDataArray(i)->getIsSelectable() == true) + { + // if this data array is the first one that is selectable + if (m_isLastSelectedArray == false) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + } + // if this data array's location is bigger than the old location + // if this is false then m_selectedArray will equal to the first selectable array + if (i > oldSelectedArray) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + break; + } + } + } + //qDebug("mouseRelease select new array final:", m_selectedArray); + } m_addition = false; m_mouseDown = false; m_mouseDrag = false; @@ -442,7 +486,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) int y = me->y(); // if a data/sample is selected then show input dialog to change the data - if (isGraphPressed(m_graphHeight - y) == true) + if (isGraphPressed(x, m_graphHeight - y) == true) { if (m_isSelected == true && me->button() == Qt::LeftButton) { @@ -452,7 +496,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) setSelectedData(curData); } } - else + else if (isEditingWindowPressed(m_graphHeight - y) == true) { int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); if (pressLocation >= 0 && pressLocation != m_editingInputCount) @@ -477,6 +521,13 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_editingHeight : height(); + p.setPen(QPen(QColor(127, 127, 127, 255), 1)); + p.drawLine(0, 0, width() - 1, 0); + p.drawLine(width() - 1, 0, width() - 1, height() - 1); + p.drawLine(0, height() - 1, width() - 1, height() - 1); + p.drawLine(0, 0, 0, height() - 1); + + VectorGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { @@ -487,10 +538,6 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) unsigned int length = dataArray->size(); - if (m_isSelected == true) - { - p.drawLine(10, 10, 20, 20); - } if (length > 0) { @@ -541,7 +588,10 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + if (j > 0) + { + p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + } posA = posB; } dataArrayValues.clear(); @@ -628,6 +678,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) p.drawText(m_editingInputCount * segmentLength, m_graphHeight + m_editingHeight / 2, ">>"); // draw outline p.setPen(*dataArray->getLineColor()); + p.drawRect(0, 0, m_editingHeight, m_editingHeight); p.drawLine(0, m_graphHeight, width(), m_graphHeight); for (unsigned int i = 1; i < m_editingInputCount + 1; i++) { @@ -637,6 +688,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) } } } + qDebug("paint event end"); } void VectorGraphView::modelChanged() @@ -702,13 +754,52 @@ float VectorGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBI return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); } -bool VectorGraphView::isGraphPressed(int mouseYIn) +bool VectorGraphView::addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn) { - if (m_isEditingActive == true && mouseYIn > m_graphHeight) + bool output = false; + std::pair curMouseCoords = mapMousePos(mouseXIn, mouseYIn); + int location = model()->getDataArray(locationIn)->add(curMouseCoords.first); + // if adding was successful + if (location >= 0) + { + output = true; + qDebug("addPoint point added: array: %d location: %d %f,%d", locationIn, location, curMouseCoords.second, m_graphHeight); + model()->getDataArray(locationIn)->setY(location, curMouseCoords.second); + } + qDebug("addPoint LocationIn: %d", locationIn); + return output; +} + +bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) +{ + bool output = true; + // mouseYIn is calculated like this: + // m_graphHeight - y + if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_editingHeight && mouseXIn < m_editingHeight) + { + // if switch selected data array was pressed + qDebug("isGraphPressed switch selected dataArray"); + output = false; + } + else if (isEditingWindowPressed(mouseYIn) == true) + { + // if the editing window was pressed + output = false; + } + qDebug("isGraphPressed end"); + return output; +} +bool VectorGraphView::isEditingWindowPressed(int mouseYIn) +{ + bool output = false; + // mouseYIn is calculated like this: + // m_graphHeight - y + if (m_isEditingActive == true && mouseYIn <= 0) { - return false; + qDebug("isGraphPressed editing window was pressed"); + output = true; } - return true; + return output; } int VectorGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) { @@ -939,7 +1030,7 @@ std::pair VectorGraphView::showCoordInputDialog() double changedX = QInputDialog::getDouble(this, tr("Set value"), tr("Please enter a new value between 0 and 100"), static_cast(curData.first * 100.0f), - 0.0, 100.0, 0, &ok); + 0.0, 100.0, 2, &ok); if (ok == true) { curData.first = static_cast(changedX) / 100.0f; @@ -964,7 +1055,7 @@ float VectorGraphView::showInputDialog(float curInputValueIn) double changedPos = QInputDialog::getDouble(this, tr("Set value"), tr("Please enter a new value between -100 and 100"), static_cast(curInputValueIn * 100.0f), - -100.0, 100.0, 0, &ok); + -100.0, 100.0, 2, &ok); if (ok == true) { output = static_cast(changedPos) / 100.0f; @@ -976,54 +1067,78 @@ float VectorGraphView::showInputDialog(float curInputValueIn) void VectorGraphView::selectData(int mouseXIn, int mouseYIn) { qDebug("selectData"); - m_selectedLocation = 0; - m_selectedArray = 0; + m_isSelected = false; - m_isCurveSelected = false; - m_isEditingActive = false; - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + // trying to select the last selected array + if (m_isLastSelectedArray == true) { - VectorGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getIsSelectable() == true) + VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); + int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); + if (location > -1) { - int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); - if (location > -1) - { - qDebug("selected data!"); - m_selectedLocation = location; - m_selectedArray = i; - qDebug("selected data location: %d, %d", location, i); - m_isSelected = true; - m_isCurveSelected = false; - m_isEditingActive = dataArray->getIsEditableAttrib(); - break; - } + m_selectedLocation = location; + // m_selectedArray + m_isSelected = true; + m_isCurveSelected = false; + m_isEditingActive = dataArray->getIsEditableAttrib(); } - } + } + if (m_isSelected == false) { + m_selectedLocation = 0; + // m_selectedArray can not be set to 0 in case of + // m_isLastSelectedArray is active + // m_selectedArray = 0; + m_isSelected = false; + m_isCurveSelected = false; + m_isEditingActive = false; + //m_isLastSelectedArray = false; + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { VectorGraphDataArray* dataArray = model()->getDataArray(i); if (dataArray->getIsSelectable() == true) { - int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); + int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); if (location > -1) { - qDebug("selected data curve!"); + //qDebug("selected data!"); m_selectedLocation = location; m_selectedArray = i; - qDebug("selected data curve location: %d, %d", location, i); + //qDebug("selected data location: %d, %d", location, i); m_isSelected = true; - m_isCurveSelected = true; + m_isCurveSelected = false; m_isEditingActive = dataArray->getIsEditableAttrib(); break; } } } + if (m_isSelected == false) + { + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + VectorGraphDataArray* dataArray = model()->getDataArray(i); + if (dataArray->getIsSelectable() == true) + { + int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); + if (location > -1) + { + //qDebug("selected data curve!"); + m_selectedLocation = location; + m_selectedArray = i; + //qDebug("selected data curve location: %d, %d", location, i); + m_isSelected = true; + m_isCurveSelected = true; + m_isEditingActive = dataArray->getIsEditableAttrib(); + break; + } + } + } + } } - qDebug("selectDataEnd"); + qDebug("selectDataEnd, Arr: %d, location: %d", m_selectedArray, m_selectedLocation); } int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn) @@ -1039,7 +1154,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance bool isBefore = false; // get the nearest data to the mouse pos (x) in an optimalized way int location = arrayIn->getNearestLocation(transformedMouse.first, &found, &isBefore); - qDebug("selected location: %d", location); + //qDebug("selected location: %d", location); // if getNearestLocation was successful if (location >= 0) @@ -1067,17 +1182,17 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance } } // check distance against x coord - qDebug("selected x distance: %f", std::abs(dataX - transformedMouse.first)); + //qDebug("selected x distance: %f", std::abs(dataX - transformedMouse.first)); if (std::abs(dataX - transformedMouse.first) <= maxDistance) { // calculate real distance (x and y) float curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - qDebug("selected full distance: %f (%d, %d)", curDistance, location, (location - curvedBefore)); + //qDebug("selected full distance: %f (%d, %d)", curDistance, location, (location - curvedBefore)); if (curDistance <= maxDistance) { - qDebug("search successful"); + //qDebug("search successful"); output = location - curvedBefore; } else @@ -1098,7 +1213,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance break; } } - qDebug("search V2AAA temp, start: %d, end: %d", searchStart, searchEnd); + //qDebug("search V2AAA temp, start: %d, end: %d", searchStart, searchEnd); // getting where the search needs to end for (int i = location - curvedBefore + 1; i < arrayIn->size(); i++) { @@ -1108,7 +1223,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance break; } } - qDebug("search V2, start: %d, end: %d", searchStart, searchEnd); + //qDebug("search V2, start: %d, end: %d", searchStart, searchEnd); // calculating real distances from the point coords for (int i = searchStart; i <= searchEnd; i++) { @@ -1129,10 +1244,10 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance } curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); + //qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); if (curDistance <= maxDistance) { - qDebug("search successful V2"); + //qDebug("search successful V2"); output = i; break; } @@ -1176,7 +1291,8 @@ unsigned int VectorGraphModel::addArray(std::vector* arrayIn, bool isCurv unsigned int VectorGraphModel::addArray() { VectorGraphDataArray tempArray( - false, false, false, false, false, false, false, false, true, this); + false, false, false, false, false, false, false, + false, true, this, getDataArrayNewId()); m_dataArrays.push_back(tempArray); return m_dataArrays.size() - 1; } @@ -1199,10 +1315,34 @@ void VectorGraphModel::dataArrayStyleChanged() { emit styleChanged(); } -unsigned int VectorGraphModel::getDataArrayLocation(VectorGraphDataArray* dataArrayIn) +int VectorGraphModel::getDataArrayLocationFromId(int idIn) +{ + int output = -1; + if (idIn >= 0) + { + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + if (m_dataArrays[i].getId() == idIn) + { + output = i; + break; + } + } + } + return output; +} +int VectorGraphModel::getDataArrayNewId() { - return reinterpret_cast(&dataArrayIn) - - reinterpret_cast(&m_dataArrays) / sizeof(VectorGraphDataArray); + int maxId = 0; + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + if (m_dataArrays[i].getId() > maxId) + { + maxId = m_dataArrays[i].getId(); + } + } + maxId++; + return maxId; } // VectorGraphDataArray ------ @@ -1227,17 +1367,19 @@ VectorGraphDataArray::VectorGraphDataArray() m_effectorLocation = -1; - m_dataArray = {}; + //m_dataArray = {}; m_isDataChanged = false; //m_isUpdatedNeedsUpdating = false; - m_bakedValues = {}; - m_needsUpdating = {}; + //m_bakedValues = {}; + //m_needsUpdating = {}; + + m_id = -1; } VectorGraphDataArray::VectorGraphDataArray( bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, VectorGraphModel* parentIn) + bool isSaveableIn, VectorGraphModel* parentIn, int idIn) { m_isFixedSize = isFixedSizeIn; m_isFixedValue = isFixedValueIn; @@ -1262,6 +1404,7 @@ VectorGraphDataArray::VectorGraphDataArray( // m_bakedValues = {}; // m_needsUpdating = {}; + m_id = idIn; updateConnections(parentIn); } @@ -1276,6 +1419,9 @@ void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) { // call VectorGraphModel signals without qt m_parent = parentIn; + m_id = m_parent->getDataArrayNewId(); + // reseting effectors + setEffectorArrayLocation(-1); } void VectorGraphDataArray::setIsFixedSize(bool valueIn) @@ -1351,25 +1497,30 @@ void VectorGraphDataArray::setAutomatedColor(QColor colorIn) m_automatedColor = colorIn; styleChanged(); } -bool VectorGraphDataArray::setEffectorArrayLocation(unsigned int locationIn) +bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) { + qDebug("setEffectorArrayLocation start"); bool found = true; if (locationIn >= 0) { - unsigned int curLocation = m_parent->getDataArrayLocation(this); - qDebug("setEffectorArrayLocation cur_loaction %d", curLocation); + if (m_id < 0) + { + m_id = m_parent->getDataArrayNewId(); + } + qDebug("setEffectorArrayLocation cur_id %d", m_id); int arrayLocation = locationIn; found = false; for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) { + int arrayId = m_parent->getDataArray(arrayLocation)->getId(); arrayLocation = m_parent->getDataArray(arrayLocation)->getEffectorArrayLocation(); - if (arrayLocation == -1) + if(arrayId == m_id) { + found = true; break; } - else if(arrayLocation == curLocation) + if (arrayLocation == -1) { - found = true; break; } } @@ -1446,6 +1597,11 @@ int VectorGraphDataArray::getEffectorArrayLocation() { return m_effectorLocation; } +int VectorGraphDataArray::getId() +{ + return m_id; +} + // array: @@ -1746,7 +1902,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, std::vector> effectorData; VectorGraphDataArray* effector = nullptr; - if (m_effectorLocation >= 0) + if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) { effector = m_parent->getDataArray(m_effectorLocation); } @@ -1760,14 +1916,16 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); if (curLocation >= 0) { - curLocation = isBefore == false ? (curLocation > 1 ? curLocation - 1 : curLocation) : curLocation; + curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; // location effectorData[i].first = curLocation; + qDebug("getValuesB5.1, [%d] set to: %d", i, curLocation); // next location effectorData[i].second = curLocation; // if the location of this is the next location for before this if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) { + qDebug("getValuesB5.2, [%d - 1] changed to: %d", i, curLocation); effectorData[i - 1].second = curLocation; } } @@ -1784,19 +1942,26 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); if (curLocation >= 0) { - curLocation = isBefore == false ? (curLocation > 1 ? curLocation - 1 : curLocation) : curLocation; + curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; // next location + qDebug("getValuesB5.3, [%d] set after to: %d", i, curLocation); effectorData[i].second = curLocation; } } } } - qDebug("getValuesB6"); + for (unsigned int j = 0; j < effectorData.size(); j++) + { + qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); + } + qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); // calculate final line for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { + qDebug("getValuesB6.1 m_needsUpdating[%d]: %d", i, m_needsUpdating[i]); unsigned int effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[i]].m_x / stepSize)); + qDebug("getValuesB6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutput.size()); float curEffectY = effectorOutput[effectYLocation]; float nextEffectY = effectorOutput[effectYLocation]; @@ -1805,8 +1970,10 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i float curValA = m_dataArray[m_needsUpdating[i]].m_valA; float curValB = m_dataArray[m_needsUpdating[i]].m_valB; // TODO run processAutomation separatly + qDebug("getValuesB6.3, effectorDataSize: %ld", effectorData.size()); if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].first) == true) { + qDebug("getValuesB6.5"); curY = processAutomation( processEffect(m_dataArray[m_needsUpdating[i]].m_y, 0, curEffectY, effector, effectorData[i].first), m_needsUpdating[i], 0); @@ -1947,7 +2114,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; } } - if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].second) == false) + if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].first) == false) { // process line effect // if it is enabled From ac25ceec5d0a4597c6f7cc56b8d3fbe4772b1eb0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:21:18 +0100 Subject: [PATCH 017/184] VectorGraph_added_clearedEvent --- include/VectorGraph.h | 8 +++++++ src/gui/widgets/VectorGraph.cpp | 39 ++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 783ed2216a4..1ec524aaa75 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -254,6 +254,7 @@ Q_OBJECT { m_dataArrays.clear(); } + // if the id is not found then it will return 0 int getDataArrayLocationFromId(int idIn); int getDataArrayNewId(); @@ -263,12 +264,17 @@ Q_OBJECT signals: // data changed inside m_dataArray or m_maxLength changed void dataChanged(); + // signals when a dataArray gets to 0 element + // locationIn is the location of the dataArray + // locationIn can be -1 + void clearedEvent(int locationIn); // style changed inside m_dataArray void styleChanged(); // m_dataArrays length changed void lengthChanged(); public slots: void dataArrayChanged(); + void dataArrayClearedEvent(int idIn); void dataArrayStyleChanged(); private: std::vector m_dataArrays; @@ -336,6 +342,7 @@ class LMMS_EXPORT VectorGraphDataArray inline void clear() { m_dataArray.clear(); + clearedEvent(); dataChanged(-1); } inline size_t size() @@ -440,6 +447,7 @@ class LMMS_EXPORT VectorGraphDataArray // m_dataArray // if locationIn > 0 -> adds it to the void dataChanged(int locationIn); + void clearedEvent(); // color void styleChanged(); private: diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index a913c725fc4..21937b11017 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1310,6 +1310,12 @@ void VectorGraphModel::dataArrayChanged() { emit dataChanged(); } +void VectorGraphModel::dataArrayClearedEvent(int idIn) +{ + // TODO needs testing + int location = getDataArrayLocationFromId(idIn); + emit clearedEvent(location); +} void VectorGraphModel::dataArrayStyleChanged() { @@ -1317,6 +1323,7 @@ void VectorGraphModel::dataArrayStyleChanged() } int VectorGraphModel::getDataArrayLocationFromId(int idIn) { + // TODO needs testing int output = -1; if (idIn >= 0) { @@ -1672,6 +1679,11 @@ void VectorGraphDataArray::del(unsigned int locationIn) formatDataArrayEndPoints(); dataChanged(locationIn == 0 ? 0 : locationIn - 1); } + // calling clearedEvent + if (m_dataArray.size() == 0) + { + clearedEvent(); + } // if locationIn - 1 == -1 then update the entire m_bakedValues / m_dataArray dataChanged(static_cast(locationIn) - 1); } @@ -1722,7 +1734,7 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) // delete duplicates // TODO update name - float lastPos = 0.0f; + float lastPos = -1.0f; if (m_dataArray.size() > 0) { lastPos = m_dataArray[0].m_x; @@ -1738,6 +1750,8 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) lastPos = m_dataArray[i].m_x; } } + // calling clearedEvent is not needed + // because all of the values can not be cleared here dataChanged(-1); } @@ -2310,8 +2324,13 @@ float PointGraphDataArray::getValueAtPosition(float xIn) void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { + // TODO test // TODO implement formatArray option - m_dataArray.clear(); + m_dataArray.resize(dataArrayIn->size()); + if (m_dataArray.size() == 0) + { + clearedEvent(); + } for (unsigned int i = 0; i < dataArrayIn->size(); i++) { m_dataArray.push_back(VectorGraphPoint(dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second)); @@ -2323,15 +2342,15 @@ void VectorGraphDataArray::setDataArray(std::vector>* da } void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) { - m_dataArray.clear(); + // TODO test + std::vector> convertedDataArray(dataArrayIn->size()); + float stepSize = 1.0f / static_cast(convertedDataArray.size()); for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - m_dataArray.push_back(VectorGraphPoint((i / static_cast(dataArrayIn->size())), dataArrayIn->operator[](i))); - if (isCurvedIn == true) - { - // TODO - } + convertedDataArray[i].first = i * stepSize; + convertedDataArray[i].second = dataArrayIn->operator[](i); } + setDataArray(&convertedDataArray, isCurvedIn); } unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) @@ -3161,6 +3180,10 @@ void VectorGraphDataArray::dataChanged(int locationIn) } m_parent->dataArrayChanged(); } +void VectorGraphDataArray::clearedEvent() +{ + m_parent->dataArrayClearedEvent(m_id); +} void VectorGraphDataArray::styleChanged() { m_parent->dataArrayStyleChanged(); From 8223578647a41e5e0d5b2e9c8fdeddf1790dfc58 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:45:20 +0100 Subject: [PATCH 018/184] VectorGraph_updated_optimizations --- include/VectorGraph.h | 21 +- src/gui/widgets/VectorGraph.cpp | 546 +++++++++++++------------------- 2 files changed, 236 insertions(+), 331 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 1ec524aaa75..e6999f2a8c8 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -97,6 +97,8 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // TODO: licensing email TODO // TODO: check selectedLocation, selectedArray, isSelected, isLastSelectedArray usage + // TODO: finish gui, hint texts, context menu + // TODO: separate big functions VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, @@ -343,7 +345,8 @@ class LMMS_EXPORT VectorGraphDataArray { m_dataArray.clear(); clearedEvent(); - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } inline size_t size() { @@ -444,9 +447,8 @@ class LMMS_EXPORT VectorGraphDataArray // signals: // not qt - // m_dataArray - // if locationIn > 0 -> adds it to the - void dataChanged(int locationIn); + void dataChanged(); + // runs when m_dataArray.size() gets to 0 void clearedEvent(); // color void styleChanged(); @@ -586,10 +588,15 @@ class LMMS_EXPORT VectorGraphDataArray // effected by the effector's values changing // ONLY WORKS IN SORTED ARRAYS void getUpdatingFromEffector(std::shared_ptr> updatingValuesIn); + // if locationIn > 0 -> adds the location to m_needsUpdating + // else it will update the whole m_dataArray and m_bakedValues + // changes in the size of m_dataArray (addtition, deletion, ect.) + // needs to cause a full update + void getUpdatingFromPoint(int locationIn); // adds the points that are changed because their // automation is changed - void getUpdatingFromAuromation(); - // recalculates m_needsUpdating so + void getUpdatingFromAutomation(); + // recalculates and sorts m_needsUpdating so // every point is in there only once void getUpdatingOriginals(); @@ -641,6 +648,8 @@ class LMMS_EXPORT VectorGraphDataArray // if m_isDataChanged is true, then getValues adds all the points // to m_needsUpdating before running // getValues() clears m_needsUpdating after it has run + // every change is only applyed to the point's line (line started by the point) + // changes in y will cause multiple points to update // if we want to update all bool m_isDataChanged; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 21937b11017..bb87e2a7bdd 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -533,12 +533,9 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) { dataArray = model()->getDataArray(i); p.setPen(QPen(*dataArray->getLineColor(), 1)); - QColor gcolor = QColor(dataArray->getLineColor()->red(), dataArray->getLineColor()->green(), - dataArray->getLineColor()->blue(), 100); unsigned int length = dataArray->size(); - if (length > 0) { @@ -1434,33 +1431,39 @@ void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) void VectorGraphDataArray::setIsFixedSize(bool valueIn) { m_isFixedSize = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsFixedValue(bool valueIn) { m_isFixedValue = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsFixedPos(bool valueIn) { m_isFixedPos = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsFixedEndPoints(bool valueIn) { m_isFixedEndPoints = valueIn; formatDataArrayEndPoints(); - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsSelectable(bool valueIn) { m_isSelectable = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsEditableAttrib(bool valueIn) { m_isEditableAttrib = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) { @@ -1472,7 +1475,8 @@ void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) else { // setEffectorArray will call dataChanged() - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } } void VectorGraphDataArray::setIsSaveable(bool valueIn) @@ -1482,7 +1486,8 @@ void VectorGraphDataArray::setIsSaveable(bool valueIn) void VectorGraphDataArray::setNonNegative(bool valueIn) { m_nonNegative = valueIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setLineColor(QColor colorIn) { @@ -1534,14 +1539,16 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) if (found == false) { m_effectorLocation = locationIn; - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } } else { if (m_effectorLocation != -1) { - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); m_effectorLocation = -1; } } @@ -1654,6 +1661,7 @@ int VectorGraphDataArray::add(float xIn) } qDebug("add size: %ld", m_dataArray.size()); location = targetLocation; + if (m_dataArray.size() <= 2) { formatDataArrayEndPoints(); @@ -1661,7 +1669,10 @@ int VectorGraphDataArray::add(float xIn) } if (dataChangedVal == true) { - dataChanged(-1); + // addtition breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); } } } @@ -1677,15 +1688,16 @@ void VectorGraphDataArray::del(unsigned int locationIn) if (locationIn == 0 || locationIn == m_dataArray.size()) { formatDataArrayEndPoints(); - dataChanged(locationIn == 0 ? 0 : locationIn - 1); } // calling clearedEvent if (m_dataArray.size() == 0) { clearedEvent(); } - // if locationIn - 1 == -1 then update the entire m_bakedValues / m_dataArray - dataChanged(static_cast(locationIn) - 1); + // deletion breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); } } @@ -1752,7 +1764,8 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) } // calling clearedEvent is not needed // because all of the values can not be cleared here - dataChanged(-1); + getUpdatingFromPoint(-1); + dataChanged(); } int VectorGraphDataArray::getLocation(float xIn) @@ -1844,7 +1857,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i std::shared_ptr> effectorUpdatingValues = std::make_shared>(); std::vector effectorOutput; std::vector outputXLocations(countIn); - m_isDataChanged = true; // TODO DEBUG, delete this line + //m_isDataChanged = true; // TODO DEBUG, delete this line bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { @@ -1854,19 +1867,20 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { effectorOutput.resize(countIn); } - qDebug("getValuesB1, size: %ld", outputXLocations.size()); + qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); + m_isDataChanged = m_isDataChanged || effectorIsChanged; // updating m_needsUpdating if (m_isDataChanged == false && countIn == m_bakedValues.size()) { - if (isEffected == true && effectorUpdatingValues->size() > 1) + if (isEffected == true && effectorUpdatingValues->size() > 0) { // effectorUpdatingValues needs to be sorted // before use (in this case it is already sorted) getUpdatingFromEffector(effectorUpdatingValues); } qDebug("getValuesB2"); - getUpdatingFromAuromation(); + getUpdatingFromAutomation(); // sort and select only original // values getUpdatingOriginals(); @@ -2051,10 +2065,6 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // calculate curve for (int j = start; j < end; j++) { - // accessing m_dataArray[m_needsUpdating[i] + 1] should be safe bacause at the endpoint - // start = end (-> end is not bigger than j) - //float transformedX = (outputXLocations[j] - m_dataArray[m_needsUpdating[i]].m_x) / (m_dataArray[m_needsUpdating[i] + 1].m_x - m_dataArray[m_needsUpdating[i]].m_x); - //qDebug("getValuesB8 [%d] %f outputX", j, outputXLocations[j]); m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); } } @@ -2159,9 +2169,9 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i effectorData.clear(); } + *isChangedOut = m_isDataChanged; if (m_needsUpdating.size() > 0) { - updatingValuesOut = std::make_shared>(); *updatingValuesOut = m_needsUpdating; // clearing the updated values @@ -2174,154 +2184,6 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i return m_bakedValues; } -// this function is hard to maintain so it is inaccessible -/* -float PointGraphDataArray::getValueAtPosition(float xIn) -{ - float output = 0.0f; - bool found = false; - bool isBefore = false; - int curLocation = getNearestLocation(xIn, &found, &isBefore); - // get values of points (process effect if it effects only points) - // draw line - // process effect (if it effects lines too) - if (curLocation >= 0) - { - // location after should be location before + 1 - // or it is equal to curLocation when it is on an edge - curLocation = isBefore == true ? curLocation : curLocation - 1; - int nextLocation = curLocation + 1; - if (nextLocation >= m_dataArray.size()) - { - nextLocation = curLocation; - } - if (curLocation < 0) - { - curLocation++; - nextLocation = curLocation; - } - - float curY = m_dataArray[curLocation].m_y; - float curC = m_dataArray[curLocation].m_c; - float curValA = m_dataArray[curLocation].m_valA; - float curValB = m_dataArray[curLocation].m_valB; - - float nextY = curY; - - //qDebug("getVALUE, curLocation: %d", curLocation); - //qDebug("getVALUE, locationAfer: %d", nextLocation); - // temp effecor data - VectorGraphDataArray* effector = nullptr; - bool tempEFound = false; - bool tempEIsBefore = false; - int tempELocation = -1; - // if this data array has an effector data array - if (m_effectorLocation >= 0) - { - effector = m_parent->getDataArray(m_effectorLocation); - - // do not change order - // because tempELocation is used somewhere else - // nextLocation - tempELocation = effector->getNearestLocation(m_dataArray[nextLocation].m_x, &tempEFound, &tempEIsBefore); - tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; - if (tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) - { - float curEffectY = effector->getValueAtPosition(m_dataArray[nextLocation].m_x); - // apply effects - nextY = processAutomation( - processEffect(m_dataArray[nextLocation].m_y, 0, curEffectY, effector, tempELocation), - } - - // curLocation - tempELocation = effector->getNearestLocation(m_dataArray[curLocation].m_x, &tempEFound, &tempEIsBefore); - tempELocation = tempEIsBefore == true ? tempELocation : tempELocation > 0 ? tempELocation - 1 : tempELocation; - // if the effector point can only change points - if (tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) - { - float curEffectY = effector->getValueAtPosition(m_dataArray[curLocation].m_x); - // apply effects - curY = processAutomation( - processEffect(m_dataArray[curLocation].m_y, 0, curEffectY, effector, tempELocation), - curLocation, 0); - curC = processAutomation( - processEffect(m_dataArray[curLocation].m_c, 1, curEffectY, effector, tempELocation), - curLocation, 1); - curValA = processAutomation( - processEffect(m_dataArray[curLocation].m_valA, 2, curEffectY, effector, tempELocation), - curLocation, 2); - curValB = processAutomation( - processEffect(m_dataArray[curLocation].m_valB, 3, curEffectY, effector, tempELocation), - curLocation, 3); - } - } - - if (found == true) - { - output = nextY; - } - else if (nextLocation == curLocation) - { - // if the nearest point is an edge - output = curY; - } - else - { - float transformedX = (xIn - m_dataArray[curLocation].m_x) / (m_dataArray[nextLocation].m_x - m_dataArray[curLocation].m_x); - // type effects - unsigned int type = getType(curLocation); - float fadeOutStart = 0.05f; - if (type == 0) - { - output = processCurve(curY, nextY, curC, curLocation, 1), transformedX); - } - else if (type == 1) - { - output = processCurve(curY, nextY, curC, transformedX); - output = output + processLineTypeSine(transformedX, curValA, - curValB, fadeOutStart); - } - else if (type == 2) - { - output = processCurve(curY, nextY, 0.0f, transformedX); - output = output + processLineTypeSineB(transformedX, curValA, - curValB, processAutomation(curLocation, 3), fadeOutStart); - } - else if (type == 3) - { - output = processCurve(curY, nextY, 0.0f, transformedX); - output = output + processLineTypePeak(transformedX, curValA, - curValB, curC, fadeOutStart); - } - else if (type == 4) - { - output = processCurve(curY, nextY, curC, transformedX); - output = output + processLineTypeSteps(transformedX, output, curValA, - curValB, fadeOutStart); - } - else if (type == 5) - { - output = processCurve(curY, nextY, 0.0f, transformedX); - output = output + processLineTypeRandom(transformedX, curValA, - curValB, curC, fadeOutStart); - } - //qDebug("getVALUE, value2: %f %f - %d %d - %f %f", output, xIn, curLocation, nextLocation, transformedX, pointEffectBefore); - //qDebug("getVALUE, transfrmedX: %f", transformedX); - //qDebug("getVALUE, x: %f", xIn); - } - - // if this data array has an effector data array - // and it does not only effect data points - if (m_effectorLocation >= 0 && tempELocation >= 0 && effector->getEffectOnlyPoints(tempELocation) == true) - { - float curEffectY = effector->getValueAtPosition(xIn); - output = processEffect(output, 0, curEffectY, effector, tempELocation) - } - } - return output; -} -*/ - void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { // TODO test @@ -2339,6 +2201,9 @@ void VectorGraphDataArray::setDataArray(std::vector>* da // TODO } } + // the whole m_dataArray needs to be updated + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) { @@ -2393,7 +2258,15 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) m_dataArray[locationIn].m_x = xIn; swap(locationIn, targetLocation, true); location = targetLocation; - dataChanged(location); + + getUpdatingFromPoint(-1); + // changes in the position can change lines before + // so the point before this is updated + if (location > 0) + { + getUpdatingFromPoint(location - 1); + } + dataChanged(); } else { @@ -2416,7 +2289,14 @@ void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) locationIn > 0) || m_isFixedEndPoints == false) { m_dataArray[locationIn].m_y = yIn; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + // changes in the position can change lines before + // so the point before this is updated + if (locationIn > 0) + { + getUpdatingFromPoint(locationIn - 1); + } + dataChanged(); } } } @@ -2424,23 +2304,27 @@ void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) void VectorGraphDataArray::setC(unsigned int locationIn, float cIn) { m_dataArray[locationIn].m_c = cIn; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } void VectorGraphDataArray::setValA(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valA = valueIn; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } void VectorGraphDataArray::setValB(unsigned int locationIn, float valueIn) { m_dataArray[locationIn].m_valB = valueIn; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } void VectorGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { // set the type without changing the automated attribute location m_dataArray[locationIn].m_type = typeIn; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { @@ -2450,7 +2334,8 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set automated location correctly (effected_location = automatedEffectedLocation % 4) m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } } void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) @@ -2461,7 +2346,8 @@ void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned i attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set effected location correctly m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } } unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) @@ -2485,7 +2371,8 @@ void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boo m_dataArray[locationIn].m_effectOnlyPoints = boolIn; // this change does effect the main output if this // data array is an effector of an other so dataChanged() is called - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } } } @@ -2546,11 +2433,13 @@ void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effec break; } } - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) { - if (m_dataArray[locationIn].m_bufferedAutomationValue != m_dataArray[locationIn].m_automationModel->value()) + if (m_dataArray[locationIn].m_automationModel != nullptr && + m_dataArray[locationIn].m_bufferedAutomationValue != m_dataArray[locationIn].m_automationModel->value()) { m_dataArray[locationIn].m_bufferedAutomationValue = m_dataArray[locationIn].m_automationModel->value(); return true; @@ -2566,7 +2455,8 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate if (m_dataArray[locationIn].m_automationModel == nullptr) { m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false); - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } } else if (m_dataArray[locationIn].m_automationModel != nullptr) @@ -2574,7 +2464,8 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate // TODO correctly deconstruct delete m_dataArray[locationIn].m_automationModel; m_dataArray[locationIn].m_automationModel = nullptr; - dataChanged(locationIn); + getUpdatingFromPoint(locationIn); + dataChanged(); } } } @@ -2624,9 +2515,11 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; } - dataChanged(locationAIn - 1 > 0 ? locationAIn - 1 : 0); - dataChanged(locationBIn - 1 > 0 ? locationBIn - 1 : 0); - dataChanged(locationBIn); + getUpdatingFromPoint(locationBIn - 1 > 0 ? locationBIn - 1 : 0); + getUpdatingFromPoint(locationAIn - 1 > 0 ? locationAIn - 1 : 0); + getUpdatingFromPoint(locationAIn); + getUpdatingFromPoint(locationBIn); + dataChanged(); } } float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) @@ -2874,25 +2767,6 @@ std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector 1.0f - fadeInStartIn) - { - output = output * (1.0f - xIn) / fadeInStartIn; - } - return output; } */ // y: calculate steps from, valA: y count, valB: curve @@ -2941,27 +2815,6 @@ std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector(blend); - blend = blend - randomSeed; - std::srand(randomSeed); - int curLocation = static_cast(xIn * (1.0f + valBIn) * 50.0f); - float output = 0.0f; - // getting the current random value - for (unsigned int i = 1; i <= curLocation; i++) - { - if (i == curLocation) - { - output = rand(); - } - else - { - rand(); - } - } - output = output * blend * (blend - 2.0f) * - 1.0f - rand() * (1.0f - blend) * (-1.0f - blend); - return output * valAIn; } */ // valA: amp, valB: random number count, curveIn: seed @@ -3008,108 +2861,139 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr> updatingValuesIn) { + // Debug testing + for (unsigned int i = 0; i < updatingValuesIn->size(); i++) + { + qDebug("getUpdatingFromEffector #1: [%d] -> %d", i, updatingValuesIn->operator[](i)); + } VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); for (unsigned int i = 0; i < updatingValuesIn->size(); i++) { - if (updatingValuesIn->operator[](i) > 0) + // since updatingValuesIn is a sorted list, we can get the end + // location and update everithing between them + // starting effector location is i, end effector location is updatingEnd + unsigned int updatingEnd = i; + for (unsigned int j = i + 1; j < updatingValuesIn->size(); j++) { - // since updatingValuesIn is a sorted list, we can get the end - // values and update everithing between them - // starting value is i, end value is updatingEnd - unsigned int updatingEnd = i; - for (unsigned int j = i + 1; j < updatingValuesIn->size(); j++) - { - // we can skip 1 wide gaps because - // changes in Y can effect the line before j - if (updatingValuesIn->operator[](updatingEnd) + 2 >= - updatingValuesIn->operator[](j)) - { - updatingEnd = j; - } - else - { - break; - } - } - - bool found = false; - bool isBefore = false; - // i - 1 because changes in Y can effect the line before this - int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i) - 1), &found, &isBefore); - if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i) - 1) == true && isBefore == true) + // we can skip 1 wide gaps because + // every updatingValuesIn point effects their line only + // (the line that starts with the point) + if (updatingValuesIn->operator[](updatingEnd) + 1 >= + updatingValuesIn->operator[](j)) { - // if only points are effected and the nearest point - // is before [i] (so it needs to be uneffected) - // add 1 - locationBefore++; + updatingEnd = j; + qDebug("getUpdatingFromEffector new updatingEnd: %d, i: %d", updatingEnd, i); } - else if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i) - 1) == false && isBefore == false) - { - // if lines are effected and the nearest point - // is after [i] (so the line before this is effected) - // subtract 1 - // remember points control the line after them - locationBefore--; - } - locationBefore = locationBefore < 0 ? 0 : locationBefore > m_dataArray.size() - 1 ? - m_dataArray.size() - 1 : locationBefore; - isBefore = false; - int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd)), &found, &isBefore); - if (isBefore == false) - { - locationAfter--; - } - // if updatingEnd is the last point in effecor, then - // update everithing after i - 1 - if (updatingValuesIn->operator[](updatingEnd) + 1 > effector->size()) + else { - locationAfter = m_dataArray.size() - 1; + qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, (updatingValuesIn->operator[](updatingEnd) + 1), updatingValuesIn->operator[](j), j); + break; } - locationAfter = locationAfter < 0 ? 0 : locationAfter > m_dataArray.size() - 1 ? - m_dataArray.size() - 1 : locationAfter; + } + // getting the point that comes after updatingEnd + int updatingEndSlide = 0; + if (updatingEnd + 1 < effector->size()) + { + qDebug("getUpdatingFromEffector updatingEndSlide = 1"); + updatingEndSlide = 1; + } - // adding the values between locationBefore, locationAfter - for (unsigned int j = i - 1; j <= locationAfter; j++) - { - m_needsUpdating.push_back(j); - } + bool found = false; + bool isBefore = false; + int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i)), &found, &isBefore); + qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); + if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i)) == true && isBefore == true) + { + qDebug("getUpdatingFromEffector locationBefore = %d + 1", locationBefore); + // if only points are effected and the nearest point + // is before [i] (so it needs to be uneffected) + // add 1 + locationBefore++; + } + else if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i)) == false && isBefore == false) + { + qDebug("getUpdatingFromEffector locationBefore = %d - 1", locationBefore); + // if only points are effected and the nearest point + // if lines are effected and the nearest point + // is after [i] (so the line and the point before this is effected) + // subtract 1 + // remember points control the line after (connected to) them + locationBefore--; } - else + // clamp + locationBefore = locationBefore < 0 ? 0 : locationBefore > m_dataArray.size() - 1 ? + m_dataArray.size() - 1 : locationBefore; + isBefore = false; + int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); + qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d, ex: %f, dx: %f", locationAfter, updatingEnd, effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); + if (isBefore == true) { - // if updatingValuesIn[i] == 0 - if (effector->size() > 1) - { - // add every value before getX(1) - for (unsigned int j = 0; j < m_dataArray.size(); j++) - { - if (getX(j) > effector->getX(1)) - { - break; - } - m_needsUpdating.push_back(j); - } - } - else - { - // if there is only 1 point in effector - // add everithing - for (unsigned int j = 0; j < m_dataArray.size(); j++) - { - m_needsUpdating.push_back(j); - } + qDebug("getUpdatingFromEffector locationAfter = %d - 1", locationAfter); + // if [updatingEnd] is before the last nearest value + locationAfter--; + } + // updating everything before if i -> 0 + if (updatingValuesIn->operator[](i) == 0) + { + qDebug("getUpdatingFromEffector updating everything before"); + locationBefore = 0; + } + // if updatingEnd is the last point in effecor, then + // update everithing after if updatingend is the last location + if (updatingValuesIn->operator[](updatingEnd) + updatingEndSlide + 1 >= effector->size()) + { + qDebug("getUpdatingFromEffector updating everything after"); + locationAfter = m_dataArray.size() - 1; + } + // clamp + locationAfter = locationAfter < 0 ? 0 : locationAfter > m_dataArray.size() - 1 ? + m_dataArray.size() - 1 : locationAfter; - } + qDebug("getUpdatingFromEffector start: %d, end: %d", locationBefore, locationAfter); + // adding the values between locationBefore, locationAfter + for (unsigned int j = locationBefore; j <= locationAfter; j++) + { + qDebug("getUpdatingFromEffector: [%d] -> %d", i, j); + m_needsUpdating.push_back(j); + } + if (i < updatingEnd) + { + i = updatingEnd; } } } -void VectorGraphDataArray::getUpdatingFromAuromation() +void VectorGraphDataArray::getUpdatingFromPoint(int locationIn) +{ + // changes in position need to cause updates before the changed point + // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) + if (m_isDataChanged == false && locationIn >= 0) + { + m_needsUpdating.push_back(locationIn); + if (m_needsUpdating.size() > m_dataArray.size() * 3) + { + m_isDataChanged = true; + } + } + else if (locationIn < 0) + { + m_isDataChanged = true; + } +} +void VectorGraphDataArray::getUpdatingFromAutomation() { // adding points with changed automation values for (unsigned int i = 0; i < m_dataArray.size(); i++) { if (getIsAutomationValueChanged(i) == true) { + qDebug("getUpdatingFromAutomation: %d", i); m_needsUpdating.push_back(i); + // if the automatable value effects the y (so the position) + // so the point before this is updated too + if (i > 0 && getAutomatedAttribLocation(i) == 0) + { + m_needsUpdating.push_back(i - 1); + } } } } @@ -3122,7 +3006,14 @@ void VectorGraphDataArray::getUpdatingOriginals() { originalValues.push_back(m_needsUpdating[0]); } + + // Debug testing for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + qDebug("getUpatingOriginals: [%d] -> %d", i, m_needsUpdating[i]); + } + + for (unsigned int i = 1; i < m_needsUpdating.size(); i++) { bool found = false; for (unsigned int j = 0; j < originalValues.size(); j++) @@ -3144,10 +3035,27 @@ void VectorGraphDataArray::getUpdatingOriginals() std::sort(originalValues.begin(), originalValues.end(), [](unsigned int a, unsigned int b) { - return a > b; + return a < b; }); + // removing invalid locations + // because sometimes deleted locations can be in originalValues + for (unsigned int i = 0; i < originalValues.size(); i++) + { + if (originalValues[i] >= m_dataArray.size()) + { + originalValues.resize(i); + break; + } + } + + m_needsUpdating = originalValues; + // Debug testing + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); + } originalValues.clear(); } @@ -3164,20 +3072,8 @@ void VectorGraphDataArray::formatDataArrayEndPoints() } } -void VectorGraphDataArray::dataChanged(int locationIn) +void VectorGraphDataArray::dataChanged() { - if (m_isDataChanged == false && locationIn >= 0) - { - m_needsUpdating.push_back(locationIn); - if (m_needsUpdating.size() > m_dataArray.size() * 3) - { - m_isDataChanged = true; - } - } - else if (locationIn < 0) - { - m_isDataChanged = true; - } m_parent->dataArrayChanged(); } void VectorGraphDataArray::clearedEvent() From a0d941b5db3e3068f5760a32d2d74535c4326f77 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 27 Mar 2024 22:16:32 +0100 Subject: [PATCH 019/184] VectorGraph_updated_optimizations2 --- include/VectorGraph.h | 1 + src/gui/widgets/VectorGraph.cpp | 34 +++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index e6999f2a8c8..e6bb90ad210 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -389,6 +389,7 @@ class LMMS_EXPORT VectorGraphDataArray unsigned int getEffectedAttribLocation(unsigned int locationIn); // returns true when m_effectOnlyPoints is true or // when getEffectedAttribLocation > 0 (y is uneffected) + // -> when the current point CAN effect lines before it bool getEffectOnlyPoints(unsigned int locationIn); // returns if the [effectNumberIn] effect is active based on effectNumberIn bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index bb87e2a7bdd..2fcd783c50f 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2334,7 +2334,12 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set automated location correctly (effected_location = automatedEffectedLocation % 4) m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); + getUpdatingFromPoint(locationIn); + // the line before this can get added + // in getUpdatingFromAutomation + // so the point before this is not updated here + dataChanged(); } } @@ -2346,7 +2351,14 @@ void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned i attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set effected location correctly m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); + getUpdatingFromPoint(locationIn); + // if the current point can effect line before it + // update the point before it + if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + { + getUpdatingFromPoint(locationIn - 1); + } dataChanged(); } } @@ -2368,10 +2380,22 @@ void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boo { if (m_dataArray[locationIn].m_effectOnlyPoints != boolIn) { + // getEffectOnlyPoints does not return m_effecteOnlyPoints + bool dataChangedValue = getEffectOnlyPoints(locationIn); m_dataArray[locationIn].m_effectOnlyPoints = boolIn; // this change does effect the main output if this - // data array is an effector of an other so dataChanged() is called - getUpdatingFromPoint(locationIn); + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectOnlyPoints(locationIn)) + { + getUpdatingFromPoint(locationIn); + // if the current point can effect line before it + // update the point before it + if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + { + getUpdatingFromPoint(locationIn - 1); + } + } dataChanged(); } } @@ -2434,6 +2458,12 @@ void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effec } } getUpdatingFromPoint(locationIn); + // if the current point can effect line before it + // update the point before it + if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + { + getUpdatingFromPoint(locationIn - 1); + } dataChanged(); } bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) From 1e6d6499036be18c48f1d864b5651adc9cb6c55d Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:59:33 +0100 Subject: [PATCH 020/184] VectorGraph_ability_to_update_from_last_used_values --- include/VectorGraph.h | 9 ++++++++- src/gui/widgets/VectorGraph.cpp | 33 +++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index e6bb90ad210..636542ca93d 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -123,6 +123,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView int getLastSelectedArray(); void setSelectedData(std::pair dataIn); + void useGetLastValues(); signals: inline void drawn(); protected: @@ -188,6 +189,9 @@ protected slots: unsigned int m_pointSize; // draw simplified lines bool m_isSimplified; + // for 1 draw, it will use the VectorGraphDataArray + // m_bakedValues without calling GetValues() + bool m_useGetLastValues; // if m_isLastSelectedArray == true then // m_selectedArray can be used @@ -410,9 +414,12 @@ class LMMS_EXPORT VectorGraphDataArray // get changed locations // std::vector getUpdatingValues(); + // returns the latest updated graph values + // countIn is the retuned vector's size std::vector getValues(unsigned int countIn); std::vector getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut); - //float getValueAtPosition(float xIn); // TODO + // returns m_bakedValues without updating + std::vector getLastValues(); // set: ------------------- diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 2fcd783c50f..1ea71eb5948 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -57,6 +57,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, m_pointSize = pointSizeIn; m_isSimplified = false; + m_useGetLastValues = false; m_selectedLocation = 0; m_selectedArray = 0; @@ -99,12 +100,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, setCursor(Qt::CrossCursor); - auto gModel = model(); - - QObject::connect(gModel, SIGNAL(dataChanged()), - this, SLOT(updateGraph())); - QObject::connect(gModel, SIGNAL(lengthChanged()), - this, SLOT(updateGraph())); + modelChanged(); } VectorGraphView::~VectorGraphView() { @@ -180,6 +176,10 @@ void VectorGraphView::setSelectedData(std::pair dataIn) qDebug("set position done"); } } +void VectorGraphView::useGetLastValues() +{ + m_useGetLastValues = true; +} void VectorGraphView::mousePressEvent(QMouseEvent* me) { @@ -573,7 +573,17 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) if (m_isSimplified == false) { posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); - std::vector dataArrayValues = dataArray->getValues(width()); + + std::vector dataArrayValues; + if (m_useGetLastValues == true) + { + dataArrayValues = dataArray->getLastValues(); + } + else + { + dataArrayValues = dataArray->getValues(width()); + } + qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); for (unsigned int j = 0; j < dataArrayValues.size(); j++) { @@ -585,7 +595,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); // x1, y1, x2, y2 //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - if (j > 0) + if (j > 0 && posA.first != posB.first) { p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } @@ -685,7 +695,10 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) } } } + + m_useGetLastValues = false; qDebug("paint event end"); + emit drawn(); } void VectorGraphView::modelChanged() @@ -2183,6 +2196,10 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i qDebug("getValuesB9"); return m_bakedValues; } +std::vector VectorGraphDataArray::getLastValues() +{ + return m_bakedValues; +} void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) { From 203bddc1c1e8014d8f123c945bd810191793d8c0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:20:40 +0100 Subject: [PATCH 021/184] VectorGraph_added_calmp_effect --- include/VectorGraph.h | 6 +++++ src/gui/widgets/VectorGraph.cpp | 39 +++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 636542ca93d..bc50445cef6 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -482,6 +482,8 @@ class LMMS_EXPORT VectorGraphDataArray m_effectPower = false; m_effectLog = false; m_effectSine = false; + m_effectClampLower = false; + m_effectClampUpper = false; m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; @@ -504,6 +506,8 @@ class LMMS_EXPORT VectorGraphDataArray m_effectPower = false; m_effectLog = false; m_effectSine = false; + m_effectClampLower = false; + m_effectClampUpper = false; m_bufferedAutomationValue = 0.0f; m_automationModel = nullptr; @@ -552,6 +556,8 @@ class LMMS_EXPORT VectorGraphDataArray bool m_effectPower; bool m_effectLog; bool m_effectSine; + bool m_effectClampLower; + bool m_effectClampUpper; // stores m_automationModel->value(), used in updating float m_bufferedAutomationValue; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1ea71eb5948..dbeb49b4fe8 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -75,7 +75,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), - tr("\"sine\" effect") + tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; m_editingLineEffectText = { tr("none"), @@ -90,7 +90,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, true, false, false, false, false, false, false, false, false, false, false, - false + false, false, false }; m_lastTrackPoint.first = -1; @@ -891,6 +891,12 @@ float VectorGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, case 15: *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); break; + case 16: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); + break; + case 17: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 8); + break; } } return output; @@ -994,6 +1000,12 @@ void VectorGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, f case 15: model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValueIn); break; + case 16: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValueIn); + break; + case 17: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValueIn); + break; } } qDebug("setInputAttribValue finished"); @@ -2442,6 +2454,12 @@ bool VectorGraphDataArray::getEffect(unsigned int locationIn, unsigned int effec case 6: return m_dataArray[locationIn].m_effectSine; break; + case 7: + return m_dataArray[locationIn].m_effectClampLower; + break; + case 8: + return m_dataArray[locationIn].m_effectClampUpper; + break; } return false; } @@ -2472,6 +2490,12 @@ void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effec case 6: m_dataArray[locationIn].m_effectSine = boolIn; break; + case 7: + m_dataArray[locationIn].m_effectClampLower = boolIn; + break; + case 8: + m_dataArray[locationIn].m_effectClampUpper = boolIn; + break; } } getUpdatingFromPoint(locationIn); @@ -2638,6 +2662,17 @@ float VectorGraphDataArray::processEffect(float attribValueIn, unsigned int attr output -= effectValueIn; } + if (effectArrayIn->getEffect(effectLocationIn, 7) == true) + { + // clamp lower + output = std::max(effectValueIn, output); + } + else if (effectArrayIn->getEffect(effectLocationIn, 8) == true) + { + // clamp upper + output = std::min(effectValueIn, output); + } + // clamp output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; } From 7bc14ff26d9998ddc13aaa1d3ac2fbb26c38a93a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:22:20 +0100 Subject: [PATCH 022/184] VectorGraph_separated_big_functions --- include/VectorGraph.h | 6 + src/gui/widgets/VectorGraph.cpp | 640 ++++++++++++++++---------------- 2 files changed, 332 insertions(+), 314 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index bc50445cef6..c63a5f050d2 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -137,6 +137,9 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView protected slots: void updateGraph(); private: + void paintGraph(QPainter* pIn, unsigned int locationIn); + void paintEditing(QPainter* pIn); + void modelChanged() override; std::pair mapMousePos(int xIn, int yIn); @@ -613,6 +616,9 @@ class LMMS_EXPORT VectorGraphDataArray // recalculates and sorts m_needsUpdating so // every point is in there only once void getUpdatingOriginals(); + void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); + void getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, + std::vector* outputXLocationsIn, std::vector>* effectorDataIn, unsigned int iIn, float stepSizeIn); // checks m_isFixedEndPoints, does not call dataChanged() void formatDataArrayEndPoints(); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index dbeb49b4fe8..497e5bebc1a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -531,88 +531,100 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) VectorGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - dataArray = model()->getDataArray(i); - p.setPen(QPen(*dataArray->getLineColor(), 1)); - unsigned int length = dataArray->size(); + // if first data/sample > 0, draw a line to the first data/sample from 0 + //if (posA.first > 0) + //{ + //p.drawLine(0, posA.second, posA.first, posA.second); + //} + // drawing lines + paintGraph(&p, i); + //if (posA.first < width()) + //{ + //p.drawLine(posA.first, posA.second, width(), posA.second); + //} + } - if (length > 0) - { + paintEditing(&p); - std::pair posA(0, 0); - std::pair posB(0, 0); - // if first data/sample > 0, draw a line to the first data/sample from 0 - //if (posA.first > 0) - //{ - //p.drawLine(0, posA.second, posA.first, posA.second); - //} - // drawing lines - qDebug("paint size: %d", length); - if (dataArray->getIsSelectable() == true) + m_useGetLastValues = false; + qDebug("paint event end"); + emit drawn(); +} + +void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) +{ + VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); + unsigned int length = dataArray->size(); + if (length > 0) + { + pIn->setPen(QPen(*dataArray->getLineColor(), 1)); + + + std::pair posA(0, 0); + std::pair posB(0, 0); + if (dataArray->getIsSelectable() == true) + { + for (unsigned int j = 0; j < length; j++) { - for (unsigned int j = 0; j < length; j++) + //qDebug("draw: x: %f, y: %f", dataArray->getX(j), dataArray->getY(j)); + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); + pIn->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + if (j > 0) { - //qDebug("draw: x: %f, y: %f", dataArray->getX(j), dataArray->getY(j)); - posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); - p.drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); - if (j > 0) + if (dataArray->getIsEditableAttrib() == true) { - if (dataArray->getIsEditableAttrib() == true) - { - std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - p.drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); - } - if (m_isSimplified == true) - { - p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } + std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + pIn->drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + } + if (m_isSimplified == true) + { + pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } - posA = posB; } + posA = posB; } - if (m_isSimplified == false) - { - posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); + } + if (m_isSimplified == false) + { + posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); - std::vector dataArrayValues; - if (m_useGetLastValues == true) - { - dataArrayValues = dataArray->getLastValues(); - } - else - { - dataArrayValues = dataArray->getValues(width()); - } + std::vector dataArrayValues; + if (m_useGetLastValues == true) + { + dataArrayValues = dataArray->getLastValues(); + } + else + { + dataArrayValues = dataArray->getValues(width()); + } - qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); - for (unsigned int j = 0; j < dataArrayValues.size(); j++) + qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); + for (unsigned int j = 0; j < dataArrayValues.size(); j++) + { + //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1)); + //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width()))); + posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); + //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); + posB.first = j; + //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); + // x1, y1, x2, y2 + //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); + if (j > 0 && posA.first != posB.first) { - //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1)); - //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width()))); - posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); - //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); - posB.first = j; - //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); - // x1, y1, x2, y2 - //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - if (j > 0 && posA.first != posB.first) - { - p.drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - posA = posB; + pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } - dataArrayValues.clear(); + posA = posB; } - //if (posA.first < width()) - //{ - //p.drawLine(posA.first, posA.second, width(), posA.second); - //} + dataArrayValues.clear(); } } - +} +void VectorGraphView::paintEditing(QPainter* pIn) +{ if (m_isEditingActive == true) { - dataArray = model()->getDataArray(m_selectedArray); + VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); // background of float values QColor backColor(25, 25, 25, 255); @@ -638,7 +650,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) int segmentLength = width() / (m_editingInputCount + 1); // draw inputs - p.setPen(textColor); + pIn->setPen(textColor); for (unsigned int i = 0; i < m_editingInputCount; i++) { if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount) @@ -657,9 +669,9 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) { curForeColor = *dataArray->getActiveColor(); } - p.fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, backColor); - p.fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_editingHeight, curForeColor); - p.drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, + pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, backColor); + pIn->fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_editingHeight, curForeColor); + pIn->drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); } else @@ -672,33 +684,29 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) { curForeColor = *dataArray->getActiveColor(); } - p.fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, curForeColor); - p.drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, + pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, curForeColor); + pIn->drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); } } } // draw "next page" button - p.fillRect(m_editingInputCount * segmentLength, m_graphHeight, segmentLength, m_editingHeight, *dataArray->getFillColor()); - p.setPen(textColor); - p.drawText(m_editingInputCount * segmentLength, m_graphHeight + m_editingHeight / 2, ">>"); + pIn->fillRect(m_editingInputCount * segmentLength, m_graphHeight, segmentLength, m_editingHeight, *dataArray->getFillColor()); + pIn->setPen(textColor); + pIn->drawText(m_editingInputCount * segmentLength, m_graphHeight + m_editingHeight / 2, ">>"); // draw outline - p.setPen(*dataArray->getLineColor()); - p.drawRect(0, 0, m_editingHeight, m_editingHeight); - p.drawLine(0, m_graphHeight, width(), m_graphHeight); + pIn->setPen(*dataArray->getLineColor()); + pIn->drawRect(0, 0, m_editingHeight, m_editingHeight); + pIn->drawLine(0, m_graphHeight, width(), m_graphHeight); for (unsigned int i = 1; i < m_editingInputCount + 1; i++) { if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount || i >= m_editingInputCount) { - p.drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); + pIn->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); } } } - - m_useGetLastValues = false; - qDebug("paint event end"); - emit drawn(); } void VectorGraphView::modelChanged() @@ -1105,7 +1113,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) m_isCurveSelected = false; m_isEditingActive = dataArray->getIsEditableAttrib(); } - } + } if (m_isSelected == false) { @@ -1947,7 +1955,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i for (unsigned int j = start; j < end; j++) { outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); + //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); } } } @@ -1959,237 +1967,18 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { effector = m_parent->getDataArray(m_effectorLocation); } - if (effector != nullptr) + + getValuesLocations(effector, &effectorData); + for (unsigned int j = 0; j < effectorData.size(); j++) { - effectorData.resize(m_needsUpdating.size()); - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - bool found = false; - bool isBefore = false; - int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); - if (curLocation >= 0) - { - curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; - // location - effectorData[i].first = curLocation; - qDebug("getValuesB5.1, [%d] set to: %d", i, curLocation); - // next location - effectorData[i].second = curLocation; - // if the location of this is the next location for before this - if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) - { - qDebug("getValuesB5.2, [%d - 1] changed to: %d", i, curLocation); - effectorData[i - 1].second = curLocation; - } - } - } - qDebug("getValuesB5"); - // getting the missing next location values - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - if (i + 1 < m_needsUpdating.size() && m_needsUpdating[i] + 1 < m_dataArray.size() && - m_needsUpdating[i + 1] != m_needsUpdating[i] + 1) - { - bool found = false; - bool isBefore = false; - int curLocation = effector->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); - if (curLocation >= 0) - { - curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; - // next location - qDebug("getValuesB5.3, [%d] set after to: %d", i, curLocation); - effectorData[i].second = curLocation; - } - } - } + qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); } - for (unsigned int j = 0; j < effectorData.size(); j++) - { - qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); - } - qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); - // calculate final line + qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); + + // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - qDebug("getValuesB6.1 m_needsUpdating[%d]: %d", i, m_needsUpdating[i]); - unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[i]].m_x / stepSize)); - qDebug("getValuesB6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutput.size()); - float curEffectY = effectorOutput[effectYLocation]; - float nextEffectY = effectorOutput[effectYLocation]; - - float curY = m_dataArray[m_needsUpdating[i]].m_y; - float curC = m_dataArray[m_needsUpdating[i]].m_c; - float curValA = m_dataArray[m_needsUpdating[i]].m_valA; - float curValB = m_dataArray[m_needsUpdating[i]].m_valB; - // TODO run processAutomation separatly - qDebug("getValuesB6.3, effectorDataSize: %ld", effectorData.size()); - if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].first) == true) - { - qDebug("getValuesB6.5"); - curY = processAutomation( - processEffect(m_dataArray[m_needsUpdating[i]].m_y, 0, curEffectY, effector, effectorData[i].first), - m_needsUpdating[i], 0); - curC = processAutomation( - processEffect(m_dataArray[m_needsUpdating[i]].m_c, 1, curEffectY, effector, effectorData[i].first), - m_needsUpdating[i], 1); - curValA = processAutomation( - processEffect(m_dataArray[m_needsUpdating[i]].m_valA, 2, curEffectY, effector, effectorData[i].first), - m_needsUpdating[i], 2); - curValB = processAutomation( - processEffect(m_dataArray[m_needsUpdating[i]].m_valB, 3, curEffectY, effector, effectorData[i].first), - m_needsUpdating[i], 3); - } - qDebug("getValuesB7"); - int start = effectYLocation; - int end = start; - - float nextY = curY; - - if (m_needsUpdating[i] + 1 < m_dataArray.size()) - { - effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[i] + 1].m_x / stepSize)); - end = effectYLocation; - if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].second) == true) - { - nextEffectY = effectorOutput[effectYLocation]; - nextY = processAutomation( - processEffect(m_dataArray[m_needsUpdating[i] + 1].m_y, 0, nextEffectY, effector, effectorData[i].second), - m_needsUpdating[i] + 1, 0); - } - else - { - nextY = m_dataArray[m_needsUpdating[i] + 1].m_y; - } - } - // calculating line ends - if (m_needsUpdating[i] + 1 >= m_dataArray.size()) - { - // if this point is at the last location in m_dataArray - for (int j = end; j < m_bakedValues.size(); j++) - { - m_bakedValues[j] = curY; - } - } - if (m_needsUpdating[i] == 0) - { - // if this point is at the 0 location in m_dataArray - for (int j = 0; j < start; j++) - { - m_bakedValues[j] = curY; - } - } - - float fadeInStart = 0.05f; - unsigned int type = m_dataArray[m_needsUpdating[i]].m_type; - qDebug("getValuesB8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", i, start, end, type, curY, nextY, curC, curValA, curValB); - // calculate final updated line - if (type == 0) - { - // calculate curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); - } - } - else if (type == 1) - { - // curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); - } - // line type - std::vector lineTypeOutput = processLineTypeArraySine(&outputXLocations, start, end, curValA, curValB, fadeInStart); - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; - } - } - else if (type == 2) - { - // curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); - } - // line type - std::vector lineTypeOutput = processLineTypeArraySineB(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; - } - } - else if (type == 3) - { - // curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); - } - // line type - std::vector lineTypeOutput = processLineTypeArrayPeak(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; - } - } - else if (type == 4) - { - // curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocations[j]); - } - // line type - std::vector lineTypeOutput = processLineTypeArraySteps(&outputXLocations, start, end, &m_bakedValues, curValA, curValB, fadeInStart); - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; - } - } - else if (type == 5) - { - // curve - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocations[j]); - } - // line type - std::vector lineTypeOutput = processLineTypeArrayRandom(&outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; - } - } - if (effector != nullptr && effector->getEffectOnlyPoints(effectorData[i].first) == false) - { - // process line effect - // if it is enabled - for (int j = start; j < end; j++) - { - m_bakedValues[j] = processEffect(m_bakedValues[j], 0, effectorOutput[j], effector, effectorData[i].first); - } - } - for (int j = start; j < end; j++) - { - if (m_bakedValues[j] > 1.0f) - { - m_bakedValues[j] = 1.0f; - } - else if (m_bakedValues[j] < -1.0f) - { - m_bakedValues[j] = -1.0f; - } - } - if (m_nonNegative == true) - { - for (int j = start; j < end; j++) - { - m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; - } - } + getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, &effectorData, i, stepSize); } effectorData.clear(); } @@ -2995,7 +2784,6 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptrgetEffectOnlyPoints(updatingValuesIn->operator[](i)) == false && isBefore == false) { qDebug("getUpdatingFromEffector locationBefore = %d - 1", locationBefore); - // if only points are effected and the nearest point // if lines are effected and the nearest point // is after [i] (so the line and the point before this is effected) // subtract 1 @@ -3006,12 +2794,13 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr m_dataArray.size() - 1 ? m_dataArray.size() - 1 : locationBefore; isBefore = false; + // *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); - qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d, ex: %f, dx: %f", locationAfter, updatingEnd, effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); - if (isBefore == true) + qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); + if (isBefore == false) { qDebug("getUpdatingFromEffector locationAfter = %d - 1", locationAfter); - // if [updatingEnd] is before the last nearest value + // if the nearest point is after ([updatingEnd] + upadtingEndSlide) (where updating ends) locationAfter--; } // updating everything before if i -> 0 @@ -3140,6 +2929,229 @@ void VectorGraphDataArray::getUpdatingOriginals() } originalValues.clear(); } +void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) +{ + if (effectorIn != nullptr) + { + effectorDataOut->resize(m_needsUpdating.size()); + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + bool found = false; + bool isBefore = false; + int curLocation = effectorIn->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + if (curLocation >= 0) + { + curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; + // location + effectorDataOut->operator[](i).first = curLocation; +qDebug("getValuesC5.1, [%d] set to: %d", i, curLocation); + // next location + effectorDataOut->operator[](i).second = curLocation; + // if the location of this is the next location for before this + if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) + { +qDebug("getValuesC5.2, [%d - 1] changed to: %d", i, curLocation); + effectorDataOut->operator[](i- 1).second = curLocation; + } + } + } +qDebug("getValuesC5"); + // getting the missing next location values + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + if (i + 1 < m_needsUpdating.size() && m_needsUpdating[i] + 1 < m_dataArray.size() && + m_needsUpdating[i + 1] != m_needsUpdating[i] + 1) + { + bool found = false; + bool isBefore = false; + int curLocation = effectorIn->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + if (curLocation >= 0) + { + curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; + // next location +qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); + effectorDataOut->operator[](i).second = curLocation; + } + } + } + } +} +void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, + std::vector* outputXLocationsIn, std::vector>* effectorDataIn, unsigned int iIn, float stepSizeIn) +{ + qDebug("getValuesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); + unsigned int effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSizeIn)); + qDebug("getValuesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutputIn->size()); + float curEffectY = effectorOutputIn->operator[](effectYLocation); + float nextEffectY = effectorOutputIn->operator[](effectYLocation); + + float curY = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_y, m_needsUpdating[iIn], 0); + float curC = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_c, m_needsUpdating[iIn], 1); + float curValA = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valA, m_needsUpdating[iIn], 2); + float curValB = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valB, m_needsUpdating[iIn], 3); +qDebug("getValuesD6.3, effectorDataInSize: %ld", effectorDataIn->size()); + if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == true) + { +qDebug("getValuesD6.5"); + curY = processEffect(curY, 0, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); + curC = processEffect(curC, 1, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); + curValA = processEffect(curValA, 2, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); + curValB = processEffect(curValB, 3, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); + } +qDebug("getValuesD7"); + int start = effectYLocation; + int end = start; + + float nextY = curY; + + if (m_needsUpdating[iIn] + 1 < m_dataArray.size()) + { + effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSizeIn)); + end = effectYLocation; + if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).second) == true) + { + nextEffectY = effectorOutputIn->operator[](effectYLocation); + nextY = processAutomation( + processEffect(m_dataArray[m_needsUpdating[iIn] + 1].m_y, 0, nextEffectY, effectorIn, effectorDataIn->operator[](iIn).second), + m_needsUpdating[iIn] + 1, 0); + } + else + { + nextY = m_dataArray[m_needsUpdating[iIn] + 1].m_y; + } + } + // calculating line ends + if (m_needsUpdating[iIn] + 1 >= m_dataArray.size()) + { + // if this point is at the last location in m_dataArray + for (int j = end; j < m_bakedValues.size(); j++) + { + m_bakedValues[j] = curY; + } + } + if (m_needsUpdating[iIn] == 0) + { + // if this point is at the 0 location in m_dataArray + for (int j = 0; j < start; j++) + { + m_bakedValues[j] = curY; + } + } + + float fadeInStart = 0.05f; + unsigned int type = m_dataArray[m_needsUpdating[iIn]].m_type; +qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", iIn, start, end, type, curY, nextY, curC, curValA, curValB); + + // calculate final updated line + if (type == 0) + { + // calculate curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + } + } + else if (type == 1) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySine(outputXLocationsIn, start, end, curValA, curValB, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 2) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 3) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + } + // line type + std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 4) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + } + // line type + std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_bakedValues, curValA, curValB, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + else if (type == 5) + { + // curve + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + } + // line type + std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + } + } + if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == false) + { + // process line effect + // if it is enabled + for (int j = start; j < end; j++) + { + m_bakedValues[j] = processEffect(m_bakedValues[j], 0, effectorOutputIn->operator[](j), effectorIn, effectorDataIn->operator[](iIn).first); + } + } + // clamp + for (int j = start; j < end; j++) + { + if (m_bakedValues[j] > 1.0f) + { + m_bakedValues[j] = 1.0f; + } + else if (m_bakedValues[j] < -1.0f) + { + m_bakedValues[j] = -1.0f; + } + } + if (m_nonNegative == true) + { + for (int j = start; j < end; j++) + { + m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; + } + } +} void VectorGraphDataArray::formatDataArrayEndPoints() { From 5cb8bcd67fd8b52faa2a8036c942ddbae6b2b090 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:04:01 +0100 Subject: [PATCH 023/184] VectorGraph_added_context_menu --- include/VectorGraph.h | 12 ++ src/gui/widgets/VectorGraph.cpp | 306 ++++++++++++++++++++------------ 2 files changed, 209 insertions(+), 109 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index c63a5f050d2..c24f24a82ae 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "Model.h" @@ -136,12 +137,17 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void mouseDoubleClickEvent(QMouseEvent* me) override; //TODO protected slots: void updateGraph(); + + void execConnectionDialog(); + void removeAutomation(); + void removeController(); private: void paintGraph(QPainter* pIn, unsigned int locationIn); void paintEditing(QPainter* pIn); void modelChanged() override; + // utility std::pair mapMousePos(int xIn, int yIn); // calculate curve position std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); @@ -154,10 +160,12 @@ protected slots: bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); + // editing // returns true if the graph was clicked bool isGraphPressed(int mouseXIn, int mouseYIn); // returns true if the editing window was clicked while in editing mode bool isEditingWindowPressed(int mouseYIn); + void processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int xIn, int yIn); // returns -1 if no attribute was clicked int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); // returns a float attrib value, valueOut = attrib value if it is a bool @@ -169,9 +177,13 @@ protected slots: // returns the first x char that fits in the displayedLength(in pixel) // cuts the string to displayedLength(in px) size QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); + void addDefaultActions(QMenu* menu); + // inputDialog std::pair showCoordInputDialog(); float showInputDialog(float curInputValueIn); + + // selection // searches arrays to select // clicked datapoint void selectData(int mouseXIn, int mouseYIn); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 497e5bebc1a..d5715c1f242 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -30,10 +30,18 @@ #include // smartpointers #include #include -#include +#include // showInputDialog() +#include // context menu #include "VectorGraph.h" #include "StringPairDrag.h" +#include "CaptionMenu.h" // context menu +#include "embed.h" // context menu +#include "MainWindow.h" // getGUI +#include "GuiApplication.h" // getGUI +#include "AutomatableModel.h" +#include "ControllerConnectionDialog.h" +#include "ControllerConnection.h" namespace lmms @@ -187,6 +195,7 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) int x = me->x(); int y = me->y(); m_addition = false; + m_mousePress = false; if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) { @@ -202,11 +211,8 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) me->accept(); } } - else if (isGraphPressed(x, m_graphHeight - y) == true) + else { - // try selecting the clicked point (if it is near) - selectData(x, m_graphHeight - y); - if (me->button() == Qt::LeftButton) { // add @@ -219,11 +225,13 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) m_addition = false; m_mousePress = true; } + if (isGraphPressed(x, m_graphHeight - y) == true) + { + // try selecting the clicked point (if it is near) + selectData(x, m_graphHeight - y); + } } - else - { - m_mousePress = true; - } + m_mouseDown = true; qDebug("mousePressEnd ---------"); } @@ -296,32 +304,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (isEditingWindowPressed(m_lastScndTrackPoint.second) == true) { - // if editing inputs were pressed (not graph) - int pressLocation = getPressedInput(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, m_editingInputCount + 1); - if (pressLocation >= 0 && pressLocation < m_editingInputCount) - { - // pressLocation should always be bigger than -1 - // if the editing window was pressed - unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; - // if the input type is a float - if (location < m_editingText.size() && m_editingInputIsFloat[location] == true) - { - // if the user just started to move the mouse it is pressed - if (startMoving == true) - { - // unused bool - bool isTrue = false; - // set m_lastScndTrackPoint.first to the current input value - m_lastScndTrackPoint.first = mapInputPos(getInputAttribValue(location, &isTrue), m_graphHeight); - - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = m_graphHeight - y; - qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, x, (m_graphHeight - y), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); - } - std::pair convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(m_graphHeight - y - m_lastTrackPoint.second) / 2); - setInputAttribValue(location, convertedCoords.second, false); - } - } + processEditingWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); } } } @@ -379,57 +362,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } else if (m_mousePress == true && isEditingWindowPressed(m_graphHeight - y) == true) { - qDebug("mouseMove 7: %d", m_lastTrackPoint.first); - int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); - if (pressLocation == m_editingInputCount) - { - // if the last button was pressed - - // how many inputs are there - int editingTextCount = m_editingText.size(); - if (m_isSelected == true) - { - if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) - { - // x, y - editingTextCount = 2; - } - else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) - { - // x, y, curve, valA, valB, switch type - editingTextCount = 6; - } - } - - m_editingDisplayPage++; - if (m_editingInputCount * m_editingDisplayPage >= editingTextCount) - { - m_editingDisplayPage = 0; - } - qDebug("mouseMove editingPage: %d", m_editingDisplayPage); - } - else if (pressLocation >= 0) - { - unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; - // setting the boolean values - if (location < m_editingText.size() && m_editingInputIsFloat[location] == false) - { - bool curBoolValue = true; - //if (location >= 5 && location <= 7) - //{ - // curBoolValue = true; - //} - //else - // if location is not at "set type" or "set automation location" or "set effect location" - // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) - if (location < 5 || location > 7) - { - getInputAttribValue(location, &curBoolValue); - curBoolValue = !curBoolValue; - } - setInputAttribValue(location, 0.0f, curBoolValue); - } - } + processEditingWindowPressed(x, m_graphHeight - y, false, false, 0, 0); } else { @@ -531,18 +464,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) VectorGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - - // if first data/sample > 0, draw a line to the first data/sample from 0 - //if (posA.first > 0) - //{ - //p.drawLine(0, posA.second, posA.first, posA.second); - //} - // drawing lines paintGraph(&p, i); - //if (posA.first < width()) - //{ - //p.drawLine(posA.first, posA.second, width(), posA.second); - //} } paintEditing(&p); @@ -678,8 +600,7 @@ void VectorGraphView::paintEditing(QPainter* pIn) { QColor curForeColor = *dataArray->getFillColor(); bool isTrue = false; - // unused float - float inputValue = getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); + getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); if (isTrue == true) { curForeColor = *dataArray->getActiveColor(); @@ -722,13 +643,64 @@ void VectorGraphView::updateGraph() { update(); } +void VectorGraphView::execConnectionDialog() +{ + if (m_isSelected == true) + { + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), curAutomationModel); + + if (dialog.exec() == 1) + { + // Actually chose something + if (curAutomationModel != nullptr && dialog.chosenController() != nullptr) + { + // Update + if (curAutomationModel->controllerConnection() != nullptr) + { + curAutomationModel->controllerConnection()->setController(dialog.chosenController()); + } + else + { + // New + auto cc = new ControllerConnection(dialog.chosenController()); + curAutomationModel->setControllerConnection(cc); + } + } + else + { + // no controller, so delete existing connection + removeController(); + } + } + else + { + // did not return 1 -> delete the created floatModel + removeController(); + } + } +} +void VectorGraphView::removeAutomation() +{ + if (m_isSelected == true) + { + // deleting the floatmodel will delete the connecitons + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); + } +} +void VectorGraphView::removeController() +{ + removeAutomation(); +} std::pair VectorGraphView::mapMousePos(int xIn, int yIn) { - // mapping the position to 0 - 1, 0 - 1 using qWidget width and height + // mapping the position to 0 - 1, -1 - 1 using qWidget width and height + qDebug("map mouse pos y: %d", yIn); return std::pair( static_cast(xIn / (float)width()), - static_cast(yIn * 2.0f / (float)m_graphHeight) - 1.0f); + static_cast(yIn) * 2.0f / static_cast(m_graphHeight) - 1.0f); } std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) { @@ -819,6 +791,91 @@ bool VectorGraphView::isEditingWindowPressed(int mouseYIn) } return output; } +void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int xIn, int yIn) +{ + qDebug("mouseMove 7: %d", m_lastTrackPoint.first); + if (m_isEditingActive == true) + { + int pressLocation = getPressedInput(mouseXIn, m_graphHeight - mouseYIn, m_editingInputCount + 1); + int location = m_editingInputCount * m_editingDisplayPage + pressLocation; + if (isDraggingIn == false && pressLocation == m_editingInputCount) + { + // if the last button was pressed + + // how many inputs are there + int editingTextCount = m_editingText.size(); + if (m_isSelected == true) + { + if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) + { + // x, y + editingTextCount = 2; + } + else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) + { + // x, y, curve, valA, valB, switch type + editingTextCount = 6; + } + } + + m_editingDisplayPage++; + if (m_editingInputCount * m_editingDisplayPage >= editingTextCount) + { + m_editingDisplayPage = 0; + } + qDebug("mouseRelease editingPage: %d", m_editingDisplayPage); + } + else if (pressLocation >= 0 && location < m_editingText.size()) + { + // pressLocation should always be bigger than -1 + // if the editing window was pressed + + if (m_addition == false) + { + // if the right mouse button was pressed + // show context menu + CaptionMenu contextMenu(model()->displayName()); + addDefaultActions(&contextMenu); + contextMenu.exec(QCursor::pos()); + } + else if (isDraggingIn == false && m_editingInputIsFloat[location] == false) + { + // if the input type is a bool + + bool curBoolValue = true; + // if location is not at "set type" or "set automation location" or "set effect location" + // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) + if (location < 5 || location > 7) + { + getInputAttribValue(location, &curBoolValue); + curBoolValue = !curBoolValue; + } + setInputAttribValue(location, 0.0f, curBoolValue); + } + else if (isDraggingIn == true && m_editingInputIsFloat[location] == true) + { + // if the input type is a float + + // if the user just started to move the mouse it is pressed + if (startMovingIn == true) + { + // unused bool + bool isTrue = false; + // set m_lastScndTrackPoint.first to the current input value + m_lastScndTrackPoint.first = mapInputPos(getInputAttribValue(location, &isTrue), m_graphHeight); + + m_lastTrackPoint.first = xIn; + m_lastTrackPoint.second = yIn; + qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, xIn, (yIn), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); + } + std::pair convertedCoords = mapMousePos(0, + m_lastScndTrackPoint.first + static_cast(yIn - m_lastTrackPoint.second) / 2); + qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(yIn - m_lastTrackPoint.second) / 2), convertedCoords.second); + setInputAttribValue(location, convertedCoords.second, false); + } + } + } +} int VectorGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) { int output = -1; @@ -1046,6 +1103,41 @@ QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int d } return output; } +void VectorGraphView::addDefaultActions(QMenu* menu) +{ + menu->addAction(embed::getIconPixmap("reload"), + tr("remove automation"), + this, SLOT(removeAutomation())); + menu->addSeparator(); + + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + QString controllerTxt; + + menu->addAction(embed::getIconPixmap("controller"), + tr("Connect to controller..."), + this, SLOT(execConnectionDialog())); + if(curAutomationModel != nullptr && curAutomationModel->controllerConnection() != nullptr) + { + + Controller* cont = curAutomationModel->controllerConnection()->getController(); + if(cont) + { + controllerTxt = AutomatableModel::tr( "Connected to %1" ).arg( cont->name() ); + } + else + { + controllerTxt = AutomatableModel::tr( "Connected to controller" ); + } + + + QMenu* contMenu = menu->addMenu(embed::getIconPixmap("controller"), controllerTxt); + + contMenu->addAction(embed::getIconPixmap("cancel"), + tr("Remove connection"), + this, SLOT(removeConnection())); + } +} std::pair VectorGraphView::showCoordInputDialog() { @@ -2857,7 +2949,7 @@ void VectorGraphDataArray::getUpdatingFromAutomation() { if (getIsAutomationValueChanged(i) == true) { - qDebug("getUpdatingFromAutomation: %d", i); + qDebug("getUpdatingFromAutomation: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); m_needsUpdating.push_back(i); // if the automatable value effects the y (so the position) // so the point before this is updated too @@ -3010,16 +3102,12 @@ qDebug("getValuesD7"); effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSizeIn)); end = effectYLocation; + nextY = processAutomation(m_dataArray[m_needsUpdating[iIn] + 1].m_y, m_needsUpdating[iIn] + 1, 0); + if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).second) == true) { nextEffectY = effectorOutputIn->operator[](effectYLocation); - nextY = processAutomation( - processEffect(m_dataArray[m_needsUpdating[iIn] + 1].m_y, 0, nextEffectY, effectorIn, effectorDataIn->operator[](iIn).second), - m_needsUpdating[iIn] + 1, 0); - } - else - { - nextY = m_dataArray[m_needsUpdating[iIn] + 1].m_y; + nextY = processEffect(nextY, 0, nextEffectY, effectorIn, effectorDataIn->operator[](iIn).second); } } // calculating line ends From 51354f960d0969faa986d776fa9231e84370e4de Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:55:15 +0100 Subject: [PATCH 024/184] VectorGraph_automation_fixed --- include/VectorGraph.h | 24 +++++-------- src/gui/widgets/VectorGraph.cpp | 63 ++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 31 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index c24f24a82ae..730ef7980da 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -413,10 +413,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns if the [effectNumberIn] effect is active based on effectNumberIn bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); bool getIsAutomationValueChanged(unsigned int locationIn); - inline FloatModel* getAutomationModel(unsigned int locationIn) - { - return m_dataArray[locationIn].m_automationModel; - } + inline FloatModel* getAutomationModel(unsigned int locationIn); // get: ------------------- @@ -501,7 +498,7 @@ class LMMS_EXPORT VectorGraphDataArray m_effectClampUpper = false; m_bufferedAutomationValue = 0.0f; - m_automationModel = nullptr; + m_automationModel = -1; } inline VectorGraphPoint(float xIn, float yIn) { @@ -525,15 +522,10 @@ class LMMS_EXPORT VectorGraphDataArray m_effectClampUpper = false; m_bufferedAutomationValue = 0.0f; - m_automationModel = nullptr; + m_automationModel = -1; } inline ~VectorGraphPoint() { - // TODO make safer, delete in automationTrack - if (m_automationModel != nullptr) - { - delete m_automationModel; - } } // 0 - 1 float m_x; @@ -576,8 +568,8 @@ class LMMS_EXPORT VectorGraphDataArray // stores m_automationModel->value(), used in updating float m_bufferedAutomationValue; - // automation: connecting to floatmodels, nullptr when it isn't conntected' - FloatModel* m_automationModel; + // automation: connecting to floatmodels, -1 when it isn't conntected' + int m_automationModel; }; // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this @@ -685,13 +677,15 @@ class LMMS_EXPORT VectorGraphDataArray // if we want to update all bool m_isDataChanged; - // if m_needsUpdating is up to date - // bool m_isUpdatedNeedsUpdating; // array containing output final float values for optimalization std::vector m_bakedValues; // unsorted array of locations in m_dataArray // that need to be updated std::vector m_needsUpdating; + + // this stores all the FloatModels + // used for automation + std::vector m_automationModelArray; }; } // namespace lmms diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d5715c1f242..0a5deb988f5 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1496,11 +1496,11 @@ VectorGraphDataArray::VectorGraphDataArray() m_effectorLocation = -1; - //m_dataArray = {}; + // m_dataArray m_isDataChanged = false; - //m_isUpdatedNeedsUpdating = false; - //m_bakedValues = {}; - //m_needsUpdating = {}; + // m_bakedValues; + // m_needsUpdating; + // m_automationModelArray; m_id = -1; } @@ -1527,11 +1527,11 @@ VectorGraphDataArray::VectorGraphDataArray( m_effectorLocation = -1; - // m_dataArray = {}; + // m_dataArray; m_isDataChanged = false; - //m_isUpdatedNeedsUpdating = false; - // m_bakedValues = {}; - // m_needsUpdating = {}; + // m_bakedValues; + // m_needsUpdating; + // m_automationModelArray; m_id = idIn; updateConnections(parentIn); @@ -1542,6 +1542,12 @@ VectorGraphDataArray::~VectorGraphDataArray() m_dataArray.clear(); m_bakedValues.clear(); m_needsUpdating.clear(); + + for (unsigned int i = 0; i < m_automationModelArray.size(); i++) + { + delete m_automationModelArray[i]; + } + m_automationModelArray.clear(); } void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) @@ -2390,10 +2396,10 @@ void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effec } bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) { - if (m_dataArray[locationIn].m_automationModel != nullptr && - m_dataArray[locationIn].m_bufferedAutomationValue != m_dataArray[locationIn].m_automationModel->value()) + if (getAutomationModel(locationIn) != nullptr && + m_dataArray[locationIn].m_bufferedAutomationValue != getAutomationModel(locationIn)->value()) { - m_dataArray[locationIn].m_bufferedAutomationValue = m_dataArray[locationIn].m_automationModel->value(); + m_dataArray[locationIn].m_bufferedAutomationValue = getAutomationModel(locationIn)->value(); return true; } return false; @@ -2404,23 +2410,48 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate { if (isAutomatedIn == true) { - if (m_dataArray[locationIn].m_automationModel == nullptr) + if (m_dataArray[locationIn].m_automationModel == -1) { - m_dataArray[locationIn].m_automationModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false); + m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); + m_dataArray[locationIn].m_automationModel = m_automationModelArray.size() - 1; getUpdatingFromPoint(locationIn); dataChanged(); } } - else if (m_dataArray[locationIn].m_automationModel != nullptr) + else if (m_dataArray[locationIn].m_automationModel != -1) { // TODO correctly deconstruct - delete m_dataArray[locationIn].m_automationModel; - m_dataArray[locationIn].m_automationModel = nullptr; + FloatModel* swap = m_automationModelArray[m_dataArray[locationIn].m_automationModel]; + // copy the last FloatModel* to the current location + m_automationModelArray[m_dataArray[locationIn].m_automationModel] = + m_automationModelArray[m_automationModelArray.size() - 1]; + m_automationModelArray.pop_back(); + + // replace all last m_automationModel-s to the currently deleted m_automationModel + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) + { + m_dataArray[i].m_automationModel = m_dataArray[locationIn].m_automationModel; + // we dont break for safety + } + } + m_dataArray[locationIn].m_automationModel = -1; + delete swap; + getUpdatingFromPoint(locationIn); dataChanged(); } } } +FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int locationIn) +{ + if (m_dataArray[locationIn].m_automationModel != -1) + { + return m_automationModelArray[m_dataArray[locationIn].m_automationModel]; + } + return nullptr; +} void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) { From db9f4f84742e6c4ff823e06e4393dcc984c48e0f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:28:24 +0200 Subject: [PATCH 025/184] FFTFilter_FFT_processor_class_added --- plugins/FFTFilter/FFTProcessor.cpp | 219 +++++++++++++++++++++++++++++ plugins/FFTFilter/FFTProcessor.h | 111 +++++++++++++++ 2 files changed, 330 insertions(+) create mode 100644 plugins/FFTFilter/FFTProcessor.cpp create mode 100644 plugins/FFTFilter/FFTProcessor.h diff --git a/plugins/FFTFilter/FFTProcessor.cpp b/plugins/FFTFilter/FFTProcessor.cpp new file mode 100644 index 00000000000..117c0306509 --- /dev/null +++ b/plugins/FFTFilter/FFTProcessor.cpp @@ -0,0 +1,219 @@ + + +#include +#include +#include +#include + +#include "FFTProcessor.h" +#include "fft_helpers.h" +#include "lmms_basics.h" +#include "LocklessRingBuffer.h" + +// some parts of the code were copyed from SaProcessor.cpp +// credit: 2019 Martin Pavelek + +namespace lmms +{ + +FFTProcessor::FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWindow FFTWindowIn)// : + //m_reader(bufferSizeIn * 4) +{ + m_blockSize = bufferSizeIn; + m_isThreaded = isThreadedIn; + m_FFTWindowType = FFTWindowIn; + + m_terminate = true; + m_frameFillLoc = 0; + + m_samplesIn.resize(outputSize()); + m_normSpectrum.resize(outputSize()); + + m_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); + m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); + // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); + // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); + m_plan = fftwf_plan_dft_r2c_1d(m_blockSize, m_samplesIn.data(), m_out, FFTW_ESTIMATE); + m_iplan = fftwf_plan_dft_c2r_1d(m_blockSize, m_in, m_samplesIn.data(), FFTW_ESTIMATE); + + m_fftWindow.resize(m_blockSize, 1.0); + precomputeWindow(m_fftWindow.data(), m_blockSize, m_FFTWindowType); +} +FFTProcessor::~FFTProcessor() +{ + qDebug("FFTProcessor destrc -1"); + + threadedTerminate(); + if (m_plan != nullptr) + { + fftwf_destroy_plan(m_plan); + } + if (m_iplan != nullptr) + { + fftwf_destroy_plan(m_iplan); + } + qDebug("FFTProcessor destrc 0"); + if (m_in != nullptr) + { + fftwf_free(m_in); + } + qDebug("FFTProcessor destrc 1"); + if (m_out != nullptr) + { + fftwf_free(m_out); + } + + qDebug("FFTProcessor destrc 2"); + m_in = nullptr; + m_out = nullptr; + qDebug("FFTProcessor destrc 3"); +} + +void FFTProcessor::analyze(sampleFrame* sampleBufferIn, unsigned int sizeIn, unsigned int sampLocIn) +{ + if (m_isThreaded == false) + { + /* + while (frameIn < frameCount && m_frameFillLoc < blockSizeIn) + { + //qDebug("analyzeB 2"); + samples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + frameIn++; + frameFillLoc++; + } + */ + + } +} + +void FFTProcessor::threadedStartThread(LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, bool computeSpectrum, bool computeInverse) +{ + qDebug("analyze threaded start"); + if (m_isThreaded == true && m_terminate == true && ringBufferIn != nullptr && + (computeSpectrum == true || computeInverse == true)) + { + qDebug("analyze threaded thread init"); + m_terminate = false; + unsigned int blockSize = m_blockSize; + m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, m_out, &m_outputSpectrumChanged, &m_outputSamplesChanged, + ringBufferIn, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); + qDebug("analyze threaded thread running"); + } +} + +std::vector FFTProcessor::getNormSpectrum() +{ + m_outputAccess.lock(); + std::vector output = m_normSpectrum; + m_outputAccess.unlock(); + return output; +} +bool FFTProcessor::getOutputSpectrumChanged() +{ + bool output = m_outputSpectrumChanged; + m_outputSpectrumChanged = false; + return output; +} +bool FFTProcessor::getOutputSamplesChanged() +{ + bool output = m_outputSamplesChanged; + m_outputSamplesChanged = false; + return output; +} + + +void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, + std::vector* spectrumOut, std::mutex* outputAccessIn) +{ + LocklessRingBufferReader reader(*ringBufferIn); + + std::vector samples(blockSizeIn); + std::vector outputSpectrum(blockSizeIn); + fpp_t frameFillLoc = 0; + + qDebug("analyzeB 0"); + while (*terminateIn == false) + { + if (reader.empty() == false) + { + reader.waitForData(); + } + + auto bufferIn = reader.read_max(ringBufferIn->capacity() / 4); + size_t frameCount = bufferIn.size(); + + fpp_t frameIn = 0; + + while (frameIn < frameCount) + { + qDebug("analyzeB 1"); + while (frameIn < frameCount && frameFillLoc < blockSizeIn) + { + //qDebug("analyzeB 2"); + samples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + frameIn++; + frameFillLoc++; + } + + + if (frameFillLoc < blockSizeIn) + { + break; + } + frameFillLoc = 0; + + qDebug("analyzeB run"); + + + /* + for (unsigned int i = 0; i < m_blockSize; i++) + { + m_samplesIn[i] = m_samplesIn * m_FFTWindow[i]; + } + */ + + fftwf_execute(*planIn); + + absspec(complexIn, outputSpectrum.data(), (blockSizeIn / 2 + 1)); + normalize(outputSpectrum, outputSpectrum, blockSizeIn); + + outputAccessIn->lock(); + *spectrumOut = outputSpectrum; + outputAccessIn->unlock(); + *spectrumChangedOut = true; + } + } + qDebug("analyzeB end"); +} + +// TODO +void FFTProcessor::reverse(std::vector processedDataIn) +{ + +} + +void FFTProcessor::threadedTerminate() +{ + m_terminate = true; + if (m_isThreaded == true) + { + m_FFTThread.join(); + } +} + +// TODO multithread +void FFTProcessor::rebuildWindow(FFTWindow FFTWindowIn) +{ + m_FFTWindowType = FFTWindowIn; + precomputeWindow(m_fftWindow.data(), m_blockSize, FFTWindowIn); +} + +// TODO multithread + +unsigned int FFTProcessor::outputSize() +{ + return m_blockSize / 2 + 1; +} + +} // namespace lmms diff --git a/plugins/FFTFilter/FFTProcessor.h b/plugins/FFTFilter/FFTProcessor.h new file mode 100644 index 00000000000..32f2947cb62 --- /dev/null +++ b/plugins/FFTFilter/FFTProcessor.h @@ -0,0 +1,111 @@ +/* + * FFTFilter.h - FFTFilter effect for lmms + * + * Copyright (c) 2019 Martin Pavelek + * Copyright (c) 2024 Szeli1 TODO + * + * 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 LMMS_FFTPROCESSOR_H +#define LMMS_FFTPROCESSOR_H + +#include +#include +#include +#include +#include + +#include "lmms_basics.h" +#include "fft_helpers.h" +#include "LocklessRingBuffer.h" + +namespace lmms +{ + +template +class LocklessRingBuffer; + +class FFTProcessor +{ +public: + + FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWindow FFTWindowIn); + ~FFTProcessor(); + + //void analyze(LocklessRingBuffer &ringBufferIn); + // if m_isThreaded and termilnate == false -> block, else start thread or run on current thread + void analyze(sampleFrame* sampleBufferIn, unsigned int sizeIn, unsigned int sampLocIn); + //void analyze(std::vector* inputArrayIn, unsigned int readStartIn, bool isStereoIn); + + void threadedStartThread(LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, bool computeSpectrum, bool computeInverse); + void threadedTerminate(); + + // getters + std::vector getNormSpectrum(); + bool getOutputSpectrumChanged(); + bool getOutputSamplesChanged(); + + void reverse(std::vector processedDataIn); + + void rebuildWindow(FFTWindow FFTWindowIn); + + unsigned int outputSize(); + + +private: + static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, + std::vector* spectrumOut, std::mutex* outputAccessIn); + + // Thread: + // terminates the thread + std::atomic m_terminate; + std::atomic m_outputSpectrumChanged; + std::atomic m_outputSamplesChanged; + // it analyze gets ran on a different thread + bool m_isThreaded; + // worker thread if m_isThreaded is enabled + std::thread m_FFTThread; + std::mutex m_outputAccess; + + + unsigned int m_frameFillLoc; + + // fft + fftwf_complex* m_in; + fftwf_complex* m_out; + + fftwf_plan m_plan; + fftwf_plan m_iplan; //inverse + + std::atomic m_blockSize; + + std::vector m_samplesIn; + std::vector m_normSpectrum; + + std::vector m_absSpectrumOut; + + std::vector m_fftWindow; + FFTWindow m_FFTWindowType; +}; + +} // namespace lmms + +#endif // LMMS_FFTPROCESSOR_H From 9452d1517f6d08f13860f4870c6613a2165002f7 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:29:42 +0200 Subject: [PATCH 026/184] FFTFilter_FFTProcessor_support_added --- plugins/FFTFilter/CMakeLists.txt | 2 +- plugins/FFTFilter/FFTFilter.cpp | 101 ++++++++++++++++++++++-- plugins/FFTFilter/FFTFilter.h | 18 +++-- plugins/FFTFilter/FFTFilterControls.cpp | 9 +++ plugins/FFTFilter/FFTFilterControls.h | 4 +- 5 files changed, 120 insertions(+), 14 deletions(-) diff --git a/plugins/FFTFilter/CMakeLists.txt b/plugins/FFTFilter/CMakeLists.txt index 01d3a4e2984..95f08a747eb 100644 --- a/plugins/FFTFilter/CMakeLists.txt +++ b/plugins/FFTFilter/CMakeLists.txt @@ -1,3 +1,3 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(FFTFilter FFTFilter.cpp FFTFilterControls.cpp FFTFilterControlDialog.cpp MOCFILES FFTFilterControls.h FFTFilterControlDialog.h EMBEDDED_RESOURCES artwork.png logo.png) +BUILD_PLUGIN(FFTFilter FFTFilter.cpp FFTFilterControls.cpp FFTFilterControlDialog.cpp FFTProcessor.cpp MOCFILES FFTFilterControls.h FFTFilterControlDialog.h FFTProcessor.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index fb99d91bb25..dee99a963c6 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -25,9 +25,11 @@ #include #include "FFTFilter.h" +#include "FFTProcessor.h" #include "embed.h" #include "plugin_export.h" +#include "fft_helpers.h" namespace lmms { @@ -53,18 +55,85 @@ Plugin::Descriptor PLUGIN_EXPORT FFTFilter_plugin_descriptor = FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : Effect(&FFTFilter_plugin_descriptor, parent, key), - m_filterControls(this) + m_filterControls(this), + m_FFTProcessor(2048, true, FFTWindow::Rectangular), + m_inputBuffer(4 * 2048) { + m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); +} +FFTFilterEffect::~FFTFilterEffect() +{ + qDebug("FFTFilterEffect destrc 0"); + m_inputBuffer.wakeAll(); + //m_FFTProcessor.~FFTProcessor(); + //m_FFTProcessor.terminate(); + qDebug("FFTFilterEffect destrc 1"); } - bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { return false ; } - double outSum = 0.0; - const float d = dryLevel(); - const float w = wetLevel(); + if (isNoneInput(buf, frames, 0.05f) == true) + { + //qDebug("FFTFilterEffect return false"); + return false; + } + + + qDebug("FFTFilterEffect write"); + + m_inputBuffer.write(buf, frames, true); + + qDebug("FFTFilterEffect analyze"); + + //m_FFTProcessor.analyze(&m_inputBuffer, &target); + if (m_FFTProcessor.getOutputSpectrumChanged() == true) + { + std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); + std::vector graphInput(20); + float avgY = 0; + int avgCount = FFTSpectrumOutput.size() / graphInput.size(); + if (avgCount <= 0) + { + avgCount = 1; + } + int j = 0; + for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) + { + avgY = FFTSpectrumOutput[i]; + if (i + 1 > (j + 1) * avgCount) + { + graphInput[j] = avgY; + j++; + if (j >= graphInput.size()) + { + break; + } + avgY = 0; + } + } + for (unsigned int i = 0; i < graphInput.size(); i++) + { + graphInput[i] = graphInput[i] / static_cast(avgCount); + } + // DEBUG + for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) + { + qDebug("FFTFilterEffect: [%d], %f", i, FFTSpectrumOutput[i]); + } + //m_filterControls.setGraph(&graphInput); + } + //std::vector* output; + //for (unsigned int i = 0; i < output->size(); i++) + //{ + //qDebug("FFTFilterEffect: [%d], %f", i, output->operator[](i)); + //} + //std::vector testVector = {0.0f, 0.3f, 0.5f, -0.5f, 0.2f}; + //std::vector testVector = {0.0f, 1.3f, 0.5f, -2.5f, 0.2f}; + + + //m_filterControls.setGraph(&testVector); /* const ValueBuffer* volumeBuf = m_filterControls.m_volumeModel.valueBuffer(); @@ -93,11 +162,31 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) } */ - checkGate(outSum / frames); + //checkGate(outSum / frames); return isRunning(); } +bool FFTFilterEffect::isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, const float cutOffIn) +{ + bool output = true; + //qDebug("FFTFilterEffect check none input"); + for (unsigned int i = 0; i < cutOffIn; i++) + { + if (std::abs(bufferIn[i][0]) > cutOffIn) + { + output = false; + break; + } + else if (std::abs(bufferIn[i][1]) > cutOffIn) + { + output = false; + break; + } + } + return output; +} + extern "C" { diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index 2dec6b8a71e..ec765f9f435 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -25,10 +25,12 @@ #ifndef LMMS_FFTFILTER_H #define LMMS_FFTFILTER_H -#include "vector" +#include #include "Effect.h" #include "FFTFilterControls.h" +#include "FFTProcessor.h" +#include "LocklessRingBuffer.h" namespace lmms { @@ -37,7 +39,7 @@ class FFTFilterEffect : public Effect { public: FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); - ~FFTFilterEffect() override = default; + ~FFTFilterEffect() override; bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; EffectControls* controls() override @@ -47,6 +49,8 @@ class FFTFilterEffect : public Effect private: + bool isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, const float cutOffIn); + /* inline sample_t getCurSample(unsigned int posIn) { if (m_useSecondBufferOut == true) @@ -69,14 +73,16 @@ class FFTFilterEffect : public Effect m_bufferB[posIn] = sampleIn; } } +*/ FFTFilterControls m_filterControls; + FFTProcessor m_FFTProcessor; - std::vector m_bufferA; - std::vector m_bufferB; - bool m_useSecondBufferOut; + //std::vector m_bufferA; + //std::vector m_bufferB; + //bool m_useSecondBufferOut; - std::vector m_FFTFilterData; + LocklessRingBuffer m_inputBuffer; friend class FFTFilterControls; diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index d6335282c60..e0dc8048d28 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -89,5 +89,14 @@ void FFTFilterControls::resetClicked() { } +void FFTFilterControls::setGraph(std::vector* dataArrayIn) +{ + if (1 < m_graphModel.getDataArraySize()) + { + qDebug("set graph"); + // void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); + m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, true, false, true); + } +} } // namespace lmms diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h index fba69e9a95e..a9a9a6b22a3 100644 --- a/plugins/FFTFilter/FFTFilterControls.h +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -56,7 +56,9 @@ class FFTFilterControls : public EffectControls { return new gui::FFTFilterControlDialog(this); } - int controlCount() override { return 6; } + int controlCount() override { return 8; } + + void setGraph(std::vector* dataArrayIn); private slots: void resetClicked(); From eacd923292ff94af100d112f97f388fbbe22cbdf Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 20:30:58 +0200 Subject: [PATCH 027/184] VectorGraph_setDataArray_implementation_started --- include/VectorGraph.h | 10 +- src/gui/widgets/VectorGraph.cpp | 176 ++++++++++++++++++++++++-------- 2 files changed, 139 insertions(+), 47 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 730ef7980da..5b4b172a4b3 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -264,9 +264,9 @@ Q_OBJECT } } // returns location - unsigned int addArray(std::vector>* arrayIn, bool isCurvedIn); + unsigned int addArray(std::vector>* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); // returns location - unsigned int addArray(std::vector* arrayIn, bool isCurvedIn); + unsigned int addArray(std::vector* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); // returns location unsigned int addArray(); // preservs the order @@ -375,7 +375,7 @@ class LMMS_EXPORT VectorGraphDataArray // does check m_isFixedSize, m_isFixedValue, m_isFixedPos, // sorts array, removes duplicated positions, calls dataChanged() // clampIn: should clamp, sortIn: should sort - void formatArray(bool clampIn, bool sortIn); + void formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); // get attribute: ------------------- @@ -438,9 +438,9 @@ class LMMS_EXPORT VectorGraphDataArray // sets data array without any checks // inport x and y coords // TODO should call dataChanged - void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn); + void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); // inport y coords - void setDataArray(std::vector* dataArrayIn, bool isCurvedIn); + void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); // set attribute: ------------------- diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 0a5deb988f5..90f60f6c95b 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -33,6 +33,9 @@ #include // showInputDialog() #include // context menu + +#include + #include "VectorGraph.h" #include "StringPairDrag.h" #include "CaptionMenu.h" // context menu @@ -112,9 +115,13 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, } VectorGraphView::~VectorGraphView() { + std::cout<<"count 5"; + qDebug("VectorGraphView dstc"); m_editingText.clear(); m_editingInputIsFloat.clear(); m_editingLineEffectText.clear(); + qDebug("VectorGraphView dstc end"); + std::cout<<"count 6"; } void VectorGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -1393,20 +1400,25 @@ VectorGraphModel::VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bo VectorGraphModel::~VectorGraphModel() { + std::cout<<"count 1"; + qDebug("VectorGraphModel dstc"); m_dataArrays.clear(); + + std::cout<<"count 2"; + qDebug("VectorGraphModel dstc end"); } -unsigned int VectorGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn) +unsigned int VectorGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) { unsigned int location = addArray(); - m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); + m_dataArrays[location].setDataArray(arrayIn, isCurvedIn, clearIn, clampIn, rescaleIn, sortIn, callDataChangedIn); return location; } -unsigned int VectorGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn) +unsigned int VectorGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) { unsigned int location = addArray(); - m_dataArrays[location].setDataArray(arrayIn, isCurvedIn); + m_dataArrays[location].setDataArray(arrayIn, isCurvedIn, clearIn, clampIn, rescaleIn, callDataChangedIn); return location; } @@ -1539,15 +1551,23 @@ VectorGraphDataArray::VectorGraphDataArray( VectorGraphDataArray::~VectorGraphDataArray() { + std::cout<<"count 3"; + qDebug("VectorGraphDataArray dstc"); m_dataArray.clear(); m_bakedValues.clear(); m_needsUpdating.clear(); for (unsigned int i = 0; i < m_automationModelArray.size(); i++) { - delete m_automationModelArray[i]; + if (m_automationModelArray[i] != nullptr) + { + delete m_automationModelArray[i]; + } } m_automationModelArray.clear(); + + std::cout<<"count 4"; + qDebug("VectorGraphDataArray dstc end"); } void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) @@ -1833,33 +1853,75 @@ void VectorGraphDataArray::del(unsigned int locationIn) } // TODO input scaleing values -void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) +void VectorGraphDataArray::formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) { - // clamp - // TODO implement - float minY = 0.0f; - float maxY = 0.0f; - float minX = 0.0f; - float maxX = 0.0f; - if (clampIn == true) + if (rescaleIn == true) { - for (unsigned int i = 0; i < m_dataArray.size(); i++) + // scale + float minX = 0.0f; + float maxX = 1.0f; + float minY = -1.0f; + float maxY = 1.0f; + for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - if (m_dataArray[i].m_x < 0) + if (dataArrayIn->operator[](i).first < minX) + { + minX = dataArrayIn->operator[](i).first; + } + if (dataArrayIn->operator[](i).first > maxX) + { + maxX = dataArrayIn->operator[](i).first; + } + if (dataArrayIn->operator[](i).second < minY) { - m_dataArray[i].m_x = 0; + minY = dataArrayIn->operator[](i).second; } - if (m_dataArray[i].m_x > 1) + if (dataArrayIn->operator[](i).second > maxY) { - m_dataArray[i].m_x = 1; + maxY = dataArrayIn->operator[](i).second; } - if (m_dataArray[i].m_y > 1) + } + //qDebug("formatArray 1: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); + maxX = (maxX - minX); + minX = -minX; + maxY = (maxY - minY) * 0.5f; + minY = -minY; + //qDebug("formatArray 2: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); + if (minX != 0.0f || maxX != 1.0f) + { + for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - m_dataArray[i].m_y = 1; + dataArrayIn->operator[](i).first = (dataArrayIn->operator[](i).first + minX) / maxX; } - if (m_dataArray[i].m_y < -1) + } + if (minY != -1.0f || maxY != 1.0f) + { + for (unsigned int i = 0; i < dataArrayIn->size(); i++) { - m_dataArray[i].m_y = -1; + dataArrayIn->operator[](i).second = (dataArrayIn->operator[](i).second + minY) / maxY - 1.0f; + } + } + } + if (clampIn == true || rescaleIn == true) + { + // clamp + for (unsigned int i = 0; i < dataArrayIn->size(); i++) + { + if (dataArrayIn->operator[](i).first < 0.0f) + { + dataArrayIn->operator[](i).first = 0.0f; + } + if (dataArrayIn->operator[](i).first > 1.0f) + { + dataArrayIn->operator[](i).first = 1.0f; + } + if (dataArrayIn->operator[](i).second < -1.0f) + { + dataArrayIn->operator[](i).second = -1.0f; + } + if (dataArrayIn->operator[](i).second > 1.0f) + { + dataArrayIn->operator[](i).second = 1.0f; } } formatDataArrayEndPoints(); @@ -1868,35 +1930,37 @@ void VectorGraphDataArray::formatArray(bool clampIn, bool sortIn) // sort if (sortIn == true) { - std::sort(m_dataArray.begin(), m_dataArray.end(), - [](VectorGraphPoint a, VectorGraphPoint b) + std::sort(dataArrayIn->begin(), dataArrayIn->end(), + [](std::pair a, std::pair b) { - return a.m_x > b.m_x; + return a.first < b.first; }); } // delete duplicates - // TODO update name float lastPos = -1.0f; - if (m_dataArray.size() > 0) + if (dataArrayIn->size() > 0) { - lastPos = m_dataArray[0].m_x; + lastPos = dataArrayIn->operator[](0).first; } - for (unsigned int i = 1; i < m_dataArray.size(); i++) + for (unsigned int i = 1; i < dataArrayIn->size(); i++) { - if (m_dataArray[i].m_x == lastPos) + if (dataArrayIn->operator[](i).first == lastPos) { del(i); } else { - lastPos = m_dataArray[i].m_x; + lastPos = dataArrayIn->operator[](i).first; } } // calling clearedEvent is not needed // because all of the values can not be cleared here getUpdatingFromPoint(-1); - dataChanged(); + if (callDataChangedIn == true) + { + dataChanged(); + } } int VectorGraphDataArray::getLocation(float xIn) @@ -2100,28 +2164,48 @@ std::vector VectorGraphDataArray::getLastValues() return m_bakedValues; } -void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn) +void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, + bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) { - // TODO test - // TODO implement formatArray option + qDebug("setDataArray size: %ld", dataArrayIn->size()); + if (clearIn == true) + { + m_dataArray.clear(); + } m_dataArray.resize(dataArrayIn->size()); if (m_dataArray.size() == 0) { clearedEvent(); } - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + if (clampIn == true || rescaleIn == true || sortIn == true) + { + qDebug("setDataArray format"); + formatArray(dataArrayIn, clampIn, rescaleIn, sortIn, false); + } + for (unsigned int i = 0; i < m_dataArray.size(); i++) { - m_dataArray.push_back(VectorGraphPoint(dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second)); - if (isCurvedIn == true) + qDebug("setDataArray 1, x: %f, y: %f", dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second); + m_dataArray[i].m_x = dataArrayIn->operator[](i).first; + m_dataArray[i].m_y = dataArrayIn->operator[](i).second; + if (isCurvedIn == true && i > 0) { + float diff = m_dataArray[i - 1].m_x - m_dataArray[i].m_x; + diff = diff * diff * diff; + diff = std::clamp(diff, -1.0f, 1.0f); + m_dataArray[i - 1].m_c = diff; // TODO } } // the whole m_dataArray needs to be updated getUpdatingFromPoint(-1); - dataChanged(); + if (callDataChangedIn == true) + { + dataChanged(); + } + qDebug("setDataArray end"); } -void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn) +void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, + bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) { // TODO test std::vector> convertedDataArray(dataArrayIn->size()); @@ -2131,7 +2215,7 @@ void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool is convertedDataArray[i].first = i * stepSize; convertedDataArray[i].second = dataArrayIn->operator[](i); } - setDataArray(&convertedDataArray, isCurvedIn); + setDataArray(&convertedDataArray, isCurvedIn, clearIn, clampIn, rescaleIn, false, callDataChangedIn); } unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) @@ -2406,10 +2490,12 @@ bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) } void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) { + qDebug("setAutomated start"); if (m_isAutomatableEffectable == true) { if (isAutomatedIn == true) { + qDebug("setAutomated make"); if (m_dataArray[locationIn].m_automationModel == -1) { m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); @@ -2420,6 +2506,7 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate } else if (m_dataArray[locationIn].m_automationModel != -1) { + qDebug("setAutomated delete"); // TODO correctly deconstruct FloatModel* swap = m_automationModelArray[m_dataArray[locationIn].m_automationModel]; // copy the last FloatModel* to the current location @@ -2437,12 +2524,17 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate } } m_dataArray[locationIn].m_automationModel = -1; - delete swap; + if (swap != nullptr) + { + delete swap; + swap = nullptr; + } getUpdatingFromPoint(locationIn); dataChanged(); } } + qDebug("setAutomated end"); } FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int locationIn) { From d6fbf80287020d4fd27f695109968f1005d84208 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:22:19 +0200 Subject: [PATCH 028/184] VectorGraph_finished_setDataArray --- src/gui/widgets/VectorGraph.cpp | 38 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 90f60f6c95b..a9ba44f4f2c 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -34,8 +34,6 @@ #include // context menu -#include - #include "VectorGraph.h" #include "StringPairDrag.h" #include "CaptionMenu.h" // context menu @@ -115,13 +113,11 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, } VectorGraphView::~VectorGraphView() { - std::cout<<"count 5"; qDebug("VectorGraphView dstc"); m_editingText.clear(); m_editingInputIsFloat.clear(); m_editingLineEffectText.clear(); qDebug("VectorGraphView dstc end"); - std::cout<<"count 6"; } void VectorGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -1400,11 +1396,9 @@ VectorGraphModel::VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bo VectorGraphModel::~VectorGraphModel() { - std::cout<<"count 1"; qDebug("VectorGraphModel dstc"); m_dataArrays.clear(); - std::cout<<"count 2"; qDebug("VectorGraphModel dstc end"); } @@ -1551,7 +1545,6 @@ VectorGraphDataArray::VectorGraphDataArray( VectorGraphDataArray::~VectorGraphDataArray() { - std::cout<<"count 3"; qDebug("VectorGraphDataArray dstc"); m_dataArray.clear(); m_bakedValues.clear(); @@ -1566,7 +1559,6 @@ VectorGraphDataArray::~VectorGraphDataArray() } m_automationModelArray.clear(); - std::cout<<"count 4"; qDebug("VectorGraphDataArray dstc end"); } @@ -2179,21 +2171,38 @@ void VectorGraphDataArray::setDataArray(std::vector>* da } if (clampIn == true || rescaleIn == true || sortIn == true) { - qDebug("setDataArray format"); formatArray(dataArrayIn, clampIn, rescaleIn, sortIn, false); } + bool noneBefore = true; + bool isNegativeBefore = false; for (unsigned int i = 0; i < m_dataArray.size(); i++) { - qDebug("setDataArray 1, x: %f, y: %f", dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second); + //qDebug("setDataArray 1, x: %f, y: %f", dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second); m_dataArray[i].m_x = dataArrayIn->operator[](i).first; m_dataArray[i].m_y = dataArrayIn->operator[](i).second; if (isCurvedIn == true && i > 0) { - float diff = m_dataArray[i - 1].m_x - m_dataArray[i].m_x; - diff = diff * diff * diff; - diff = std::clamp(diff, -1.0f, 1.0f); + // TODO take in to account x coords + float diff = m_dataArray[i - 1].m_y - m_dataArray[i].m_y; + // if before is bigger than after + bool isNegative = diff >= 0; + float direction = 0; + if (noneBefore == true) + { + direction = isNegative == true ? 1.0f : -1.0f; + } + else + { + direction = isNegative == isNegativeBefore ? 1.0f : isNegative == true ? -1.0f : 1.0f; + } + + diff = diff * diff * 10.0f * direction; + diff = std::clamp(diff, -0.7f, 0.7f); m_dataArray[i - 1].m_c = diff; - // TODO + + noneBefore = diff < 0.1f && diff > -0.1f; + isNegativeBefore = isNegative; + //qDebug("setDataArray curve: %f", m_dataArray[i].m_c); } } // the whole m_dataArray needs to be updated @@ -2202,7 +2211,6 @@ void VectorGraphDataArray::setDataArray(std::vector>* da { dataChanged(); } - qDebug("setDataArray end"); } void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) From 53925b3b6230bc01a68430081e2e45c0d5816b8e Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:31:14 +0200 Subject: [PATCH 029/184] VectorGraph_deleted_VectorGraphDataArray_effectors_cleared --- include/VectorGraph.h | 2 +- src/gui/widgets/VectorGraph.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 5b4b172a4b3..6e4014dc901 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -126,7 +126,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void useGetLastValues(); signals: - inline void drawn(); + void drawn(); protected: void paintEvent(QPaintEvent* pe) override; //TODO //void dropEvent(QDropEvent* de) override; //ignore diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index a9ba44f4f2c..e2980ba339c 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -464,7 +464,6 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) p.drawLine(0, 0, 0, height() - 1); - VectorGraphDataArray* dataArray = nullptr; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { paintGraph(&p, i); @@ -1427,8 +1426,13 @@ unsigned int VectorGraphModel::addArray() void VectorGraphModel::delArray(unsigned int locationIn) { + // TODO test for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) { + if (m_dataArrays[i].getEffectorArrayLocation() == locationIn) + { + m_dataArrays[i].setEffectorArrayLocation(-1); + } m_dataArrays[i] = m_dataArrays[i + 1]; } m_dataArrays.pop_back(); @@ -1690,9 +1694,9 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) { if (m_effectorLocation != -1) { + m_effectorLocation = -1; getUpdatingFromPoint(-1); dataChanged(); - m_effectorLocation = -1; } } return !found; From c288ca54ec908a43ccfcb0261f1bd82ca32eb3e6 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 31 Mar 2024 21:56:16 +0200 Subject: [PATCH 030/184] VectorGraph_deleted_VectorGraphDataArray_effectors_cleared2 --- include/VectorGraph.h | 2 +- plugins/FFTFilter/FFTFilter.cpp | 5 +++- plugins/FFTFilter/FFTFilterControls.cpp | 3 +- src/gui/widgets/VectorGraph.cpp | 39 ++++++++++++++++++++----- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 6e4014dc901..894f74b1e93 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -333,7 +333,7 @@ class LMMS_EXPORT VectorGraphDataArray void setAutomatedColor(QColor colorIn); // returns true if successful - bool setEffectorArrayLocation(int locationIn); + bool setEffectorArrayLocation(int locationIn, bool callDataChangedIn); bool getIsFixedSize(); bool getIsFixedValue(); diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index dee99a963c6..24ed7d33a98 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -118,10 +118,12 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) graphInput[i] = graphInput[i] / static_cast(avgCount); } // DEBUG + /* for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) { qDebug("FFTFilterEffect: [%d], %f", i, FFTSpectrumOutput[i]); } + */ //m_filterControls.setGraph(&graphInput); } //std::vector* output; @@ -131,9 +133,10 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) //} //std::vector testVector = {0.0f, 0.3f, 0.5f, -0.5f, 0.2f}; //std::vector testVector = {0.0f, 1.3f, 0.5f, -2.5f, 0.2f}; + std::vector testVector = {0.0f, 0.1f, 0.5f, 0.7f, 0.5f, 0.2f, 0.1f, -1.0f, -0.1f, -0.1f, 0.2f}; - //m_filterControls.setGraph(&testVector); + m_filterControls.setGraph(&testVector); /* const ValueBuffer* volumeBuf = m_filterControls.m_volumeModel.valueBuffer(); diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index e0dc8048d28..b370f9458ba 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -62,7 +62,8 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); // effectors: - m_graphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB); + // true -> m_graphModel will call update() -> paintEvent() + m_graphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); } diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index e2980ba339c..b241abf3bec 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1427,15 +1427,34 @@ unsigned int VectorGraphModel::addArray() void VectorGraphModel::delArray(unsigned int locationIn) { // TODO test + std::vector effectorArrayLocations(m_dataArrays.size()); for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) { if (m_dataArrays[i].getEffectorArrayLocation() == locationIn) { - m_dataArrays[i].setEffectorArrayLocation(-1); + m_dataArrays[i].setEffectorArrayLocation(-1, false); } m_dataArrays[i] = m_dataArrays[i + 1]; } m_dataArrays.pop_back(); + // reset effector locations to the correct locations + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + effectorArrayLocations[i] = m_dataArrays[i].getEffectorArrayLocation(); + if (effectorArrayLocations[i] >= locationIn) + { + effectorArrayLocations[i]--; + } + // effectorLocations are cleared to avoid the + // dataArrays detecting loops and then not setting + m_dataArrays[i].setEffectorArrayLocation(-1, false); + } + // setting updated locations + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); + } + emit dataChanged(); } void VectorGraphModel::dataArrayChanged() @@ -1572,7 +1591,7 @@ void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) m_parent = parentIn; m_id = m_parent->getDataArrayNewId(); // reseting effectors - setEffectorArrayLocation(-1); + setEffectorArrayLocation(-1, true); } void VectorGraphDataArray::setIsFixedSize(bool valueIn) @@ -1617,11 +1636,11 @@ void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) m_isAutomatableEffectable = valueIn; if (valueIn == false) { - setEffectorArrayLocation(-1); + // setEffectorArray will call dataChanged() + setEffectorArrayLocation(-1, true); } else { - // setEffectorArray will call dataChanged() getUpdatingFromPoint(-1); dataChanged(); } @@ -1656,7 +1675,7 @@ void VectorGraphDataArray::setAutomatedColor(QColor colorIn) m_automatedColor = colorIn; styleChanged(); } -bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) +bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDataChangedIn) { qDebug("setEffectorArrayLocation start"); bool found = true; @@ -1687,7 +1706,10 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) { m_effectorLocation = locationIn; getUpdatingFromPoint(-1); - dataChanged(); + if (callDataChangedIn == true) + { + dataChanged(); + } } } else @@ -1696,7 +1718,10 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn) { m_effectorLocation = -1; getUpdatingFromPoint(-1); - dataChanged(); + if (callDataChangedIn == true) + { + dataChanged(); + } } } return !found; From 001ba1959b3bf00500c7cdcdabc5ff9576b433b0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:22:22 +0200 Subject: [PATCH 031/184] VectorGraph_added_attribute_names_in_context_menu --- include/VectorGraph.h | 6 +++--- src/gui/widgets/VectorGraph.cpp | 33 ++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 894f74b1e93..ca243cd89f3 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -45,7 +45,7 @@ class FloatModel; namespace gui { - +// class SimpleTextFloat; TODO class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView { Q_OBJECT @@ -165,7 +165,7 @@ protected slots: bool isGraphPressed(int mouseXIn, int mouseYIn); // returns true if the editing window was clicked while in editing mode bool isEditingWindowPressed(int mouseYIn); - void processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int xIn, int yIn); + void processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn); // returns -1 if no attribute was clicked int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); // returns a float attrib value, valueOut = attrib value if it is a bool @@ -177,7 +177,7 @@ protected slots: // returns the first x char that fits in the displayedLength(in pixel) // cuts the string to displayedLength(in px) size QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); - void addDefaultActions(QMenu* menu); + void addDefaultActions(QMenu* menu, QString controlDisplayTextIn); // inputDialog std::pair showCoordInputDialog(); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index b241abf3bec..d8bdffe7cc9 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -38,7 +38,7 @@ #include "StringPairDrag.h" #include "CaptionMenu.h" // context menu #include "embed.h" // context menu -#include "MainWindow.h" // getGUI +#include "MainWindow.h" // getting main window for context menu #include "GuiApplication.h" // getGUI #include "AutomatableModel.h" #include "ControllerConnectionDialog.h" @@ -793,7 +793,7 @@ bool VectorGraphView::isEditingWindowPressed(int mouseYIn) } return output; } -void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int xIn, int yIn) +void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) { qDebug("mouseMove 7: %d", m_lastTrackPoint.first); if (m_isEditingActive == true) @@ -835,9 +835,20 @@ void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bo if (m_addition == false) { // if the right mouse button was pressed + // get context menu input text + QString controlDisplayText = m_editingText[location]; + if (location == 5) + { + bool isTrue = false; + int typeVal = static_cast(getInputAttribValue(location, &isTrue)); + if (typeVal < m_editingLineEffectText.size()) + { + controlDisplayText = controlDisplayText + QString(" (") + m_editingLineEffectText[typeVal] + QString(")"); + } + } // show context menu - CaptionMenu contextMenu(model()->displayName()); - addDefaultActions(&contextMenu); + CaptionMenu contextMenu(model()->displayName() + QString(" - ") + controlDisplayText); + addDefaultActions(&contextMenu, QString("(") + m_editingText[location] + QString(")")); contextMenu.exec(QCursor::pos()); } else if (isDraggingIn == false && m_editingInputIsFloat[location] == false) @@ -866,13 +877,13 @@ void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bo // set m_lastScndTrackPoint.first to the current input value m_lastScndTrackPoint.first = mapInputPos(getInputAttribValue(location, &isTrue), m_graphHeight); - m_lastTrackPoint.first = xIn; - m_lastTrackPoint.second = yIn; - qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, xIn, (yIn), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); + m_lastTrackPoint.first = curXIn; + m_lastTrackPoint.second = curYIn; + qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, curXIn, (curYIn), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); } std::pair convertedCoords = mapMousePos(0, - m_lastScndTrackPoint.first + static_cast(yIn - m_lastTrackPoint.second) / 2); - qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(yIn - m_lastTrackPoint.second) / 2), convertedCoords.second); + m_lastScndTrackPoint.first + static_cast(curYIn - m_lastTrackPoint.second) / 2); + qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curYIn - m_lastTrackPoint.second) / 2), convertedCoords.second); setInputAttribValue(location, convertedCoords.second, false); } } @@ -1105,10 +1116,10 @@ QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int d } return output; } -void VectorGraphView::addDefaultActions(QMenu* menu) +void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayTextIn) { menu->addAction(embed::getIconPixmap("reload"), - tr("remove automation"), + controlDisplayTextIn + tr(" remove automation") , this, SLOT(removeAutomation())); menu->addSeparator(); From 5c71db883420ed6cc0aa4957369722b190725738 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:38:45 +0200 Subject: [PATCH 032/184] VectorGraph_renamed_editing_values --- include/VectorGraph.h | 24 +++--- src/gui/widgets/VectorGraph.cpp | 136 ++++++++++++++++---------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index ca243cd89f3..95dd5c07b9b 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -160,18 +160,18 @@ protected slots: bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); - // editing + // editing menu / controls // returns true if the graph was clicked bool isGraphPressed(int mouseXIn, int mouseYIn); - // returns true if the editing window was clicked while in editing mode - bool isEditingWindowPressed(int mouseYIn); - void processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn); + // returns true if the control window was clicked while in editing mode + bool isControlWindowPressed(int mouseYIn); + void processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn); // returns -1 if no attribute was clicked int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); // returns a float attrib value, valueOut = attrib value if it is a bool - float getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut); + float getInputAttribValue(unsigned int controlArrayLocationIn, bool* valueOut); // sets the attrib to floatValueIn it it is float, else it sets the attrib to boolValueIn - void setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn); + void setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn); // calculates the ideal text color QColor getTextColorFromBaseColor(QColor baseColorIn); // returns the first x char that fits in the displayedLength(in pixel) @@ -220,14 +220,14 @@ protected slots: bool m_isLastSelectedArray; unsigned int m_graphHeight; - unsigned int m_editingHeight; + unsigned int m_controlHeight; // displayed attrib count - unsigned int m_editingInputCount; - unsigned int m_editingDisplayPage; + unsigned int m_controlDisplayCount; + unsigned int m_controlDisplayPage; bool m_isEditingActive; - std::vector m_editingText; - std::vector m_editingLineEffectText; - std::vector m_editingInputIsFloat; + std::vector m_controlText; + std::vector m_controlLineEffectText; + std::vector m_controlIsFloat; std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d8bdffe7cc9..d650b5a0a9e 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -75,18 +75,18 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, m_isLastSelectedArray = false; m_graphHeight = height(); - m_editingHeight = 30; - m_editingInputCount = 4; - m_editingDisplayPage = 0; + m_controlHeight = 30; + m_controlDisplayCount = 4; + m_controlDisplayPage = 0; m_isEditingActive = false; - m_editingText = { + m_controlText = { tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; - m_editingLineEffectText = { + m_controlLineEffectText = { tr("none"), tr("sine"), tr("phase changable sine"), @@ -94,7 +94,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, tr("steps"), tr("random") }; - m_editingInputIsFloat = { + m_controlIsFloat = { true, true, true, true, true, false, false, false, false, false, false, @@ -114,9 +114,9 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, VectorGraphView::~VectorGraphView() { qDebug("VectorGraphView dstc"); - m_editingText.clear(); - m_editingInputIsFloat.clear(); - m_editingLineEffectText.clear(); + m_controlText.clear(); + m_controlIsFloat.clear(); + m_controlLineEffectText.clear(); qDebug("VectorGraphView dstc end"); } @@ -305,9 +305,9 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) // else m_mousePress does not change } } - else if (isEditingWindowPressed(m_lastScndTrackPoint.second) == true) + else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) { - processEditingWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); + processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); } } } @@ -363,9 +363,9 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } } - else if (m_mousePress == true && isEditingWindowPressed(m_graphHeight - y) == true) + else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) { - processEditingWindowPressed(x, m_graphHeight - y, false, false, 0, 0); + processControlWindowPressed(x, m_graphHeight - y, false, false, 0, 0); } else { @@ -432,13 +432,13 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) setSelectedData(curData); } } - else if (isEditingWindowPressed(m_graphHeight - y) == true) + else if (isControlWindowPressed(m_graphHeight - y) == true) { - int pressLocation = getPressedInput(x, m_graphHeight - y, m_editingInputCount + 1); - if (pressLocation >= 0 && pressLocation != m_editingInputCount) + int pressLocation = getPressedInput(x, m_graphHeight - y, m_controlDisplayCount + 1); + if (pressLocation >= 0 && pressLocation != m_controlDisplayCount) { - unsigned int location = m_editingInputCount * m_editingDisplayPage + pressLocation; - if (location < m_editingText.size() && m_editingInputIsFloat[location] == true) + unsigned int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; + if (location < m_controlText.size() && m_controlIsFloat[location] == true) { // unused bool bool isTrue = false; @@ -455,7 +455,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) QPainter p(this); //QPainterPath pt(); // TODO qDebug("paintEvent"); - m_graphHeight = m_isEditingActive == true ? height() - m_editingHeight : height(); + m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); p.setPen(QPen(QColor(127, 127, 127, 255), 1)); p.drawLine(0, 0, width() - 1, 0); @@ -560,31 +560,31 @@ void VectorGraphView::paintEditing(QPainter* pIn) foreColor = *dataArray->getFillColor(); } - int editingTextCount = m_editingText.size(); + int controlTextCount = m_controlText.size(); if (dataArray->getIsEditableAttrib() == false) { // x, y - editingTextCount = 2; + controlTextCount = 2; } else if (dataArray->getIsAutomatableEffectable() == false) { // x, y, curve, valA, valB, switch type - editingTextCount = 6; + controlTextCount = 6; } - int segmentLength = width() / (m_editingInputCount + 1); + int segmentLength = width() / (m_controlDisplayCount + 1); // draw inputs pIn->setPen(textColor); - for (unsigned int i = 0; i < m_editingInputCount; i++) + for (unsigned int i = 0; i < m_controlDisplayCount; i++) { - if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount) + if (m_controlDisplayCount * m_controlDisplayPage + i < controlTextCount) { - if (m_editingInputIsFloat[m_editingInputCount * m_editingDisplayPage + i] == true) + if (m_controlIsFloat[m_controlDisplayCount * m_controlDisplayPage + i] == true) { QColor curForeColor = foreColor; // unused bool bool isTrue = false; - float inputValue = getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); + float inputValue = getInputAttribValue(m_controlDisplayCount * m_controlDisplayPage + i, &isTrue); if (dataArray->getAutomationModel(m_selectedLocation) != nullptr && static_cast(getInputAttribValue(6, &isTrue)) == i - 1) { curForeColor = *dataArray->getAutomatedColor(); @@ -593,38 +593,38 @@ void VectorGraphView::paintEditing(QPainter* pIn) { curForeColor = *dataArray->getActiveColor(); } - pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, backColor); - pIn->fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_editingHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, - getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); + pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, backColor); + pIn->fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_controlHeight, curForeColor); + pIn->drawText(i * segmentLength, m_graphHeight + m_controlHeight / 2, + getTextFromDisplayLength(m_controlText[m_controlDisplayCount * m_controlDisplayPage + i], segmentLength)); } else { QColor curForeColor = *dataArray->getFillColor(); bool isTrue = false; - getInputAttribValue(m_editingInputCount * m_editingDisplayPage + i, &isTrue); + getInputAttribValue(m_controlDisplayCount * m_controlDisplayPage + i, &isTrue); if (isTrue == true) { curForeColor = *dataArray->getActiveColor(); } - pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_editingHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + m_editingHeight / 2, - getTextFromDisplayLength(m_editingText[m_editingInputCount * m_editingDisplayPage + i], segmentLength)); + pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); + pIn->drawText(i * segmentLength, m_graphHeight + m_controlHeight / 2, + getTextFromDisplayLength(m_controlText[m_controlDisplayCount * m_controlDisplayPage + i], segmentLength)); } } } // draw "next page" button - pIn->fillRect(m_editingInputCount * segmentLength, m_graphHeight, segmentLength, m_editingHeight, *dataArray->getFillColor()); + pIn->fillRect(m_controlDisplayCount * segmentLength, m_graphHeight, segmentLength, m_controlHeight, *dataArray->getFillColor()); pIn->setPen(textColor); - pIn->drawText(m_editingInputCount * segmentLength, m_graphHeight + m_editingHeight / 2, ">>"); + pIn->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + m_controlHeight / 2, ">>"); // draw outline pIn->setPen(*dataArray->getLineColor()); - pIn->drawRect(0, 0, m_editingHeight, m_editingHeight); + pIn->drawRect(0, 0, m_controlHeight, m_controlHeight); pIn->drawLine(0, m_graphHeight, width(), m_graphHeight); - for (unsigned int i = 1; i < m_editingInputCount + 1; i++) + for (unsigned int i = 1; i < m_controlDisplayCount + 1; i++) { - if (m_editingInputCount * m_editingDisplayPage + i < editingTextCount || i >= m_editingInputCount) + if (m_controlDisplayCount * m_controlDisplayPage + i < controlTextCount || i >= m_controlDisplayCount) { pIn->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); } @@ -767,91 +767,91 @@ bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) bool output = true; // mouseYIn is calculated like this: // m_graphHeight - y - if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_editingHeight && mouseXIn < m_editingHeight) + if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_controlHeight && mouseXIn < m_controlHeight) { // if switch selected data array was pressed qDebug("isGraphPressed switch selected dataArray"); output = false; } - else if (isEditingWindowPressed(mouseYIn) == true) + else if (isControlWindowPressed(mouseYIn) == true) { - // if the editing window was pressed + // if the control window was pressed output = false; } qDebug("isGraphPressed end"); return output; } -bool VectorGraphView::isEditingWindowPressed(int mouseYIn) +bool VectorGraphView::isControlWindowPressed(int mouseYIn) { bool output = false; // mouseYIn is calculated like this: // m_graphHeight - y if (m_isEditingActive == true && mouseYIn <= 0) { - qDebug("isGraphPressed editing window was pressed"); + qDebug("isGraphPressed control window was pressed"); output = true; } return output; } -void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) +void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) { qDebug("mouseMove 7: %d", m_lastTrackPoint.first); if (m_isEditingActive == true) { - int pressLocation = getPressedInput(mouseXIn, m_graphHeight - mouseYIn, m_editingInputCount + 1); - int location = m_editingInputCount * m_editingDisplayPage + pressLocation; - if (isDraggingIn == false && pressLocation == m_editingInputCount) + int pressLocation = getPressedInput(mouseXIn, m_graphHeight - mouseYIn, m_controlDisplayCount + 1); + int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; + if (isDraggingIn == false && pressLocation == m_controlDisplayCount) { // if the last button was pressed // how many inputs are there - int editingTextCount = m_editingText.size(); + int controlTextCount = m_controlText.size(); if (m_isSelected == true) { if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) { // x, y - editingTextCount = 2; + controlTextCount = 2; } else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) { // x, y, curve, valA, valB, switch type - editingTextCount = 6; + controlTextCount = 6; } } - m_editingDisplayPage++; - if (m_editingInputCount * m_editingDisplayPage >= editingTextCount) + m_controlDisplayPage++; + if (m_controlDisplayCount * m_controlDisplayPage >= controlTextCount) { - m_editingDisplayPage = 0; + m_controlDisplayPage = 0; } - qDebug("mouseRelease editingPage: %d", m_editingDisplayPage); + qDebug("mouseRelease controlPage: %d", m_controlDisplayPage); } - else if (pressLocation >= 0 && location < m_editingText.size()) + else if (pressLocation >= 0 && location < m_controlText.size()) { // pressLocation should always be bigger than -1 - // if the editing window was pressed + // if the control window was pressed if (m_addition == false) { // if the right mouse button was pressed // get context menu input text - QString controlDisplayText = m_editingText[location]; + QString controlDisplayText = m_controlText[location]; if (location == 5) { bool isTrue = false; int typeVal = static_cast(getInputAttribValue(location, &isTrue)); - if (typeVal < m_editingLineEffectText.size()) + if (typeVal < m_controlLineEffectText.size()) { - controlDisplayText = controlDisplayText + QString(" (") + m_editingLineEffectText[typeVal] + QString(")"); + controlDisplayText = controlDisplayText + QString(" (") + m_controlLineEffectText[typeVal] + QString(")"); } } // show context menu CaptionMenu contextMenu(model()->displayName() + QString(" - ") + controlDisplayText); - addDefaultActions(&contextMenu, QString("(") + m_editingText[location] + QString(")")); + addDefaultActions(&contextMenu, QString("(") + m_controlText[location] + QString(")")); contextMenu.exec(QCursor::pos()); } - else if (isDraggingIn == false && m_editingInputIsFloat[location] == false) + else if (isDraggingIn == false && m_controlIsFloat[location] == false) { // if the input type is a bool @@ -865,7 +865,7 @@ void VectorGraphView::processEditingWindowPressed(int mouseXIn, int mouseYIn, bo } setInputAttribValue(location, 0.0f, curBoolValue); } - else if (isDraggingIn == true && m_editingInputIsFloat[location] == true) + else if (isDraggingIn == true && m_controlIsFloat[location] == true) { // if the input type is a float @@ -903,12 +903,12 @@ qDebug("getPressedInput x location ERRROR: %d", mouseXIn); } return output; } -float VectorGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, bool* valueOut) +float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocationIn, bool* valueOut) { float output = 0.0f; if (m_isSelected == true) { - switch (editingArrayLocationIn) + switch (controlArrayLocationIn) { case 0: *valueOut = false; @@ -979,14 +979,14 @@ float VectorGraphView::getInputAttribValue(unsigned int editingArrayLocationIn, } return output; } -void VectorGraphView::setInputAttribValue(unsigned int editingArrayLocationIn, float floatValueIn, bool boolValueIn) +void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn) { qDebug("setInputAttribValue started"); if (m_isSelected == true) { float clampedValue = floatValueIn < -1.0f ? -1.0f : floatValueIn > 1.0f ? 1.0f : floatValueIn; unsigned int clampedValueB = 0; - switch (editingArrayLocationIn) + switch (controlArrayLocationIn) { case 0: m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, clampedValue < 0.0f ? 0.0f : clampedValue); From 9ac013aa93e8ba6d5db087af95997f3436dacdf0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 1 Apr 2024 20:50:48 +0200 Subject: [PATCH 033/184] VectorGraph_gui_updated --- include/VectorGraph.h | 8 +- plugins/FFTFilter/FFTFilterControls.cpp | 5 +- src/gui/widgets/VectorGraph.cpp | 280 +++++++++++++++++++----- 3 files changed, 231 insertions(+), 62 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 95dd5c07b9b..115575c2322 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -80,7 +80,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // TODO: ability to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) // TODO: check PointGraphDataArray signals Done // TODO: journalling in PointGraphModel - // TODO: m_maxLenght* should be replaced with m_parent->getMaxLength() Done + // TODO: m_maxLength* should be replaced with m_parent->getMaxLength() Done // TODO: setDataArray keep attributes option, formatArray option which runs formatArray // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option Done // TODO: baked automation values in PointGraphPoint Done @@ -123,6 +123,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // returns -1 it can not return a array location int getLastSelectedArray(); void setSelectedData(std::pair dataIn); + void setBackground(const QPixmap backgoundIn); void useGetLastValues(); signals: @@ -174,6 +175,8 @@ protected slots: void setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn); // calculates the ideal text color QColor getTextColorFromBaseColor(QColor baseColorIn); + // calculates a replacement fill color + QColor getFillColorFromBaseColor(QColor baseColorIn); // returns the first x char that fits in the displayedLength(in pixel) // cuts the string to displayedLength(in px) size QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); @@ -202,8 +205,10 @@ protected slots: // radius, rx = ry unsigned int m_pointSize; + unsigned int m_fontSize; // draw simplified lines bool m_isSimplified; + QPixmap m_background; // for 1 draw, it will use the VectorGraphDataArray // m_bakedValues without calling GetValues() bool m_useGetLastValues; @@ -429,6 +434,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns the latest updated graph values // countIn is the retuned vector's size std::vector getValues(unsigned int countIn); + //std::vector getValues(unsigned int countIn, bool* isChangedOut); std::vector getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut); // returns m_bakedValues without updating std::vector getLastValues(); diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index b370f9458ba..0f695e5f35d 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -48,7 +48,7 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); - m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 255)); + m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); unsigned int arrayLocationB = m_graphModel.addArray(); @@ -57,8 +57,7 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); m_graphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); m_graphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); - m_graphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 255)); - m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); + m_graphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); // effectors: diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d650b5a0a9e..40f08683536 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -29,6 +29,7 @@ #include // unintptr_t #include // smartpointers #include +#include #include #include // showInputDialog() #include // context menu @@ -65,7 +66,9 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, m_addition = false; m_pointSize = pointSizeIn; + m_fontSize = 12; m_isSimplified = false; + //m_background; m_useGetLastValues = false; m_selectedLocation = 0; @@ -187,6 +190,10 @@ void VectorGraphView::setSelectedData(std::pair dataIn) qDebug("set position done"); } } +void VectorGraphView::setBackground(const QPixmap backgroundIn) +{ + m_background = backgroundIn; +} void VectorGraphView::useGetLastValues() { m_useGetLastValues = true; @@ -232,6 +239,21 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) { // try selecting the clicked point (if it is near) selectData(x, m_graphHeight - y); + // avoid triggering editing window while deleting + // points are only added when + // m_isSelected == false -> m_isEditingActive = false + if (m_isSelected == true && m_addition == false) + { + m_isEditingActive = false; + } + if (m_isSelected == true) + { + setCursor(Qt::ArrowCursor); + } + else + { + setCursor(Qt::CrossCursor); + } } } @@ -453,10 +475,25 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) void VectorGraphView::paintEvent(QPaintEvent* pe) { QPainter p(this); - //QPainterPath pt(); // TODO + p.setRenderHint(QPainter::Antialiasing, true); + qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); + if (m_isEditingActive == true) + { + qDebug("paintEvent editing active"); + } + else + { + qDebug("paintEvent editing not active"); + } + + if (m_background.isNull() == false) + { + p.drawPixmap(0, 0, m_background); + } + p.setPen(QPen(QColor(127, 127, 127, 255), 1)); p.drawLine(0, 0, width() - 1, 0); p.drawLine(width() - 1, 0, width() - 1, height() - 1); @@ -482,36 +519,19 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) unsigned int length = dataArray->size(); if (length > 0) { - pIn->setPen(QPen(*dataArray->getLineColor(), 1)); + pIn->setPen(QPen(*dataArray->getLineColor(), 2)); + pIn->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); std::pair posA(0, 0); std::pair posB(0, 0); - if (dataArray->getIsSelectable() == true) - { - for (unsigned int j = 0; j < length; j++) - { - //qDebug("draw: x: %f, y: %f", dataArray->getX(j), dataArray->getY(j)); - posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); - pIn->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); - if (j > 0) - { - if (dataArray->getIsEditableAttrib() == true) - { - std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - pIn->drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); - } - if (m_isSimplified == true) - { - pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - } - posA = posB; - } - } + std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), dataArray->getNonNegative())); + // draw line if (m_isSimplified == false) { - posA = mapDataPos(dataArray->getX(0), dataArray->getY(0), dataArray->getNonNegative()); + QPainterPath pt; + posA = startPos; + pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); std::vector dataArrayValues; if (m_useGetLastValues == true) @@ -526,37 +546,115 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); for (unsigned int j = 0; j < dataArrayValues.size(); j++) { - //posB = mapDataPos(*dataArray->getX(j + 1), dataArray->getY(j + 1)); - //posB = mapDataPos(0, dataArray->getValueAtPosition(static_cast(j) / static_cast(width()))); posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); - //posB = dataArray->getValueAtPosition(static_cast(j) / static_cast(width())); posB.first = j; - //qDebug("paint positions: x: %d, y: %d", posB.first, posB.second); - // x1, y1, x2, y2 - //qDebug("paint positions: x: %d, y: %d, x2: %d, y2: %d", posA.first, posA.second, posB.first, posB.second); - if (j > 0 && posA.first != posB.first) + + if (posA.first != posB.first) + { + pt.lineTo(j, m_graphHeight - posB.second); + // pt replaces drawing with path + //pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + } + posA = posB; + } + + // final draw line, fill + if (dataArray->getFillColor()->alpha() > 0) + { + // getting the line for + // drawing later + QPainterPath ptline(pt); + pt.lineTo(width() - 1, posB.second); + pt.lineTo(width() - 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, startPos.second); + // draw fill + pIn->fillPath(pt, QBrush(*dataArray->getFillColor())); + // draw line + pIn->drawPath(ptline); + } + else + { + pIn->drawPath(pt); + } + } + + // draw points + if (dataArray->getIsSelectable() == true || m_isSimplified == true) + { + posA = startPos; + + QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); + bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; + bool resetColor = false; + for (unsigned int j = 0; j < length; j++) + { + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); + // draw point + if (drawPoints == true) + { + // set point color + if (dataArray->getAutomationModel(j) != nullptr) + { + // if automated + pIn->setPen(QPen(*dataArray->getAutomatedColor(), 2)); + pIn->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); + resetColor = true; + } + else if (m_isSelected == true && m_selectedArray == locationIn && m_selectedLocation == j) + { + // if selected + pIn->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); + resetColor = true; + } + + pIn->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + + // reset point color + if (resetColor == true) + { + pIn->setPen(QPen(*dataArray->getLineColor(), 2)); + pIn->setBrush(Qt::NoBrush); + resetColor = false; + } + + if (j > 0) + { + if (dataArray->getIsEditableAttrib() == true) + { + std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + pIn->drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + } + } + } + + // draw simplified line + if (m_isSimplified == true) { pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } posA = posB; } - dataArrayValues.clear(); + } + // draw last simplified line + if (m_isSimplified == true) + { + pIn->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); } } } void VectorGraphView::paintEditing(QPainter* pIn) { + pIn->setFont(QFont("Arial", m_fontSize)); if (m_isEditingActive == true) { VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); // background of float values - QColor backColor(25, 25, 25, 255); + QColor backColor(getFillColorFromBaseColor(*dataArray->getFillColor())); QColor foreColor = *dataArray->getLineColor(); if (dataArray->getFillColor()->alpha() > 0) { - backColor = QColor(dataArray->getFillColor()->red() / 2, dataArray->getFillColor()->green() / 2, - dataArray->getFillColor()->blue() / 2, 255); foreColor = *dataArray->getFillColor(); } @@ -574,42 +672,46 @@ void VectorGraphView::paintEditing(QPainter* pIn) int segmentLength = width() / (m_controlDisplayCount + 1); // draw inputs - pIn->setPen(textColor); + pIn->setPen(QPen(textColor, 1)); for (unsigned int i = 0; i < m_controlDisplayCount; i++) { - if (m_controlDisplayCount * m_controlDisplayPage + i < controlTextCount) + int controlLocation = m_controlDisplayCount * m_controlDisplayPage + i; + if (controlLocation < controlTextCount) { - if (m_controlIsFloat[m_controlDisplayCount * m_controlDisplayPage + i] == true) + if (m_controlIsFloat[controlLocation] == true) { + QColor curBackColor = backColor; QColor curForeColor = foreColor; // unused bool bool isTrue = false; - float inputValue = getInputAttribValue(m_controlDisplayCount * m_controlDisplayPage + i, &isTrue); - if (dataArray->getAutomationModel(m_selectedLocation) != nullptr && static_cast(getInputAttribValue(6, &isTrue)) == i - 1) + float inputValue = getInputAttribValue(controlLocation, &isTrue); + if (dataArray->getAutomationModel(m_selectedLocation) != nullptr && static_cast(getInputAttribValue(6, &isTrue)) == controlLocation - 1) { curForeColor = *dataArray->getAutomatedColor(); + curBackColor = getFillColorFromBaseColor(curForeColor); } - else if (dataArray->getIsAutomatableEffectable() == true && static_cast(getInputAttribValue(7, &isTrue)) == i - 1) + else if (dataArray->getIsAutomatableEffectable() == true && static_cast(getInputAttribValue(7, &isTrue)) == controlLocation - 1) { curForeColor = *dataArray->getActiveColor(); + curBackColor = getFillColorFromBaseColor(curForeColor); } - pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, backColor); + pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curBackColor); pIn->fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_controlHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + m_controlHeight / 2, - getTextFromDisplayLength(m_controlText[m_controlDisplayCount * m_controlDisplayPage + i], segmentLength)); + pIn->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, + getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); } else { QColor curForeColor = *dataArray->getFillColor(); bool isTrue = false; - getInputAttribValue(m_controlDisplayCount * m_controlDisplayPage + i, &isTrue); + getInputAttribValue(controlLocation, &isTrue); if (isTrue == true) { curForeColor = *dataArray->getActiveColor(); } pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + m_controlHeight / 2, - getTextFromDisplayLength(m_controlText[m_controlDisplayCount * m_controlDisplayPage + i], segmentLength)); + pIn->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, + getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); } } } @@ -617,10 +719,11 @@ void VectorGraphView::paintEditing(QPainter* pIn) // draw "next page" button pIn->fillRect(m_controlDisplayCount * segmentLength, m_graphHeight, segmentLength, m_controlHeight, *dataArray->getFillColor()); pIn->setPen(textColor); - pIn->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + m_controlHeight / 2, ">>"); - // draw outline + pIn->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, ">>"); + // draw selected array display outline pIn->setPen(*dataArray->getLineColor()); pIn->drawRect(0, 0, m_controlHeight, m_controlHeight); + // draw outline pIn->drawLine(0, m_graphHeight, width(), m_graphHeight); for (unsigned int i = 1; i < m_controlDisplayCount + 1; i++) { @@ -630,6 +733,12 @@ void VectorGraphView::paintEditing(QPainter* pIn) } } } + if (m_isLastSelectedArray == true) + { + // draw selected array number + pIn->setPen(QPen(QColor(127, 127, 127, 255), 2)); + pIn->drawText(2, (m_controlHeight - m_fontSize) / 2 + m_fontSize, QString::number(m_selectedArray)); + } } void VectorGraphView::modelChanged() @@ -767,6 +876,14 @@ bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) bool output = true; // mouseYIn is calculated like this: // m_graphHeight - y + if (m_isEditingActive == true) + { + qDebug("isGraphPressed editing active"); + } + else + { + qDebug("isGraphPressed editing not active"); + } if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_controlHeight && mouseXIn < m_controlHeight) { // if switch selected data array was pressed @@ -795,6 +912,8 @@ bool VectorGraphView::isControlWindowPressed(int mouseYIn) } void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) { + setCursor(Qt::ArrowCursor); + qDebug("mouseMove 7: %d", m_lastTrackPoint.first); if (m_isEditingActive == true) { @@ -1092,28 +1211,71 @@ QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColorIn) { QColor output(255, 255, 255, 255); int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); + // > 127 * 3 if (colorSum > 382) { output = QColor(0, 0, 0, 255); } return output; } +QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColorIn) +{ + QColor output; + int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); + int brighten = 0; + int alpha = baseColorIn.alpha(); + if (alpha == 0) + { + alpha = 255; + } + if (std::abs(colorSum - 382) > 191) + { + brighten = 45; + } + //qDebug("getFillColorFromBaseColor r: %d, g: %d, b: %d", baseColorIn.red(), baseColorIn.green(), baseColorIn.blue()); + // > 127 * 3 + if (colorSum > 382) + { + // (red * 0.6f + avg * 0.4f / 3.0f) * 0.7 + //qDebug("getFillColorFromBaseColor bigger, %d", brighten); + output = QColor(static_cast(static_cast(baseColorIn.red()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColorIn.green()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColorIn.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); + } + else + { + // (red * 0.6f + avg * 0.4f / 3.0f) * 1.3 + output = QColor(static_cast(static_cast(baseColorIn.red()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColorIn.green()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColorIn.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); + } + //qDebug("getFillColorFromBaseColor r: %d, g: %d, b: %d", output.red(), output.green(), output.blue()); + return output; +} QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) { - int charLength = 4; + // estimating text length + int charLength = static_cast(m_fontSize * 0.65f); QString output = ""; int targetSize = displayLengthIn / charLength < textIn.size() ? displayLengthIn / charLength : textIn.size(); - for (unsigned int i = 0; i < targetSize; i++) + if (targetSize != textIn.size()) { - if (i + 3 < targetSize) - { - output = output + textIn[i]; - } - else + for (unsigned int i = 0; i < targetSize; i++) { - output = output + QString("."); + if (i + 2 < targetSize) + { + output = output + textIn[i]; + } + else + { + output = output + QString("."); + } } } + else + { + output = textIn; + } return output; } void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayTextIn) @@ -1245,6 +1407,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) //qDebug("selected data location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = false; + m_isLastSelectedArray = true; m_isEditingActive = dataArray->getIsEditableAttrib(); break; } @@ -1266,6 +1429,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) //qDebug("selected data curve location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = true; + m_isLastSelectedArray = true; m_isEditingActive = dataArray->getIsEditableAttrib(); break; } From c11010d5eece202db1003375c6e7814ced8eed04 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 1 Apr 2024 21:59:25 +0200 Subject: [PATCH 034/184] VectorGraph_added_dragging --- src/gui/widgets/VectorGraph.cpp | 54 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 40f08683536..1a0276bba72 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -312,15 +312,56 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (m_addition == false) { + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) + { + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + selectData(x, m_graphHeight - y); + if (m_isSelected == true) + { + model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + m_isSelected = false; + m_isEditingActive = false; + } + } // TODO deletion } else { + if (startMoving == true && m_isLastSelectedArray == true) + { + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); + } float curDistance = getDistance(x, m_graphHeight - y, m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize * 2) + if (curDistance > m_pointSize) { - // TODO drawing + // calculating angle + // getting the angle between (lastScndTrackPoint and lastTrackPoint) + // and (lastTrackPoint and x and y) + float curAngle = static_cast( + (m_lastTrackPoint.second - m_lastScndTrackPoint.second) * + (m_graphHeight - y - m_lastTrackPoint.second) + + (m_lastTrackPoint.first - m_lastScndTrackPoint.first) * + (x - m_lastTrackPoint.first)); + curAngle = std::acos(curAngle / curDistance / + getDistance(m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, + m_lastTrackPoint.first, m_lastTrackPoint.second)); + // if the angle difference is bigger than 0.3 rad + if (std::abs(curAngle) * curDistance * curDistance / static_cast(m_pointSize * m_pointSize) > 0.3f) + { + m_lastScndTrackPoint.first = m_lastTrackPoint.first; + m_lastScndTrackPoint.second = m_lastTrackPoint.second; + + if (m_isLastSelectedArray == true) + { + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); + } + } m_lastTrackPoint.first = x; m_lastTrackPoint.second = m_graphHeight - y; } @@ -361,9 +402,11 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) // trying to add to all the selected arrays for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - success = addPoint(m_selectedArray, x, m_graphHeight - y); + success = addPoint(i, x, m_graphHeight - y); if (success == true) { + m_selectedArray = i; + m_isLastSelectedArray = true; break; } } @@ -379,11 +422,6 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) m_mousePress = false; } - else - { - // add/set/delete line end - - } } else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) { From 967af3ee97048d39923adffc2b7c99c527ac8f9d Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 2 Apr 2024 15:01:21 +0200 Subject: [PATCH 035/184] VectorGraph_FloatModel_deletion_inproved --- include/VectorGraph.h | 3 + src/gui/widgets/VectorGraph.cpp | 99 +++++++++++++++++---------------- 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 115575c2322..4983c7d6d0f 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -577,6 +577,9 @@ class LMMS_EXPORT VectorGraphDataArray // automation: connecting to floatmodels, -1 when it isn't conntected' int m_automationModel; }; + // deletes the point's automation model + // locationIn = point location + void delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn); // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1a0276bba72..f4a51a7d609 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -318,6 +318,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { m_lastTrackPoint.first = x; m_lastTrackPoint.second = m_graphHeight - y; + m_isSelected = false; selectData(x, m_graphHeight - y); if (m_isSelected == true) { @@ -326,7 +327,6 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) m_isEditingActive = false; } } - // TODO deletion } else { @@ -518,15 +518,6 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); - if (m_isEditingActive == true) - { - qDebug("paintEvent editing active"); - } - else - { - qDebug("paintEvent editing not active"); - } - if (m_background.isNull() == false) { p.drawPixmap(0, 0, m_background); @@ -846,7 +837,6 @@ void VectorGraphView::removeController() std::pair VectorGraphView::mapMousePos(int xIn, int yIn) { // mapping the position to 0 - 1, -1 - 1 using qWidget width and height - qDebug("map mouse pos y: %d", yIn); return std::pair( static_cast(xIn / (float)width()), static_cast(yIn) * 2.0f / static_cast(m_graphHeight) - 1.0f); @@ -914,18 +904,10 @@ bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) bool output = true; // mouseYIn is calculated like this: // m_graphHeight - y - if (m_isEditingActive == true) - { - qDebug("isGraphPressed editing active"); - } - else - { - qDebug("isGraphPressed editing not active"); - } if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_controlHeight && mouseXIn < m_controlHeight) { // if switch selected data array was pressed - qDebug("isGraphPressed switch selected dataArray"); + //qDebug("isGraphPressed switch selected dataArray"); output = false; } else if (isControlWindowPressed(mouseYIn) == true) @@ -933,7 +915,7 @@ bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) // if the control window was pressed output = false; } - qDebug("isGraphPressed end"); + //qDebug("isGraphPressed end"); return output; } bool VectorGraphView::isControlWindowPressed(int mouseYIn) @@ -943,7 +925,7 @@ bool VectorGraphView::isControlWindowPressed(int mouseYIn) // m_graphHeight - y if (m_isEditingActive == true && mouseYIn <= 0) { - qDebug("isGraphPressed control window was pressed"); + //qDebug("isGraphPressed control window was pressed"); output = true; } return output; @@ -2068,6 +2050,10 @@ void VectorGraphDataArray::del(unsigned int locationIn) { if (m_isFixedSize == false && locationIn < m_dataArray.size()) { + // deleting the points automationModel + delAutomationModel(m_dataArray[locationIn].m_automationModel, true); + // swapping the point to the last location + // in m_dataArray swap(locationIn, m_dataArray.size() - 1, true); m_dataArray.pop_back(); if (locationIn == 0 || locationIn == m_dataArray.size()) @@ -2754,34 +2740,13 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate dataChanged(); } } - else if (m_dataArray[locationIn].m_automationModel != -1) + else { qDebug("setAutomated delete"); - // TODO correctly deconstruct - FloatModel* swap = m_automationModelArray[m_dataArray[locationIn].m_automationModel]; - // copy the last FloatModel* to the current location - m_automationModelArray[m_dataArray[locationIn].m_automationModel] = - m_automationModelArray[m_automationModelArray.size() - 1]; - m_automationModelArray.pop_back(); - - // replace all last m_automationModel-s to the currently deleted m_automationModel - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) - { - m_dataArray[i].m_automationModel = m_dataArray[locationIn].m_automationModel; - // we dont break for safety - } - } - m_dataArray[locationIn].m_automationModel = -1; - if (swap != nullptr) - { - delete swap; - swap = nullptr; - } - getUpdatingFromPoint(locationIn); - dataChanged(); + // dataChanged() is called in this function + // this function check if the current point has an automationModel + delAutomationModel(m_dataArray[locationIn].m_automationModel, true); } } qDebug("setAutomated end"); @@ -2794,6 +2759,46 @@ FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int locationIn) } return nullptr; } +void VectorGraphDataArray::delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn) +{ + if (modelLocationIn != -1) + { + FloatModel* curModel = m_automationModelArray[modelLocationIn]; + + // copy the last FloatModel* to the current location + m_automationModelArray[modelLocationIn] = + m_automationModelArray[m_automationModelArray.size() - 1]; + + m_automationModelArray.pop_back(); + + // replace all m_auttomationModel-s in the current copyed location with -1 + // replace all last m_automationModel-s to the currently copyed location + // there should be only 2 points changed but because of safety + // all of them are checked + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].m_automationModel == modelLocationIn) + { + m_dataArray[i].m_automationModel = -1; + getUpdatingFromPoint(i); + } + if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) + { + m_dataArray[i].m_automationModel = modelLocationIn; + } + } + if (curModel != nullptr) + { + delete curModel; + curModel = nullptr; + } + + if (callDataChangedIn == true) + { + dataChanged(); + } + } +} void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) { From 7e88b811260c24dfba086f5cb5fb31438567f04e Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:44:10 +0200 Subject: [PATCH 036/184] VectorGraph_clamps_changed --- src/gui/widgets/VectorGraph.cpp | 80 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index f4a51a7d609..7280bb87094 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -201,6 +201,7 @@ void VectorGraphView::useGetLastValues() void VectorGraphView::mousePressEvent(QMouseEvent* me) { + qDebug("\n\nmousePressStart ---------"); // get position int x = me->x(); int y = me->y(); @@ -258,7 +259,6 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) } m_mouseDown = true; - qDebug("mousePressEnd ---------"); } void VectorGraphView::mouseMoveEvent(QMouseEvent* me) @@ -298,15 +298,15 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) if (m_isCurveSelected == false) { std::pair convertedCoords = mapMousePos(x, m_graphHeight - y); - convertedCoords.first = convertedCoords.first > 1.0f ? 1.0f : convertedCoords.first < 0.0f ? 1.0f : convertedCoords.first; - convertedCoords.second = convertedCoords.second > 1.0f ? 1.0f : convertedCoords.second < -1.0f ? -1.0f : convertedCoords.second; + convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); + convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); setSelectedData(convertedCoords); } else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; - curveValue = curveValue > 1.0f ? 1.0f : curveValue < -1.0f ? -1.0f : curveValue; + curveValue = std::clamp(curveValue, -1.0f, 1.0f); model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); } } @@ -392,7 +392,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) // get the first editable daraArray and add value qDebug("release size: %ld", model()->getDataArraySize()); bool success = false; - if (m_isLastSelectedArray == true && m_isSelected == true) + if (m_isLastSelectedArray == true) { // trying to add to the last selected array success = addPoint(m_selectedArray, x, m_graphHeight - y); @@ -1123,12 +1123,12 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f qDebug("setInputAttribValue started"); if (m_isSelected == true) { - float clampedValue = floatValueIn < -1.0f ? -1.0f : floatValueIn > 1.0f ? 1.0f : floatValueIn; + float clampedValue = std::clamp(floatValueIn, -1.0f, 1.0f); unsigned int clampedValueB = 0; switch (controlArrayLocationIn) { case 0: - m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, clampedValue < 0.0f ? 0.0f : clampedValue); + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); break; case 1: model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); @@ -1155,7 +1155,7 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 5.0f ? 5.0f : floatValueIn)); + clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 5.0f)); } model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); break; @@ -1172,7 +1172,7 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 4.0f ? 4.0f : floatValueIn)); + clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 4.0f)); } model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); break; @@ -1189,7 +1189,7 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast((floatValueIn < 0.0f ? 0.0f : floatValueIn > 4.0f ? 4.0f : floatValueIn)); + clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 4.0f)); } model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); break; @@ -1340,7 +1340,6 @@ std::pair VectorGraphView::showCoordInputDialog() if (m_isSelected == true) { curData = getSelectedData(); - double minValue = model()->getDataArray(m_selectedArray)->getNonNegative() == true ? 0.0 : -100.0; // show position input dialog bool ok; @@ -1354,9 +1353,9 @@ std::pair VectorGraphView::showCoordInputDialog() } double changedY = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between ") + QString::number(minValue) + tr(" and 100"), + tr("Please enter a new value between -100 and 100"), static_cast(curData.second * 100.0f), - minValue, 100.0, 2, &ok); + -100.0, 100.0, 2, &ok); if (ok == true) { curData.second = static_cast(changedY) / 100.0f; @@ -2238,14 +2237,6 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is } //qDebug("getNearestLocation, outputDif: %d", outputDif); *foundOut = false; - //if (mid + 1 < m_dataArray.size()) - //{ - //bool isBeforeOutB = xIn < m_dataArray[mid].m_x ? true : m_dataArray[mid + 1].m_x < xIn; - // if (isBeforeOutB != *isBeforeOut) - // { - // qDebug("getNearestLocation, BEFOREBUG xIn: %f", xIn); - //} - //} *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } @@ -2443,7 +2434,6 @@ void VectorGraphDataArray::setDataArray(std::vector>* da void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) { - // TODO test std::vector> convertedDataArray(dataArrayIn->size()); float stepSize = 1.0f / static_cast(convertedDataArray.size()); for (unsigned int i = 0; i < dataArrayIn->size(); i++) @@ -2566,7 +2556,7 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned { if (m_isAutomatableEffectable == true) { - // only 4 attributes can be automated (y, c, valA, valB) + // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set automated location correctly (effected_location = automatedEffectedLocation % 4) m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); @@ -2583,7 +2573,7 @@ void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned i { if (m_isAutomatableEffectable == true) { - // only 4 attributes can be effected (y, c, valA, valB) + // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; // set effected location correctly m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); @@ -2856,21 +2846,18 @@ float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn { float absCurveIn = std::abs(curveIn); float pow = curveIn < 0.0f ? 1.0f - xIn : xIn; - // float xVal = curveIn > 0.0f ? xIn + (1.0f - xIn) * absCurveIn : xIn * (1.0f - absCurveIn); - // float xVal = curveIn > 0.0f ? 1.0 - xIn : xIn; pow = std::pow(pow, 1.0f - absCurveIn) - pow; - //float output = valueBeforeIn + (valueAfterIn - valueBeforeIn) * xVal + log * (valueAfterIn - valueBeforeIn); - float output = valueBeforeIn + (valueAfterIn - valueBeforeIn) * xIn; output = curveIn > 0.0f ? output + pow * (valueAfterIn - valueBeforeIn) : output - pow * (valueAfterIn - valueBeforeIn); + // clamp if (valueBeforeIn > valueAfterIn) { - output = output < valueAfterIn ? valueAfterIn : output > valueBeforeIn ? valueBeforeIn : output; + output = std::clamp(output, valueAfterIn, valueBeforeIn); } else { - output = output < valueBeforeIn ? valueBeforeIn : output > valueAfterIn ? valueAfterIn : output; + output = std::clamp(output, valueBeforeIn, valueAfterIn); } return output; } @@ -2933,7 +2920,7 @@ float VectorGraphDataArray::processEffect(float attribValueIn, unsigned int attr } // clamp - output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; + output = std::clamp(output, -1.0f, 1.0f); } return output; } @@ -2953,7 +2940,7 @@ float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int } output += attribValueIn; - output = output < -1.0f ? -1.0f : output > 1.0f ? 1.0f : output; + output = std::clamp(output, -1.0f, 1.0f); return output; } @@ -3261,8 +3248,8 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr m_dataArray.size() - 1 ? - m_dataArray.size() - 1 : locationBefore; + locationBefore = locationBefore < 0 ? 0 : + m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; // *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); @@ -3287,8 +3274,8 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr m_dataArray.size() - 1 ? - m_dataArray.size() - 1 : locationAfter; + locationAfter = locationAfter < 0 ? 0 : + m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; qDebug("getUpdatingFromEffector start: %d, end: %d", locationBefore, locationAfter); // adding the values between locationBefore, locationAfter @@ -3408,7 +3395,7 @@ void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, { bool found = false; bool isBefore = false; - int curLocation = effectorIn->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + int curLocation = effectorIn->getNearestLocation(m_dataArray[m_needsUpdating[i]].m_x, &found, &isBefore); if (curLocation >= 0) { curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; @@ -3429,12 +3416,14 @@ qDebug("getValuesC5"); // getting the missing next location values for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { + // if there is a gap in m_needsUpdating + // (next needsUpdating point is not the point after this one in m_dataArray) if (i + 1 < m_needsUpdating.size() && m_needsUpdating[i] + 1 < m_dataArray.size() && m_needsUpdating[i + 1] != m_needsUpdating[i] + 1) { bool found = false; bool isBefore = false; - int curLocation = effectorIn->getNearestLocation(getX(m_needsUpdating[i]), &found, &isBefore); + int curLocation = effectorIn->getNearestLocation(m_dataArray[m_needsUpdating[i] + 1].m_x, &found, &isBefore); if (curLocation >= 0) { curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; @@ -3444,6 +3433,11 @@ qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); } } } + // getting the last updated point's next location value + if (m_needsUpdating[m_needsUpdating.size() - 1] + 1 >= m_dataArray.size()) + { + effectorDataOut->operator[](m_needsUpdating.size() - 1).second = effectorIn->size() - 1; + } } } void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, @@ -3482,7 +3476,11 @@ qDebug("getValuesD7"); end = effectYLocation; nextY = processAutomation(m_dataArray[m_needsUpdating[iIn] + 1].m_y, m_needsUpdating[iIn] + 1, 0); - if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).second) == true) + // if the effector point effecting the current point can only effect points (and not lines) + // and the effector point effecting the next point can only effect points + // this is done to avoid adding effectorOutputIn to the line and to the next point (line's end point) at the same time + if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == true && + effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).second) == true) { nextEffectY = effectorOutputIn->operator[](effectYLocation); nextY = processEffect(nextY, 0, nextEffectY, effectorIn, effectorDataIn->operator[](iIn).second); @@ -3591,9 +3589,11 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f } if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == false) { + int startB = iIn == 0 ? 0 : start; + int endB = iIn >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; // process line effect // if it is enabled - for (int j = start; j < end; j++) + for (int j = startB; j < endB; j++) { m_bakedValues[j] = processEffect(m_bakedValues[j], 0, effectorOutputIn->operator[](j), effectorIn, effectorDataIn->operator[](iIn).first); } From a9c28bde79714c9ec2744daed7a865a1aed2c8d4 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 3 Apr 2024 19:37:32 +0200 Subject: [PATCH 037/184] VectorGraph_saving_implementation --- include/VectorGraph.h | 26 +++- plugins/FFTFilter/FFTFilterControls.cpp | 6 + src/gui/widgets/VectorGraph.cpp | 165 ++++++++++++++++++++++++ 3 files changed, 192 insertions(+), 5 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 4983c7d6d0f..dccf4c4d3a0 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -35,6 +35,7 @@ #include "ModelView.h" #include "lmms_basics.h" #include "AutomatableModel.h" +#include "JournallingObject.h" namespace lmms { @@ -240,7 +241,7 @@ protected slots: } // namespace gui -class LMMS_EXPORT VectorGraphModel : public Model//, public JournallingObject +class LMMS_EXPORT VectorGraphModel : public Model, public JournallingObject { Q_OBJECT public: @@ -285,8 +286,16 @@ Q_OBJECT int getDataArrayNewId(); // save, load - //void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO - //void loadSettings(const QDomElement& element, const QString& name); //TODO + QString nodeName() const override + { + return "VectorGraphModel"; + } + //virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO + //virtual void loadSettings(const QDomElement& element, const QString& name); //TODO + virtual void saveSettings(QDomDocument& doc, QDomElement& element); + virtual void loadSettings(const QDomElement& element); + // read locations from saved data attributes + //int readLoc(unsigned int startIn, QString dataIn); signals: // data changed inside m_dataArray or m_maxLength changed void dataChanged(); @@ -428,8 +437,7 @@ class LMMS_EXPORT VectorGraphDataArray // foundOut is true when the nearest position = posIn, // reurns -1 when search failed int getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut); - // get changed locations - // std::vector getUpdatingValues(); + // returns the latest updated graph values // countIn is the retuned vector's size @@ -478,6 +486,11 @@ class LMMS_EXPORT VectorGraphDataArray void clearedEvent(); // color void styleChanged(); +protected: + // returns m_automationModelArray + std::vector* getAutomationModelArray(); + QString getSavedDataArray(); + void loadDataArray(QString dataIn, unsigned int sizeIn); private: class VectorGraphPoint { @@ -695,6 +708,9 @@ class LMMS_EXPORT VectorGraphDataArray // this stores all the FloatModels // used for automation std::vector m_automationModelArray; + + // used for saving + friend class lmms::VectorGraphModel; }; } // namespace lmms diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 0f695e5f35d..372994086db 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -46,6 +46,7 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_graphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_graphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); + m_graphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); @@ -73,6 +74,9 @@ void FFTFilterControls::loadSettings(const QDomElement& parent) m_effectControlModel.loadSettings(parent, "effectcontrol"); m_bufferModel.loadSettings(parent, "buffer"); m_displayFFTModel.loadSettings(parent, "display"); + + + m_graphModel.loadSettings(parent); } @@ -83,6 +87,8 @@ void FFTFilterControls::saveSettings(QDomDocument& doc, QDomElement& parent) m_effectControlModel.saveSettings(doc, parent, "effectcontrol"); m_bufferModel.saveSettings(doc, parent, "buffer"); m_displayFFTModel.saveSettings(doc, parent, "display"); + + m_graphModel.saveSettings(doc, parent); } void FFTFilterControls::resetClicked() diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 7280bb87094..d3bd96e3fef 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -44,6 +44,9 @@ #include "AutomatableModel.h" #include "ControllerConnectionDialog.h" #include "ControllerConnection.h" +#include "ProjectJournal.h" +#include "JournallingObject.h" +#include "base64.h" namespace lmms @@ -1696,6 +1699,130 @@ int VectorGraphModel::getDataArrayNewId() maxId++; return maxId; } +//void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) +void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) +{ + qDebug("saveSettings"); + + //bool mustQuote = mustQuoteName(name); + //QDomElement me = doc.createElement(QString("VectorGraphModel") : name ); + QDomElement me = doc.createElement(QString("VectorGraphModel")); + me.setAttribute("DataArrayCount", static_cast(m_dataArrays.size())); + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + // getting rid of nullptr FloatMdoels + // (there should be 0) + for (unsigned int j = 0; j < m_dataArrays[i].size(); j++) + { + if (m_dataArrays[i].getAutomationModel(j) == nullptr) + { + m_dataArrays[i].setAutomated(j, false); + } + } + + QString readLocation = "a" + QString::number(i) + "-"; + std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); + bool isSaveable = m_dataArrays[i].getIsSaveable(); + me.setAttribute(readLocation + "DataArraySize", isSaveable == true ? static_cast(m_dataArrays[i].size()) : 0); + me.setAttribute(readLocation + "AutomationSize", isSaveable == true ? static_cast(automationModels->size()) : 0); + + if (isSaveable == true && m_dataArrays[i].size() > 0) + { + // saving the DataArray + me.setAttribute(readLocation + "DataArray", m_dataArrays[i].getSavedDataArray()); + + // saving the FloatModels + for (unsigned int j = 0; j < automationModels->size(); j++) + { + QString readLocationB = QString::number(j) + "-"; + automationModels->operator[](j)->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); + } + } + } + element.appendChild(me); + + //me.setAttribute("id", ProjectJournal::idToSave( id() ) ); + //me.setAttribute("value", m_value ); + //me.setAttribute( "scale_type", m_scaleType == ScaleType::Logarithmic ? "log" : "linear" ); + + //QString sampleString; + //base64::encode( (const char *)m_wavegraphModel.samples(), + //m_wavegraphModel.length() * sizeof(float), sampleString ); + //_this.setAttribute( "waveShape", sampleString ); + +} +//void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) +void VectorGraphModel::loadSettings(const QDomElement& element) +{ + QDomNode node = element.namedItem("VectorGraphModel"); + qDebug("loadSettings"); + /* + if (node.hasAttributes("DataArrayCount") == true) + { + qDebug("loadSettings 2"); + unsigned int loadSize = node.attributes("DataArrayCount").toInt(); + for (unsigned int i = 0; i < loadSize; i++) + { + qDebug("loadSettings 3"); + QString readLocation = "a" + QString::number(i) + "-"; + if (i < m_dataArrays.size() && node.hasAttribute(readLocation + "DataArraySize") == true) + { + unsigned int dataArraySize = node.attributes(readLocation + "DataArraySize").toInt(); + unsigned int automationSize = node.attributes(readLocation + "AutomationSize").toInt(); + // load m_dataArray + if (dataArraySize > 0) + { + qDebug("loadSettings 4"); + m_dataArrays[i].loadDataArray(node.attributes(readLocation + "DataArray"), dataArraySize); + } + + // load automationModelDataArray + std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); + for (unsigned int j = 0; j < automationSize; j++) + { + qDebug("loadSettings 5"); + QString readLocationB = QString::number(j) + "-"; + FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, this, QString(), false); + curModel->loadSettings(element, readLocation + readLocationB + "AutomationModel"); + automationModels->push_back(curModel); + } + } + else + { + break; + } + } + */ + /* + if( nodeElement.hasAttribute( "scale_type" ) ) + { + if( nodeElement.attribute( "scale_type" ) == "linear" ) + { + setScaleType( ScaleType::Linear ); + } + else if( nodeElement.attribute( "scale_type" ) == "log" ) + { + setScaleType( ScaleType::Logarithmic ); + } + } + */ + //} +} +/* +int VectorGraphModel::readLoc(unsigned int startIn, QString dataIn) +{ + int output = -1; + for (unsigned int i = startIn; i < dataIn.size(); i++) + { + if (dataIn[i] == QString("-")) + { + output = dataIn.left(i - 1).toInt(); + break; + } + } + return output; +} +*/ // VectorGraphDataArray ------ @@ -2749,6 +2876,44 @@ FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int locationIn) } return nullptr; } + +// protected: +std::vector* VectorGraphDataArray::getAutomationModelArray() +{ + return &m_automationModelArray; +} +QString VectorGraphDataArray::getSavedDataArray() +{ + QString output; + base64::encode((const char *)(&m_dataArray), + m_dataArray.size() * sizeof(VectorGraphPoint), output); + return output; +} +void VectorGraphDataArray::loadDataArray(QString dataIn, unsigned int sizeIn) +{ + qDebug("loadDatatArray start"); +//qDebug().nospace() << "loadDataArray: " << qPrintable(dataIn) << " end"; + int size = 0; + char* dst = 0; + base64::decode(dataIn, &dst, &size); + + size = size > sizeIn ? sizeIn : size; + m_dataArray.resize(size); + + VectorGraphPoint* points = (VectorGraphPoint*)dst; + std::copy(points, points + size, m_dataArray.begin()); + /* + for (unsigned int i = 0; i < size; i++) + { + m_dataArray[i] = ((VectorGraphPoint*)dst)[i]; + } + */ + + delete[] dst; + qDebug("loadDatatArray end"); +} + +// private: void VectorGraphDataArray::delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn) { if (modelLocationIn != -1) From 2520044b4e57ca3216c89d6229c08ebec7a1a399 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:20:28 +0200 Subject: [PATCH 038/184] VectorGraph_loading_implemented --- src/gui/widgets/VectorGraph.cpp | 64 +++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d3bd96e3fef..8e506f21ad7 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1734,6 +1734,7 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) // saving the FloatModels for (unsigned int j = 0; j < automationModels->size(); j++) { + qDebug("saveSettings saved automatinModel %d, %d", i, j); QString readLocationB = QString::number(j) + "-"; automationModels->operator[](j)->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); } @@ -1755,25 +1756,47 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) void VectorGraphModel::loadSettings(const QDomElement& element) { QDomNode node = element.namedItem("VectorGraphModel"); - qDebug("loadSettings"); + /* - if (node.hasAttributes("DataArrayCount") == true) + if(node.isNull() || + node.isElement() && + node.toElement().hasAttribute("VectorGraphModel") && + node.toElement().attribute("VectorGraphModel") != name) + { + for(QDomElement othernode = element.firstChildElement(); + !othernode.isNull(); + othernode = othernode.nextSiblingElement()) + { + if((!othernode.hasAttribute("VectorGraphModel") && + othernode.nodeName() == name) || + othernode.attribute("VectorGraphModel") == name) + { + node = othernode; + break; + } + } + } + */ + + QDomElement curElement = node.toElement(); + qDebug("loadSettings"); + if (curElement.hasAttribute("DataArrayCount") == true) { qDebug("loadSettings 2"); - unsigned int loadSize = node.attributes("DataArrayCount").toInt(); + unsigned int loadSize = curElement.attribute("DataArrayCount").toInt(); for (unsigned int i = 0; i < loadSize; i++) { qDebug("loadSettings 3"); QString readLocation = "a" + QString::number(i) + "-"; - if (i < m_dataArrays.size() && node.hasAttribute(readLocation + "DataArraySize") == true) + if (i < m_dataArrays.size() && curElement.hasAttribute(readLocation + "DataArraySize") == true) { - unsigned int dataArraySize = node.attributes(readLocation + "DataArraySize").toInt(); - unsigned int automationSize = node.attributes(readLocation + "AutomationSize").toInt(); + unsigned int dataArraySize = curElement.attribute(readLocation + "DataArraySize").toInt(); + unsigned int automationSize = curElement.attribute(readLocation + "AutomationSize").toInt(); // load m_dataArray if (dataArraySize > 0) { qDebug("loadSettings 4"); - m_dataArrays[i].loadDataArray(node.attributes(readLocation + "DataArray"), dataArraySize); + m_dataArrays[i].loadDataArray(curElement.attribute(readLocation + "DataArray"), dataArraySize); } // load automationModelDataArray @@ -1783,8 +1806,9 @@ void VectorGraphModel::loadSettings(const QDomElement& element) qDebug("loadSettings 5"); QString readLocationB = QString::number(j) + "-"; FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, this, QString(), false); - curModel->loadSettings(element, readLocation + readLocationB + "AutomationModel"); + curModel->loadSettings(curElement, readLocation + readLocationB + "AutomationModel"); automationModels->push_back(curModel); + qDebug("loaded automatinModel %d, %d, size: %ld", i, j, automationModels->size()); } } else @@ -1792,7 +1816,6 @@ void VectorGraphModel::loadSettings(const QDomElement& element) break; } } - */ /* if( nodeElement.hasAttribute( "scale_type" ) ) { @@ -1806,7 +1829,7 @@ void VectorGraphModel::loadSettings(const QDomElement& element) } } */ - //} + } } /* int VectorGraphModel::readLoc(unsigned int startIn, QString dataIn) @@ -2390,7 +2413,6 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i std::shared_ptr> effectorUpdatingValues = std::make_shared>(); std::vector effectorOutput; std::vector outputXLocations(countIn); - //m_isDataChanged = true; // TODO DEBUG, delete this line bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { @@ -2885,29 +2907,27 @@ std::vector* VectorGraphDataArray::getAutomationModelArray() QString VectorGraphDataArray::getSavedDataArray() { QString output; - base64::encode((const char *)(&m_dataArray), + base64::encode((const char *)(m_dataArray.data()), m_dataArray.size() * sizeof(VectorGraphPoint), output); return output; } void VectorGraphDataArray::loadDataArray(QString dataIn, unsigned int sizeIn) { qDebug("loadDatatArray start"); -//qDebug().nospace() << "loadDataArray: " << qPrintable(dataIn) << " end"; int size = 0; char* dst = 0; base64::decode(dataIn, &dst, &size); - size = size > sizeIn ? sizeIn : size; - m_dataArray.resize(size); - - VectorGraphPoint* points = (VectorGraphPoint*)dst; - std::copy(points, points + size, m_dataArray.begin()); - /* - for (unsigned int i = 0; i < size; i++) + if (size == sizeIn * sizeof(VectorGraphPoint)) { - m_dataArray[i] = ((VectorGraphPoint*)dst)[i]; + m_dataArray.resize(sizeIn); + + VectorGraphPoint* points = (VectorGraphPoint*)dst; + for (unsigned int i = 0; i < sizeIn; i++) + { + m_dataArray[i] = points[i]; + } } - */ delete[] dst; qDebug("loadDatatArray end"); From 784f3bf7d6229b23d4cbb195a775b61d0932451e Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:50:08 +0200 Subject: [PATCH 039/184] VectorGraph_added_saving_custom_name_support --- include/VectorGraph.h | 4 ++-- src/gui/widgets/VectorGraph.cpp | 42 +++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index dccf4c4d3a0..f5303426482 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -290,8 +290,8 @@ Q_OBJECT { return "VectorGraphModel"; } - //virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO - //virtual void loadSettings(const QDomElement& element, const QString& name); //TODO + virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO + virtual void loadSettings(const QDomElement& element, const QString& name); //TODO virtual void saveSettings(QDomDocument& doc, QDomElement& element); virtual void loadSettings(const QDomElement& element); // read locations from saved data attributes diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 8e506f21ad7..2ab61764c4d 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1699,14 +1699,19 @@ int VectorGraphModel::getDataArrayNewId() maxId++; return maxId; } -//void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) -void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) +void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) { qDebug("saveSettings"); //bool mustQuote = mustQuoteName(name); //QDomElement me = doc.createElement(QString("VectorGraphModel") : name ); - QDomElement me = doc.createElement(QString("VectorGraphModel")); + QString saveName("VectorGraphModel"); + if (name.size() > 0) + { + saveName = name; + } + + QDomElement me = doc.createElement(saveName); me.setAttribute("DataArrayCount", static_cast(m_dataArrays.size())); for (unsigned int i = 0; i < m_dataArrays.size(); i++) { @@ -1752,31 +1757,30 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) //_this.setAttribute( "waveShape", sampleString ); } -//void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) -void VectorGraphModel::loadSettings(const QDomElement& element) +void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) { - QDomNode node = element.namedItem("VectorGraphModel"); + QString loadName("VectorGraphModel"); + if (name.size() > 0) + { + loadName = name; + } - /* - if(node.isNull() || - node.isElement() && - node.toElement().hasAttribute("VectorGraphModel") && - node.toElement().attribute("VectorGraphModel") != name) + QDomNode node = element.namedItem(loadName); + + if(node.isNull() == true) { for(QDomElement othernode = element.firstChildElement(); !othernode.isNull(); othernode = othernode.nextSiblingElement()) { - if((!othernode.hasAttribute("VectorGraphModel") && - othernode.nodeName() == name) || - othernode.attribute("VectorGraphModel") == name) + if((!othernode.hasAttribute("DataArrayCount") && + othernode.nodeName() == loadName)) { node = othernode; break; } } } - */ QDomElement curElement = node.toElement(); qDebug("loadSettings"); @@ -1831,6 +1835,14 @@ void VectorGraphModel::loadSettings(const QDomElement& element) */ } } +void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) +{ + saveSettings(doc, element, QString("")); +} +void VectorGraphModel::loadSettings(const QDomElement& element) +{ + loadSettings(element, QString("")); +} /* int VectorGraphModel::readLoc(unsigned int startIn, QString dataIn) { From 9e5f804b7cf0e170f8d23b41ee7025f95e47fc0e Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:20:10 +0200 Subject: [PATCH 040/184] VectorGraph_PaintEvent_optimized --- include/VectorGraph.h | 11 ++--- src/gui/widgets/VectorGraph.cpp | 75 +++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f5303426482..f7c56b8c2dd 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -144,7 +144,7 @@ protected slots: void removeAutomation(); void removeController(); private: - void paintGraph(QPainter* pIn, unsigned int locationIn); + void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* alreadyUpdatedDataArraysIn); void paintEditing(QPainter* pIn); void modelChanged() override; @@ -290,8 +290,8 @@ Q_OBJECT { return "VectorGraphModel"; } - virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); //TODO - virtual void loadSettings(const QDomElement& element, const QString& name); //TODO + virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); + virtual void loadSettings(const QDomElement& element, const QString& name); virtual void saveSettings(QDomDocument& doc, QDomElement& element); virtual void loadSettings(const QDomElement& element); // read locations from saved data attributes @@ -446,6 +446,7 @@ class LMMS_EXPORT VectorGraphDataArray std::vector getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut); // returns m_bakedValues without updating std::vector getLastValues(); + std::vector getEffectorArrayLocations(); // set: ------------------- @@ -506,7 +507,7 @@ class LMMS_EXPORT VectorGraphDataArray m_automatedEffectedAttribLocations = 0; m_effectOnlyPoints = false; - m_effectAdd = true; + m_effectAdd = false; m_effectSubtract = false; m_effectMultiply = false; m_effectDivide = false; @@ -530,7 +531,7 @@ class LMMS_EXPORT VectorGraphDataArray m_automatedEffectedAttribLocations = 0; m_effectOnlyPoints = false; - m_effectAdd = true; + m_effectAdd = false; m_effectSubtract = false; m_effectMultiply = false; m_effectDivide = false; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 2ab61764c4d..1c4033a6515 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -532,10 +532,11 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) p.drawLine(0, height() - 1, width() - 1, height() - 1); p.drawLine(0, 0, 0, height() - 1); + std::vector alreadyUpdatedDataArrays; for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - paintGraph(&p, i); + paintGraph(&p, i, &alreadyUpdatedDataArrays); } paintEditing(&p); @@ -545,7 +546,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) emit drawn(); } -void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) +void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* alreadyUpdatedDataArraysIn) { VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); unsigned int length = dataArray->size(); @@ -554,7 +555,6 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) pIn->setPen(QPen(*dataArray->getLineColor(), 2)); pIn->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); - std::pair posA(0, 0); std::pair posB(0, 0); std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), dataArray->getNonNegative())); @@ -572,7 +572,31 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn) } else { - dataArrayValues = dataArray->getValues(width()); + // getting most updated dataArray values + // if this dataArray has not been updated by + // an other dataArray while paintEvent is happening + bool found = false; + for (unsigned int j = 0; j < alreadyUpdatedDataArraysIn->size(); j++) + { + if (locationIn == alreadyUpdatedDataArraysIn->operator[](j)) + { + found = true; + break; + } + } + if (found == false) + { + dataArrayValues = dataArray->getValues(width()); + std::vector updatedArrays = dataArray->getEffectorArrayLocations(); + for (unsigned int j = 0; j < updatedArrays.size(); j++) + { + alreadyUpdatedDataArraysIn->push_back(updatedArrays[j]); + } + } + else + { + dataArrayValues = dataArray->getLastValues(); + } } qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); @@ -1746,16 +1770,6 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con } } element.appendChild(me); - - //me.setAttribute("id", ProjectJournal::idToSave( id() ) ); - //me.setAttribute("value", m_value ); - //me.setAttribute( "scale_type", m_scaleType == ScaleType::Logarithmic ? "log" : "linear" ); - - //QString sampleString; - //base64::encode( (const char *)m_wavegraphModel.samples(), - //m_wavegraphModel.length() * sizeof(float), sampleString ); - //_this.setAttribute( "waveShape", sampleString ); - } void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) { @@ -1820,19 +1834,6 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n break; } } - /* - if( nodeElement.hasAttribute( "scale_type" ) ) - { - if( nodeElement.attribute( "scale_type" ) == "linear" ) - { - setScaleType( ScaleType::Linear ); - } - else if( nodeElement.attribute( "scale_type" ) == "log" ) - { - setScaleType( ScaleType::Logarithmic ); - } - } - */ } } void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) @@ -2535,6 +2536,24 @@ std::vector VectorGraphDataArray::getLastValues() { return m_bakedValues; } +std::vector VectorGraphDataArray::getEffectorArrayLocations() +{ + std::vector output; + int currentLocation = m_effectorLocation; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + if (currentLocation == -1) + { + break; + } + else + { + output.push_back(m_effectorLocation); + currentLocation = m_parent->getDataArray(currentLocation)->getEffectorArrayLocation(); + } + } + return output; +} void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) @@ -3387,10 +3406,12 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr> updatingValuesIn) { // Debug testing + /* for (unsigned int i = 0; i < updatingValuesIn->size(); i++) { qDebug("getUpdatingFromEffector #1: [%d] -> %d", i, updatingValuesIn->operator[](i)); } + */ VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); for (unsigned int i = 0; i < updatingValuesIn->size(); i++) { From 0bed2a35b702b74d1e7334348133cf486876d21b Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 4 Apr 2024 21:53:04 +0200 Subject: [PATCH 041/184] FFTFilter_Processor_FFT_outputing_fixed --- include/VectorGraph.h | 3 ++- plugins/FFTFilter/FFTProcessor.cpp | 36 ++++++++++++++++++++---------- plugins/FFTFilter/FFTProcessor.h | 4 ++-- src/gui/widgets/VectorGraph.cpp | 13 ++++++++++- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f7c56b8c2dd..6050a9f3881 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -25,11 +25,12 @@ #ifndef LMMS_GUI_VECTORGRAPH_H #define LMMS_GUI_VECTORGRAPH_H +#include // smartpointers +#include #include #include #include #include -#include #include "Model.h" #include "ModelView.h" diff --git a/plugins/FFTFilter/FFTProcessor.cpp b/plugins/FFTFilter/FFTProcessor.cpp index 117c0306509..57fcedf242b 100644 --- a/plugins/FFTFilter/FFTProcessor.cpp +++ b/plugins/FFTFilter/FFTProcessor.cpp @@ -26,8 +26,8 @@ FFTProcessor::FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWind m_terminate = true; m_frameFillLoc = 0; - m_samplesIn.resize(outputSize()); - m_normSpectrum.resize(outputSize()); + m_samplesIn.resize(m_blockSize); + m_normSpectrum.resize(outputSize(m_blockSize)); m_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); @@ -95,7 +95,7 @@ void FFTProcessor::threadedStartThread(LocklessRingBuffer* ringBuff qDebug("analyze threaded thread init"); m_terminate = false; unsigned int blockSize = m_blockSize; - m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, m_out, &m_outputSpectrumChanged, &m_outputSamplesChanged, + m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, m_out, &m_samplesIn, &m_outputSpectrumChanged, &m_outputSamplesChanged, ringBufferIn, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); qDebug("analyze threaded thread running"); } @@ -122,13 +122,14 @@ bool FFTProcessor::getOutputSamplesChanged() } -void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, +void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::vector* samplesIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, std::vector* spectrumOut, std::mutex* outputAccessIn) { LocklessRingBufferReader reader(*ringBufferIn); - std::vector samples(blockSizeIn); + //std::vector samples(blockSizeIn); + std::vector absSpectrum(blockSizeIn); std::vector outputSpectrum(blockSizeIn); fpp_t frameFillLoc = 0; @@ -140,7 +141,7 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p reader.waitForData(); } - auto bufferIn = reader.read_max(ringBufferIn->capacity() / 4); + auto bufferIn = reader.read_max(ringBufferIn->capacity()); size_t frameCount = bufferIn.size(); fpp_t frameIn = 0; @@ -151,7 +152,7 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p while (frameIn < frameCount && frameFillLoc < blockSizeIn) { //qDebug("analyzeB 2"); - samples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + samplesIn->operator[](frameFillLoc) = bufferIn[frameIn][sampLocIn]; frameIn++; frameFillLoc++; } @@ -175,11 +176,22 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p fftwf_execute(*planIn); - absspec(complexIn, outputSpectrum.data(), (blockSizeIn / 2 + 1)); - normalize(outputSpectrum, outputSpectrum, blockSizeIn); + + absspec(complexIn, absSpectrum.data(), outputSize(blockSizeIn)); + normalize(absSpectrum, outputSpectrum, blockSizeIn); + + /* + for (unsigned int i = 0; i < blockSizeIn; i++) + { + qDebug("[%d] %f, %f, %f, - %f, %f", i, complexIn[i][0], complexIn[i][1], samplesIn->operator[](i), absSpectrum[i], outputSpectrum[i]); + } + */ outputAccessIn->lock(); - *spectrumOut = outputSpectrum; + for (unsigned int i = 0; i < outputSize(blockSizeIn); i++) + { + spectrumOut->operator[](i) = outputSpectrum[i]; + } outputAccessIn->unlock(); *spectrumChangedOut = true; } @@ -211,9 +223,9 @@ void FFTProcessor::rebuildWindow(FFTWindow FFTWindowIn) // TODO multithread -unsigned int FFTProcessor::outputSize() +unsigned int FFTProcessor::outputSize(unsigned int blockSizeIn) { - return m_blockSize / 2 + 1; + return blockSizeIn / 2 + 1; } } // namespace lmms diff --git a/plugins/FFTFilter/FFTProcessor.h b/plugins/FFTFilter/FFTProcessor.h index 32f2947cb62..b59985e7441 100644 --- a/plugins/FFTFilter/FFTProcessor.h +++ b/plugins/FFTFilter/FFTProcessor.h @@ -66,11 +66,11 @@ class FFTProcessor void rebuildWindow(FFTWindow FFTWindowIn); - unsigned int outputSize(); + static unsigned int outputSize(unsigned int blockSizeIn); private: - static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::vector* samplesIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, std::vector* spectrumOut, std::mutex* outputAccessIn); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1c4033a6515..8a8204f283a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3015,10 +3015,12 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB qDebug("swap: -------"); qDebug("first.: %d, second.: %d", locationAIn, locationBIn); + /* for (unsigned int i = 0; i < m_dataArray.size(); i++) { qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } + */ if (locationAIn < locationBIn) { @@ -3039,11 +3041,13 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB m_dataArray[locationBIn] = swap; } + /* qDebug(" --------- "); for (unsigned int i = 0; i < m_dataArray.size(); i++) { qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } + */ } else { @@ -3209,7 +3213,14 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector(std::floor(count / (valB * 100.0f))); //qDebug("sineB_1, %f, %d", (count / (valB * 100.0f)), end); - end = end > count ? count : end + 1; + if (count <= 0) + { + end = 0; + } + else + { + end = end > count ? count : end + 1; + } // calculate 1 wave of sine for (unsigned int i = 0; i < end; i++) From 7f5ac8bad7aeb222b37e7f29c2463a27c50005a5 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 4 Apr 2024 21:54:07 +0200 Subject: [PATCH 042/184] FFTFilter_graph_input_reworked --- plugins/FFTFilter/FFTFilter.cpp | 82 ++++++++++++++++++++++--- plugins/FFTFilter/FFTFilter.h | 36 ++++------- plugins/FFTFilter/FFTFilterControls.cpp | 6 +- plugins/FFTFilter/FFTFilterControls.h | 2 +- 4 files changed, 88 insertions(+), 38 deletions(-) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index 24ed7d33a98..1fd571985a7 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -30,6 +30,7 @@ #include "embed.h" #include "plugin_export.h" #include "fft_helpers.h" +#include "lmms_constants.h" namespace lmms { @@ -57,9 +58,13 @@ FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatu Effect(&FFTFilter_plugin_descriptor, parent, key), m_filterControls(this), m_FFTProcessor(2048, true, FFTWindow::Rectangular), - m_inputBuffer(4 * 2048) + m_inputBuffer(2048) { m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); + + //std::vector graphXArray; + //m_sampleRate; + updateSampleRate(); } FFTFilterEffect::~FFTFilterEffect() { @@ -91,40 +96,58 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) if (m_FFTProcessor.getOutputSpectrumChanged() == true) { std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); - std::vector graphInput(20); + + std::vector> graphInput(80); + if (graphInput.size() != graphXArray.size()) + { + updateGraphXArray(graphInput.size()); + } + float avgY = 0; - int avgCount = FFTSpectrumOutput.size() / graphInput.size(); + int avgCount = 5;//FFTSpectrumOutput.size() / graphInput.size(); if (avgCount <= 0) { avgCount = 1; } + int avgSum = 0; int j = 0; for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) { - avgY = FFTSpectrumOutput[i]; - if (i + 1 > (j + 1) * avgCount) + avgY = avgY + FFTSpectrumOutput[i]; + if (i + 1 > avgSum + avgCount) { - graphInput[j] = avgY; + graphInput[j].second = avgY / static_cast(avgCount); j++; if (j >= graphInput.size()) { break; } avgY = 0; + avgSum = avgSum + avgCount; + avgCount = static_cast(avgCount * 1.4f); } } + // log_10(100) = 2 -> 10^2 = 100 for (unsigned int i = 0; i < graphInput.size(); i++) { - graphInput[i] = graphInput[i] / static_cast(avgCount); + graphInput[i].second = FFTSpectrumOutput[i]; + graphInput[i].first = graphXArray[i]; } // DEBUG + /* for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) { qDebug("FFTFilterEffect: [%d], %f", i, FFTSpectrumOutput[i]); } */ - //m_filterControls.setGraph(&graphInput); + + m_filterControls.setGraph(&graphInput); + + // bin to freq + //return getNyquistFreq() * bin_index / binCount(); + //return getSampleRate() / 2.0f; + //return (getSampleRate() / 2.0f) * x / binCount(); } //std::vector* output; //for (unsigned int i = 0; i < output->size(); i++) @@ -133,10 +156,10 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) //} //std::vector testVector = {0.0f, 0.3f, 0.5f, -0.5f, 0.2f}; //std::vector testVector = {0.0f, 1.3f, 0.5f, -2.5f, 0.2f}; - std::vector testVector = {0.0f, 0.1f, 0.5f, 0.7f, 0.5f, 0.2f, 0.1f, -1.0f, -0.1f, -0.1f, 0.2f}; + //std::vector testVector = {0.0f, 0.1f, 0.5f, 0.7f, 0.5f, 0.2f, 0.1f, -1.0f, -0.1f, -0.1f, 0.2f}; - m_filterControls.setGraph(&testVector); + //m_filterControls.setGraph(&testVector); /* const ValueBuffer* volumeBuf = m_filterControls.m_volumeModel.valueBuffer(); @@ -189,6 +212,45 @@ bool FFTFilterEffect::isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, c } return output; } +void FFTFilterEffect::updateBufferSize(unsigned int newBufferSizeIn) +{ + m_bufferSize = newBufferSizeIn; + // TODO +} + +void FFTFilterEffect::updateSampleRate() +{ + m_sampleRate = Engine::audioEngine()->processingSampleRate(); +} +void FFTFilterEffect::updateGraphXArray(unsigned int sizeIn) +{ + updateSampleRate(); + graphXArray.resize(sizeIn); + for (unsigned int i = 0; i < graphXArray.size(); i++) + { + graphXArray[i] = getTransformedX(i, graphXArray.size()); + qDebug("updateGraphXArray [%d] %f", i, graphXArray[i]); + } +} +float FFTFilterEffect::getTransformedX(unsigned int locationIn, unsigned int sizeIn) +{ + float freq = (m_sampleRate / 2.0f) * locationIn / sizeIn; + // bin to freq + //return getNyquistFreq() * bin_index / binCount(); + //return getSampleRate() / 2.0f; + //return (getSampleRate() / 2.0f) * x / binCount(); + + float min = std::log10(FRANGE_AUDIBLE_START); + float range = std::log10(FRANGE_AUDIBLE_END) - min; + freq = (log10(freq) - min) / range; + + /* + float min = FRANGE_AUDIBLE_START; + float range = FRANGE_AUDIBLE_END - min; + freq = (freq - min) / range; + */ + return freq > 0.0f ? freq : 0.0f; +} extern "C" { diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index ec765f9f435..0bd6cd89342 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -50,40 +50,28 @@ class FFTFilterEffect : public Effect private: bool isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, const float cutOffIn); - /* - inline sample_t getCurSample(unsigned int posIn) - { - if (m_useSecondBufferOut == true) - { - return m_bufferB[posIn]; - } - else - { - return m_bufferA[posIn]; - } - } - inline void setCurSample(unsigned int posIn, sample_t sampleIn) - { - if (m_useSecondBufferOut == true) - { - m_bufferA[posIn] = sampleIn; - } - else - { - m_bufferB[posIn] = sampleIn; - } - } -*/ + + void updateBufferSize(unsigned int newBufferSizeIn); + + void updateSampleRate(); + void updateGraphXArray(unsigned int sizeIn); + float getTransformedX(unsigned int locationIn, unsigned int sizeIn); + FFTFilterControls m_filterControls; FFTProcessor m_FFTProcessor; + //std::vector m_bufferA; //std::vector m_bufferB; //bool m_useSecondBufferOut; LocklessRingBuffer m_inputBuffer; + std::vector graphXArray; + unsigned int m_sampleRate; + + unsigned int m_bufferSize; friend class FFTFilterControls; }; diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 372994086db..4f06898c186 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -95,13 +95,13 @@ void FFTFilterControls::resetClicked() { } -void FFTFilterControls::setGraph(std::vector* dataArrayIn) +void FFTFilterControls::setGraph(std::vector>* dataArrayIn) { if (1 < m_graphModel.getDataArraySize()) { qDebug("set graph"); - // void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); - m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, true, false, true); + // void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); + m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, false, true, false, true); } } diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h index a9a9a6b22a3..467d778b8f6 100644 --- a/plugins/FFTFilter/FFTFilterControls.h +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -58,7 +58,7 @@ class FFTFilterControls : public EffectControls } int controlCount() override { return 8; } - void setGraph(std::vector* dataArrayIn); + void setGraph(std::vector>* dataArrayIn); private slots: void resetClicked(); From c0e0c5435a20216e19c459115064e4b6d8d5f2fa Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:57:34 +0200 Subject: [PATCH 043/184] VectorGraph_effector_attributes_reworked --- include/VectorGraph.h | 4 +-- src/gui/widgets/VectorGraph.cpp | 64 ++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 6050a9f3881..54a96418b3c 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -601,8 +601,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns the curve value at a given x coord float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); // applys the effect on a given value, does clamp - float processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, - VectorGraphDataArray* effectArrayIn, unsigned int effectLocationIn); + float processEffect(unsigned int locationIn, float attribValueIn, unsigned int attribLocationIn, float effectValueIn); // returns a VectorGraphPoint with modified attributes float processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn); @@ -647,6 +646,7 @@ class LMMS_EXPORT VectorGraphDataArray void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); void getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, std::vector* outputXLocationsIn, std::vector>* effectorDataIn, unsigned int iIn, float stepSizeIn); + bool isEffectedPoint(unsigned int locationIn); // checks m_isFixedEndPoints, does not call dataChanged() void formatDataArrayEndPoints(); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 8a8204f283a..7f0e18f2660 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2797,7 +2797,7 @@ void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boo getUpdatingFromPoint(locationIn); // if the current point can effect line before it // update the point before it - if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + if (getEffectedAttribLocation(locationIn) <= 0&& locationIn > 0) { getUpdatingFromPoint(locationIn - 1); } @@ -3082,58 +3082,58 @@ float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn return output; } -float VectorGraphDataArray::processEffect(float attribValueIn, unsigned int attribLocationIn, float effectValueIn, - VectorGraphDataArray* effectArrayIn, unsigned int effectLocationIn) +float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribValueIn, + unsigned int attribLocationIn, float effectValueIn) { float output = attribValueIn; - unsigned int attribLocation = effectArrayIn->getEffectedAttribLocation(effectLocationIn); + unsigned int attribLocation = getEffectedAttribLocation(locationIn); // effects if (attribLocationIn == attribLocation) { - if (effectArrayIn->getEffect(effectLocationIn, 6) == true) + if (getEffect(locationIn, 6) == true) { // sine output = output + std::sin(effectValueIn * 100.0f); } - if (effectArrayIn->getEffect(effectLocationIn, 4) == true) + if (getEffect(locationIn, 4) == true) { // power output = std::pow(output, effectValueIn); } - else if (effectArrayIn->getEffect(effectLocationIn, 5) == true) + else if (getEffect(locationIn, 5) == true) { // log output = std::log(output) / std::log(effectValueIn); } - if (effectArrayIn->getEffect(effectLocationIn, 2) == true) + if (getEffect(locationIn, 2) == true) { // multiply output = output * 5.0f * effectValueIn; } - else if (effectArrayIn->getEffect(effectLocationIn, 3) == true) + else if (getEffect(locationIn, 3) == true) { output = output / 5.0f / effectValueIn; // divide } - if (effectArrayIn->getEffect(effectLocationIn, 0) == true) + if (getEffect(locationIn, 0) == true) { // add output += effectValueIn; } - else if (effectArrayIn->getEffect(effectLocationIn, 1) == true) + else if (getEffect(locationIn, 1) == true) { // subtract output -= effectValueIn; } - if (effectArrayIn->getEffect(effectLocationIn, 7) == true) + if (getEffect(locationIn, 7) == true) { // clamp lower output = std::max(effectValueIn, output); } - else if (effectArrayIn->getEffect(effectLocationIn, 8) == true) + else if (getEffect(locationIn, 8) == true) { // clamp upper output = std::min(effectValueIn, output); @@ -3684,13 +3684,13 @@ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn float curValA = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valA, m_needsUpdating[iIn], 2); float curValB = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valB, m_needsUpdating[iIn], 3); qDebug("getValuesD6.3, effectorDataInSize: %ld", effectorDataIn->size()); - if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == true) + if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) { qDebug("getValuesD6.5"); - curY = processEffect(curY, 0, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); - curC = processEffect(curC, 1, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); - curValA = processEffect(curValA, 2, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); - curValB = processEffect(curValB, 3, curEffectY, effectorIn, effectorDataIn->operator[](iIn).first); + curY = processEffect(m_needsUpdating[iIn], curY, 0, curEffectY); + curC = processEffect(m_needsUpdating[iIn], curC, 1, curEffectY); + curValA = processEffect(m_needsUpdating[iIn], curValA, 2, curEffectY); + curValB = processEffect(m_needsUpdating[iIn], curValB, 3, curEffectY); } qDebug("getValuesD7"); int start = effectYLocation; @@ -3705,14 +3705,15 @@ qDebug("getValuesD7"); end = effectYLocation; nextY = processAutomation(m_dataArray[m_needsUpdating[iIn] + 1].m_y, m_needsUpdating[iIn] + 1, 0); - // if the effector point effecting the current point can only effect points (and not lines) - // and the effector point effecting the next point can only effect points + // if the current point can only be effected (and not its line) + // and the next point can only be effected // this is done to avoid adding effectorOutputIn to the line and to the next point (line's end point) at the same time - if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == true && - effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).second) == true) + if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn] + 1) == true && + ((getEffectOnlyPoints(m_needsUpdating[iIn]) == true && isEffectedPoint(m_needsUpdating[iIn]) == true) || + isEffectedPoint(m_needsUpdating[iIn]) == false)) { nextEffectY = effectorOutputIn->operator[](effectYLocation); - nextY = processEffect(nextY, 0, nextEffectY, effectorIn, effectorDataIn->operator[](iIn).second); + nextY = processEffect(m_needsUpdating[iIn] + 1, nextY, 0, nextEffectY); } } // calculating line ends @@ -3816,7 +3817,7 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; } } - if (effectorIn != nullptr && effectorIn->getEffectOnlyPoints(effectorDataIn->operator[](iIn).first) == false) + if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) { int startB = iIn == 0 ? 0 : start; int endB = iIn >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; @@ -3824,7 +3825,7 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // if it is enabled for (int j = startB; j < endB; j++) { - m_bakedValues[j] = processEffect(m_bakedValues[j], 0, effectorOutputIn->operator[](j), effectorIn, effectorDataIn->operator[](iIn).first); + m_bakedValues[j] = processEffect(m_needsUpdating[iIn], m_bakedValues[j], 0, effectorOutputIn->operator[](j)); } } // clamp @@ -3848,6 +3849,19 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f } } +bool VectorGraphDataArray::isEffectedPoint(unsigned int locationIn) +{ + bool output = false; + for (unsigned int i = 0; i <= 8; i++) + { + if (getEffect(locationIn, i) == true) + { + output = true; + break; + } + } + return output; +} void VectorGraphDataArray::formatDataArrayEndPoints() { if (m_isFixedEndPoints == true && m_dataArray.size() > 0) From 3b6909e4f9189d2b5fa5e45e1fd6751d5e9ea29f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 5 Apr 2024 10:19:33 +0200 Subject: [PATCH 044/184] VectorGraph_getValues_effector_optimizations --- include/VectorGraph.h | 4 ++-- src/gui/widgets/VectorGraph.cpp | 40 ++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 54a96418b3c..f5080bc4b68 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -643,9 +643,9 @@ class LMMS_EXPORT VectorGraphDataArray // recalculates and sorts m_needsUpdating so // every point is in there only once void getUpdatingOriginals(); - void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); + //void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); void getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, - std::vector* outputXLocationsIn, std::vector>* effectorDataIn, unsigned int iIn, float stepSizeIn); + std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn); bool isEffectedPoint(unsigned int locationIn); // checks m_isFixedEndPoints, does not call dataChanged() diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 7f0e18f2660..4296d687586 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2437,11 +2437,25 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); - m_isDataChanged = m_isDataChanged || effectorIsChanged; + // deciding if the whole dataArray should be updated + // if the whole effectorArray was updated + int effectedCount = 0; + if (effectorIsChanged == true) + { + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + effectedCount += isEffectedPoint(i) == true? 1 : 0; + } + if (effectedCount > m_dataArray.size() / 2) + { + m_isDataChanged = m_isDataChanged || effectorIsChanged; + } + } + // updating m_needsUpdating if (m_isDataChanged == false && countIn == m_bakedValues.size()) { - if (isEffected == true && effectorUpdatingValues->size() > 0) + if (isEffected == true && effectorUpdatingValues->size() > 0 && effectedCount > 0) { // effectorUpdatingValues needs to be sorted // before use (in this case it is already sorted) @@ -2496,26 +2510,28 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, - std::vector> effectorData; + //std::vector> effectorData; VectorGraphDataArray* effector = nullptr; if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) { effector = m_parent->getDataArray(m_effectorLocation); } - getValuesLocations(effector, &effectorData); + //getValuesLocations(effector, &effectorData); + /* for (unsigned int j = 0; j < effectorData.size(); j++) { qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); } + */ qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, &effectorData, i, stepSize); + getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); } - effectorData.clear(); + //effectorData.clear(); } *isChangedOut = m_isDataChanged; @@ -3510,8 +3526,11 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr %d", i, j); - m_needsUpdating.push_back(j); + if (isEffectedPoint(j) == true) + { + qDebug("getUpdatingFromEffector: [%d] -> %d", i, j); + m_needsUpdating.push_back(j); + } } if (i < updatingEnd) { @@ -3615,6 +3634,7 @@ void VectorGraphDataArray::getUpdatingOriginals() } originalValues.clear(); } +/* void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) { if (effectorIn != nullptr) @@ -3669,8 +3689,9 @@ qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); } } } +*/ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, - std::vector* outputXLocationsIn, std::vector>* effectorDataIn, unsigned int iIn, float stepSizeIn) + std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn) { qDebug("getValuesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); unsigned int effectYLocation = static_cast @@ -3683,7 +3704,6 @@ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn float curC = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_c, m_needsUpdating[iIn], 1); float curValA = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valA, m_needsUpdating[iIn], 2); float curValB = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valB, m_needsUpdating[iIn], 3); -qDebug("getValuesD6.3, effectorDataInSize: %ld", effectorDataIn->size()); if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) { qDebug("getValuesD6.5"); From 71f88f536579a91ef9991a7f6144aef6a18678bc Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:20:27 +0200 Subject: [PATCH 045/184] FFTFilter_better_graph_display --- plugins/FFTFilter/FFTFilter.cpp | 27 ++++++++++++++++++--------- plugins/FFTFilter/FFTFilter.h | 2 ++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index 1fd571985a7..b922725c2c4 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -79,7 +79,7 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) { if (!isEnabled() || !isRunning()) { return false ; } - if (isNoneInput(buf, frames, 0.05f) == true) + if (isNoneInput(buf, frames, 0.01f) == true) { //qDebug("FFTFilterEffect return false"); return false; @@ -104,33 +104,34 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) } float avgY = 0; - int avgCount = 5;//FFTSpectrumOutput.size() / graphInput.size(); + int avgCount = 0;//FFTSpectrumOutput.size() / graphInput.size(); if (avgCount <= 0) { avgCount = 1; } - int avgSum = 0; + float avgSum = 0; int j = 0; for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) { avgY = avgY + FFTSpectrumOutput[i]; - if (i + 1 > avgSum + avgCount) + avgCount++; + if (i + 1 > avgSum + graphXArray[j] * FFTSpectrumOutput.size() / graphXArraySum) { - graphInput[j].second = avgY / static_cast(avgCount); - j++; + graphInput[j].second = amplifyY(avgY / static_cast(avgCount), avgCount + 1.0f); + qDebug("FFTFiterEffect i: %d, %f", i, graphInput[j].second); if (j >= graphInput.size()) { break; } avgY = 0; - avgSum = avgSum + avgCount; - avgCount = static_cast(avgCount * 1.4f); + avgSum = avgSum + graphXArray[j] * FFTSpectrumOutput.size() / graphXArraySum; + avgCount = 0; + j++; } } // log_10(100) = 2 -> 10^2 = 100 for (unsigned int i = 0; i < graphInput.size(); i++) { - graphInput[i].second = FFTSpectrumOutput[i]; graphInput[i].first = graphXArray[i]; } // DEBUG @@ -226,9 +227,11 @@ void FFTFilterEffect::updateGraphXArray(unsigned int sizeIn) { updateSampleRate(); graphXArray.resize(sizeIn); + graphXArraySum = 0.0f; for (unsigned int i = 0; i < graphXArray.size(); i++) { graphXArray[i] = getTransformedX(i, graphXArray.size()); + graphXArraySum += graphXArray[i]; qDebug("updateGraphXArray [%d] %f", i, graphXArray[i]); } } @@ -251,6 +254,12 @@ float FFTFilterEffect::getTransformedX(unsigned int locationIn, unsigned int siz */ return freq > 0.0f ? freq : 0.0f; } +float FFTFilterEffect::amplifyY(float yIn, float powerIn) +{ + float power = std::max(powerIn, 2.0f); + return -std::pow(power, -yIn * power) + 1.0f; + //return -std::pow(std::abs(yIn - 1.0f), 3.0f) + 1.0f; +} extern "C" { diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index 0bd6cd89342..74d66ef2bf7 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -56,6 +56,7 @@ class FFTFilterEffect : public Effect void updateSampleRate(); void updateGraphXArray(unsigned int sizeIn); float getTransformedX(unsigned int locationIn, unsigned int sizeIn); + float amplifyY(float yIn, float powerIn); FFTFilterControls m_filterControls; @@ -69,6 +70,7 @@ class FFTFilterEffect : public Effect LocklessRingBuffer m_inputBuffer; std::vector graphXArray; + float graphXArraySum; unsigned int m_sampleRate; unsigned int m_bufferSize; From 764ea8dfab8a5206ec68252406f3de121a9962b8 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 16:31:54 +0200 Subject: [PATCH 046/184] VectorGraph_bugfixes --- include/VectorGraph.h | 5 ++--- src/gui/widgets/VectorGraph.cpp | 40 ++++++++++++++++++++------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f5080bc4b68..c81b8e5353f 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -443,8 +443,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns the latest updated graph values // countIn is the retuned vector's size std::vector getValues(unsigned int countIn); - //std::vector getValues(unsigned int countIn, bool* isChangedOut); - std::vector getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut); + std::vector getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut); // returns m_bakedValues without updating std::vector getLastValues(); std::vector getEffectorArrayLocations(); @@ -631,7 +630,7 @@ class LMMS_EXPORT VectorGraphDataArray // adds the points that are // effected by the effector's values changing // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::shared_ptr> updatingValuesIn); + void getUpdatingFromEffector(std::vector* updatingValuesIn); // if locationIn > 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedValues // changes in the size of m_dataArray (addtition, deletion, ect.) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 4296d687586..3578c641281 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -27,7 +27,6 @@ #include // sort #include // rand #include // unintptr_t -#include // smartpointers #include #include #include @@ -603,11 +602,11 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve for (unsigned int j = 0; j < dataArrayValues.size(); j++) { posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); - posB.first = j; + posB.first = static_cast((j * width()) / static_cast(dataArrayValues.size())); if (posA.first != posB.first) { - pt.lineTo(j, m_graphHeight - posB.second); + pt.lineTo(posB.first, m_graphHeight - posB.second); // pt replaces drawing with path //pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } @@ -914,6 +913,8 @@ bool VectorGraphView::addPoint(unsigned int locationIn, int mouseXIn, int mouseY { bool output = false; std::pair curMouseCoords = mapMousePos(mouseXIn, mouseYIn); + curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); + curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); int location = model()->getDataArray(locationIn)->add(curMouseCoords.first); // if adding was successful if (location >= 0) @@ -2411,25 +2412,26 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is std::vector VectorGraphDataArray::getValues(unsigned int countIn) { - bool isChanged = false; - std::shared_ptr> updatingValues = std::make_shared>(); + //std::shared_ptr> updatingValues = std::make_shared>(); + //std::shared_ptr> updatingValues = std::make_shared>(); qDebug("getValuesA1"); - std::vector output = getValues(countIn, &isChanged, updatingValues); + std::vector output = getValues(countIn, nullptr, nullptr); qDebug("getValuesA2, size: %ld", output.size()); - updatingValues->clear(); qDebug("getValuesA3 finished"); return output; } -std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) +//std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) +std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut) { bool effectorIsChanged = false; - std::shared_ptr> effectorUpdatingValues = std::make_shared>(); + //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); + std::vector effectorUpdatingValues; std::vector effectorOutput; std::vector outputXLocations(countIn); bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { - effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, effectorUpdatingValues); + effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, &effectorUpdatingValues); } else { @@ -2455,11 +2457,11 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // updating m_needsUpdating if (m_isDataChanged == false && countIn == m_bakedValues.size()) { - if (isEffected == true && effectorUpdatingValues->size() > 0 && effectedCount > 0) + if (isEffected == true && effectorUpdatingValues.size() > 0 && effectedCount > 0) { // effectorUpdatingValues needs to be sorted // before use (in this case it is already sorted) - getUpdatingFromEffector(effectorUpdatingValues); + getUpdatingFromEffector(&effectorUpdatingValues); } qDebug("getValuesB2"); getUpdatingFromAutomation(); @@ -2534,17 +2536,23 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i //effectorData.clear(); } - *isChangedOut = m_isDataChanged; + if (isChangedOut != nullptr) + { + *isChangedOut = m_isDataChanged; + } if (m_needsUpdating.size() > 0) { - *updatingValuesOut = m_needsUpdating; + if (updatingValuesOut != nullptr) + { + *updatingValuesOut = m_needsUpdating; + } // clearing the updated values m_needsUpdating.clear(); } m_isDataChanged = false; - effectorUpdatingValues->clear(); + //effectorUpdatingValues->clear(); qDebug("getValuesB9"); return m_bakedValues; } @@ -3430,7 +3438,7 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< return output; } -void VectorGraphDataArray::getUpdatingFromEffector(std::shared_ptr> updatingValuesIn) +void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingValuesIn) { // Debug testing /* From 498d954dcffe8b251dc6f8ec3875360a7100dfa6 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 16:33:51 +0200 Subject: [PATCH 047/184] FFTFilter_partial_implementation --- plugins/FFTFilter/FFTFilter.cpp | 116 ++++++++++++++- plugins/FFTFilter/FFTFilter.h | 11 ++ plugins/FFTFilter/FFTFilterControls.cpp | 17 ++- plugins/FFTFilter/FFTFilterControls.h | 1 + plugins/FFTFilter/FFTProcessor.cpp | 179 +++++++++++++++++++++--- plugins/FFTFilter/FFTProcessor.h | 15 +- 6 files changed, 303 insertions(+), 36 deletions(-) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index b922725c2c4..86d6ae3e2fa 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -58,8 +58,14 @@ FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatu Effect(&FFTFilter_plugin_descriptor, parent, key), m_filterControls(this), m_FFTProcessor(2048, true, FFTWindow::Rectangular), - m_inputBuffer(2048) + m_inputBuffer(2048), + m_outSampleBufferA(2048), + m_outSampleBufferB(2048), + m_outSampleUsedUp(0), + m_outSampleBufferAUsed(false), + m_complexMultiplier(2048, 1) { + //m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); //std::vector graphXArray; @@ -77,22 +83,38 @@ FFTFilterEffect::~FFTFilterEffect() bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) { - if (!isEnabled() || !isRunning()) { return false ; } + bool processed = false; + //if (!isEnabled() || !isRunning()) { return false ; } + if (isEnabled() && isRunning()) + { + if (isNoneInput(buf, frames, 0.01f) == true) { //qDebug("FFTFilterEffect return false"); return false; } + else + { qDebug("FFTFilterEffect write"); + //m_complexMultiplier = m_filterControls.getGraph(2048); + //m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); + m_inputBuffer.write(buf, frames, true); qDebug("FFTFilterEffect analyze"); //m_FFTProcessor.analyze(&m_inputBuffer, &target); + + if (m_FFTProcessor.getOutputSamplesChanged() == true) + { + //std::vector samples = m_FFTProcessor.getSample(); + //updateSampleArray(&samples, 0); + //updateSampleArray(&samples, 1); + } if (m_FFTProcessor.getOutputSpectrumChanged() == true) { std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); @@ -118,7 +140,7 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) if (i + 1 > avgSum + graphXArray[j] * FFTSpectrumOutput.size() / graphXArraySum) { graphInput[j].second = amplifyY(avgY / static_cast(avgCount), avgCount + 1.0f); - qDebug("FFTFiterEffect i: %d, %f", i, graphInput[j].second); + //qDebug("FFTFiterEffect i: %d, %f", i, graphInput[j].second); if (j >= graphInput.size()) { break; @@ -191,6 +213,30 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) //checkGate(outSum / frames); + } // isNoneInput + } // enabled && isRunning + //setOutputSamples(buf, frames); + + float cutOff = 0.003f; + /* + for (unsigned int i = 0; i < frames; i++) + { + qDebug("FFTFilter processAtudioBuffer [%d] %f", i, buf[i][0]); + if (i > 0 && std::abs(buf[i - 1][0] - buf[i][0]) > cutOff) + { + qDebug("setOutputSamples BAD OUTPUT"); + int* debugval = nullptr; + *debugval = 3; + } + else if (std::abs(debugLastSample[0] - buf[i][0]) > cutOff) + { + qDebug("setOutputSamples BAD OUTPUT 2 --------"); + int* debugval = nullptr; + *debugval = 3; + } + } + */ + //debugLastSample = buf[frames - 1]; return isRunning(); } @@ -232,7 +278,7 @@ void FFTFilterEffect::updateGraphXArray(unsigned int sizeIn) { graphXArray[i] = getTransformedX(i, graphXArray.size()); graphXArraySum += graphXArray[i]; - qDebug("updateGraphXArray [%d] %f", i, graphXArray[i]); + //qDebug("updateGraphXArray [%d] %f", i, graphXArray[i]); } } float FFTFilterEffect::getTransformedX(unsigned int locationIn, unsigned int sizeIn) @@ -260,6 +306,68 @@ float FFTFilterEffect::amplifyY(float yIn, float powerIn) return -std::pow(power, -yIn * power) + 1.0f; //return -std::pow(std::abs(yIn - 1.0f), 3.0f) + 1.0f; } +void FFTFilterEffect::setOutputSamples(sampleFrame* sampleStartIn, unsigned int sizeIn) +{ + std::vector* curOutBuffer = m_outSampleBufferAUsed == true ? &m_outSampleBufferA : &m_outSampleBufferB; + unsigned int size = curOutBuffer->size() <= m_outSampleUsedUp + sizeIn ? curOutBuffer->size() - m_outSampleUsedUp: sizeIn; + for (unsigned int i = 0; i < size; i++) + { + sampleStartIn[i] = curOutBuffer->operator[](m_outSampleUsedUp + i); + //qDebug("setOutputSamples [%d] %f", m_outSampleUsedUp + i, sampleStartIn[i][0]); + } + m_outSampleUsedUp += size; + if (size != sizeIn) + { + qDebug("setOutputSamples Switched!!"); + m_outSampleBufferAUsed = !m_outSampleBufferAUsed; + m_outSampleUsedUp = 0; + std::vector* curOutBuffer = m_outSampleBufferAUsed == true ? &m_outSampleBufferA : &m_outSampleBufferB; + size = curOutBuffer->size() <= m_outSampleUsedUp + sizeIn ? curOutBuffer->size() - m_outSampleUsedUp : sizeIn; + for (unsigned int i = 0; i < size; i++) + { + sampleStartIn[i] = curOutBuffer->operator[](i); + //qDebug("setOutputSamples [%d] %f", m_outSampleUsedUp + i, sampleStartIn[i][0]); + } + m_outSampleUsedUp += size; + + for (unsigned int i = 0; i < curOutBuffer->size(); i++) + { + //qDebug("setOutputSamples sv [%d] %f", i, curOutBuffer->operator[](i)[0]); + } + } + + /* + for (unsigned int i = 0; i < sizeIn; i++) + { + qDebug("setOutputSamples [%d] %f", i, sampleStartIn[i][0]); + if (i > 0 && std::abs(sampleStartIn[i - 1][0] - sampleStartIn[i][0]) > 0.003f) + { + qDebug("setOutputSamples BAD OUTPUT"); + } + } + */ +} +void FFTFilterEffect::updateSampleArray(std::vector* newSamplesIn, unsigned int sampleLocIn) +{ + if (m_outSampleBufferAUsed == true) + { + unsigned int size = m_outSampleBufferB.size() < newSamplesIn->size() ? m_outSampleBufferB.size() : newSamplesIn->size(); + qDebug("FFTFilter updateSampleArray size: %d, sampLoc: %d", size, sampleLocIn); + for (unsigned int i = 0; i < size; i++) + { + m_outSampleBufferB[i][sampleLocIn] = newSamplesIn->operator[](i); + } + } + else + { + unsigned int size = m_outSampleBufferA.size() < newSamplesIn->size() ? m_outSampleBufferA.size() : newSamplesIn->size(); + qDebug("FFTFilter updateSampleArray size: %d, sampLoc: %d", size, sampleLocIn); + for (unsigned int i = 0; i < size; i++) + { + m_outSampleBufferA[i][sampleLocIn] = newSamplesIn->operator[](i); + } + } +} extern "C" { diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h index 74d66ef2bf7..feb7886b539 100644 --- a/plugins/FFTFilter/FFTFilter.h +++ b/plugins/FFTFilter/FFTFilter.h @@ -58,6 +58,8 @@ class FFTFilterEffect : public Effect float getTransformedX(unsigned int locationIn, unsigned int sizeIn); float amplifyY(float yIn, float powerIn); + void setOutputSamples(sampleFrame* sampleStartIn, unsigned int sizeIn); + void updateSampleArray(std::vector* newSamplesIn, unsigned int sampleLocIn); FFTFilterControls m_filterControls; FFTProcessor m_FFTProcessor; @@ -69,12 +71,21 @@ class FFTFilterEffect : public Effect LocklessRingBuffer m_inputBuffer; + std::vector m_outSampleBufferA; + std::vector m_outSampleBufferB; + unsigned int m_outSampleUsedUp; + bool m_outSampleBufferAUsed; + std::vector graphXArray; float graphXArraySum; unsigned int m_sampleRate; unsigned int m_bufferSize; + sampleFrame debugLastSample; + + std::vector m_complexMultiplier; + friend class FFTFilterControls; }; diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 4f06898c186..1b1790b14e4 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -76,7 +76,7 @@ void FFTFilterControls::loadSettings(const QDomElement& parent) m_displayFFTModel.loadSettings(parent, "display"); - m_graphModel.loadSettings(parent); + m_graphModel.loadSettings(parent, "VectorGraph"); } @@ -88,18 +88,29 @@ void FFTFilterControls::saveSettings(QDomDocument& doc, QDomElement& parent) m_bufferModel.saveSettings(doc, parent, "buffer"); m_displayFFTModel.saveSettings(doc, parent, "display"); - m_graphModel.saveSettings(doc, parent); + m_graphModel.saveSettings(doc, parent, "VectorGraph"); } void FFTFilterControls::resetClicked() { } + +std::vector FFTFilterControls::getGraph(unsigned int sizeIn) +{ + std::vector output; + if (0 < m_graphModel.getDataArraySize()) + { + qDebug("FFTFilterControls: get graph"); + output = m_graphModel.getDataArray(0)->getValues(sizeIn); + } + return output; +} void FFTFilterControls::setGraph(std::vector>* dataArrayIn) { if (1 < m_graphModel.getDataArraySize()) { - qDebug("set graph"); + qDebug("FFTFilterControls: set graph"); // void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, false, true, false, true); } diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h index 467d778b8f6..86a238c3d87 100644 --- a/plugins/FFTFilter/FFTFilterControls.h +++ b/plugins/FFTFilter/FFTFilterControls.h @@ -58,6 +58,7 @@ class FFTFilterControls : public EffectControls } int controlCount() override { return 8; } + std::vector getGraph(unsigned int sizeIn); void setGraph(std::vector>* dataArrayIn); private slots: diff --git a/plugins/FFTFilter/FFTProcessor.cpp b/plugins/FFTFilter/FFTProcessor.cpp index 57fcedf242b..de3a62187b0 100644 --- a/plugins/FFTFilter/FFTProcessor.cpp +++ b/plugins/FFTFilter/FFTProcessor.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -27,14 +28,15 @@ FFTProcessor::FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWind m_frameFillLoc = 0; m_samplesIn.resize(m_blockSize); - m_normSpectrum.resize(outputSize(m_blockSize)); + m_samplesOut.resize(m_blockSize); + m_normSpectrum.resize(binCount(m_blockSize)); + //m_complexMultiplier; - m_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); - m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * m_blockSize); + m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * binCount(m_blockSize)); // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); m_plan = fftwf_plan_dft_r2c_1d(m_blockSize, m_samplesIn.data(), m_out, FFTW_ESTIMATE); - m_iplan = fftwf_plan_dft_c2r_1d(m_blockSize, m_in, m_samplesIn.data(), FFTW_ESTIMATE); + m_iplan = fftwf_plan_dft_c2r_1d(m_blockSize, m_out, m_samplesOut.data(), FFTW_ESTIMATE); m_fftWindow.resize(m_blockSize, 1.0); precomputeWindow(m_fftWindow.data(), m_blockSize, m_FFTWindowType); @@ -53,10 +55,6 @@ FFTProcessor::~FFTProcessor() fftwf_destroy_plan(m_iplan); } qDebug("FFTProcessor destrc 0"); - if (m_in != nullptr) - { - fftwf_free(m_in); - } qDebug("FFTProcessor destrc 1"); if (m_out != nullptr) { @@ -64,7 +62,6 @@ FFTProcessor::~FFTProcessor() } qDebug("FFTProcessor destrc 2"); - m_in = nullptr; m_out = nullptr; qDebug("FFTProcessor destrc 3"); } @@ -95,8 +92,8 @@ void FFTProcessor::threadedStartThread(LocklessRingBuffer* ringBuff qDebug("analyze threaded thread init"); m_terminate = false; unsigned int blockSize = m_blockSize; - m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, m_out, &m_samplesIn, &m_outputSpectrumChanged, &m_outputSamplesChanged, - ringBufferIn, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); + m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, &m_iplan, m_out, &m_samplesIn, &m_samplesOut, &m_outputSpectrumChanged, &m_outputSamplesChanged, + ringBufferIn, &m_complexMultiplier, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); qDebug("analyze threaded thread running"); } } @@ -108,6 +105,13 @@ std::vector FFTProcessor::getNormSpectrum() m_outputAccess.unlock(); return output; } +std::vector FFTProcessor::getSample() +{ + m_outputAccess.lock(); + std::vector output = m_samplesOut; + m_outputAccess.unlock(); + return output; +} bool FFTProcessor::getOutputSpectrumChanged() { bool output = m_outputSpectrumChanged; @@ -120,10 +124,14 @@ bool FFTProcessor::getOutputSamplesChanged() m_outputSamplesChanged = false; return output; } +void FFTProcessor::setComplexMultiplier(std::vector* complexMultiplierIn) +{ + m_complexMultiplier = *complexMultiplierIn; +} - -void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::vector* samplesIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, - LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, +void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_plan* inversePlanIn, fftwf_complex* complexIn, std::vector* samplesIn, std::vector* samplesOut, + std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + LocklessRingBuffer* ringBufferIn, std::vector* filterSpectrumIn, unsigned int sampLocIn, unsigned int blockSizeIn, std::vector* spectrumOut, std::mutex* outputAccessIn) { LocklessRingBufferReader reader(*ringBufferIn); @@ -131,6 +139,36 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p //std::vector samples(blockSizeIn); std::vector absSpectrum(blockSizeIn); std::vector outputSpectrum(blockSizeIn); + + // TODO might not be the correct size + float pi = 3.141592654f; + std::vector hanningWindow(blockSizeIn); + precomputeWindow(hanningWindow.data(), blockSizeIn, FFTWindow::Hanning); + float sumWindow = 0.0f; + for (int i = 0; i < blockSizeIn; i++) + { + // applying sinc function + float sincVal = pi * 0.25f * (i - (static_cast(blockSizeIn) / 2.0f)); + if (sincVal != 0) + { + hanningWindow[i] = hanningWindow[i] * std::sin(sincVal) / sincVal; + } + sumWindow = sumWindow + hanningWindow[i]; + qDebug("FFTProcessor final window [%d]: %f, %f", i, hanningWindow[i], sumWindow); + } + for (int i = 0; i < blockSizeIn; i++) + { + // normalise + hanningWindow[i] = hanningWindow[i] / sumWindow; + //qDebug("FFTProcessor sumWindow [%d]: %f, %f", i, hanningWindow[i], sumWindow); + } + + std::vector inverseOldReal(binCount(blockSizeIn)); + std::vector inverseOldImg(binCount(blockSizeIn)); + + + std::vector storedSamples(binCount(blockSizeIn)); + fpp_t frameFillLoc = 0; qDebug("analyzeB 0"); @@ -149,16 +187,22 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p while (frameIn < frameCount) { qDebug("analyzeB 1"); + outputAccessIn->lock(); while (frameIn < frameCount && frameFillLoc < blockSizeIn) + //while (frameIn < frameCount && frameFillLoc < blockSizeIn / 2) { //qDebug("analyzeB 2"); - samplesIn->operator[](frameFillLoc) = bufferIn[frameIn][sampLocIn]; + samplesIn->operator[](frameFillLoc + blockSizeIn / 2) = bufferIn[frameIn][sampLocIn]; + samplesIn->operator[](frameFillLoc) = storedSamples[frameFillLoc]; + storedSamples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; frameIn++; frameFillLoc++; } + outputAccessIn->unlock(); if (frameFillLoc < blockSizeIn) + //if (frameFillLoc < blockSizeIn / 2) { break; } @@ -166,18 +210,51 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p qDebug("analyzeB run"); + for (unsigned int i = 0; i < blockSizeIn; i++) + { + //qDebug("FFTProcessor analyze samplesIn [%d]: %f", i, samplesIn->operator[](i)); + } - /* - for (unsigned int i = 0; i < m_blockSize; i++) + // applying window + // this is needed to attenuate the reverse complex correctly + for (unsigned int i = 0; i < blockSizeIn; i++) { - m_samplesIn[i] = m_samplesIn * m_FFTWindow[i]; + //qDebug("FFTProcessor analyze samplesIn before window [%d]: %f", i, samplesIn->operator[](i)); + //samplesIn->operator[](i) = samplesIn->operator[](i) * hanningWindow[i]; + //qDebug("FFTProcessor analyze samplesOut after window [%d]: %f", i, samplesIn->operator[](i)); } - */ - fftwf_execute(*planIn); + // TODO 1.: + // TODO x = samples (x is the sound input with a big length) Done + // TODO create hanning widnow Done + // TODO window = element wise multiplication of hanning and sinc(?) TODO function Done + // TODO normalise window Done + // TODO window_complex = fft(window, N) (it can be applyed before too?) Done + // TODO complex * window_complex Done + // TODO ifft() + // + // TODO 2.: + // TODO size = 512 + // TODO buffer(size * 2, 0) // create a (size * 2) buffer filled with 0-s + // TODO index = iterator througth 1 - 512 + // TODO output_buffer(size * 2, 0) + // TODO for (unsingned int j = 0; j < size; j++) // process 512 points of x at a time + // TODO shift buffer's second half to the first half + // TODO fill buffer's second half with new data x[index] (=samples) + // TODO fftbuffer = ifft(fft(buffer) * fft(window, size * 2)) // multiply complexes, window_complex is sized (size * 2) and contains the fft of window + // TODO output_buffer[index] = real(fftbuffer(size + 1:end)) // getting the real part (when complex?) of fftbuffer (from size + 1 to end) (setting output_buffers first 512 (sie) values) + // TODO index = index + size; // iterate througth the next 512 x (=sample) values + // + // TODO 3.: + // TODO + + //unsigned int reverseSize = blockSizeIn / 2; + + + //fftwf_execute(*planIn); - absspec(complexIn, absSpectrum.data(), outputSize(blockSizeIn)); + absspec(complexIn, absSpectrum.data(), binCount(blockSizeIn)); normalize(absSpectrum, outputSpectrum, blockSizeIn); /* @@ -188,14 +265,70 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p */ outputAccessIn->lock(); - for (unsigned int i = 0; i < outputSize(blockSizeIn); i++) + for (unsigned int i = 0; i < binCount(blockSizeIn); i++) { spectrumOut->operator[](i) = outputSpectrum[i]; } outputAccessIn->unlock(); *spectrumChangedOut = true; + + qDebug("analyzeB try inverse"); + if (filterSpectrumIn->size() == blockSizeIn && false) + { + for (unsigned int i = 0; i < binCount(blockSizeIn); i++) + { + inverseOldReal[i] = complexIn[i][0]; + inverseOldImg[i] = complexIn[i][1]; + //qDebug("analyzeB complex %d, %f, %f", i, inverseOldReal[i], inverseOldImg[i]); + } + + qDebug("analyzeB inverse"); + //int inverseabsspec(const fftwf_complex *complex_buffer, float *absspec_buffer, unsigned int compl_length) + // the input filter spectrum gets copyed in 2 halfs (rotation part) + // and then it gets run througth an fft + for (unsigned int i = 0; i < blockSizeIn / 2; i++) + { + /* + complexIn[i][0] = complexIn[i][0] * complexMultiplierIn->operator[](i); + complexIn[i][1] = complexIn[i][1] * complexMultiplierIn->operator[](i); + */ + samplesIn->operator[](i) = filterSpectrumIn->operator[](i + blockSizeIn / 2); + //changedAbsSpectum[i] = absSpectrum[i]; + //qDebug("FFTProcessor analyze complexMultiplier [%d]: %f", i, complexMultiplierIn->operator[](i)); + } + for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) + { + samplesIn->operator[](i) = filterSpectrumIn->operator[](i); + } + for (unsigned int i = 0; i < blockSizeIn; i++) + { + //qDebug("FFTProcessor filterIn [%d]: %f %f", i, samplesIn->operator[](i), filterSpectrumIn->operator[](i)); + } + fftwf_execute(*planIn); + + outputAccessIn->lock(); + //inverseabsspec(complexIn, changedAbsSpectum.data(), binCount(blockSizeIn)); + for (unsigned int i = 0; i < binCount(blockSizeIn); i++) + { + //qDebug("analyzeB complex %d, %f, %f, multiply: %f, %f", i, inverseOldReal[i], inverseOldImg[i], complexIn[i][0], complexIn[i][1]); + complexIn[i][0] = inverseOldReal[i] * complexIn[i][0]; + complexIn[i][1] = inverseOldImg[i] * complexIn[i][1]; + //complexIn[i][0] = inverseOldReal[i];// * complexIn[i][0]; + //complexIn[i][1] = inverseOldImg[i];// * complexIn[i][1]; + } + fftwf_execute(*inversePlanIn); + for (unsigned int i = 0; i < blockSizeIn; i++) + { + samplesOut->operator[](i) = samplesOut->operator[](i) / blockSizeIn; + //samplesOut->operator[](i) = samplesOut->operator[](i) / hanningWindow[i] / blockSizeIn; + //qDebug("FFTProcessor analyze samplesOut [%d]: %f", i, samplesOut->operator[](i)); + } + outputAccessIn->unlock(); + *samplesChangedOut = true; + } } } + qDebug("analyzeB end"); } @@ -223,7 +356,7 @@ void FFTProcessor::rebuildWindow(FFTWindow FFTWindowIn) // TODO multithread -unsigned int FFTProcessor::outputSize(unsigned int blockSizeIn) +unsigned int FFTProcessor::binCount(unsigned int blockSizeIn) { return blockSizeIn / 2 + 1; } diff --git a/plugins/FFTFilter/FFTProcessor.h b/plugins/FFTFilter/FFTProcessor.h index b59985e7441..fbd935df8d4 100644 --- a/plugins/FFTFilter/FFTProcessor.h +++ b/plugins/FFTFilter/FFTProcessor.h @@ -59,20 +59,23 @@ class FFTProcessor // getters std::vector getNormSpectrum(); + std::vector getSample(); bool getOutputSpectrumChanged(); bool getOutputSamplesChanged(); + void setComplexMultiplier(std::vector* complexMultiplierIn); void reverse(std::vector processedDataIn); void rebuildWindow(FFTWindow FFTWindowIn); - static unsigned int outputSize(unsigned int blockSizeIn); + static unsigned int binCount(unsigned int blockSizeIn); private: - static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_complex* complexIn, std::vector* samplesIn, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, - LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, unsigned int blockSizeIn, - std::vector* spectrumOut, std::mutex* outputAccessIn); + static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_plan* inversePlanIn, fftwf_complex* complexIn, std::vector* samplesIn, std::vector* samplesOut, + std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + LocklessRingBuffer* ringBufferIn, std::vector* complexMultiplierIn, unsigned int sampLocIn, unsigned int blockSizeIn, + std::vector* spectrumOut, std::mutex* outputAccessIn); // Thread: // terminates the thread @@ -89,7 +92,6 @@ class FFTProcessor unsigned int m_frameFillLoc; // fft - fftwf_complex* m_in; fftwf_complex* m_out; fftwf_plan m_plan; @@ -98,9 +100,10 @@ class FFTProcessor std::atomic m_blockSize; std::vector m_samplesIn; + std::vector m_samplesOut; std::vector m_normSpectrum; - std::vector m_absSpectrumOut; + std::vector m_complexMultiplier; std::vector m_fftWindow; FFTWindow m_FFTWindowType; From 357c4bab88b0fbbc3fa88a5c036c54a3690a4d00 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 17:48:19 +0200 Subject: [PATCH 048/184] VectorGraph_tested_dataArray_deletion --- include/VectorGraph.h | 5 ----- plugins/FFTFilter/FFTFilter.cpp | 6 +++--- src/gui/widgets/VectorGraph.cpp | 28 ++++++++-------------------- 3 files changed, 11 insertions(+), 28 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index c81b8e5353f..9bfc2b64aef 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -271,10 +271,6 @@ Q_OBJECT } } // returns location - unsigned int addArray(std::vector>* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); - // returns location - unsigned int addArray(std::vector* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); - // returns location unsigned int addArray(); // preservs the order void delArray(unsigned int locationIn); @@ -452,7 +448,6 @@ class LMMS_EXPORT VectorGraphDataArray // set: ------------------- // sets data array without any checks // inport x and y coords - // TODO should call dataChanged void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); // inport y coords void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index 86d6ae3e2fa..44b6acd00ef 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -57,7 +57,7 @@ Plugin::Descriptor PLUGIN_EXPORT FFTFilter_plugin_descriptor = FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : Effect(&FFTFilter_plugin_descriptor, parent, key), m_filterControls(this), - m_FFTProcessor(2048, true, FFTWindow::Rectangular), + m_FFTProcessor(2048, false, FFTWindow::Rectangular), m_inputBuffer(2048), m_outSampleBufferA(2048), m_outSampleBufferB(2048), @@ -66,7 +66,7 @@ FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatu m_complexMultiplier(2048, 1) { //m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); - m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); + //m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); //std::vector graphXArray; //m_sampleRate; @@ -117,7 +117,7 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) } if (m_FFTProcessor.getOutputSpectrumChanged() == true) { - std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); + std::vector FFTSpectrumOutput;// = m_FFTProcessor.getNormSpectrum(); std::vector> graphInput(80); if (graphInput.size() != graphXArray.size()) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 3578c641281..6c768379dad 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1623,20 +1623,6 @@ VectorGraphModel::~VectorGraphModel() qDebug("VectorGraphModel dstc end"); } -unsigned int VectorGraphModel::addArray(std::vector>* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) -{ - unsigned int location = addArray(); - m_dataArrays[location].setDataArray(arrayIn, isCurvedIn, clearIn, clampIn, rescaleIn, sortIn, callDataChangedIn); - return location; -} - -unsigned int VectorGraphModel::addArray(std::vector* arrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) -{ - unsigned int location = addArray(); - m_dataArrays[location].setDataArray(arrayIn, isCurvedIn, clearIn, clampIn, rescaleIn, callDataChangedIn); - return location; -} - unsigned int VectorGraphModel::addArray() { VectorGraphDataArray tempArray( @@ -1648,14 +1634,11 @@ unsigned int VectorGraphModel::addArray() void VectorGraphModel::delArray(unsigned int locationIn) { - // TODO test + qDebug("delArray"); std::vector effectorArrayLocations(m_dataArrays.size()); for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) { - if (m_dataArrays[i].getEffectorArrayLocation() == locationIn) - { - m_dataArrays[i].setEffectorArrayLocation(-1, false); - } + //qDebug("copyed [%d] to [%d]", i + 1, i); m_dataArrays[i] = m_dataArrays[i + 1]; } m_dataArrays.pop_back(); @@ -1663,7 +1646,11 @@ void VectorGraphModel::delArray(unsigned int locationIn) for (unsigned int i = 0; i < m_dataArrays.size(); i++) { effectorArrayLocations[i] = m_dataArrays[i].getEffectorArrayLocation(); - if (effectorArrayLocations[i] >= locationIn) + if (m_dataArrays[i].getEffectorArrayLocation() == static_cast(locationIn)) + { + effectorArrayLocations[i] = -1; + } + else if (effectorArrayLocations[i] >= static_cast(locationIn)) { effectorArrayLocations[i]--; } @@ -1674,6 +1661,7 @@ void VectorGraphModel::delArray(unsigned int locationIn) // setting updated locations for (unsigned int i = 0; i < m_dataArrays.size(); i++) { + //qDebug("delArray end: set effector location: [%d], %d", i, effectorArrayLocations[i]); m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); } emit dataChanged(); From aaa5385293d44a8a16ffeec5bbb8bc7983504be1 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 18:25:38 +0200 Subject: [PATCH 049/184] VectorGraph_VectorGraphDataArray_settings_reworked --- include/VectorGraph.h | 20 +++--- src/gui/widgets/VectorGraph.cpp | 121 ++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 62 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 9bfc2b64aef..4a91387dd94 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -322,7 +322,7 @@ class LMMS_EXPORT VectorGraphDataArray // avoid using this or run updateConnections() after initialization VectorGraphDataArray(); VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, + bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, bool isSaveableIn, VectorGraphModel* parentIn, int idIn); ~VectorGraphDataArray(); @@ -330,8 +330,8 @@ class LMMS_EXPORT VectorGraphDataArray void updateConnections(VectorGraphModel* parentIn); void setIsFixedSize(bool valueIn); - void setIsFixedValue(bool valueIn); - void setIsFixedPos(bool valueIn); + void setIsFixedX(bool valueIn); + void setIsFixedY(bool valueIn); void setIsFixedEndPoints(bool valueIn); void setIsSelectable(bool valueIn); void setIsEditableAttrib(bool valueIn); @@ -347,8 +347,8 @@ class LMMS_EXPORT VectorGraphDataArray bool setEffectorArrayLocation(int locationIn, bool callDataChangedIn); bool getIsFixedSize(); - bool getIsFixedValue(); - bool getIsFixedPos(); + bool getIsFixedX(); + bool getIsFixedY(); bool getIsFixedEndPoints(); bool getIsSelectable(); bool getIsEditableAttrib(); @@ -647,18 +647,20 @@ class LMMS_EXPORT VectorGraphDataArray // can new data be added or removed bool m_isFixedSize; - // can the values be changed - bool m_isFixedValue; // can the positions be changed - bool m_isFixedPos; + bool m_isFixedX; + // can the values be changed + bool m_isFixedY; // if true then it makes the last position coordinate 1, 1, the first point coordinate to -1 (ot 0), 0 bool m_isFixedEndPoints; // can VectorGraphView select this bool m_isSelectable; - // can VectorGraphView edit the point attributes + // can the point attributes be edited // every attribute outside of x and y + // automation can be changed bool m_isEditableAttrib; // can the points be automated or effected + // (can these settings be changed) bool m_isAutomatableEffectable; // if VectorGraphDataArray is allowed to save this bool m_isSaveable; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 6c768379dad..24a999f6f45 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1854,8 +1854,8 @@ int VectorGraphModel::readLoc(unsigned int startIn, QString dataIn) VectorGraphDataArray::VectorGraphDataArray() { m_isFixedSize = false; - m_isFixedValue = false; - m_isFixedPos = false; + m_isFixedY = false; + m_isFixedX = false; m_isFixedEndPoints = false; m_isSelectable = false; m_isEditableAttrib = false; @@ -1881,13 +1881,13 @@ VectorGraphDataArray::VectorGraphDataArray() } VectorGraphDataArray::VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedValueIn, bool isFixedPosIn, bool nonNegativeIn, + bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool nonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, bool isSaveableIn, VectorGraphModel* parentIn, int idIn) { m_isFixedSize = isFixedSizeIn; - m_isFixedValue = isFixedValueIn; - m_isFixedPos = isFixedPosIn; + m_isFixedY = isFixedXIn; + m_isFixedX = isFixedYIn; m_isFixedEndPoints = isFixedEndPointsIn; m_isSelectable = isSelectableIn; m_isEditableAttrib = isEditableAttribIn; @@ -1946,15 +1946,15 @@ void VectorGraphDataArray::setIsFixedSize(bool valueIn) getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsFixedValue(bool valueIn) +void VectorGraphDataArray::setIsFixedX(bool valueIn) { - m_isFixedValue = valueIn; + m_isFixedX = valueIn; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsFixedPos(bool valueIn) +void VectorGraphDataArray::setIsFixedY(bool valueIn) { - m_isFixedPos = valueIn; + m_isFixedY = valueIn; getUpdatingFromPoint(-1); dataChanged(); } @@ -2077,13 +2077,13 @@ bool VectorGraphDataArray::getIsFixedSize() { return m_isFixedSize; } -bool VectorGraphDataArray::getIsFixedValue() +bool VectorGraphDataArray::getIsFixedX() { - return m_isFixedValue; + return m_isFixedX; } -bool VectorGraphDataArray::getIsFixedPos() +bool VectorGraphDataArray::getIsFixedY() { - return m_isFixedPos; + return m_isFixedY; } bool VectorGraphDataArray::getIsFixedEndPoints() { @@ -2140,13 +2140,13 @@ int VectorGraphDataArray::getId() int VectorGraphDataArray::add(float xIn) { int location = -1; - if (m_dataArray.size() < m_parent->getMaxLength()) + if (m_isFixedSize == false && m_dataArray.size() < m_parent->getMaxLength()) { qDebug("add 1. success"); bool found = false; bool isBefore = false; location = getNearestLocation(xIn, &found, &isBefore); - if (found == false && m_isFixedSize == false) + if (found == false) { qDebug("add 2. success, nearest: %d", location); int targetLocation = -1; @@ -2639,7 +2639,7 @@ void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) { int location = locationIn; - if (m_isFixedPos == false && xIn <= 1.0f) + if (m_isFixedX == false && xIn <= 1.0f) { bool found = false; bool isBefore = false; @@ -2701,52 +2701,67 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) { - if (m_isFixedValue == false) + if (m_isFixedY == false) { - if ((m_isFixedEndPoints == true && locationIn < m_dataArray.size() - 1 && - locationIn > 0) || m_isFixedEndPoints == false) + m_dataArray[locationIn].m_y = yIn; + getUpdatingFromPoint(locationIn); + // changes in the position can change lines before + // so the point before this is updated + if (locationIn > 0) { - m_dataArray[locationIn].m_y = yIn; - getUpdatingFromPoint(locationIn); - // changes in the position can change lines before - // so the point before this is updated - if (locationIn > 0) - { - getUpdatingFromPoint(locationIn - 1); - } - dataChanged(); + getUpdatingFromPoint(locationIn - 1); } + if (m_isFixedEndPoints == true && + (locationIn <= 0 || locationIn >= m_dataArray.size() - 1)) + { + formatDataArrayEndPoints(); + getUpdatingFromPoint(0); + getUpdatingFromPoint(m_dataArray.size() - 1); + } + dataChanged(); } } void VectorGraphDataArray::setC(unsigned int locationIn, float cIn) { - m_dataArray[locationIn].m_c = cIn; - getUpdatingFromPoint(locationIn); - dataChanged(); + if (m_isEditableAttrib == true) + { + m_dataArray[locationIn].m_c = cIn; + getUpdatingFromPoint(locationIn); + dataChanged(); + } } void VectorGraphDataArray::setValA(unsigned int locationIn, float valueIn) { - m_dataArray[locationIn].m_valA = valueIn; - getUpdatingFromPoint(locationIn); - dataChanged(); + if (m_isEditableAttrib == true) + { + m_dataArray[locationIn].m_valA = valueIn; + getUpdatingFromPoint(locationIn); + dataChanged(); + } } void VectorGraphDataArray::setValB(unsigned int locationIn, float valueIn) { - m_dataArray[locationIn].m_valB = valueIn; - getUpdatingFromPoint(locationIn); - dataChanged(); + if (m_isEditableAttrib == true) + { + m_dataArray[locationIn].m_valB = valueIn; + getUpdatingFromPoint(locationIn); + dataChanged(); + } } void VectorGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) { - // set the type without changing the automated attribute location - m_dataArray[locationIn].m_type = typeIn; - getUpdatingFromPoint(locationIn); - dataChanged(); + if (m_isEditableAttrib == true) + { + // set the type without changing the automated attribute location + m_dataArray[locationIn].m_type = typeIn; + getUpdatingFromPoint(locationIn); + dataChanged(); + } } void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { - if (m_isAutomatableEffectable == true) + if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; @@ -2763,7 +2778,7 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned } void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) { - if (m_isAutomatableEffectable == true) + if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; @@ -2794,7 +2809,7 @@ bool VectorGraphDataArray::getEffectOnlyPoints(unsigned int locationIn) } void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) { - if (m_isAutomatableEffectable == true) + if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { if (m_dataArray[locationIn].m_effectOnlyPoints != boolIn) { @@ -2854,7 +2869,7 @@ bool VectorGraphDataArray::getEffect(unsigned int locationIn, unsigned int effec } void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) { - if (m_isAutomatableEffectable == true) + if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { switch (effectNumberIn) { @@ -2886,15 +2901,15 @@ void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effec m_dataArray[locationIn].m_effectClampUpper = boolIn; break; } + getUpdatingFromPoint(locationIn); + // if the current point can effect line before it + // update the point before it + if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + { + getUpdatingFromPoint(locationIn - 1); + } + dataChanged(); } - getUpdatingFromPoint(locationIn); - // if the current point can effect line before it - // update the point before it - if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) - { - getUpdatingFromPoint(locationIn - 1); - } - dataChanged(); } bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) { From 1c035c9817272c6803be9c5023d43966d586b0e2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 19:56:49 +0200 Subject: [PATCH 050/184] VectorGraph_tested_settings --- include/VectorGraph.h | 11 +++++------ src/gui/widgets/VectorGraph.cpp | 34 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 4a91387dd94..83a883ebdd2 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -263,7 +263,6 @@ Q_OBJECT } inline void setMaxLength(unsigned int maxLengthIn) { - // TODO run formatArray on all the dataArrays if (m_maxLength != maxLengthIn) { m_maxLength = maxLengthIn; @@ -322,7 +321,7 @@ class LMMS_EXPORT VectorGraphDataArray // avoid using this or run updateConnections() after initialization VectorGraphDataArray(); VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool nonNegativeIn, + bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool isNonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, bool isSaveableIn, VectorGraphModel* parentIn, int idIn); ~VectorGraphDataArray(); @@ -337,7 +336,7 @@ class LMMS_EXPORT VectorGraphDataArray void setIsEditableAttrib(bool valueIn); void setIsAutomatableEffectable(bool valueIn); void setIsSaveable(bool valueIn); - void setNonNegative(bool valueIn); + void setIsNonNegative(bool valueIn); void setLineColor(QColor colorIn); void setActiveColor(QColor colorIn); void setFillColor(QColor colorIn); @@ -354,7 +353,7 @@ class LMMS_EXPORT VectorGraphDataArray bool getIsEditableAttrib(); bool getIsAutomatableEffectable(); bool getIsSaveable(); - bool getNonNegative(); + bool getIsNonNegative(); QColor* getLineColor(); QColor* getActiveColor(); QColor* getFillColor(); @@ -664,9 +663,9 @@ class LMMS_EXPORT VectorGraphDataArray bool m_isAutomatableEffectable; // if VectorGraphDataArray is allowed to save this bool m_isSaveable; - // can values be less than 0 - bool m_nonNegative; + bool m_isNonNegative; + QColor m_lineColor; QColor m_activeColor; QColor m_fillColor; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 24a999f6f45..c1165081a08 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -556,7 +556,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve std::pair posA(0, 0); std::pair posB(0, 0); - std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), dataArray->getNonNegative())); + std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), false)); // draw line if (m_isSimplified == false) { @@ -601,7 +601,9 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); for (unsigned int j = 0; j < dataArrayValues.size(); j++) { - posB = mapDataPos(0, dataArrayValues[j], dataArray->getNonNegative()); + // if nonNegative then only the dataArray output (getDataValues) + // is bigger than 0 so it matters only here + posB = mapDataPos(0, dataArrayValues[j], dataArray->getIsNonNegative()); posB.first = static_cast((j * width()) / static_cast(dataArrayValues.size())); if (posA.first != posB.first) @@ -644,7 +646,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve bool resetColor = false; for (unsigned int j = 0; j < length; j++) { - posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), dataArray->getNonNegative()); + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), false); // draw point if (drawPoints == true) { @@ -1425,7 +1427,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) // m_selectedArray m_isSelected = true; m_isCurveSelected = false; - m_isEditingActive = dataArray->getIsEditableAttrib(); + m_isEditingActive = true; } } @@ -1455,7 +1457,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) m_isSelected = true; m_isCurveSelected = false; m_isLastSelectedArray = true; - m_isEditingActive = dataArray->getIsEditableAttrib(); + m_isEditingActive = true; break; } } @@ -1477,7 +1479,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) m_isSelected = true; m_isCurveSelected = true; m_isLastSelectedArray = true; - m_isEditingActive = dataArray->getIsEditableAttrib(); + m_isEditingActive = true; break; } } @@ -1861,7 +1863,7 @@ VectorGraphDataArray::VectorGraphDataArray() m_isEditableAttrib = false; m_isAutomatableEffectable = false; m_isSaveable = false; - m_nonNegative = false; + m_isNonNegative = false; m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); @@ -1881,7 +1883,7 @@ VectorGraphDataArray::VectorGraphDataArray() } VectorGraphDataArray::VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool nonNegativeIn, + bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool isNonNegativeIn, bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, bool isSaveableIn, VectorGraphModel* parentIn, int idIn) { @@ -1893,7 +1895,7 @@ VectorGraphDataArray::VectorGraphDataArray( m_isEditableAttrib = isEditableAttribIn; m_isAutomatableEffectable = isAutomatableEffectableIn; m_isSaveable = isSaveableIn; - m_nonNegative = nonNegativeIn; + m_isNonNegative = isNonNegativeIn; m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); @@ -1995,9 +1997,9 @@ void VectorGraphDataArray::setIsSaveable(bool valueIn) { m_isSaveable = valueIn; } -void VectorGraphDataArray::setNonNegative(bool valueIn) +void VectorGraphDataArray::setIsNonNegative(bool valueIn) { - m_nonNegative = valueIn; + m_isNonNegative = valueIn; getUpdatingFromPoint(-1); dataChanged(); } @@ -2105,9 +2107,9 @@ bool VectorGraphDataArray::getIsSaveable() { return m_isSaveable; } -bool VectorGraphDataArray::getNonNegative() +bool VectorGraphDataArray::getIsNonNegative() { - return m_nonNegative; + return m_isNonNegative; } QColor* VectorGraphDataArray::getLineColor() { @@ -3871,9 +3873,11 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f m_bakedValues[j] = -1.0f; } } - if (m_nonNegative == true) + if (m_isNonNegative == true) { - for (int j = start; j < end; j++) + int startB = iIn == 0 ? 0 : start; + int endB = iIn >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; + for (int j = startB; j < endB; j++) { m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; } From fad472ecb77ee2e9954128dbd34ccab22ae6b422 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 7 Apr 2024 20:06:29 +0200 Subject: [PATCH 051/184] VectorGraph_done_TODOs --- include/VectorGraph.h | 67 +++------------------------------ src/gui/widgets/VectorGraph.cpp | 3 -- 2 files changed, 6 insertions(+), 64 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 83a883ebdd2..1421a5701cd 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -25,7 +25,6 @@ #ifndef LMMS_GUI_VECTORGRAPH_H #define LMMS_GUI_VECTORGRAPH_H -#include // smartpointers #include #include #include @@ -47,62 +46,10 @@ class FloatModel; namespace gui { -// class SimpleTextFloat; TODO class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView { Q_OBJECT public: - // TODO: remove styles Done - // TODO: change x unsigned int to float Done - // TODO: make a new class inside PointGraphDataArray to store the point data Done - // TODO: add is selectable Done - // TODO: add new setting to make the last point cord 1, 1 Done - // TODO: flip mouse y position Done - // TODO: function to get multiple values Done - // TODO: rewrite comments - // TODO: rename functions and values - - // TODO: automation: - // TODO: add 4 new values to the nested class: curve, type, valueA, valueB (1 type is 4 value long) Done - // TODO: add automation support - // TODO: make FloatModel pointer array Done - // TODO: allocate FloatModels with new Done - // TODO: delete FloatModels in destructor Done - // TODO: save FloatModels (run saveSettings) - // TODO: getter for the FloatModels for saving Done - // TODO: connect FloatModels connect with getter Done - // TODO: setPointAutomatedAttrib() --> changes the type value between y pos, curve, valueA, valueB Done - // TODO: setPointType(unsigned int type) Done - // TODO: add effector(PointGraphDataArray) int location to the PointGraphDataArray class Done - // TODO: add effector line attributes to the nested class Done - // TODO: add effect implementation Done - - // TODO: clear array when 2. last point is deleted in the widget IGNORE - // TODO: event when a dataArray's size gets to 0 - // TODO: ability to scale displayed coords in PointGraphView (not 0 - 100) (add scalers) - // TODO: check PointGraphDataArray signals Done - // TODO: journalling in PointGraphModel - // TODO: m_maxLength* should be replaced with m_parent->getMaxLength() Done - // TODO: setDataArray keep attributes option, formatArray option which runs formatArray - // TODO: PointGraphDataArray shouldSaveAll and shouldSavePointAttributesOnly (for saving only editable graphs) option Done - // TODO: baked automation values in PointGraphPoint Done - // TODO: rename class to VectorGraph Done - // TODO: make std::vector last used values Done - // TODO: make update logic (isChanged and update only automation / effected lines) Done - // TODO: effector location (same as automation location) Done - // TODO: PointGraphView isSimplified Done - // TODO: new automated color Done - // TODO: context menu in gui (clear automation, connect to controller) - // TODO: display hints (full text) in the editing - // TODO: ability to edit multiple graphs using m_isLastSelectedArray - // TODO: handle effector arrays when deleting VectorGraphDataArray - // TODO: update formatArray - // TODO: licensing email TODO - - // TODO: check selectedLocation, selectedArray, isSelected, isLastSelectedArray usage - // TODO: finish gui, hint texts, context menu - // TODO: separate big functions - VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn); @@ -131,13 +78,11 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView signals: void drawn(); protected: - void paintEvent(QPaintEvent* pe) override; //TODO - //void dropEvent(QDropEvent* de) override; //ignore - //void dragEnterEvent(QDragEnterEvent* dee) override; //ignore - void mousePressEvent(QMouseEvent* me) override; //TODO - void mouseMoveEvent(QMouseEvent* me) override; //TODO - void mouseReleaseEvent(QMouseEvent* me) override; //TODO - void mouseDoubleClickEvent(QMouseEvent* me) override; //TODO + void paintEvent(QPaintEvent* pe) override; + void mousePressEvent(QMouseEvent* me) override; + void mouseMoveEvent(QMouseEvent* me) override; + void mouseReleaseEvent(QMouseEvent* me) override; + void mouseDoubleClickEvent(QMouseEvent* me) override; protected slots: void updateGraph(); @@ -472,7 +417,7 @@ class LMMS_EXPORT VectorGraphDataArray void setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn); // if isAutomatedIn is true then make a new FloatModel and connect it, else delete // the currently used FloatModel - void setAutomated(unsigned int locationIn, bool isAutomatedIn); // TODO + void setAutomated(unsigned int locationIn, bool isAutomatedIn); // signals: // not qt diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index c1165081a08..bbadce41a7a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1686,7 +1686,6 @@ void VectorGraphModel::dataArrayStyleChanged() } int VectorGraphModel::getDataArrayLocationFromId(int idIn) { - // TODO needs testing int output = -1; if (idIn >= 0) { @@ -2225,7 +2224,6 @@ void VectorGraphDataArray::del(unsigned int locationIn) } } -// TODO input scaleing values void VectorGraphDataArray::formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) { if (rescaleIn == true) @@ -2658,7 +2656,6 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) // if getNearestLocation returned a value if (location >= 0) { - // slide the new data if the closest data pos is bigger TODO test ifs qDebug("set 3. success, location: %d", targetLocation); if (location < locationIn && isBefore == true) { From 2284e5e2d718933a48f750957e2fbabe0d9ff75f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 8 Apr 2024 22:53:31 +0200 Subject: [PATCH 052/184] VectorGraph_comments_reviewed --- include/VectorGraph.h | 126 +++++++++++++++++----------- src/gui/widgets/VectorGraph.cpp | 143 ++++++++++++++++++-------------- 2 files changed, 157 insertions(+), 112 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 1421a5701cd..e9edc5cb34a 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -65,17 +65,26 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView return castModel(); } + // draws estimated line, does not call getValues() + // does not fill graphs with VectorGraphDataArray FillColor void setIsSimplified(bool isSimplifiedIn); - // returns -1.0f at first when nothing is selected + // returns -1.0f at .first when nothing is selected std::pair getSelectedData(); - // returns -1 it can not return a array location + // returns -1 it can not return an array location int getLastSelectedArray(); + // sets the position of the currently selected point void setSelectedData(std::pair dataIn); + // sets the background pixmap void setBackground(const QPixmap backgoundIn); + // if this function is called + // paintEvent will not call getValues() (optimization) + // insted calls getLastValues + // resets after every paint event void useGetLastValues(); signals: + // emited after paintEvent void drawn(); protected: void paintEvent(QPaintEvent* pe) override; @@ -96,16 +105,21 @@ protected slots: void modelChanged() override; // utility + // calculate graph coords from screen space coords std::pair mapMousePos(int xIn, int yIn); - // calculate curve position + // calculate gui curve point's position std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); - std::pair mapDataPos(float xIn, float yIn, bool nonNegativeIn); - int mapInputPos(float inputValueIn, unsigned int displayLengthIn); + // calculate screen space coords from graph coords + // isNonNegativeIn can only be true when graph line / getValues() is mapped + std::pair mapDataPos(float xIn, float yIn, bool isNonNegativeIn); + // map where each Control is displayed when m_isEdtitingActive is true + int mapControlInputX(float inputValueIn, unsigned int displayLengthIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); float getDistance(float xAIn, float yAIn, float xBIn, float yBIn); + // adds point to the selected VectorGraphDataArray bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); // editing menu / controls @@ -114,19 +128,20 @@ protected slots: // returns true if the control window was clicked while in editing mode bool isControlWindowPressed(int mouseYIn); void processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn); - // returns -1 if no attribute was clicked - int getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); + // returns -1 if no control / input was clicked + // returns displayed absolute control / input location based on inputCountIn + int getPressedControlInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); // returns a float attrib value, valueOut = attrib value if it is a bool float getInputAttribValue(unsigned int controlArrayLocationIn, bool* valueOut); - // sets the attrib to floatValueIn it it is float, else it sets the attrib to boolValueIn + // sets the selected point's attrib to floatValueIn it it is float, else it sets the attrib to boolValueIn void setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn); // calculates the ideal text color QColor getTextColorFromBaseColor(QColor baseColorIn); - // calculates a replacement fill color + // calculates a replacement background fill color QColor getFillColorFromBaseColor(QColor baseColorIn); - // returns the first x char that fits in the displayedLength(in pixel) - // cuts the string to displayedLength(in px) size + // cuts the string to displayedLength(in px) size (estimated) QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); + // context menu actions void addDefaultActions(QMenu* menu, QString controlDisplayTextIn); // inputDialog @@ -134,17 +149,15 @@ protected slots: float showInputDialog(float curInputValueIn); // selection - // searches arrays to select - // clicked datapoint + // searches VectorGraphDataArray-s to select + // near clicked location void selectData(int mouseXIn, int mouseYIn); - // searches for data in a given array - // returns found location, when a data + // searches for point in a given VectorGraphDataArray + // returns found location, when a point // was found in the given distance // else it returns -1 int searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn); - bool m_mouseDown; - bool m_mouseDrag; // if the mouse is not moved bool m_mousePress; // decides addition or deletion @@ -173,7 +186,7 @@ protected slots: unsigned int m_graphHeight; unsigned int m_controlHeight; - // displayed attrib count + // displayed control count (+1 because of the ">>" button in editing mode) unsigned int m_controlDisplayCount; unsigned int m_controlDisplayPage; bool m_isEditingActive; @@ -214,8 +227,9 @@ Q_OBJECT emit dataChanged(); } } - // returns location + // returns added VectorGraphDataArray location unsigned int addArray(); + // deletes VectorGraphDataArray at locationIn // preservs the order void delArray(unsigned int locationIn); inline void clearArray() @@ -235,13 +249,13 @@ Q_OBJECT virtual void loadSettings(const QDomElement& element, const QString& name); virtual void saveSettings(QDomDocument& doc, QDomElement& element); virtual void loadSettings(const QDomElement& element); - // read locations from saved data attributes + // read locations from saved data attributes unused but implemeted //int readLoc(unsigned int startIn, QString dataIn); signals: - // data changed inside m_dataArray or m_maxLength changed + // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); - // signals when a dataArray gets to 0 element - // locationIn is the location of the dataArray + // signals when a dataArray gets to 0 element size + // locationIn is the location of the VectorGraphDataArray // locationIn can be -1 void clearedEvent(int locationIn); // style changed inside m_dataArray @@ -273,6 +287,7 @@ class LMMS_EXPORT VectorGraphDataArray void updateConnections(VectorGraphModel* parentIn); + // see descriptions in privete void setIsFixedSize(bool valueIn); void setIsFixedX(bool valueIn); void setIsFixedY(bool valueIn); @@ -286,8 +301,9 @@ class LMMS_EXPORT VectorGraphDataArray void setActiveColor(QColor colorIn); void setFillColor(QColor colorIn); void setAutomatedColor(QColor colorIn); - // returns true if successful + // returns true if successful + // if callDataChangedIn then it will call dataChanged() --> paintEvent() bool setEffectorArrayLocation(int locationIn, bool callDataChangedIn); bool getIsFixedSize(); @@ -310,14 +326,16 @@ class LMMS_EXPORT VectorGraphDataArray // array: ------------------- - // returns the location of added/found point, -1 if not found and can not be added + // returns the location of added/found point, -1 if not found or can not be added int add(float xIn); - // deletes the data/sample if m_isFixedSize is disabled + // deletes the point in locationIn location if m_isFixedSize is disabled void del(unsigned int locationIn); - // clears data/sample array without any checks + // clears m_dataArray without any checks inline void clear() { m_dataArray.clear(); + m_needsUpdating.clear(); + // m_automationModelArray sould not be cleared without destruction clearedEvent(); getUpdatingFromPoint(-1); dataChanged(); @@ -327,8 +345,7 @@ class LMMS_EXPORT VectorGraphDataArray return m_dataArray.size(); } // clamps down the values to 0 - 1, -1 - 1 - // does check m_isFixedSize, m_isFixedValue, m_isFixedPos, - // sorts array, removes duplicated positions, calls dataChanged() + // sorts array, removes duplicated positions, calls dataChanged() if callDataChangedIn // clampIn: should clamp, sortIn: should sort void formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); @@ -358,16 +375,18 @@ class LMMS_EXPORT VectorGraphDataArray { return m_dataArray[locationIn].m_type; } - // returns attribLocation: 0 = y, 1 = c, 2 = valA, 3 = valB + // returns attribLocation: 0 = m_y, 1 = m_c, 2 = m_valA, 3 = m_valB (int VectorGraphPoint) unsigned int getAutomatedAttribLocation(unsigned int locationIn); unsigned int getEffectedAttribLocation(unsigned int locationIn); // returns true when m_effectOnlyPoints is true or // when getEffectedAttribLocation > 0 (y is uneffected) // -> when the current point CAN effect lines before it bool getEffectOnlyPoints(unsigned int locationIn); - // returns if the [effectNumberIn] effect is active based on effectNumberIn + // returns if the effectNumberIn-th effect is active bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); + // true when the automationModel's value changed since last check bool getIsAutomationValueChanged(unsigned int locationIn); + // can return nullptr inline FloatModel* getAutomationModel(unsigned int locationIn); @@ -390,33 +409,39 @@ class LMMS_EXPORT VectorGraphDataArray // set: ------------------- - // sets data array without any checks - // inport x and y coords + // sets / adds m_dataArray points + // .first = x, .second = y coords + // isCurvedIn -> should set curve automatically + // clearIn -> clear m_dataArray before setting + // clampIn -> clamp input positions + // rescaleIn -> scale input positions + // sortIn -> sort input positions + // callDataChangedIn -> call dataChanged() after -> paintEvent() void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); - // inport y coords void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); // set attribute: ------------------- - // sets position when m_isFixedPos is disabled, returns final location + // sets position when m_isFixedX is disabled, returns final location unsigned int setX(unsigned int locationIn, float xIn); - // sets value when m_isFixedValue is disabled + // sets value when m_isFixedY is disabled void setY(unsigned int locationIn, float yIn); - // sets value when m_isFixedValue is disabled + // sets value when m_isEditableAttrib is enabled void setC(unsigned int locationIn, float cIn); - // sets value when m_isFixedValue is disabled + // sets value when m_isEditableAttrib is enabled void setValA(unsigned int locationIn, float valueIn); - // + // sets value when m_isEditableAttrib is enabled void setValB(unsigned int locationIn, float valueIn); - // + // sets value when m_isEditableAttrib is enabled void setType(unsigned int locationIn, unsigned int typeIn); - // + // sets attribute settings when m_isEditableAttrib and m_isAutomatableEffectable is enabled void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); void setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn); void setEffectOnlyPoints(unsigned int locationIn, bool boolIn); void setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn); // if isAutomatedIn is true then make a new FloatModel and connect it, else delete // the currently used FloatModel + // runs if m_isAutomatableEffectable is enabled void setAutomated(unsigned int locationIn, bool isAutomatedIn); @@ -531,16 +556,16 @@ class LMMS_EXPORT VectorGraphDataArray int m_automationModel; }; // deletes the point's automation model - // locationIn = point location + // if locationIn == point location void delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn); // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); - // returns the curve value at a given x coord + // returns the curve value at a given x coord, does clamp float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); // applys the effect on a given value, does clamp float processEffect(unsigned int locationIn, float attribValueIn, unsigned int attribLocationIn, float effectValueIn); - // returns a VectorGraphPoint with modified attributes + // returns a VectorGraphPoint with modified attributes, does clamp float processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn); // line effects / types, m_type is used for this @@ -570,10 +595,10 @@ class LMMS_EXPORT VectorGraphDataArray // effected by the effector's values changing // ONLY WORKS IN SORTED ARRAYS void getUpdatingFromEffector(std::vector* updatingValuesIn); - // if locationIn > 0 -> adds the location to m_needsUpdating + // if locationIn >= 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedValues // changes in the size of m_dataArray (addtition, deletion, ect.) - // needs to cause a full update + // should to cause a full update void getUpdatingFromPoint(int locationIn); // adds the points that are changed because their // automation is changed @@ -581,6 +606,8 @@ class LMMS_EXPORT VectorGraphDataArray // recalculates and sorts m_needsUpdating so // every point is in there only once void getUpdatingOriginals(); + // gets every m_needsUpdating point's line's start and end effector point's location in the effector dataArray + // .first = start, .second = line end location (effector dataArray) //void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); void getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn); @@ -637,14 +664,15 @@ class LMMS_EXPORT VectorGraphDataArray // to m_needsUpdating before running // getValues() clears m_needsUpdating after it has run // every change is only applyed to the point's line (line started by the point) - // changes in y will cause multiple points to update + // changes in position will cause multiple points to update - // if we want to update all + // if we want to update all (the full line in getValues()) bool m_isDataChanged; // array containing output final float values for optimalization std::vector m_bakedValues; // unsorted array of locations in m_dataArray // that need to be updated + // sorted in getUpdatingOriginals() because some functions need this to be sorted std::vector m_needsUpdating; // this stores all the FloatModels @@ -657,4 +685,4 @@ class LMMS_EXPORT VectorGraphDataArray } // namespace lmms -#endif // LMMS_VECTORGRAPH_H +#endif // LMMS_GUI_VECTORGRAPH_H diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index bbadce41a7a..a8dbb5cdcd0 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -62,8 +62,6 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, { resize(widthIn, heightIn); - m_mouseDown = false; - m_mouseDrag = false; m_mousePress = false; m_addition = false; @@ -259,8 +257,6 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) } } } - - m_mouseDown = true; } void VectorGraphView::mouseMoveEvent(QMouseEvent* me) @@ -281,6 +277,8 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) if (m_mousePress == true) { + // the mouse needs to move a bigger distance + // before it is registered as dragging (-> m_mousePress = false) float curDistance = getDistance(x, m_graphHeight - y, m_lastTrackPoint.first, m_lastTrackPoint.second); if (curDistance > m_pointSize) @@ -299,6 +297,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { if (m_isCurveSelected == false) { + // dragging point std::pair convertedCoords = mapMousePos(x, m_graphHeight - y); convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); @@ -306,6 +305,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { + // dragging curve std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; curveValue = std::clamp(curveValue, -1.0f, 1.0f); @@ -314,6 +314,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (m_addition == false) { + // deleting points float curDistance = getDistance(x, m_graphHeight - y, m_lastTrackPoint.first, m_lastTrackPoint.second); if (curDistance > m_pointSize) @@ -332,6 +333,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else { + // adding points if (startMoving == true && m_isLastSelectedArray == true) { // trying to add to the last selected array @@ -385,6 +387,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) if (isGraphPressed(x, m_graphHeight - y) == true) { qDebug("mouseMove graphPressed: %d", m_lastTrackPoint.first); + // if did not drag if (m_mousePress == true) { // add/delete point @@ -416,7 +419,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } else if (m_isSelected == true && m_addition == false) { - // if selection was successful and deletion + // if selection was successful -> deletion model()->getDataArray(m_selectedArray)->del(m_selectedLocation); m_isSelected = false; m_isEditingActive = false; @@ -432,7 +435,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) else { qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray); - // if the "switch graph" button was pressed + // if the "switch graph" button was pressed in editing mode unsigned int oldSelectedArray = m_selectedArray; m_selectedLocation = 0; m_selectedArray = 0; @@ -467,14 +470,9 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) //qDebug("mouseRelease select new array final:", m_selectedArray); } m_addition = false; - m_mouseDown = false; - m_mouseDrag = false; // reset trackpoint m_lastTrackPoint.first = -1; - // triggering paintEvent qDebug("mouseReleaseEnd"); - update(); - emit drawn(); } void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) @@ -496,7 +494,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) } else if (isControlWindowPressed(m_graphHeight - y) == true) { - int pressLocation = getPressedInput(x, m_graphHeight - y, m_controlDisplayCount + 1); + int pressLocation = getPressedControlInput(x, m_graphHeight - y, m_controlDisplayCount + 1); if (pressLocation >= 0 && pressLocation != m_controlDisplayCount) { unsigned int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; @@ -520,11 +518,13 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); + // paint background if (m_background.isNull() == false) { p.drawPixmap(0, 0, m_background); } + // paint outline p.setPen(QPen(QColor(127, 127, 127, 255), 1)); p.drawLine(0, 0, width() - 1, 0); p.drawLine(width() - 1, 0, width() - 1, height() - 1); @@ -753,7 +753,7 @@ void VectorGraphView::paintEditing(QPainter* pIn) curBackColor = getFillColorFromBaseColor(curForeColor); } pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curBackColor); - pIn->fillRect(i * segmentLength, m_graphHeight, mapInputPos(inputValue, segmentLength), m_controlHeight, curForeColor); + pIn->fillRect(i * segmentLength, m_graphHeight, mapControlInputX(inputValue, segmentLength), m_controlHeight, curForeColor); pIn->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); } @@ -869,11 +869,11 @@ std::pair VectorGraphView::mapMousePos(int xIn, int yIn) static_cast(xIn / (float)width()), static_cast(yIn) * 2.0f / static_cast(m_graphHeight) - 1.0f); } -std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool nonNegativeIn) +std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool isNonNegativeIn) { - if (nonNegativeIn == true) + // mapping the point/sample positon to mouse/view position + if (isNonNegativeIn == true) { - // mapping the point/sample positon to mouse/view position return std::pair( static_cast(xIn * width()), static_cast(yIn * m_graphHeight)); @@ -897,7 +897,7 @@ std::pair VectorGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBI (xAIn + xBIn) / 2, yAIn + static_cast((curveIn / 2.0f + 0.5f) * (yBIn - yAIn))); } -int VectorGraphView::mapInputPos(float inputValueIn, unsigned int displayLengthIn) +int VectorGraphView::mapControlInputX(float inputValueIn, unsigned int displayLengthIn) { return (inputValueIn / 2.0f + 0.5f) * displayLengthIn; } @@ -913,6 +913,8 @@ float VectorGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBI bool VectorGraphView::addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn) { + // mouseYIn is calculated like this: + // m_graphHeight - y bool output = false; std::pair curMouseCoords = mapMousePos(mouseXIn, mouseYIn); curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); @@ -945,7 +947,6 @@ bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) // if the control window was pressed output = false; } - //qDebug("isGraphPressed end"); return output; } bool VectorGraphView::isControlWindowPressed(int mouseYIn) @@ -962,12 +963,14 @@ bool VectorGraphView::isControlWindowPressed(int mouseYIn) } void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) { + // mouseYIn is calculated like this: + // m_graphHeight - y setCursor(Qt::ArrowCursor); qDebug("mouseMove 7: %d", m_lastTrackPoint.first); if (m_isEditingActive == true) { - int pressLocation = getPressedInput(mouseXIn, m_graphHeight - mouseYIn, m_controlDisplayCount + 1); + int pressLocation = getPressedControlInput(mouseXIn, m_graphHeight - mouseYIn, m_controlDisplayCount + 1); int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; if (isDraggingIn == false && pressLocation == m_controlDisplayCount) { @@ -1044,7 +1047,7 @@ void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bo // unused bool bool isTrue = false; // set m_lastScndTrackPoint.first to the current input value - m_lastScndTrackPoint.first = mapInputPos(getInputAttribValue(location, &isTrue), m_graphHeight); + m_lastScndTrackPoint.first = mapControlInputX(getInputAttribValue(location, &isTrue), m_graphHeight); m_lastTrackPoint.first = curXIn; m_lastTrackPoint.second = curYIn; @@ -1058,7 +1061,7 @@ void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bo } } } -int VectorGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) +int VectorGraphView::getPressedControlInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) { int output = -1; if (m_isEditingActive == true && mouseYIn > m_graphHeight) @@ -1068,7 +1071,7 @@ int VectorGraphView::getPressedInput(int mouseXIn, int mouseYIn, unsigned int in if (output > inputCountIn) { output = inputCountIn; -qDebug("getPressedInput x location ERRROR: %d", mouseXIn); +qDebug("getPressedControlInput x location ERRROR: %d", mouseXIn); } return output; } @@ -1282,7 +1285,6 @@ QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColorIn) { brighten = 45; } - //qDebug("getFillColorFromBaseColor r: %d, g: %d, b: %d", baseColorIn.red(), baseColorIn.green(), baseColorIn.blue()); // > 127 * 3 if (colorSum > 382) { @@ -1299,7 +1301,6 @@ QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColorIn) static_cast(static_cast(baseColorIn.green()) * 0.78f + colorSum * 0.17f) + brighten, static_cast(static_cast(baseColorIn.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); } - //qDebug("getFillColorFromBaseColor r: %d, g: %d, b: %d", output.red(), output.green(), output.blue()); return output; } QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) @@ -1330,6 +1331,7 @@ QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int d } void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayTextIn) { + // context menu settings menu->addAction(embed::getIconPixmap("reload"), controlDisplayTextIn + tr(" remove automation") , this, SLOT(removeAutomation())); @@ -1424,7 +1426,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) if (location > -1) { m_selectedLocation = location; - // m_selectedArray + // m_selectedArray - do not set m_isSelected = true; m_isCurveSelected = false; m_isEditingActive = true; @@ -1436,7 +1438,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) m_selectedLocation = 0; // m_selectedArray can not be set to 0 in case of // m_isLastSelectedArray is active - // m_selectedArray = 0; + // m_selectedArray = 0; - do not reset m_isSelected = false; m_isCurveSelected = false; m_isEditingActive = false; @@ -1497,7 +1499,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance std::pair transformedMouse = mapMousePos(mouseXIn, mouseYIn); - // we dont use this bool + // unused bool bool found = false; bool isBefore = false; // get the nearest data to the mouse pos (x) in an optimalized way @@ -1717,8 +1719,7 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con { qDebug("saveSettings"); - //bool mustQuote = mustQuoteName(name); - //QDomElement me = doc.createElement(QString("VectorGraphModel") : name ); + // getting the models saving name QString saveName("VectorGraphModel"); if (name.size() > 0) { @@ -1739,9 +1740,11 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con } } + // getting the start of the attribute name QString readLocation = "a" + QString::number(i) + "-"; std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); bool isSaveable = m_dataArrays[i].getIsSaveable(); + // general saving attributes me.setAttribute(readLocation + "DataArraySize", isSaveable == true ? static_cast(m_dataArrays[i].size()) : 0); me.setAttribute(readLocation + "AutomationSize", isSaveable == true ? static_cast(automationModels->size()) : 0); @@ -1795,6 +1798,7 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n for (unsigned int i = 0; i < loadSize; i++) { qDebug("loadSettings 3"); + // getting the start of the attribute name QString readLocation = "a" + QString::number(i) + "-"; if (i < m_dataArrays.size() && curElement.hasAttribute(readLocation + "DataArraySize") == true) { @@ -1866,7 +1870,8 @@ VectorGraphDataArray::VectorGraphDataArray() m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); - // is not enabled by default + // fill color is not enabled by default + // (if alpha = 0) m_fillColor = QColor(0, 0, 0, 0); m_automatedColor = QColor(0, 0, 0, 0); @@ -1898,7 +1903,8 @@ VectorGraphDataArray::VectorGraphDataArray( m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); - // is not enabled by default + // fill color is not enabled by default + // (if alpha = 0) m_fillColor = QColor(0, 0, 0, 0); m_effectorLocation = -1; @@ -2028,6 +2034,7 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat bool found = true; if (locationIn >= 0) { + // if there is no valid id if (m_id < 0) { m_id = m_parent->getDataArrayNewId(); @@ -2035,6 +2042,7 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat qDebug("setEffectorArrayLocation cur_id %d", m_id); int arrayLocation = locationIn; found = false; + // checking if the effector chain has this dataArray in it for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) { int arrayId = m_parent->getDataArray(arrayLocation)->getId(); @@ -2049,6 +2057,7 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat break; } } + // if the effector chain does not contain this dataArray if (found == false) { m_effectorLocation = locationIn; @@ -2157,7 +2166,8 @@ int VectorGraphDataArray::add(float xIn) { qDebug("add 3. success, nearest: %d", location); targetLocation = location; - // slide the new data if the closest data pos is bigger + // slide the new data if the closest data x is bigger + // (done for swaping) if (isBefore == true) { // we are adding one value, so dataArray.size() will be a valid location @@ -2204,7 +2214,7 @@ void VectorGraphDataArray::del(unsigned int locationIn) { // deleting the points automationModel delAutomationModel(m_dataArray[locationIn].m_automationModel, true); - // swapping the point to the last location + // swaping the point to the last location // in m_dataArray swap(locationIn, m_dataArray.size() - 1, true); m_dataArray.pop_back(); @@ -2348,6 +2358,7 @@ int VectorGraphDataArray::getLocation(float xIn) int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut) { + // modified binary search if (m_dataArray.size() > 0) { int start = 0; @@ -2428,7 +2439,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); // deciding if the whole dataArray should be updated - // if the whole effectorArray was updated + // if the whole effectorDataArray was updated int effectedCount = 0; if (effectorIsChanged == true) { @@ -2474,11 +2485,11 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { m_needsUpdating[i] = i; } - qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); + qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); } float stepSize = 1.0f / static_cast(countIn); - // calculating point data + // calculating point data and lines if (m_needsUpdating.size() > 0 && m_bakedValues.size() > 0) { // calculating relative X locations (in lines) of the output values @@ -2498,15 +2509,15 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } } } - - // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, - //std::vector> effectorData; + // getting effectorDataArray pointer VectorGraphDataArray* effector = nullptr; if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) { effector = m_parent->getDataArray(m_effectorLocation); } + // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, + //std::vector> effectorData; //getValuesLocations(effector, &effectorData); /* for (unsigned int j = 0; j < effectorData.size(); j++) @@ -2524,6 +2535,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i //effectorData.clear(); } + // setting outputs if (isChangedOut != nullptr) { *isChangedOut = m_isDataChanged; @@ -2540,7 +2552,6 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } m_isDataChanged = false; - //effectorUpdatingValues->clear(); qDebug("getValuesB9"); return m_bakedValues; } @@ -2550,6 +2561,7 @@ std::vector VectorGraphDataArray::getLastValues() } std::vector VectorGraphDataArray::getEffectorArrayLocations() { + // getting the effector array chain std::vector output; int currentLocation = m_effectorLocation; for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) @@ -2591,6 +2603,7 @@ void VectorGraphDataArray::setDataArray(std::vector>* da //qDebug("setDataArray 1, x: %f, y: %f", dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second); m_dataArray[i].m_x = dataArrayIn->operator[](i).first; m_dataArray[i].m_y = dataArrayIn->operator[](i).second; + // calculating curves if (isCurvedIn == true && i > 0) { // TODO take in to account x coords @@ -2644,11 +2657,10 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) bool found = false; bool isBefore = false; location = getNearestLocation(xIn, &found, &isBefore); - // if an other point was not found at xIn - // and if getNearestLocation returned a value + // if an other point was not found exactly at xIn // and if dataArray end points are changeable if (found == false && ((m_isFixedEndPoints == true && - locationIn < m_dataArray.size() - 1 && location > 0) || + locationIn < m_dataArray.size() - 1 && locationIn > 0) || m_isFixedEndPoints == false)) { int targetLocation = location; @@ -2768,7 +2780,7 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); getUpdatingFromPoint(locationIn); - // the line before this can get added + // the line before this can get added later // in getUpdatingFromAutomation // so the point before this is not updated here @@ -2928,6 +2940,7 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate if (isAutomatedIn == true) { qDebug("setAutomated make"); + // if it is not already automated if (m_dataArray[locationIn].m_automationModel == -1) { m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); @@ -3077,6 +3090,7 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB } else { + // normal swap VectorGraphPoint swap = m_dataArray[locationAIn]; m_dataArray[locationAIn] = m_dataArray[locationBIn]; m_dataArray[locationBIn] = swap; @@ -3090,6 +3104,7 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB } float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) { + // calculating line curve float absCurveIn = std::abs(curveIn); float pow = curveIn < 0.0f ? 1.0f - xIn : xIn; pow = std::pow(pow, 1.0f - absCurveIn) - pow; @@ -3111,6 +3126,7 @@ float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribValueIn, unsigned int attribLocationIn, float effectValueIn) { + // calculating an effect on attribValueIn float output = attribValueIn; unsigned int attribLocation = getEffectedAttribLocation(locationIn); // effects @@ -3172,6 +3188,7 @@ float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribV } float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn) { + // adding the automation value to attribValueIn float output = 0.0f; // if automated FloatModel* automationModel = getAutomationModel(locationIn); @@ -3181,7 +3198,6 @@ float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int if (attribLocation == attribLocationIn) { output += automationModel->value(); - // qDebug("processAutomation -> value: %f", output); } } output += attribValueIn; @@ -3257,7 +3273,7 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vectoroperator[](startIn + i) * 628.318531f * valB + curveIn * 100.0f); } //qDebug("sineB_2"); - // copy values + // copy the first wave until the end for (unsigned int i = end; i < count; i++) { //qDebug("sineB_2.5: i: %d, %d, %d", (i - end), end, i); @@ -3427,6 +3443,7 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; } + // blending float size = static_cast(randomValues.size() / 2); for (unsigned int i = 0; i < count; i++) { @@ -3442,13 +3459,6 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingValuesIn) { - // Debug testing - /* - for (unsigned int i = 0; i < updatingValuesIn->size(); i++) - { - qDebug("getUpdatingFromEffector #1: [%d] -> %d", i, updatingValuesIn->operator[](i)); - } - */ VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); for (unsigned int i = 0; i < updatingValuesIn->size(); i++) { @@ -3458,7 +3468,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up unsigned int updatingEnd = i; for (unsigned int j = i + 1; j < updatingValuesIn->size(); j++) { - // we can skip 1 wide gaps because + // we can not skip gaps because // every updatingValuesIn point effects their line only // (the line that starts with the point) if (updatingValuesIn->operator[](updatingEnd) + 1 >= @@ -3481,6 +3491,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up updatingEndSlide = 1; } + // translating the effector data array locations to m_dataArray locations bool found = false; bool isBefore = false; int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i)), &found, &isBefore); @@ -3506,7 +3517,6 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - // *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); if (isBefore == false) @@ -3522,7 +3532,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationBefore = 0; } // if updatingEnd is the last point in effecor, then - // update everithing after if updatingend is the last location + // update everithing after if (updatingValuesIn->operator[](updatingEnd) + updatingEndSlide + 1 >= effector->size()) { qDebug("getUpdatingFromEffector updating everything after"); @@ -3575,7 +3585,7 @@ void VectorGraphDataArray::getUpdatingFromAutomation() qDebug("getUpdatingFromAutomation: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); m_needsUpdating.push_back(i); // if the automatable value effects the y (so the position) - // so the point before this is updated too + // the point before this is updated too if (i > 0 && getAutomatedAttribLocation(i) == 0) { m_needsUpdating.push_back(i - 1); @@ -3586,7 +3596,7 @@ void VectorGraphDataArray::getUpdatingFromAutomation() void VectorGraphDataArray::getUpdatingOriginals() { // selecting only original values - // TODO this might be faster if we sort before + // TODO this might be faster if the sort happens before std::vector originalValues; if (m_needsUpdating.size() > 0) { @@ -3617,7 +3627,8 @@ void VectorGraphDataArray::getUpdatingOriginals() } // sorting the array - // this is done because of optimalization + // this is done to optimize the functions that use + // m_needsUpdating in getValues() std::sort(originalValues.begin(), originalValues.end(), [](unsigned int a, unsigned int b) { @@ -3637,13 +3648,14 @@ void VectorGraphDataArray::getUpdatingOriginals() m_needsUpdating = originalValues; - // Debug testing + /* for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); } - originalValues.clear(); + */ } +// unused function, might be useful later /* void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) { @@ -3707,22 +3719,23 @@ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn unsigned int effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSizeIn)); qDebug("getValuesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutputIn->size()); + // current effector output Y near m_needsUpdating[iIn] point float curEffectY = effectorOutputIn->operator[](effectYLocation); float nextEffectY = effectorOutputIn->operator[](effectYLocation); + // getting the final automatable / effectable point values float curY = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_y, m_needsUpdating[iIn], 0); float curC = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_c, m_needsUpdating[iIn], 1); float curValA = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valA, m_needsUpdating[iIn], 2); float curValB = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valB, m_needsUpdating[iIn], 3); if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) { -qDebug("getValuesD6.5"); curY = processEffect(m_needsUpdating[iIn], curY, 0, curEffectY); curC = processEffect(m_needsUpdating[iIn], curC, 1, curEffectY); curValA = processEffect(m_needsUpdating[iIn], curValA, 2, curEffectY); curValB = processEffect(m_needsUpdating[iIn], curValB, 3, curEffectY); } -qDebug("getValuesD7"); + // from where to update line int start = effectYLocation; int end = start; @@ -3732,6 +3745,7 @@ qDebug("getValuesD7"); { effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSizeIn)); + // where updating line ends (+1) end = effectYLocation; nextY = processAutomation(m_dataArray[m_needsUpdating[iIn] + 1].m_y, m_needsUpdating[iIn] + 1, 0); @@ -3776,6 +3790,7 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f { m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } + // no line type } else if (type == 1) { @@ -3883,6 +3898,8 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f bool VectorGraphDataArray::isEffectedPoint(unsigned int locationIn) { + // loops througth all the effects + // return true when 1 or more effects are active bool output = false; for (unsigned int i = 0; i <= 8; i++) { From 671f8826e64a531d218c75c41410eecea74bf8ea Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 9 Apr 2024 08:33:34 +0200 Subject: [PATCH 053/184] VectorGraph_better_automation_saving --- include/VectorGraph.h | 3 +++ src/gui/widgets/VectorGraph.cpp | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index e9edc5cb34a..95c2c3732aa 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -454,6 +454,9 @@ class LMMS_EXPORT VectorGraphDataArray protected: // returns m_automationModelArray std::vector* getAutomationModelArray(); + // delete automationModels in m_automationModelArray + // that are not used by points (there should be 0 cases like this) + void delUnusedAutomation(); QString getSavedDataArray(); void loadDataArray(QString dataIn, unsigned int sizeIn); private: diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index a8dbb5cdcd0..39be1293c82 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1739,6 +1739,9 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con m_dataArrays[i].setAutomated(j, false); } } + // delete automation that is in the automationModelArray + // but not used by a point (there should be 0 cases like this) + m_dataArrays[i].delUnusedAutomation(); // getting the start of the attribute name QString readLocation = "a" + QString::number(i) + "-"; @@ -2974,6 +2977,41 @@ std::vector* VectorGraphDataArray::getAutomationModelArray() { return &m_automationModelArray; } +void VectorGraphDataArray::delUnusedAutomation() +{ + bool dataChangedVal = false; + std::vector usedAutomation; + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].m_automationModel != -1) + { + usedAutomation.push_back(m_dataArray[i].m_automationModel); + } + } + for (unsigned int i = 0; i < m_automationModelArray.size(); i++) + { + bool found = false; + for (unsigned int j = 0; j < usedAutomation.size(); j++) + { + if (i == usedAutomation[j]) + { + found = true; + break; + } + } + if (found == false) + { + dataChangedVal = true; + delAutomationModel(i, false); + } + } + + // getUpdatingFromPoint() is called in delAutomationModel() + if (dataChangedVal == true) + { + dataChanged(); + } +} QString VectorGraphDataArray::getSavedDataArray() { QString output; From 5d366d3156463ad8d111acf17b13766630a03efb Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 12 Apr 2024 20:08:26 +0200 Subject: [PATCH 054/184] fft_helpers_more_functions_added --- include/fft_helpers.h | 30 +++++++++++++ src/core/fft_helpers.cpp | 92 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/include/fft_helpers.h b/include/fft_helpers.h index 80c69a0a35a..521a65b2030 100644 --- a/include/fft_helpers.h +++ b/include/fft_helpers.h @@ -96,6 +96,36 @@ int LMMS_EXPORT absspec(const fftwf_complex *complex_buffer, float *absspec_buff unsigned int compl_length); +/** TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * @return 0 on success, else -1 + */ +int LMMS_EXPORT getPhase(const fftwf_complex *complex_buffer, float *phaseBufferOut, unsigned int compl_length); + + +/** TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * @return 0 on success, else -1 + */ +int LMMS_EXPORT inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, const float *phaseBufferIn, + unsigned int sampleRateIn, unsigned int compl_length); +int LMMS_EXPORT inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, unsigned int sampleRateIn, unsigned int compl_length); + + +/** TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * @return 0 on success, else -1 + */ +int LMMS_EXPORT getFreq(float *freqBufferOut, unsigned int sampleRateIn, unsigned int compl_length); +float LMMS_EXPORT getFreq(unsigned int locationIn, unsigned int sampleRateIn, unsigned int compl_length); + + /** Build fewer subbands from many absolute spectrum values. * Take care that - compressedbands[] array num_new elements long * - num_old > num_new diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index c2431034170..f83a45443e2 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -26,7 +26,10 @@ #include "fft_helpers.h" +#include + #include +#include #include "lmms_constants.h" namespace lmms @@ -179,6 +182,95 @@ int absspec(const fftwf_complex *complex_buffer, float *absspec_buffer, unsigned } +/* TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * return 0 on success, else -1 + */ +int getPhase(const fftwf_complex *complex_buffer, float *phaseBufferOut, unsigned int compl_length) +{ + if (complex_buffer == nullptr || phaseBufferOut == nullptr) {return -1;} + if (compl_length == 0) {return -1;} + + for (unsigned int i = 0; i < compl_length; i++) + { + phaseBufferOut[i] = std::atan(complex_buffer[i][1] / complex_buffer[i][0]); + } + + return 0; +} + + +/* TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * return 0 on success, else -1 + */ +int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, const float *phaseBufferIn, + unsigned int sampleRateIn, unsigned int compl_length) +{ + if (complex_buffer == nullptr || absspec_buffer == nullptr || phaseBufferIn == nullptr) {return -1;} + if (compl_length == 0) {return -1;} + /* + for a complex number $c$ of magnitude $m$ and phase offset $\theta$ + [ + c = me^{j(2\pi f + \theta)} = m\cos(2\pi f + \theta) + jm\sin(2\pi f + \theta) + ] + */ + // 2 / pi + float twoDivPi = 1.570796327f; + for (unsigned int i = 0; i < compl_length; i++) + { + float curFreq = getFreq(i, sampleRateIn, compl_length); + //std::cout << "inverseAbsspec i: " << i << " freq: " << curFreq << " amp: " << absspec_buffer[i] << " phase: " << phaseBufferIn[i] << std::endl; + //complex_buffer[i][0] = absspec_buffer[i] / std::cos(twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][1] = absspec_buffer[i] / std::sin(twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][0] = std::pow(absspec_buffer[i] * 2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][1] = std::pow(absspec_buffer[i] * 2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][0] = absspec_buffer[i] * std::cos(twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq + phaseBufferIn[i]); + complex_buffer[i][0] = absspec_buffer[i] * std::cos(phaseBufferIn[i]); + complex_buffer[i][1] = absspec_buffer[i] * std::sin(phaseBufferIn[i]); + } + return 0; +} +int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, unsigned int sampleRateIn, unsigned int compl_length) +{ + if (complex_buffer == nullptr || absspec_buffer == nullptr) {return -1;} + if (compl_length == 0) {return -1;} + + std::vector phaseInput(compl_length); + getPhase(complex_buffer, phaseInput.data(), compl_length); + return inverseAbsspec(complex_buffer, absspec_buffer, phaseInput.data(), sampleRateIn, compl_length); +} + + +/* TODO + * Take care that - compl_len is not bigger than complex_buffer! + * - absspec buffer is big enough! + * + * return 0 on success, else -1 + */ +int getFreq(float *freqBufferOut, unsigned int sampleRateIn, unsigned int compl_length) +{ + if (freqBufferOut == nullptr) {return -1;} + if (compl_length == 0) {return -1;} + + for (unsigned int i = 0; i < compl_length; i++) + { + freqBufferOut[i] = getFreq(i, sampleRateIn, compl_length); + } + + return 0; +} +float getFreq(unsigned int locationIn, unsigned int sampleRateIn, unsigned int compl_length) +{ + return locationIn * sampleRateIn / static_cast(compl_length) / 2.0f; +} + + /* Build fewer subbands from many absolute spectrum values. * Take care that - compressedbands[] array num_new elements long * - num_old > num_new From 38798affedacd002fb1b247851a1fa9b754a022a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:57:28 +0200 Subject: [PATCH 055/184] FFTFilter_filter_implemented_partially --- plugins/FFTFilter/FFTFilter.cpp | 26 ++- plugins/FFTFilter/FFTFilterControls.cpp | 18 +- plugins/FFTFilter/FFTProcessor.cpp | 286 +++++++++++++++++++----- plugins/FFTFilter/FFTProcessor.h | 16 +- src/core/fft_helpers.cpp | 6 + 5 files changed, 270 insertions(+), 82 deletions(-) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp index 44b6acd00ef..a2b6a440c82 100644 --- a/plugins/FFTFilter/FFTFilter.cpp +++ b/plugins/FFTFilter/FFTFilter.cpp @@ -57,16 +57,16 @@ Plugin::Descriptor PLUGIN_EXPORT FFTFilter_plugin_descriptor = FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : Effect(&FFTFilter_plugin_descriptor, parent, key), m_filterControls(this), - m_FFTProcessor(2048, false, FFTWindow::Rectangular), - m_inputBuffer(2048), + m_FFTProcessor(2048, true, FFTWindow::Rectangular), + m_inputBuffer(2048 * 2), m_outSampleBufferA(2048), m_outSampleBufferB(2048), m_outSampleUsedUp(0), m_outSampleBufferAUsed(false), m_complexMultiplier(2048, 1) { - //m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); - //m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); + m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); + m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); //std::vector graphXArray; //m_sampleRate; @@ -100,8 +100,8 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) qDebug("FFTFilterEffect write"); - //m_complexMultiplier = m_filterControls.getGraph(2048); - //m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); + m_complexMultiplier = m_filterControls.getGraph(2048); + m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); m_inputBuffer.write(buf, frames, true); @@ -111,13 +111,15 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) if (m_FFTProcessor.getOutputSamplesChanged() == true) { - //std::vector samples = m_FFTProcessor.getSample(); - //updateSampleArray(&samples, 0); - //updateSampleArray(&samples, 1); + qDebug("FFTFilterEffect get samples"); + std::vector samples = m_FFTProcessor.getSample(); + updateSampleArray(&samples, 0); + updateSampleArray(&samples, 1); + qDebug("FFTFilterEffect get samples end"); } if (m_FFTProcessor.getOutputSpectrumChanged() == true) { - std::vector FFTSpectrumOutput;// = m_FFTProcessor.getNormSpectrum(); + std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); std::vector> graphInput(80); if (graphInput.size() != graphXArray.size()) @@ -165,7 +167,7 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) } */ - m_filterControls.setGraph(&graphInput); + //m_filterControls.setGraph(&graphInput); // bin to freq //return getNyquistFreq() * bin_index / binCount(); @@ -215,7 +217,7 @@ bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) } // isNoneInput } // enabled && isRunning - //setOutputSamples(buf, frames); + setOutputSamples(buf, frames); float cutOff = 0.003f; /* diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp index 1b1790b14e4..2062e8e1c81 100644 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ b/plugins/FFTFilter/FFTFilterControls.cpp @@ -42,11 +42,27 @@ FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : m_displayFFTModel( true, this, tr("Display fft")), m_graphModel(1024, this, false) { + /* + void setIsFixedSize(bool valueIn); + void setIsFixedX(bool valueIn); + void setIsFixedY(bool valueIn); + void setIsFixedEndPoints(bool valueIn); + void setIsSelectable(bool valueIn); + void setIsEditableAttrib(bool valueIn); + void setIsAutomatableEffectable(bool valueIn); + void setIsSaveable(bool valueIn); + void setNonNegative(bool valueIn); + */ unsigned int arrayLocation = m_graphModel.addArray(); + //m_graphModel.getDataArray(arrayLocation)->setIsFixedSize(true); + //m_graphModel.getDataArray(arrayLocation)->setIsFixedX(true); + //m_graphModel.getDataArray(arrayLocation)->setIsFixedY(true); + //m_graphModel.getDataArray(arrayLocation)->setIsFixedEndPoints(true); m_graphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_graphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); m_graphModel.getDataArray(arrayLocation)->setIsSaveable(true); + //m_graphModel.getDataArray(arrayLocation)->setIsNonNegative(true); m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); @@ -112,7 +128,7 @@ void FFTFilterControls::setGraph(std::vector>* dataArray { qDebug("FFTFilterControls: set graph"); // void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); - m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, false, true, false, true); + m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, false, true, false, false); } } diff --git a/plugins/FFTFilter/FFTProcessor.cpp b/plugins/FFTFilter/FFTProcessor.cpp index de3a62187b0..869cfe62151 100644 --- a/plugins/FFTFilter/FFTProcessor.cpp +++ b/plugins/FFTFilter/FFTProcessor.cpp @@ -32,20 +32,23 @@ FFTProcessor::FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWind m_normSpectrum.resize(binCount(m_blockSize)); //m_complexMultiplier; + /* m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * binCount(m_blockSize)); // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); m_plan = fftwf_plan_dft_r2c_1d(m_blockSize, m_samplesIn.data(), m_out, FFTW_ESTIMATE); m_iplan = fftwf_plan_dft_c2r_1d(m_blockSize, m_out, m_samplesOut.data(), FFTW_ESTIMATE); + */ - m_fftWindow.resize(m_blockSize, 1.0); - precomputeWindow(m_fftWindow.data(), m_blockSize, m_FFTWindowType); + //m_fftWindow.resize(m_blockSize, 1.0); + //precomputeWindow(m_fftWindow.data(), m_blockSize, m_FFTWindowType); } FFTProcessor::~FFTProcessor() { qDebug("FFTProcessor destrc -1"); threadedTerminate(); + /* if (m_plan != nullptr) { fftwf_destroy_plan(m_plan); @@ -60,9 +63,10 @@ FFTProcessor::~FFTProcessor() { fftwf_free(m_out); } + */ qDebug("FFTProcessor destrc 2"); - m_out = nullptr; + //m_out = nullptr; qDebug("FFTProcessor destrc 3"); } @@ -92,7 +96,7 @@ void FFTProcessor::threadedStartThread(LocklessRingBuffer* ringBuff qDebug("analyze threaded thread init"); m_terminate = false; unsigned int blockSize = m_blockSize; - m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_plan, &m_iplan, m_out, &m_samplesIn, &m_samplesOut, &m_outputSpectrumChanged, &m_outputSamplesChanged, + m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_samplesOut, &m_samplesOut, &m_outputSpectrumChanged, &m_outputSamplesChanged, ringBufferIn, &m_complexMultiplier, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); qDebug("analyze threaded thread running"); } @@ -129,22 +133,33 @@ void FFTProcessor::setComplexMultiplier(std::vector* complexMultiplierIn) m_complexMultiplier = *complexMultiplierIn; } -void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_plan* inversePlanIn, fftwf_complex* complexIn, std::vector* samplesIn, std::vector* samplesOut, +void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, std::vector* samplesInB, std::vector* samplesOutB, std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, LocklessRingBuffer* ringBufferIn, std::vector* filterSpectrumIn, unsigned int sampLocIn, unsigned int blockSizeIn, std::vector* spectrumOut, std::mutex* outputAccessIn) { LocklessRingBufferReader reader(*ringBufferIn); - //std::vector samples(blockSizeIn); + std::vector samplesIn(blockSizeIn); + //std::vector samplesInBuffer(blockSizeIn); + std::vector samplesOut(blockSizeIn); + std::vector samplesOutBufferA(blockSizeIn); + std::vector samplesOutBufferB(blockSizeIn); std::vector absSpectrum(blockSizeIn); std::vector outputSpectrum(blockSizeIn); + fftwf_complex* fftComplex = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * binCount(blockSizeIn)); + // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); + // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); + fftwf_plan plan = fftwf_plan_dft_r2c_1d(blockSizeIn, samplesIn.data(), fftComplex, FFTW_ESTIMATE); + fftwf_plan iplan = fftwf_plan_dft_c2r_1d(blockSizeIn, fftComplex, samplesOut.data(), FFTW_ESTIMATE); + // TODO might not be the correct size float pi = 3.141592654f; std::vector hanningWindow(blockSizeIn); precomputeWindow(hanningWindow.data(), blockSizeIn, FFTWindow::Hanning); - float sumWindow = 0.0f; + float maxWindow = 0.0f; + /* for (int i = 0; i < blockSizeIn; i++) { // applying sinc function @@ -156,21 +171,26 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p sumWindow = sumWindow + hanningWindow[i]; qDebug("FFTProcessor final window [%d]: %f, %f", i, hanningWindow[i], sumWindow); } + */ + for (int i = 0; i < blockSizeIn; i++) + { + maxWindow = maxWindow < hanningWindow[i] ? hanningWindow[i] : maxWindow; + } for (int i = 0; i < blockSizeIn; i++) { // normalise - hanningWindow[i] = hanningWindow[i] / sumWindow; - //qDebug("FFTProcessor sumWindow [%d]: %f, %f", i, hanningWindow[i], sumWindow); + hanningWindow[i] = hanningWindow[i] / maxWindow; + qDebug("FFTProcessor sumWindow [%d]: %f, %f", i, hanningWindow[i], maxWindow); } - std::vector inverseOldReal(binCount(blockSizeIn)); - std::vector inverseOldImg(binCount(blockSizeIn)); - - std::vector storedSamples(binCount(blockSizeIn)); - - fpp_t frameFillLoc = 0; + fpp_t frameFillLoc = blockSizeIn / 2; + //fpp_t frameFillLoc = 0; + int outFillLoc = 0; + bool writeSamplesOut = true; + bool writeToBufferA = true; + int runFFTCount = 0; qDebug("analyzeB 0"); while (*terminateIn == false) { @@ -182,79 +202,79 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p auto bufferIn = reader.read_max(ringBufferIn->capacity()); size_t frameCount = bufferIn.size(); + if (frameCount > 0) + { + qDebug("analyzeB 0.5 DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG count: %ld", frameCount); + } + fpp_t frameIn = 0; while (frameIn < frameCount) { qDebug("analyzeB 1"); - outputAccessIn->lock(); while (frameIn < frameCount && frameFillLoc < blockSizeIn) //while (frameIn < frameCount && frameFillLoc < blockSizeIn / 2) { - //qDebug("analyzeB 2"); - samplesIn->operator[](frameFillLoc + blockSizeIn / 2) = bufferIn[frameIn][sampLocIn]; - samplesIn->operator[](frameFillLoc) = storedSamples[frameFillLoc]; - storedSamples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + //qDebug("analyzeB 2"); + //samplesInBuffer[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + samplesIn[frameFillLoc - blockSizeIn / 2] = samplesIn[frameFillLoc]; + samplesIn[frameFillLoc] = bufferIn[frameIn][sampLocIn]; + + //samplesIn[frameFillLoc + blockSizeIn / 2] = bufferIn[frameIn][sampLocIn]; + //samplesIn[frameFillLoc] = storedSamples[frameFillLoc]; + //storedSamples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; frameIn++; frameFillLoc++; } - outputAccessIn->unlock(); - if (frameFillLoc < blockSizeIn) //if (frameFillLoc < blockSizeIn / 2) { break; } - frameFillLoc = 0; + frameFillLoc = blockSizeIn / 2; + //frameFillLoc = 0; + /* + runFFTCount = 2; + } + while (runFFTCount > 0) + { + runFFTCount--; + int readStartLocation = runFFTCount == 1 ? 0 : blockSizeIn / 2; + for (unsigned int i = 0; i < blockSizeIn / 2; i++) + { + samplesIn[i] = samplesIn[i + blockSizeIn / 2]; + samplesIn[i + blockSizeIn / 2] = samplesInBuffer[i + readStartLocation]; + } + */ + qDebug("analyzeB run"); for (unsigned int i = 0; i < blockSizeIn; i++) { - //qDebug("FFTProcessor analyze samplesIn [%d]: %f", i, samplesIn->operator[](i)); + qDebug("FFTProcessor analyze samplesIn [%d]: %f", i, samplesIn[i]); } + qDebug("analyzeB run2 size: %ld", samplesIn.size()); // applying window // this is needed to attenuate the reverse complex correctly for (unsigned int i = 0; i < blockSizeIn; i++) { //qDebug("FFTProcessor analyze samplesIn before window [%d]: %f", i, samplesIn->operator[](i)); - //samplesIn->operator[](i) = samplesIn->operator[](i) * hanningWindow[i]; + //samplesIn[i] = samplesIn[i] * hanningWindow[i]; //qDebug("FFTProcessor analyze samplesOut after window [%d]: %f", i, samplesIn->operator[](i)); } - // TODO 1.: - // TODO x = samples (x is the sound input with a big length) Done - // TODO create hanning widnow Done - // TODO window = element wise multiplication of hanning and sinc(?) TODO function Done - // TODO normalise window Done - // TODO window_complex = fft(window, N) (it can be applyed before too?) Done - // TODO complex * window_complex Done - // TODO ifft() - // - // TODO 2.: - // TODO size = 512 - // TODO buffer(size * 2, 0) // create a (size * 2) buffer filled with 0-s - // TODO index = iterator througth 1 - 512 - // TODO output_buffer(size * 2, 0) - // TODO for (unsingned int j = 0; j < size; j++) // process 512 points of x at a time - // TODO shift buffer's second half to the first half - // TODO fill buffer's second half with new data x[index] (=samples) - // TODO fftbuffer = ifft(fft(buffer) * fft(window, size * 2)) // multiply complexes, window_complex is sized (size * 2) and contains the fft of window - // TODO output_buffer[index] = real(fftbuffer(size + 1:end)) // getting the real part (when complex?) of fftbuffer (from size + 1 to end) (setting output_buffers first 512 (sie) values) - // TODO index = index + size; // iterate througth the next 512 x (=sample) values - // - // TODO 3.: - // TODO //unsigned int reverseSize = blockSizeIn / 2; - //fftwf_execute(*planIn); + fftwf_execute(plan); + qDebug("analyzeB run3"); - absspec(complexIn, absSpectrum.data(), binCount(blockSizeIn)); + absspec(fftComplex, absSpectrum.data(), binCount(blockSizeIn)); normalize(absSpectrum, outputSpectrum, blockSizeIn); /* @@ -264,6 +284,7 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p } */ + qDebug("analyzeB run4"); outputAccessIn->lock(); for (unsigned int i = 0; i < binCount(blockSizeIn); i++) { @@ -273,8 +294,9 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p *spectrumChangedOut = true; qDebug("analyzeB try inverse"); - if (filterSpectrumIn->size() == blockSizeIn && false) + if (filterSpectrumIn->size() == blockSizeIn) { + /* for (unsigned int i = 0; i < binCount(blockSizeIn); i++) { inverseOldReal[i] = complexIn[i][0]; @@ -288,10 +310,10 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p // and then it gets run througth an fft for (unsigned int i = 0; i < blockSizeIn / 2; i++) { - /* + complexIn[i][0] = complexIn[i][0] * complexMultiplierIn->operator[](i); complexIn[i][1] = complexIn[i][1] * complexMultiplierIn->operator[](i); - */ + samplesIn->operator[](i) = filterSpectrumIn->operator[](i + blockSizeIn / 2); //changedAbsSpectum[i] = absSpectrum[i]; //qDebug("FFTProcessor analyze complexMultiplier [%d]: %f", i, complexMultiplierIn->operator[](i)); @@ -316,19 +338,161 @@ void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, fftwf_plan* p //complexIn[i][0] = inverseOldReal[i];// * complexIn[i][0]; //complexIn[i][1] = inverseOldImg[i];// * complexIn[i][1]; } - fftwf_execute(*inversePlanIn); + */ + /* + for (unsigned int i = 0; i < binCount(blockSizeIn); i++) + { + qDebug("analyzeB complex start %d, %f, %f", i, fftComplex[i][0], fftComplex[i][1]); + } + */ + std::vector absSpectrumB(blockSizeIn); for (unsigned int i = 0; i < blockSizeIn; i++) { - samplesOut->operator[](i) = samplesOut->operator[](i) / blockSizeIn; - //samplesOut->operator[](i) = samplesOut->operator[](i) / hanningWindow[i] / blockSizeIn; - //qDebug("FFTProcessor analyze samplesOut [%d]: %f", i, samplesOut->operator[](i)); + absSpectrumB[i] = absSpectrum[i] * filterSpectrumIn->operator[](i); } - outputAccessIn->unlock(); - *samplesChangedOut = true; + inverseAbsspec(fftComplex, absSpectrumB.data(), 44100, binCount(blockSizeIn)); + /* + for (unsigned int i = 0; i < binCount(blockSizeIn); i++) + { + qDebug("analyzeB complex end %d, %f, %f", i, fftComplex[i][0], fftComplex[i][1]); + } + */ + fftwf_execute(iplan); + + for (unsigned int i = 0; i < blockSizeIn; i++) + { + samplesOut[i] = samplesOut[i] / blockSizeIn * hanningWindow[i]; + //samplesOut[i] = samplesOut[i] / blockSizeIn; + //qDebug("FFTProcessor analyze 0. samplesOut convert_back: [%d]:%f", i, samplesOut[i]); + } + /* + if (writeSamplesOut == false) + { + if (writeToBufferA == true) + { + samplesOutBufferA = samplesOut; + qDebug("FFTProcessor analyze A reset reset reset reset reset reset reset reset reset reset reset reset reset"); + } + else + { + samplesOutBufferB = samplesOut; + qDebug("FFTProcessor analyze B reset reset reset reset reset reset reset reset reset reset reset reset reset"); + } + writeToBufferA = !writeToBufferA; + writeSamplesOut = true; + } + */ + //else + //{ + outputAccessIn->lock(); + float lastDebug = samplesOutB->operator[](samplesOutB->size() - 1); + /* + if (writeToBufferA == true) + { + for (unsigned int i = 0; i < blockSizeIn / 2; i++) + { + samplesOutB->operator[](i) = samplesOutBufferA[i + blockSizeIn / 2]; + qDebug("FFTProcessor analyze 1.A samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i + blockSizeIn / 2], i + blockSizeIn / 2); + } + for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) + { + samplesOutB->operator[](i) = samplesOutBufferB[i - blockSizeIn / 2]; + qDebug("FFTProcessor analyze 3.B samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferB[i - blockSizeIn / 2], i - blockSizeIn / 2); + } + } + else + { + for (unsigned int i = 0; i < blockSizeIn / 2; i++) + { + samplesOutB->operator[](i) = samplesOutBufferB[i + blockSizeIn / 2]; + qDebug("FFTProcessor analyze 1.B samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferB[i + blockSizeIn / 2], i + blockSizeIn / 2); + } + for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) + { + samplesOutB->operator[](i) = samplesOutBufferA[i - blockSizeIn / 2]; + qDebug("FFTProcessor analyze 3.A samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i - blockSizeIn / 2], i - blockSizeIn / 2); + } + } + + for (unsigned int i = 0; i < blockSizeIn; i++) + { + //qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i], i); + samplesOutB->operator[](i) += samplesOut[i]; + qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i], i); + } + */ + + if (outFillLoc == 0) + { + for (unsigned int i = 0; i < blockSizeIn; i++) + { + samplesOutB->operator[](i) = 0.0f; + } + for (unsigned int i = 0; i < blockSizeIn / 2; i++) + { + samplesOutB->operator[](i) = samplesOutBufferA[i + blockSizeIn / 2]; + //qDebug("FFTProcessor analyze 1. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i + blockSizeIn / 2], i + blockSizeIn / 2); + } + } + for (unsigned int i = outFillLoc; i < blockSizeIn; i++) + { + samplesOutB->operator[](i) += samplesOut[i - outFillLoc]; + //samplesOutB->operator[](i) = samplesOut[i - outFillLoc]; + //qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i - outFillLoc], i - outFillLoc); + } + outputAccessIn->unlock(); + + outFillLoc += blockSizeIn / 2; + if (outFillLoc + 1 >= blockSizeIn) + { + qDebug("FFTProcessor analyze write out, samplesOut copyed"); + samplesOutBufferA = samplesOut; + *samplesChangedOut = true; + outFillLoc = 0; + } + + /* + if (std::abs(samplesOutB->operator[](0) - lastDebug) > 0.08f && lastDebug != 0.0f) + { + qDebug("FFTProcessor analyze break 2"); + int* debugval = nullptr; + // *debugval = 1; + } + + for (unsigned int i = 0; i < blockSizeIn; i++) + { + qDebug("FFTProcessor analyze end samplesOut [%d]: %f", i, samplesOutB->operator[](i)); + if (i > 0 && std::abs(samplesOutB->operator[](i - 1) - samplesOutB->operator[](i)) > 0.15f && std::abs(samplesOutB->operator[](i)) >= 0.01f && std::abs(samplesOutB->operator[](i - 1)) >= 0.01f) + { + + qDebug("FFTProcessor analyze break 1"); + int* debugval = nullptr; + // *debugval = 1; + + } + } + */ + writeSamplesOut = false; + //} } } } + if (plan != nullptr) + { + fftwf_destroy_plan(plan); + } + if (iplan != nullptr) + { + fftwf_destroy_plan(iplan); + } + qDebug("FFTProcessor destrc 0"); + qDebug("FFTProcessor destrc 1"); + if (fftComplex != nullptr) + { + fftwf_free(fftComplex); + } + qDebug("analyzeB end"); } @@ -350,8 +514,8 @@ void FFTProcessor::threadedTerminate() // TODO multithread void FFTProcessor::rebuildWindow(FFTWindow FFTWindowIn) { - m_FFTWindowType = FFTWindowIn; - precomputeWindow(m_fftWindow.data(), m_blockSize, FFTWindowIn); + //m_FFTWindowType = FFTWindowIn; + //precomputeWindow(m_fftWindow.data(), m_blockSize, FFTWindowIn); } // TODO multithread diff --git a/plugins/FFTFilter/FFTProcessor.h b/plugins/FFTFilter/FFTProcessor.h index fbd935df8d4..b961ad69fc1 100644 --- a/plugins/FFTFilter/FFTProcessor.h +++ b/plugins/FFTFilter/FFTProcessor.h @@ -72,10 +72,10 @@ class FFTProcessor private: - static void threadedAnalyze(std::atomic* terminateIn, fftwf_plan* planIn, fftwf_plan* inversePlanIn, fftwf_complex* complexIn, std::vector* samplesIn, std::vector* samplesOut, - std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, - LocklessRingBuffer* ringBufferIn, std::vector* complexMultiplierIn, unsigned int sampLocIn, unsigned int blockSizeIn, - std::vector* spectrumOut, std::mutex* outputAccessIn); + static void threadedAnalyze(std::atomic* terminateIn, std::vector* samplesInB, std::vector* samplesOutB, + std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, + LocklessRingBuffer* ringBufferIn, std::vector* filterSpectrumIn, unsigned int sampLocIn, unsigned int blockSizeIn, + std::vector* spectrumOut, std::mutex* outputAccessIn); // Thread: // terminates the thread @@ -92,10 +92,10 @@ class FFTProcessor unsigned int m_frameFillLoc; // fft - fftwf_complex* m_out; + //fftwf_complex* m_out; - fftwf_plan m_plan; - fftwf_plan m_iplan; //inverse + //fftwf_plan m_plan; + //fftwf_plan m_iplan; //inverse std::atomic m_blockSize; @@ -105,7 +105,7 @@ class FFTProcessor std::vector m_complexMultiplier; - std::vector m_fftWindow; + //std::vector m_fftWindow; FFTWindow m_FFTWindowType; }; diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index f83a45443e2..57fdfc0b3f1 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -233,6 +233,12 @@ int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, c //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq + phaseBufferIn[i]); complex_buffer[i][0] = absspec_buffer[i] * std::cos(phaseBufferIn[i]); complex_buffer[i][1] = absspec_buffer[i] * std::sin(phaseBufferIn[i]); + + //complex_buffer[i][0] = absspec_buffer[i] * 2.718281828f; + //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, phaseBufferIn[i]); + //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); + //complex_buffer[i][0] = absspec_buffer[i] * std::cos(twoDivPi * curFreq / phaseBufferIn[i]); + //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq / phaseBufferIn[i]); } return 0; } From 3e0e90c019026ba48eed51e2e6e8041429d88f9c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:33:50 +0200 Subject: [PATCH 056/184] VectorGraph_editing_drawing_fixed --- src/core/fft_helpers.cpp | 8 ++-- src/gui/widgets/VectorGraph.cpp | 71 ++++++++++++++++----------------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index 57fdfc0b3f1..1345b13097f 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -231,14 +231,14 @@ int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, c //complex_buffer[i][1] = std::pow(absspec_buffer[i] * 2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); //complex_buffer[i][0] = absspec_buffer[i] * std::cos(twoDivPi * curFreq + phaseBufferIn[i]); //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq + phaseBufferIn[i]); - complex_buffer[i][0] = absspec_buffer[i] * std::cos(phaseBufferIn[i]); - complex_buffer[i][1] = absspec_buffer[i] * std::sin(phaseBufferIn[i]); + //complex_buffer[i][0] = absspec_buffer[i] * std::cos(phaseBufferIn[i]); + //complex_buffer[i][1] = absspec_buffer[i] * std::sin(phaseBufferIn[i]); //complex_buffer[i][0] = absspec_buffer[i] * 2.718281828f; //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, phaseBufferIn[i]); //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][0] = absspec_buffer[i] * std::cos(twoDivPi * curFreq / phaseBufferIn[i]); - //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq / phaseBufferIn[i]); + complex_buffer[i][0] = absspec_buffer[i] * std::acos(twoDivPi * curFreq / phaseBufferIn[i]); + complex_buffer[i][1] = absspec_buffer[i] * std::asin(twoDivPi * curFreq / phaseBufferIn[i]); } return 0; } diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 39be1293c82..1736626af48 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -241,8 +241,9 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) // try selecting the clicked point (if it is near) selectData(x, m_graphHeight - y); // avoid triggering editing window while deleting - // points are only added when - // m_isSelected == false -> m_isEditingActive = false + // points are only deleted when + // m_isSelected == true -> m_isEditingActive = true + // so m_isEditingActive is set to false if (m_isSelected == true && m_addition == false) { m_isEditingActive = false; @@ -384,55 +385,51 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) // get position int x = me->x(); int y = me->y(); - if (isGraphPressed(x, m_graphHeight - y) == true) + // if did not drag and graph is pressed + if (m_mousePress == true && isGraphPressed(x, m_graphHeight - y) == true) { qDebug("mouseMove graphPressed: %d", m_lastTrackPoint.first); - // if did not drag - if (m_mousePress == true) + // add/delete point + if (m_isSelected == false && m_addition == true) { - // add/delete point - if (m_isSelected == false && m_addition == true) + // if selection failed and addition + // get the first editable daraArray and add value + qDebug("release size: %ld", model()->getDataArraySize()); + bool success = false; + if (m_isLastSelectedArray == true) { - // if selection failed and addition - // get the first editable daraArray and add value - qDebug("release size: %ld", model()->getDataArraySize()); - bool success = false; - if (m_isLastSelectedArray == true) - { - // trying to add to the last selected array - success = addPoint(m_selectedArray, x, m_graphHeight - y); - } - if (success == false) + // trying to add to the last selected array + success = addPoint(m_selectedArray, x, m_graphHeight - y); + } + if (success == false) + { + // trying to add to all the selected arrays + for(unsigned int i = 0; i < model()->getDataArraySize(); i++) { - // trying to add to all the selected arrays - for(unsigned int i = 0; i < model()->getDataArraySize(); i++) + success = addPoint(i, x, m_graphHeight - y); + if (success == true) { - success = addPoint(i, x, m_graphHeight - y); - if (success == true) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - break; - } + m_selectedArray = i; + m_isLastSelectedArray = true; + break; } } } - else if (m_isSelected == true && m_addition == false) - { - // if selection was successful -> deletion - model()->getDataArray(m_selectedArray)->del(m_selectedLocation); - m_isSelected = false; - m_isEditingActive = false; - } - - m_mousePress = false; + } + else if (m_isSelected == true && m_addition == false) + { + // if selection was successful -> deletion + model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + m_isSelected = false; + m_isEditingActive = false; } } else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) { + qDebug("Mouse Release event try running processControlWindowPressed"); processControlWindowPressed(x, m_graphHeight - y, false, false, 0, 0); } - else + else if (isGraphPressed(x, m_graphHeight - y) == false) { qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray); // if the "switch graph" button was pressed in editing mode @@ -469,9 +466,11 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) } //qDebug("mouseRelease select new array final:", m_selectedArray); } + m_mousePress = false; m_addition = false; // reset trackpoint m_lastTrackPoint.first = -1; + updateGraph(); qDebug("mouseReleaseEnd"); } From 35697dafdb84f680e3fc77f680b2a0111ef89e36 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:01:11 +0200 Subject: [PATCH 057/184] WaveShaper_experimental_VectorGraph_implementation --- plugins/WaveShaper/WaveShaper.cpp | 14 ++- plugins/WaveShaper/WaveShaper.h | 1 + .../WaveShaper/WaveShaperControlDialog.cpp | 7 ++ plugins/WaveShaper/WaveShaperControlDialog.h | 1 + plugins/WaveShaper/WaveShaperControls.cpp | 105 +++++++++++++----- plugins/WaveShaper/WaveShaperControls.h | 10 +- 6 files changed, 104 insertions(+), 34 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index f21a2dff77f..c53582285fe 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -28,9 +28,12 @@ #include "lmms_math.h" #include "embed.h" #include "interpolation.h" +#include "VectorGraph.h" #include "plugin_export.h" +#include + namespace lmms { @@ -75,7 +78,8 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ const float w = wetLevel(); float input = m_wsControls.m_inputModel.value(); float output = m_wsControls.m_outputModel.value(); - const float * samples = m_wsControls.m_wavegraphModel.samples(); + std::vector graphSamples = m_wsControls.m_vectorGraphModel.getDataArray(0)->getValues(200); + //const float * samples = m_wsControls.m_wavegraphModel.samples(); const bool clip = m_wsControls.m_clipModel.value(); ValueBuffer *inputBuffer = m_wsControls.m_inputModel.valueBuffer(); @@ -112,17 +116,17 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ if( lookup < 1 ) { - s[i] = frac * samples[0] * posneg; + s[i] = frac * graphSamples[0] * posneg; } else if( lookup < 200 ) { - s[i] = linearInterpolate( samples[ lookup - 1 ], - samples[ lookup ], frac ) + s[i] = linearInterpolate(graphSamples[lookup - 1], + graphSamples[lookup], frac) * posneg; } else { - s[i] *= samples[199]; + s[i] *= graphSamples[199]; } } diff --git a/plugins/WaveShaper/WaveShaper.h b/plugins/WaveShaper/WaveShaper.h index 773419de8c8..c56e43b2065 100644 --- a/plugins/WaveShaper/WaveShaper.h +++ b/plugins/WaveShaper/WaveShaper.h @@ -29,6 +29,7 @@ #include "Effect.h" #include "WaveShaperControls.h" +#include "VectorGraph.h" namespace lmms { diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 045f84763f6..b9b57396801 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -29,6 +29,7 @@ #include "WaveShaperControls.h" #include "embed.h" #include "Graph.h" +#include "VectorGraph.h" #include "Knob.h" #include "PixmapButton.h" #include "LedCheckBox.h" @@ -48,6 +49,11 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); + auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024); + curGraph->setModel(&_controls->m_vectorGraphModel); + curGraph->move(10, 6); + + /* auto waveGraph = new Graph(this, Graph::Style::LinearNonCyclic, 204, 205); waveGraph -> move( 10, 6 ); waveGraph -> setModel( &_controls -> m_wavegraphModel ); @@ -58,6 +64,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( waveGraph->setPalette( pal ); waveGraph->setGraphColor( QColor( 85, 204, 145 ) ); waveGraph -> setMaximumSize( 204, 205 ); + */ auto inputKnob = new Knob(KnobType::Bright26, this); inputKnob -> setVolumeKnob( true ); diff --git a/plugins/WaveShaper/WaveShaperControlDialog.h b/plugins/WaveShaper/WaveShaperControlDialog.h index e76dcfccc3c..51f05bb7e0a 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.h +++ b/plugins/WaveShaper/WaveShaperControlDialog.h @@ -27,6 +27,7 @@ #define _WAVESHAPER_CONTROL_DIALOG_H #include "EffectControlDialog.h" +#include "VectorGraph.h" namespace lmms { diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index a03abc2efda..955a8950a48 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -24,12 +24,12 @@ */ +#include #include #include "WaveShaperControls.h" #include "WaveShaper.h" -#include "base64.h" -#include "Graph.h" +#include "VectorGraph.h" #include "Engine.h" #include "Song.h" @@ -44,13 +44,43 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_effect( _eff ), m_inputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Input gain" ) ), m_outputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Output gain" ) ), - m_wavegraphModel( 0.0f, 1.0f, 200, this ), + m_vectorGraphModel(1024, this, false), m_clipModel( false, this ) { - connect( &m_wavegraphModel, SIGNAL( samplesChanged( int, int ) ), - this, SLOT( samplesChanged( int, int ) ) ); + unsigned int arrayLocation = m_vectorGraphModel.addArray(); + //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedSize(true); + //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedX(true); + //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedY(true); + //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedEndPoints(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); + m_vectorGraphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); + m_vectorGraphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); + m_vectorGraphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); + + unsigned int arrayLocationB = m_vectorGraphModel.addArray(); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); + m_vectorGraphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); + m_vectorGraphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); + m_vectorGraphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); + + // connect VectorGraphDataArrays so the 2. will be able to effect the 1.: + m_vectorGraphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); + // draw default shape setDefaultShape(); + + connect(&m_vectorGraphModel, SIGNAL(dataChanged()), + this, SLOT(vectorGraphChanged())); } @@ -72,14 +102,8 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) m_clipModel.loadSettings( _this, "clipInput" ); -//load waveshape - int size = 0; - char * dst = 0; - base64::decode( _this.attribute( "waveShape"), &dst, &size ); - - m_wavegraphModel.setSamples( (float*) dst ); - delete[] dst; - + // loading VectorGraph + m_vectorGraphModel.loadSettings(_this, "VectorGraph"); } @@ -94,56 +118,83 @@ void WaveShaperControls::saveSettings( QDomDocument & _doc, m_clipModel.saveSettings( _doc, _this, "clipInput" ); -//save waveshape - QString sampleString; - base64::encode( (const char *)m_wavegraphModel.samples(), - m_wavegraphModel.length() * sizeof(float), sampleString ); - _this.setAttribute( "waveShape", sampleString ); - + // saving VectorGraph + m_vectorGraphModel.saveSettings(_doc, _this, "VectorGraph"); } +std::vector WaveShaperControls::getGraphSamples() +{ + if (m_vectorGraphModel.getDataArraySize() > 0) + { + std::vector output = m_vectorGraphModel.getDataArray(0)->getValues(200); + m_vectorGraphModel.dataChanged(); + } + else + { + return std::vector(200); + } +} void WaveShaperControls::setDefaultShape() { - auto shp = std::array{}; - for ( int i = 0; i<200; i++) + for (unsigned int i = 0; i < m_vectorGraphModel.getDataArraySize(); i++) { - shp[i] = ((float)i + 1.0f) / 200.0f; + // clearing the VectorGraphDataArray-s insied VectorGraphModel + m_vectorGraphModel.getDataArray(i)->clear(); } - m_wavegraphModel.setLength( 200 ); - m_wavegraphModel.setSamples( (float*)&shp ); + if (m_vectorGraphModel.getDataArraySize() > 0) + { + int addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.0f); + if (addedLocation >= 0) + { + m_vectorGraphModel.getDataArray(0)->setY(addedLocation, -1.0f); + } + + addedLocation = m_vectorGraphModel.getDataArray(0)->add(1.0f); + if (addedLocation >= 0) + { + m_vectorGraphModel.getDataArray(0)->setY(addedLocation, 1.0f); + } + } } void WaveShaperControls::resetClicked() { - setDefaultShape(); Engine::getSong()->setModified(); } void WaveShaperControls::smoothClicked() { - m_wavegraphModel.smoothNonCyclic(); + //m_wavegraphModel.smoothNonCyclic(); Engine::getSong()->setModified(); } void WaveShaperControls::addOneClicked() { + /* for( int i=0; i<200; i++ ) { m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] * onedB, 1.0f ) ); } + */ Engine::getSong()->setModified(); } void WaveShaperControls::subOneClicked() { + /* for( int i=0; i<200; i++ ) { m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] / onedB, 1.0f ) ); } + */ Engine::getSong()->setModified(); } +void WaveShaperControls::vectoGraphChanged() +{ + Engine::getSong()->setModified(); +} -} // namespace lmms \ No newline at end of file +} // namespace lmms diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 9473aae5d3f..0486ee21fa8 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -26,9 +26,11 @@ #ifndef WAVESHAPER_CONTROLS_H #define WAVESHAPER_CONTROLS_H +#include + #include "EffectControls.h" #include "WaveShaperControlDialog.h" -#include "Graph.h" +#include "VectorGraph.h" namespace lmms { @@ -63,6 +65,7 @@ class WaveShaperControls : public EffectControls return( new gui::WaveShaperControlDialog( this ) ); } + std::vector getGraphSamples(); private slots: void samplesChanged( int, int ); @@ -73,11 +76,14 @@ private slots: void addOneClicked(); void subOneClicked(); + void vectoGraphChanged(); + private: WaveShaperEffect * m_effect; FloatModel m_inputModel; FloatModel m_outputModel; - graphModel m_wavegraphModel; + //graphModel m_wavegraphModel; + VectorGraphModel m_vectorGraphModel; BoolModel m_clipModel; friend class gui::WaveShaperControlDialog; From a57bc33daa1ae594479f76615d804617148fbb67 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:31:59 +0200 Subject: [PATCH 058/184] WaveShaper_getGraphSamples_function_added --- plugins/WaveShaper/WaveShaper.cpp | 2 +- plugins/WaveShaper/WaveShaperControls.cpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index c53582285fe..18a2beaeb9f 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -78,7 +78,7 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ const float w = wetLevel(); float input = m_wsControls.m_inputModel.value(); float output = m_wsControls.m_outputModel.value(); - std::vector graphSamples = m_wsControls.m_vectorGraphModel.getDataArray(0)->getValues(200); + std::vector graphSamples = m_wsControls.getGraphSamples(); //const float * samples = m_wsControls.m_wavegraphModel.samples(); const bool clip = m_wsControls.m_clipModel.value(); diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 955a8950a48..fe46fc4b7ba 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -27,6 +27,8 @@ #include #include +#include + #include "WaveShaperControls.h" #include "WaveShaper.h" #include "VectorGraph.h" @@ -80,7 +82,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : setDefaultShape(); connect(&m_vectorGraphModel, SIGNAL(dataChanged()), - this, SLOT(vectorGraphChanged())); + this, SLOT(vectoGraphChanged())); } @@ -128,6 +130,7 @@ std::vector WaveShaperControls::getGraphSamples() { std::vector output = m_vectorGraphModel.getDataArray(0)->getValues(200); m_vectorGraphModel.dataChanged(); + return output; } else { From 7845724aaa8c86c45597bf79a750c80d9cc36707 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 12:47:30 +0200 Subject: [PATCH 059/184] VectorGraph_signals_redone --- include/VectorGraph.h | 8 ++++++-- src/gui/widgets/VectorGraph.cpp | 30 +++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 95c2c3732aa..ae8f1f1e228 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -94,6 +94,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void mouseDoubleClickEvent(QMouseEvent* me) override; protected slots: void updateGraph(); + void updateGraph(bool shouldUseGetLastValuesIn); void execConnectionDialog(); void removeAutomation(); @@ -225,6 +226,7 @@ Q_OBJECT { m_maxLength = maxLengthIn; emit dataChanged(); + emit updateGraphView(false); } } // returns added VectorGraphDataArray location @@ -235,6 +237,8 @@ Q_OBJECT inline void clearArray() { m_dataArrays.clear(); + emit dataChanged(); + emit updateGraphView(false); } // if the id is not found then it will return 0 int getDataArrayLocationFromId(int idIn); @@ -254,16 +258,16 @@ Q_OBJECT signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); + void updateGraphView(bool shouldUseGetLastValuesIn); // signals when a dataArray gets to 0 element size // locationIn is the location of the VectorGraphDataArray // locationIn can be -1 void clearedEvent(int locationIn); // style changed inside m_dataArray void styleChanged(); - // m_dataArrays length changed - void lengthChanged(); public slots: void dataArrayChanged(); + void updateGraphModel(bool shouldUseGetLastValuesIn); void dataArrayClearedEvent(int idIn); void dataArrayStyleChanged(); private: diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1736626af48..d1766426dab 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -470,7 +470,7 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) m_addition = false; // reset trackpoint m_lastTrackPoint.first = -1; - updateGraph(); + updateGraph(false); qDebug("mouseReleaseEnd"); } @@ -800,9 +800,9 @@ void VectorGraphView::paintEditing(QPainter* pIn) void VectorGraphView::modelChanged() { auto gModel = model(); - QObject::connect(gModel, SIGNAL(dataChanged()), - this, SLOT(updateGraph())); - QObject::connect(gModel, SIGNAL(lengthChanged()), + QObject::connect(gModel, SIGNAL(updateGraphView(bool)), + this, SLOT(updateGraph(bool))); + QObject::connect(gModel, SIGNAL(styleChanged()), this, SLOT(updateGraph())); } @@ -810,6 +810,11 @@ void VectorGraphView::updateGraph() { update(); } +void VectorGraphView::updateGraph(bool shouldUseGetLastValuesIn) +{ + m_useGetLastValues = shouldUseGetLastValuesIn; + update(); +} void VectorGraphView::execConnectionDialog() { if (m_isSelected == true) @@ -1632,6 +1637,7 @@ unsigned int VectorGraphModel::addArray() false, false, false, false, false, false, false, false, true, this, getDataArrayNewId()); m_dataArrays.push_back(tempArray); + emit dataChanged(); return m_dataArrays.size() - 1; } @@ -1668,17 +1674,26 @@ void VectorGraphModel::delArray(unsigned int locationIn) m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); } emit dataChanged(); + emit updateGraphView(false); } void VectorGraphModel::dataArrayChanged() { emit dataChanged(); + emit updateGraphView(false); +} +void VectorGraphModel::updateGraphModel(bool shouldUseGetLastValuesIn) +{ + // connects to external update signal + emit updateGraphView(shouldUseGetLastValuesIn); } void VectorGraphModel::dataArrayClearedEvent(int idIn) { // TODO needs testing int location = getDataArrayLocationFromId(idIn); emit clearedEvent(location); + emit dataChanged(); + emit updateGraphView(false); } void VectorGraphModel::dataArrayStyleChanged() @@ -2440,6 +2455,8 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); + m_isDataChanged = m_isDataChanged || countIn != m_bakedValues.size(); + // deciding if the whole dataArray should be updated // if the whole effectorDataArray was updated int effectedCount = 0; @@ -2475,12 +2492,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { if (countIn != m_bakedValues.size()) { - // reseting m_bakedValues m_bakedValues.resize(countIn); - for (unsigned int i = 0; i < m_bakedValues.size(); i++) - { - m_bakedValues[i] = 0.0f; - } } m_needsUpdating.resize(m_dataArray.size()); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) From b5ff696af50d537b7fe95efeeb366f3f18321714 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:07:07 +0200 Subject: [PATCH 060/184] VectorGraph_bugfixes --- include/VectorGraph.h | 10 +- src/gui/widgets/VectorGraph.cpp | 333 ++++++++++++++++---------------- 2 files changed, 180 insertions(+), 163 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index ae8f1f1e228..e9010cf7821 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -26,6 +26,7 @@ #define LMMS_GUI_VECTORGRAPH_H #include +#include #include #include #include @@ -255,6 +256,8 @@ Q_OBJECT virtual void loadSettings(const QDomElement& element); // read locations from saved data attributes unused but implemeted //int readLoc(unsigned int startIn, QString dataIn); + void lockGetValuesAccess(); + void unlockGetValuesAccess(); signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); @@ -274,6 +277,9 @@ public slots: std::vector m_dataArrays; unsigned int m_maxLength; + // block threads that want to access + // a dataArray's getValues() at the same time + std::mutex m_getValuesAccess; //friend class gui::VectorGraphView; }; @@ -406,7 +412,6 @@ class LMMS_EXPORT VectorGraphDataArray // returns the latest updated graph values // countIn is the retuned vector's size std::vector getValues(unsigned int countIn); - std::vector getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut); // returns m_bakedValues without updating std::vector getLastValues(); std::vector getEffectorArrayLocations(); @@ -613,6 +618,9 @@ class LMMS_EXPORT VectorGraphDataArray // recalculates and sorts m_needsUpdating so // every point is in there only once void getUpdatingOriginals(); + + // real getValues processing + std::vector getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut); // gets every m_needsUpdating point's line's start and end effector point's location in the effector dataArray // .first = start, .second = line end location (effector dataArray) //void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d1766426dab..fa56315a17a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -27,6 +27,7 @@ #include // sort #include // rand #include // unintptr_t +#include // locking when getValues #include #include #include @@ -481,6 +482,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) int y = me->y(); // if a data/sample is selected then show input dialog to change the data + qDebug("mouseDoubleClickEvent"); if (isGraphPressed(x, m_graphHeight - y) == true) { if (m_isSelected == true && me->button() == Qt::LeftButton) @@ -493,6 +495,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) } else if (isControlWindowPressed(m_graphHeight - y) == true) { + m_mousePress = true; int pressLocation = getPressedControlInput(x, m_graphHeight - y, m_controlDisplayCount + 1); if (pressLocation >= 0 && pressLocation != m_controlDisplayCount) { @@ -1847,6 +1850,14 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n } } } +void VectorGraphModel::lockGetValuesAccess() +{ + m_getValuesAccess.lock(); +} +void VectorGraphModel::unlockGetValuesAccess() +{ + m_getValuesAccess.unlock(); +} void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) { saveSettings(doc, element, QString("")); @@ -2428,147 +2439,14 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is std::vector VectorGraphDataArray::getValues(unsigned int countIn) { - //std::shared_ptr> updatingValues = std::make_shared>(); - //std::shared_ptr> updatingValues = std::make_shared>(); qDebug("getValuesA1"); + m_parent->lockGetValuesAccess(); std::vector output = getValues(countIn, nullptr, nullptr); + m_parent->unlockGetValuesAccess(); qDebug("getValuesA2, size: %ld", output.size()); qDebug("getValuesA3 finished"); return output; } -//std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::shared_ptr> updatingValuesOut) -std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut) -{ - bool effectorIsChanged = false; - //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); - std::vector effectorUpdatingValues; - std::vector effectorOutput; - std::vector outputXLocations(countIn); - bool isEffected = m_effectorLocation >= 0; - if (isEffected == true) - { - effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, &effectorUpdatingValues); - } - else - { - effectorOutput.resize(countIn); - } - qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); - - m_isDataChanged = m_isDataChanged || countIn != m_bakedValues.size(); - - // deciding if the whole dataArray should be updated - // if the whole effectorDataArray was updated - int effectedCount = 0; - if (effectorIsChanged == true) - { - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - effectedCount += isEffectedPoint(i) == true? 1 : 0; - } - if (effectedCount > m_dataArray.size() / 2) - { - m_isDataChanged = m_isDataChanged || effectorIsChanged; - } - } - - // updating m_needsUpdating - if (m_isDataChanged == false && countIn == m_bakedValues.size()) - { - if (isEffected == true && effectorUpdatingValues.size() > 0 && effectedCount > 0) - { - // effectorUpdatingValues needs to be sorted - // before use (in this case it is already sorted) - getUpdatingFromEffector(&effectorUpdatingValues); - } - qDebug("getValuesB2"); - getUpdatingFromAutomation(); - // sort and select only original - // values - getUpdatingOriginals(); - qDebug("getValuesB3"); - } - else - { - if (countIn != m_bakedValues.size()) - { - m_bakedValues.resize(countIn); - } - m_needsUpdating.resize(m_dataArray.size()); - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - m_needsUpdating[i] = i; - } - qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); - } - - float stepSize = 1.0f / static_cast(countIn); - // calculating point data and lines - if (m_needsUpdating.size() > 0 && m_bakedValues.size() > 0) - { - // calculating relative X locations (in lines) of the output values - // for later use in the line calculations - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - unsigned int start = static_cast - (std::ceil(m_dataArray[i].m_x / stepSize)); - if (i + 1 < m_dataArray.size()) - { - unsigned int end = static_cast - (std::ceil(m_dataArray[i + 1].m_x / stepSize)); - for (unsigned int j = start; j < end; j++) - { - outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); - } - } - } - // getting effectorDataArray pointer - VectorGraphDataArray* effector = nullptr; - if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) - { - effector = m_parent->getDataArray(m_effectorLocation); - } - - // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, - //std::vector> effectorData; - //getValuesLocations(effector, &effectorData); - /* - for (unsigned int j = 0; j < effectorData.size(); j++) - { - qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); - } - */ - qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); - - // calculate final lines - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); - } - //effectorData.clear(); - } - - // setting outputs - if (isChangedOut != nullptr) - { - *isChangedOut = m_isDataChanged; - } - if (m_needsUpdating.size() > 0) - { - if (updatingValuesOut != nullptr) - { - *updatingValuesOut = m_needsUpdating; - } - - // clearing the updated values - m_needsUpdating.clear(); - } - - m_isDataChanged = false; - qDebug("getValuesB9"); - return m_bakedValues; -} std::vector VectorGraphDataArray::getLastValues() { return m_bakedValues; @@ -3186,12 +3064,12 @@ float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribV // sine output = output + std::sin(effectValueIn * 100.0f); } - if (getEffect(locationIn, 4) == true) + if (getEffect(locationIn, 4) == true && output > 0.0f) { // power output = std::pow(output, effectValueIn); } - else if (getEffect(locationIn, 5) == true) + else if (getEffect(locationIn, 5) == true && output > 0.0f && effectValueIn != 0.0f) { // log output = std::log(output) / std::log(effectValueIn); @@ -3202,10 +3080,10 @@ float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribV // multiply output = output * 5.0f * effectValueIn; } - else if (getEffect(locationIn, 3) == true) + else if (getEffect(locationIn, 3) == true && effectValueIn != 0.0f) { - output = output / 5.0f / effectValueIn; // divide + output = output / 5.0f / effectValueIn; } if (getEffect(locationIn, 0) == true) @@ -3493,14 +3371,18 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< } // blending - float size = static_cast(randomValues.size() / 2); - for (unsigned int i = 0; i < count; i++) + if (randomValues.size() > 0) { - float randomValueX = xIn->operator[](startIn + i) * size; - float randomValueLocation = std::floor(randomValueX); - output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * - valAIn; + // real size + float size = static_cast(randomValues.size() / 2); + for (unsigned int i = 0; i < count; i++) + { + float randomValueX = xIn->operator[](startIn + i) * size; + float randomValueLocation = std::floor(randomValueX); + output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * + valAIn; + } } return output; @@ -3545,21 +3427,14 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up bool isBefore = false; int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i)), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); - if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i)) == true && isBefore == true) - { - qDebug("getUpdatingFromEffector locationBefore = %d + 1", locationBefore); - // if only points are effected and the nearest point - // is before [i] (so it needs to be uneffected) - // add 1 - locationBefore++; - } - else if (effector->getEffectOnlyPoints(updatingValuesIn->operator[](i)) == false && isBefore == false) + if (isBefore == false && locationBefore >= 0 && getEffectOnlyPoints(locationBefore) == true) { qDebug("getUpdatingFromEffector locationBefore = %d - 1", locationBefore); - // if lines are effected and the nearest point - // is after [i] (so the line and the point before this is effected) - // subtract 1 + // lines before could be effected eaven if the current nearest point + // can only be effected (its line can not be effected) + // so subtract 1 // remember points control the line after (connected to) them + // but in this case changes in the points position can effect the line before it locationBefore--; } // clamp @@ -3704,6 +3579,139 @@ void VectorGraphDataArray::getUpdatingOriginals() } */ } +std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut) +{ + bool effectorIsChanged = false; + //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); + std::vector effectorUpdatingValues; + std::vector effectorOutput; + std::vector outputXLocations(countIn); + bool isEffected = m_effectorLocation >= 0; + if (isEffected == true) + { + effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, &effectorUpdatingValues); + } + else + { + effectorOutput.resize(countIn); + } + qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); + + m_isDataChanged = m_isDataChanged || countIn != m_bakedValues.size(); + + // deciding if the whole dataArray should be updated + // if the whole effectorDataArray was updated + int effectedCount = 0; + if (effectorIsChanged == true) + { + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + effectedCount += isEffectedPoint(i) == true? 1 : 0; + } + if (effectedCount > m_dataArray.size() / 2) + { + m_isDataChanged = m_isDataChanged || effectorIsChanged; + } + } + + // updating m_needsUpdating + if (m_isDataChanged == false && countIn == m_bakedValues.size()) + { + if (isEffected == true && effectorUpdatingValues.size() > 0 && + (effectorIsChanged == false || effectedCount > 0)) + { + // effectorUpdatingValues needs to be sorted + // before use (in this case it is already sorted) + getUpdatingFromEffector(&effectorUpdatingValues); + } + qDebug("getValuesB2"); + getUpdatingFromAutomation(); + // sort and select only original + // values + getUpdatingOriginals(); + qDebug("getValuesB3"); + } + else + { + if (countIn != m_bakedValues.size()) + { + m_bakedValues.resize(countIn); + } + m_needsUpdating.resize(m_dataArray.size()); + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + m_needsUpdating[i] = i; + } + qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); + } + + float stepSize = 1.0f / static_cast(countIn); + // calculating point data and lines + if (m_needsUpdating.size() > 0 && m_bakedValues.size() > 0) + { + // calculating relative X locations (in lines) of the output values + // for later use in the line calculations + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + unsigned int start = static_cast + (std::ceil(m_dataArray[i].m_x / stepSize)); + if (i + 1 < m_dataArray.size()) + { + unsigned int end = static_cast + (std::ceil(m_dataArray[i + 1].m_x / stepSize)); + for (unsigned int j = start; j < end; j++) + { + outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); + //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); + } + } + } + // getting effectorDataArray pointer + VectorGraphDataArray* effector = nullptr; + if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) + { + effector = m_parent->getDataArray(m_effectorLocation); + } + + // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, + //std::vector> effectorData; + //getValuesLocations(effector, &effectorData); + /* + for (unsigned int j = 0; j < effectorData.size(); j++) + { + qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); + } + */ + qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); + + // calculate final lines + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); + } + //effectorData.clear(); + } + + // setting outputs + if (isChangedOut != nullptr) + { + *isChangedOut = m_isDataChanged; + } + if (m_needsUpdating.size() > 0) + { + if (updatingValuesOut != nullptr) + { + *updatingValuesOut = m_needsUpdating; + } + + // clearing the updated values + m_needsUpdating.clear(); + } + + m_isDataChanged = false; + qDebug("getValuesB9"); + return m_bakedValues; +} // unused function, might be useful later /* void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) @@ -3913,10 +3921,11 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f } if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) { - int startB = iIn == 0 ? 0 : start; - int endB = iIn >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; + int startB = m_needsUpdating[iIn] == 0 ? 0 : start; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; // process line effect // if it is enabled + qDebug("getValues run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { m_bakedValues[j] = processEffect(m_needsUpdating[iIn], m_bakedValues[j], 0, effectorOutputIn->operator[](j)); @@ -3936,8 +3945,8 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f } if (m_isNonNegative == true) { - int startB = iIn == 0 ? 0 : start; - int endB = iIn >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; + int startB = m_needsUpdating[iIn] == 0 ? 0 : start; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; for (int j = startB; j < endB; j++) { m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; From 824d5f4b4af6ad8faafd7322689b4f2f2df3639e Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:27:36 +0200 Subject: [PATCH 061/184] WaveShaper_finished_graph_implementation --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 1 + plugins/WaveShaper/WaveShaperControls.cpp | 14 ++++++++------ plugins/WaveShaper/WaveShaperControls.h | 10 ++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index b9b57396801..144e5331fef 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -51,6 +51,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024); curGraph->setModel(&_controls->m_vectorGraphModel); + curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); curGraph->move(10, 6); /* diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index fe46fc4b7ba..d819994a189 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -69,12 +69,12 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); - m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); - m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsNonNegative(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); m_vectorGraphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); m_vectorGraphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); - m_vectorGraphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); + m_vectorGraphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(144, 107, 255, 255)); // connect VectorGraphDataArrays so the 2. will be able to effect the 1.: m_vectorGraphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); @@ -82,7 +82,9 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : setDefaultShape(); connect(&m_vectorGraphModel, SIGNAL(dataChanged()), - this, SLOT(vectoGraphChanged())); + this, SLOT(vectorGraphChanged())); + connect(this, SIGNAL(vectorGraphUpdateView(bool)), + &m_vectorGraphModel, SLOT(updateGraphModel(bool))); } @@ -129,7 +131,7 @@ std::vector WaveShaperControls::getGraphSamples() if (m_vectorGraphModel.getDataArraySize() > 0) { std::vector output = m_vectorGraphModel.getDataArray(0)->getValues(200); - m_vectorGraphModel.dataChanged(); + emit vectorGraphUpdateView(true); return output; } else @@ -195,7 +197,7 @@ void WaveShaperControls::subOneClicked() Engine::getSong()->setModified(); } -void WaveShaperControls::vectoGraphChanged() +void WaveShaperControls::vectorGraphChanged() { Engine::getSong()->setModified(); } diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 0486ee21fa8..d113cf46ed0 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -67,6 +67,8 @@ class WaveShaperControls : public EffectControls std::vector getGraphSamples(); + + private slots: void samplesChanged( int, int ); @@ -76,8 +78,12 @@ private slots: void addOneClicked(); void subOneClicked(); - void vectoGraphChanged(); - + void vectorGraphChanged(); +signals: + // connected to dataArrayChanged() + // shouldUseGetLastValuesIn: when the graph is redrawn + // should it use the last updated values instead of updating again + void vectorGraphUpdateView(bool shouldUseGetLastValuesIn); private: WaveShaperEffect * m_effect; FloatModel m_inputModel; From bf8d2bb02d2b95dc6c63f6ad86f0138dde40b186 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:42:52 +0200 Subject: [PATCH 062/184] VectorGraph_aligned_curve_indicator --- src/gui/widgets/VectorGraph.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index fa56315a17a..444a30b4348 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -682,7 +682,8 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve if (dataArray->getIsEditableAttrib() == true) { std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - pIn->drawRect(posC.first - m_pointSize / 2, m_graphHeight - posC.second - m_pointSize / 2, m_pointSize, m_pointSize); + pIn->drawRect(posC.first - m_pointSize / 4 - m_pointSize / 2, + m_graphHeight - posC.second - m_pointSize / 4 - m_pointSize / 2, m_pointSize, m_pointSize); } } } From 57e6d0969713cc55feedcad9780f603659549c64 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:43:54 +0200 Subject: [PATCH 063/184] WaveShaper_removed_buttons --- .../WaveShaper/WaveShaperControlDialog.cpp | 42 +--------------- plugins/WaveShaper/WaveShaperControls.cpp | 48 ++++--------------- plugins/WaveShaper/WaveShaperControls.h | 6 --- 3 files changed, 9 insertions(+), 87 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 144e5331fef..95af4939207 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -54,19 +54,6 @@ WaveShaperControlDialog::WaveShaperControlDialog( curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); curGraph->move(10, 6); - /* - auto waveGraph = new Graph(this, Graph::Style::LinearNonCyclic, 204, 205); - waveGraph -> move( 10, 6 ); - waveGraph -> setModel( &_controls -> m_wavegraphModel ); - waveGraph -> setAutoFillBackground( true ); - pal = QPalette(); - pal.setBrush( backgroundRole(), - PLUGIN_NAME::getIconPixmap("wavegraph") ); - waveGraph->setPalette( pal ); - waveGraph->setGraphColor( QColor( 85, 204, 145 ) ); - waveGraph -> setMaximumSize( 204, 205 ); - */ - auto inputKnob = new Knob(KnobType::Bright26, this); inputKnob -> setVolumeKnob( true ); inputKnob -> setVolumeRatio( 1.0 ); @@ -84,33 +71,12 @@ WaveShaperControlDialog::WaveShaperControlDialog( outputKnob->setHintText( tr( "Output gain:" ), "" ); auto resetButton = new PixmapButton(this, tr("Reset wavegraph")); - resetButton -> move( 162, 221 ); + resetButton -> move( 142, 225 ); resetButton -> resize( 13, 46 ); resetButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_active" ) ); resetButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_inactive" ) ); resetButton->setToolTip(tr("Reset wavegraph")); - auto smoothButton = new PixmapButton(this, tr("Smooth wavegraph")); - smoothButton -> move( 162, 237 ); - smoothButton -> resize( 13, 46 ); - smoothButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_active" ) ); - smoothButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "smooth_inactive" ) ); - smoothButton->setToolTip(tr("Smooth wavegraph")); - - auto addOneButton = new PixmapButton(this, tr("Increase wavegraph amplitude by 1 dB")); - addOneButton -> move( 131, 221 ); - addOneButton -> resize( 13, 29 ); - addOneButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "add1_active" ) ); - addOneButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "add1_inactive" ) ); - addOneButton->setToolTip(tr("Increase wavegraph amplitude by 1 dB")); - - auto subOneButton = new PixmapButton(this, tr("Decrease wavegraph amplitude by 1 dB")); - subOneButton -> move( 131, 237 ); - subOneButton -> resize( 13, 29 ); - subOneButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "sub1_active" ) ); - subOneButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "sub1_inactive" ) ); - subOneButton->setToolTip(tr("Decrease wavegraph amplitude by 1 dB")); - auto clipInputToggle = new LedCheckBox("Clip input", this, tr("Clip input"), LedCheckBox::LedColor::Green); clipInputToggle -> move( 131, 252 ); clipInputToggle -> setModel( &_controls -> m_clipModel ); @@ -118,12 +84,6 @@ WaveShaperControlDialog::WaveShaperControlDialog( connect( resetButton, SIGNAL (clicked () ), _controls, SLOT ( resetClicked() ) ); - connect( smoothButton, SIGNAL (clicked () ), - _controls, SLOT ( smoothClicked() ) ); - connect( addOneButton, SIGNAL( clicked() ), - _controls, SLOT( addOneClicked() ) ); - connect( subOneButton, SIGNAL( clicked() ), - _controls, SLOT( subOneClicked() ) ); } diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index d819994a189..818f32abe92 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -70,7 +70,6 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsNonNegative(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); m_vectorGraphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); m_vectorGraphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); @@ -88,16 +87,6 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : } - - -void WaveShaperControls::samplesChanged( int _begin, int _end) -{ - Engine::getSong()->setModified(); -} - - - - void WaveShaperControls::loadSettings( const QDomElement & _this ) { //load input, output knobs @@ -148,7 +137,7 @@ void WaveShaperControls::setDefaultShape() m_vectorGraphModel.getDataArray(i)->clear(); } - if (m_vectorGraphModel.getDataArraySize() > 0) + if (m_vectorGraphModel.getDataArraySize() > 1) { int addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.0f); if (addedLocation >= 0) @@ -161,39 +150,18 @@ void WaveShaperControls::setDefaultShape() { m_vectorGraphModel.getDataArray(0)->setY(addedLocation, 1.0f); } - } -} -void WaveShaperControls::resetClicked() -{ - Engine::getSong()->setModified(); -} - -void WaveShaperControls::smoothClicked() -{ - //m_wavegraphModel.smoothNonCyclic(); - Engine::getSong()->setModified(); -} - -void WaveShaperControls::addOneClicked() -{ - /* - for( int i=0; i<200; i++ ) - { - m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] * onedB, 1.0f ) ); + addedLocation = m_vectorGraphModel.getDataArray(1)->add(0.5f); + if (addedLocation >= 0) + { + m_vectorGraphModel.getDataArray(1)->setY(addedLocation, -1.0f); + } } - */ - Engine::getSong()->setModified(); } -void WaveShaperControls::subOneClicked() +void WaveShaperControls::resetClicked() { - /* - for( int i=0; i<200; i++ ) - { - m_wavegraphModel.setSampleAt( i, qBound( 0.0f, m_wavegraphModel.samples()[i] / onedB, 1.0f ) ); - } - */ + setDefaultShape(); Engine::getSong()->setModified(); } diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index d113cf46ed0..7c59f90e51c 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -70,13 +70,7 @@ class WaveShaperControls : public EffectControls private slots: - void samplesChanged( int, int ); - void resetClicked(); - void smoothClicked(); - - void addOneClicked(); - void subOneClicked(); void vectorGraphChanged(); signals: From 5bdf5ee4a605ee86d50e1b919337ed74136b7862 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 21:50:01 +0200 Subject: [PATCH 064/184] WaveShaper_removed_pixmaps --- plugins/WaveShaper/add1_active.png | Bin 555 -> 0 bytes plugins/WaveShaper/add1_inactive.png | Bin 573 -> 0 bytes plugins/WaveShaper/smooth_active.png | Bin 674 -> 0 bytes plugins/WaveShaper/smooth_inactive.png | Bin 699 -> 0 bytes plugins/WaveShaper/sub1_active.png | Bin 525 -> 0 bytes plugins/WaveShaper/sub1_inactive.png | Bin 555 -> 0 bytes 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 plugins/WaveShaper/add1_active.png delete mode 100644 plugins/WaveShaper/add1_inactive.png delete mode 100644 plugins/WaveShaper/smooth_active.png delete mode 100644 plugins/WaveShaper/smooth_inactive.png delete mode 100644 plugins/WaveShaper/sub1_active.png delete mode 100644 plugins/WaveShaper/sub1_inactive.png diff --git a/plugins/WaveShaper/add1_active.png b/plugins/WaveShaper/add1_active.png deleted file mode 100644 index 71979b1812d8af5eaf203ade2d2b00b75a40b1bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 555 zcmV+`0@VG9P)hP0efi?$_ZpXRfAnN)L`ZzMtRk_q{uQ9Mx(S&+`Q6 z`Sd(bf*?S-t}BGjxeG}!(511Aha@&hj6-d@j5`!X5o^*Rnf6h&ty=t_as z(=yqqcU^h(cG9qDWdc$P0Ck{AKmSJhQ;K5caIa>(2@C>7vK_+O6Mi-3s58~};qB=G%h1LF1R z#BBVHWo}~UuA(+};qgbfUxb^3hIQrxsO24t**6_~ova`3n7uyj1+Ev6M_ceWhQ)1o zIBdU8yVi|CWTAp|uvEKH=j^7P)aBDJWTuGZ6f#q^m=%Wxr7WfZ$>#EBcCWK}?_X1m zyaN9M=_h4Wxqy5QQKLhN4mcZkP507_(a*l3m$sA6Ztf?hnZ7LNHChKz@+1BJ(?F@- t8;ZcCfr}6X0lx2_%irt!zSL?pjsO){Ak(*s#TNho002ovPDHLkV1mn;_4)t+ diff --git a/plugins/WaveShaper/add1_inactive.png b/plugins/WaveShaper/add1_inactive.png deleted file mode 100644 index 9557735ed752760d73c7bee56f5ca770a4c4d1d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 573 zcmV-D0>b@?P)FxxGEqiUC^+9k@RFU-$9LI{EH`vC2xLbMbeRCXfX%UqVraytq$fWhGj28SnD z&gOWL%PK6=tVlnP4#$Ui%9o!tN& z?%Mzi+#XSycXHR>uCleY&9mn#EI(ajdTKIY;d+3NpFS(BtFtR11gZ28sq_#)5Qpa$ z&K(;aA-`$SXf()gS_%u-Kb~LY;q0u!E}iLBvkUv>?>3pG1$ukB$t*2IW_l4zG)-m7 zNjtigN=Lk!>i|%59fT0Pdi{o(=_z)$zw+SzOys0B*P-S*6!ITC-y*!Llq&)BG=guW6dHSS<1zqwT+Tih^z100000 LNkvXXu0mjfPrm(e diff --git a/plugins/WaveShaper/smooth_active.png b/plugins/WaveShaper/smooth_active.png deleted file mode 100644 index 29e880834606b6d0173f07b0b082c0058aa4821e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 674 zcmV;T0$u%yP)&z>g~&W zb0bZnq8^#i`Iu|OJ6-@l3P7~3bAMtGW9l94=bptbS_4oS>x<7-#`=ir{qX_RLJ{NA z3)JfkDz{D~^3lCOQ;%9LztR^A*IL&(0$NKm4@fRc;FtuCiR7|G^>W%oJ^6%e`>4ks z(TbQEO`QE&9$Wz>$iTN7gK|Q;?2A9LR5+{q?9f~oJKEU*F7~fcc>EW>6*XT9@UqgEec6Bme zC#<3W*{9X`)rIE#exp+B5|7T_vn{S6OY6weI(l)fIx6`ha-|>1DCBBCvRq8$|H-Hr zix;cl^ESb~JfbzJ=;}K9FH>~=}cxX{2P;S zxBUn6cfD|Pe*3DgmQuu)Kyf2g zP_SA|+NCQOE?r2HnWm+i2v*3V5ut8u7R64cdCx^V<0NTDUFO1pd(VCEzVj}3K1e2$ zsH!S~rhuxdGL=dZ2#3S+$njIOw})v4E0umy_>!lkR4QTH6*e}0G=*?QQP|wvbAKt$sziPM;LXclI(4#%>Iz8Is<}|f~xtGt#Wj^xi#Vo4Y;mdn#*Ph|k zQX5;A1+Xhzh)NX_QpdF#Dx$Q00#T}+;xNfeK`B49!>Bmo#E`cOJod_$CKl} zyi*sbJHxAGKYbqIq6$cf6tbQNdSf~Pcn_D3V#yq-_8wYA0Eo43UDh%fK0 z`9HD4wE)PyTR1ixA7>^pO=ss}ip6gX$H!U9tpH${OFS63@A_wYV@Od!Q54G7HUQT4 zFBC=b<-JxLfBn4bn|Fmfw{XlbbDY0;82~*R;mJ&b3w!a?+2<@K=K;8O<2H-Qd4v$y zwoNb?#I|ihp^*FBG~&Hh8+RQ&;rfNOd|kfbjC&!a0Hixx=}eZaVUjgW(wVF~gXU6> zdv|Vfu&tH8ySFgRoG;&KhW~ZO_wD$4VeOBNY%Vuxq7{>V?!fxW)jm34)n9U zyu$G4m@n_w@xR3Y0YDz=>>>~dG{t*dO3C+PVfV`!RN7ENtxX|(r)*K#u^^R7p=nyv h{Hti1CKnbK_zi%8hD-4>h35bO002ovPDHLkV1h%`KWG2| diff --git a/plugins/WaveShaper/sub1_active.png b/plugins/WaveShaper/sub1_active.png deleted file mode 100644 index 434baca328190f35254e7dff022cb1d991a2620c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 525 zcmV+o0`mQdP)GY;Qb633IJ7$NNj&6u~(#e<6{CuQPk12v6!Zlwv|~khX6>%rm>Mh z?f#5e*QUnGDdF*4tQBVf$vuHg3eNpD(|9ieA{sLRBn+FvkMr$j&kwY7tj&#~PD-$P z1`BDJ8i^S|csv*H)!U-R^q)R^*Iu%_N;sZEUZ29>5O#jR@~B?1+gwjakj+V?g&DVr zx`|e;e7QifX=Fel*|f$q9T6y{v95b+etOk><;hDL)BCXgnZ()zYUwfZRqv^BqXVEC z621ARc_=`vzJBg&)oVd>B3=Edpj7V-Mc~2k5O|)4>$>+cdtKL+LZQGvz&sq5O5gGH P00000NkvXXu0mjf9=PUj diff --git a/plugins/WaveShaper/sub1_inactive.png b/plugins/WaveShaper/sub1_inactive.png deleted file mode 100644 index a766e6a19146342ec3232c242a149ccb40fac74a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 555 zcmV+`0@VG9P)2Yg3oRCl$=-o`ballD`#8=Y4t|x0I*!B1Nt5H_-=Ul8x=yWDBLdK9G!Q~u8mZv~ zCA;un-pY20KPcG+N_K%_;TsbV#}Pu{x-I}w03n)zUA}leLy)$W_1{ebkW9qMWOfGcOKjyqqUBwt5(Y7RzI?w$tp|(WcRHeG))WrpGqk?Iy^YvNNsut`i=I` tO-~yx%~KaF%fd9xYuUY~Y07*)&ly?Vd~3Vaoy`CM002ovPDHLkV1ku5^s)c| From a35cdd80bbc88aad428a94eeb7046d945f48f08b Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 14 Apr 2024 22:03:57 +0200 Subject: [PATCH 065/184] FFTFilter_deleted_filter --- cmake/modules/PluginList.cmake | 1 - plugins/FFTFilter/CMakeLists.txt | 3 - plugins/FFTFilter/FFTFilter.cpp | 385 -------------- plugins/FFTFilter/FFTFilter.h | 94 ---- plugins/FFTFilter/FFTFilterControlDialog.cpp | 130 ----- plugins/FFTFilter/FFTFilterControlDialog.h | 53 -- plugins/FFTFilter/FFTFilterControls.cpp | 135 ----- plugins/FFTFilter/FFTFilterControls.h | 90 ---- plugins/FFTFilter/FFTProcessor.cpp | 528 ------------------- plugins/FFTFilter/FFTProcessor.h | 114 ---- plugins/FFTFilter/artwork.png | Bin 7739 -> 0 bytes plugins/FFTFilter/logo.png | Bin 774 -> 0 bytes 12 files changed, 1533 deletions(-) delete mode 100644 plugins/FFTFilter/CMakeLists.txt delete mode 100644 plugins/FFTFilter/FFTFilter.cpp delete mode 100644 plugins/FFTFilter/FFTFilter.h delete mode 100644 plugins/FFTFilter/FFTFilterControlDialog.cpp delete mode 100644 plugins/FFTFilter/FFTFilterControlDialog.h delete mode 100644 plugins/FFTFilter/FFTFilterControls.cpp delete mode 100644 plugins/FFTFilter/FFTFilterControls.h delete mode 100644 plugins/FFTFilter/FFTProcessor.cpp delete mode 100644 plugins/FFTFilter/FFTProcessor.h delete mode 100644 plugins/FFTFilter/artwork.png delete mode 100644 plugins/FFTFilter/logo.png diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake index 6e9b53a7a2d..009679533ae 100644 --- a/cmake/modules/PluginList.cmake +++ b/cmake/modules/PluginList.cmake @@ -38,7 +38,6 @@ SET(LMMS_PLUGIN_LIST DynamicsProcessor Eq Flanger - FFTFilter GranularPitchShifter HydrogenImport LadspaBrowser diff --git a/plugins/FFTFilter/CMakeLists.txt b/plugins/FFTFilter/CMakeLists.txt deleted file mode 100644 index 95f08a747eb..00000000000 --- a/plugins/FFTFilter/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -INCLUDE(BuildPlugin) - -BUILD_PLUGIN(FFTFilter FFTFilter.cpp FFTFilterControls.cpp FFTFilterControlDialog.cpp FFTProcessor.cpp MOCFILES FFTFilterControls.h FFTFilterControlDialog.h FFTProcessor.h EMBEDDED_RESOURCES artwork.png logo.png) diff --git a/plugins/FFTFilter/FFTFilter.cpp b/plugins/FFTFilter/FFTFilter.cpp deleted file mode 100644 index a2b6a440c82..00000000000 --- a/plugins/FFTFilter/FFTFilter.cpp +++ /dev/null @@ -1,385 +0,0 @@ -/* - * FFTFilter.cpp - main FFTFilter class - * - * Copyright (c) 2024 Szeli1 TODO - * - * 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 - -#include "FFTFilter.h" -#include "FFTProcessor.h" - -#include "embed.h" -#include "plugin_export.h" -#include "fft_helpers.h" -#include "lmms_constants.h" - -namespace lmms -{ - -extern "C" -{ - -Plugin::Descriptor PLUGIN_EXPORT FFTFilter_plugin_descriptor = -{ - LMMS_STRINGIFY(PLUGIN_NAME), - "FFTFilter", - QT_TRANSLATE_NOOP("PluginBrowser", "TEMP"), - "TEMP", - 0x0100, - Plugin::Type::Effect, - new PluginPixmapLoader("logo"), - nullptr, - nullptr, -} ; - -} - - -FFTFilterEffect::FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key) : - Effect(&FFTFilter_plugin_descriptor, parent, key), - m_filterControls(this), - m_FFTProcessor(2048, true, FFTWindow::Rectangular), - m_inputBuffer(2048 * 2), - m_outSampleBufferA(2048), - m_outSampleBufferB(2048), - m_outSampleUsedUp(0), - m_outSampleBufferAUsed(false), - m_complexMultiplier(2048, 1) -{ - m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); - m_FFTProcessor.threadedStartThread(&m_inputBuffer, 0, true, false); - - //std::vector graphXArray; - //m_sampleRate; - updateSampleRate(); -} -FFTFilterEffect::~FFTFilterEffect() -{ - qDebug("FFTFilterEffect destrc 0"); - m_inputBuffer.wakeAll(); - //m_FFTProcessor.~FFTProcessor(); - //m_FFTProcessor.terminate(); - qDebug("FFTFilterEffect destrc 1"); -} - -bool FFTFilterEffect::processAudioBuffer(sampleFrame* buf, const fpp_t frames) -{ - bool processed = false; - //if (!isEnabled() || !isRunning()) { return false ; } - if (isEnabled() && isRunning()) - { - - - if (isNoneInput(buf, frames, 0.01f) == true) - { - //qDebug("FFTFilterEffect return false"); - return false; - } - else - { - - - qDebug("FFTFilterEffect write"); - - m_complexMultiplier = m_filterControls.getGraph(2048); - m_FFTProcessor.setComplexMultiplier(&m_complexMultiplier); - - m_inputBuffer.write(buf, frames, true); - - qDebug("FFTFilterEffect analyze"); - - //m_FFTProcessor.analyze(&m_inputBuffer, &target); - - if (m_FFTProcessor.getOutputSamplesChanged() == true) - { - qDebug("FFTFilterEffect get samples"); - std::vector samples = m_FFTProcessor.getSample(); - updateSampleArray(&samples, 0); - updateSampleArray(&samples, 1); - qDebug("FFTFilterEffect get samples end"); - } - if (m_FFTProcessor.getOutputSpectrumChanged() == true) - { - std::vector FFTSpectrumOutput = m_FFTProcessor.getNormSpectrum(); - - std::vector> graphInput(80); - if (graphInput.size() != graphXArray.size()) - { - updateGraphXArray(graphInput.size()); - } - - float avgY = 0; - int avgCount = 0;//FFTSpectrumOutput.size() / graphInput.size(); - if (avgCount <= 0) - { - avgCount = 1; - } - float avgSum = 0; - int j = 0; - for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) - { - avgY = avgY + FFTSpectrumOutput[i]; - avgCount++; - if (i + 1 > avgSum + graphXArray[j] * FFTSpectrumOutput.size() / graphXArraySum) - { - graphInput[j].second = amplifyY(avgY / static_cast(avgCount), avgCount + 1.0f); - //qDebug("FFTFiterEffect i: %d, %f", i, graphInput[j].second); - if (j >= graphInput.size()) - { - break; - } - avgY = 0; - avgSum = avgSum + graphXArray[j] * FFTSpectrumOutput.size() / graphXArraySum; - avgCount = 0; - j++; - } - } - // log_10(100) = 2 -> 10^2 = 100 - for (unsigned int i = 0; i < graphInput.size(); i++) - { - graphInput[i].first = graphXArray[i]; - } - // DEBUG - - /* - for (unsigned int i = 0; i < FFTSpectrumOutput.size(); i++) - { - qDebug("FFTFilterEffect: [%d], %f", i, FFTSpectrumOutput[i]); - } - */ - - //m_filterControls.setGraph(&graphInput); - - // bin to freq - //return getNyquistFreq() * bin_index / binCount(); - //return getSampleRate() / 2.0f; - //return (getSampleRate() / 2.0f) * x / binCount(); - } - //std::vector* output; - //for (unsigned int i = 0; i < output->size(); i++) - //{ - //qDebug("FFTFilterEffect: [%d], %f", i, output->operator[](i)); - //} - //std::vector testVector = {0.0f, 0.3f, 0.5f, -0.5f, 0.2f}; - //std::vector testVector = {0.0f, 1.3f, 0.5f, -2.5f, 0.2f}; - //std::vector testVector = {0.0f, 0.1f, 0.5f, 0.7f, 0.5f, 0.2f, 0.1f, -1.0f, -0.1f, -0.1f, 0.2f}; - - - //m_filterControls.setGraph(&testVector); - - /* - const ValueBuffer* volumeBuf = m_filterControls.m_volumeModel.valueBuffer(); - const ValueBuffer* panBuf = m_filterControls.m_panModel.valueBuffer(); - const ValueBuffer* leftBuf = m_filterControls.m_leftModel.valueBuffer(); - const ValueBuffer* rightBuf = m_filterControls.m_rightModel.valueBuffer(); - - for (fpp_t f = 0; f < frames; ++f) - { - const float volume = (volumeBuf ? volumeBuf->value(f) : m_filterControls.m_volumeModel.value()) * 0.01f; - const float pan = (panBuf ? panBuf->value(f) : m_filterControls.m_panModel.value()) * 0.01f; - const float left = (leftBuf ? leftBuf->value(f) : m_filterControls.m_leftModel.value()) * 0.01f; - const float right = (rightBuf ? rightBuf->value(f) : m_filterControls.m_rightModel.value()) * 0.01f; - - const float panLeft = std::min(1.0f, 1.0f - pan); - const float panRight = std::min(1.0f, 1.0f + pan); - - auto s = std::array{buf[f][0], buf[f][1]}; - - s[0] *= volume * left * panLeft; - s[1] *= volume * right * panRight; - - buf[f][0] = d * buf[f][0] + w * s[0]; - buf[f][1] = d * buf[f][1] + w * s[1]; - outSum += buf[f][0] * buf[f][0] + buf[f][1] * buf[f][1]; - } - */ - - //checkGate(outSum / frames); - - } // isNoneInput - } // enabled && isRunning - setOutputSamples(buf, frames); - - float cutOff = 0.003f; - /* - for (unsigned int i = 0; i < frames; i++) - { - qDebug("FFTFilter processAtudioBuffer [%d] %f", i, buf[i][0]); - if (i > 0 && std::abs(buf[i - 1][0] - buf[i][0]) > cutOff) - { - qDebug("setOutputSamples BAD OUTPUT"); - int* debugval = nullptr; - *debugval = 3; - } - else if (std::abs(debugLastSample[0] - buf[i][0]) > cutOff) - { - qDebug("setOutputSamples BAD OUTPUT 2 --------"); - int* debugval = nullptr; - *debugval = 3; - } - } - */ - //debugLastSample = buf[frames - 1]; - return isRunning(); -} - -bool FFTFilterEffect::isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, const float cutOffIn) -{ - bool output = true; - //qDebug("FFTFilterEffect check none input"); - for (unsigned int i = 0; i < cutOffIn; i++) - { - if (std::abs(bufferIn[i][0]) > cutOffIn) - { - output = false; - break; - } - else if (std::abs(bufferIn[i][1]) > cutOffIn) - { - output = false; - break; - } - } - return output; -} -void FFTFilterEffect::updateBufferSize(unsigned int newBufferSizeIn) -{ - m_bufferSize = newBufferSizeIn; - // TODO -} - -void FFTFilterEffect::updateSampleRate() -{ - m_sampleRate = Engine::audioEngine()->processingSampleRate(); -} -void FFTFilterEffect::updateGraphXArray(unsigned int sizeIn) -{ - updateSampleRate(); - graphXArray.resize(sizeIn); - graphXArraySum = 0.0f; - for (unsigned int i = 0; i < graphXArray.size(); i++) - { - graphXArray[i] = getTransformedX(i, graphXArray.size()); - graphXArraySum += graphXArray[i]; - //qDebug("updateGraphXArray [%d] %f", i, graphXArray[i]); - } -} -float FFTFilterEffect::getTransformedX(unsigned int locationIn, unsigned int sizeIn) -{ - float freq = (m_sampleRate / 2.0f) * locationIn / sizeIn; - // bin to freq - //return getNyquistFreq() * bin_index / binCount(); - //return getSampleRate() / 2.0f; - //return (getSampleRate() / 2.0f) * x / binCount(); - - float min = std::log10(FRANGE_AUDIBLE_START); - float range = std::log10(FRANGE_AUDIBLE_END) - min; - freq = (log10(freq) - min) / range; - - /* - float min = FRANGE_AUDIBLE_START; - float range = FRANGE_AUDIBLE_END - min; - freq = (freq - min) / range; - */ - return freq > 0.0f ? freq : 0.0f; -} -float FFTFilterEffect::amplifyY(float yIn, float powerIn) -{ - float power = std::max(powerIn, 2.0f); - return -std::pow(power, -yIn * power) + 1.0f; - //return -std::pow(std::abs(yIn - 1.0f), 3.0f) + 1.0f; -} -void FFTFilterEffect::setOutputSamples(sampleFrame* sampleStartIn, unsigned int sizeIn) -{ - std::vector* curOutBuffer = m_outSampleBufferAUsed == true ? &m_outSampleBufferA : &m_outSampleBufferB; - unsigned int size = curOutBuffer->size() <= m_outSampleUsedUp + sizeIn ? curOutBuffer->size() - m_outSampleUsedUp: sizeIn; - for (unsigned int i = 0; i < size; i++) - { - sampleStartIn[i] = curOutBuffer->operator[](m_outSampleUsedUp + i); - //qDebug("setOutputSamples [%d] %f", m_outSampleUsedUp + i, sampleStartIn[i][0]); - } - m_outSampleUsedUp += size; - if (size != sizeIn) - { - qDebug("setOutputSamples Switched!!"); - m_outSampleBufferAUsed = !m_outSampleBufferAUsed; - m_outSampleUsedUp = 0; - std::vector* curOutBuffer = m_outSampleBufferAUsed == true ? &m_outSampleBufferA : &m_outSampleBufferB; - size = curOutBuffer->size() <= m_outSampleUsedUp + sizeIn ? curOutBuffer->size() - m_outSampleUsedUp : sizeIn; - for (unsigned int i = 0; i < size; i++) - { - sampleStartIn[i] = curOutBuffer->operator[](i); - //qDebug("setOutputSamples [%d] %f", m_outSampleUsedUp + i, sampleStartIn[i][0]); - } - m_outSampleUsedUp += size; - - for (unsigned int i = 0; i < curOutBuffer->size(); i++) - { - //qDebug("setOutputSamples sv [%d] %f", i, curOutBuffer->operator[](i)[0]); - } - } - - /* - for (unsigned int i = 0; i < sizeIn; i++) - { - qDebug("setOutputSamples [%d] %f", i, sampleStartIn[i][0]); - if (i > 0 && std::abs(sampleStartIn[i - 1][0] - sampleStartIn[i][0]) > 0.003f) - { - qDebug("setOutputSamples BAD OUTPUT"); - } - } - */ -} -void FFTFilterEffect::updateSampleArray(std::vector* newSamplesIn, unsigned int sampleLocIn) -{ - if (m_outSampleBufferAUsed == true) - { - unsigned int size = m_outSampleBufferB.size() < newSamplesIn->size() ? m_outSampleBufferB.size() : newSamplesIn->size(); - qDebug("FFTFilter updateSampleArray size: %d, sampLoc: %d", size, sampleLocIn); - for (unsigned int i = 0; i < size; i++) - { - m_outSampleBufferB[i][sampleLocIn] = newSamplesIn->operator[](i); - } - } - else - { - unsigned int size = m_outSampleBufferA.size() < newSamplesIn->size() ? m_outSampleBufferA.size() : newSamplesIn->size(); - qDebug("FFTFilter updateSampleArray size: %d, sampLoc: %d", size, sampleLocIn); - for (unsigned int i = 0; i < size; i++) - { - m_outSampleBufferA[i][sampleLocIn] = newSamplesIn->operator[](i); - } - } -} - -extern "C" -{ - -// necessary for getting instance out of shared lib -PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* parent, void* data) -{ - return new FFTFilterEffect(parent, static_cast(data)); -} - -} - -} // namespace lmms diff --git a/plugins/FFTFilter/FFTFilter.h b/plugins/FFTFilter/FFTFilter.h deleted file mode 100644 index feb7886b539..00000000000 --- a/plugins/FFTFilter/FFTFilter.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * FFTFilter.h - FFTFilter effect for lmms - * - * Copyright (c) 2024 Szeli1 TODO - * - * 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 LMMS_FFTFILTER_H -#define LMMS_FFTFILTER_H - -#include - -#include "Effect.h" -#include "FFTFilterControls.h" -#include "FFTProcessor.h" -#include "LocklessRingBuffer.h" - -namespace lmms -{ - -class FFTFilterEffect : public Effect -{ -public: - FFTFilterEffect(Model* parent, const Descriptor::SubPluginFeatures::Key* key); - ~FFTFilterEffect() override; - bool processAudioBuffer(sampleFrame* buf, const fpp_t frames) override; - - EffectControls* controls() override - { - return &m_filterControls; - } - -private: - - bool isNoneInput(sampleFrame* bufferIn, const fpp_t framesIn, const float cutOffIn); - - void updateBufferSize(unsigned int newBufferSizeIn); - - void updateSampleRate(); - void updateGraphXArray(unsigned int sizeIn); - float getTransformedX(unsigned int locationIn, unsigned int sizeIn); - float amplifyY(float yIn, float powerIn); - - void setOutputSamples(sampleFrame* sampleStartIn, unsigned int sizeIn); - void updateSampleArray(std::vector* newSamplesIn, unsigned int sampleLocIn); - - FFTFilterControls m_filterControls; - FFTProcessor m_FFTProcessor; - - - //std::vector m_bufferA; - //std::vector m_bufferB; - //bool m_useSecondBufferOut; - - LocklessRingBuffer m_inputBuffer; - - std::vector m_outSampleBufferA; - std::vector m_outSampleBufferB; - unsigned int m_outSampleUsedUp; - bool m_outSampleBufferAUsed; - - std::vector graphXArray; - float graphXArraySum; - unsigned int m_sampleRate; - - unsigned int m_bufferSize; - - sampleFrame debugLastSample; - - std::vector m_complexMultiplier; - - friend class FFTFilterControls; -}; - -} // namespace lmms - -#endif // LMMS_FFTFILTER_H diff --git a/plugins/FFTFilter/FFTFilterControlDialog.cpp b/plugins/FFTFilter/FFTFilterControlDialog.cpp deleted file mode 100644 index 2e5f4b08f7f..00000000000 --- a/plugins/FFTFilter/FFTFilterControlDialog.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * AmplifierControlDialog.cpp - control dialog for amplifier effect - * - * Copyright (c) 2014 Vesa Kivimäki - * Copyright (c) 2006-2014 Tobias Doerffel - * - * 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 "FFTFilterControlDialog.h" -#include "FFTFilterControls.h" -#include "embed.h" - -#include "AutomatableButton.h" -#include "embed.h" -#include "Knob.h" -#include "LedCheckBox.h" -#include "PixmapButton.h" -#include "LcdSpinBox.h" -#include "VectorGraph.h" - -namespace lmms::gui -{ - -FFTFilterControlDialog::FFTFilterControlDialog(FFTFilterControls* controls) : - EffectControlDialog(controls) -{ - setAutoFillBackground(true); - QPalette pal; - pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); - setPalette(pal); - setFixedSize(600, 700); - /* - auto makeKnob = [this](int x, int y, const QString& label, const QString& hintText, const QString& unit, FloatModel* model, bool isVolume) - { - Knob* newKnob = new Knob(KnobType::Bright26, this); - newKnob->move(x, y); - newKnob->setModel(model); - newKnob->setLabel(label); - newKnob->setHintText(hintText, unit); - newKnob->setVolumeKnob(isVolume); - return newKnob; - };*/ - /* - m_volumeModel.loadSettings(parent, "volume"); - m_freqControlModel.loadSettings(parent, "freqcontrol"); - m_effectControlModel.loadSettings(parent, "effectcontrol"); - m_bufferModel.loadSettings(parent, "buffer"); - m_displayFFTModel.loadSettings(parent, "display"); - */ - - auto volumeKnob = new Knob(KnobType::Bright26, this); - volumeKnob->setModel(&controls->m_volumeModel); - volumeKnob->setLabel(tr("VOLUME")); - //->setCheckable(true); - volumeKnob->setHintText(tr("Input gain:"),""); - //->setVolumeKnob(true); - //->setVolumeRatio(1.0); - volumeKnob->move(10, 10); - - auto freqControlKnob = new Knob(KnobType::Bright26, this); - freqControlKnob->setModel(&controls->m_freqControlModel); - freqControlKnob->setLabel(tr("FREQ_A_TODO")); - freqControlKnob->setHintText(tr("Input gain:"),""); - freqControlKnob->move(10, 100); - - auto effectControlKnob = new Knob(KnobType::Bright26, this); - effectControlKnob->setModel(&controls->m_effectControlModel); - effectControlKnob->setLabel(tr("EFFECT_A_TODO")); - effectControlKnob->setHintText(tr("Input gain:"),""); - effectControlKnob->move(10, 150); - - auto bufferInput = new LcdSpinBox(2, this, "BUFFER_A_TODO"); - bufferInput->setModel(&controls->m_bufferModel); - //bufferInput->setLabel(tr("INPUT")); - //bufferInput->setHintText(tr("Input gain:"),""); - bufferInput->move(10, 200); - - auto displayFFTKnob = new LedCheckBox("DISPLAY_A_TODO", this, tr("DISPLAY_A_TODO"), LedCheckBox::LedColor::Green); - displayFFTKnob->setModel(&controls->m_displayFFTModel); - //displayFFTKnob->setLabel(tr("DISPLAY_A_TODO")); - displayFFTKnob->setCheckable(true); - displayFFTKnob->move(300, 10); - - auto resetButton = new PixmapButton(this, tr("RESET_A_TODO")); - resetButton->setCheckable(true); - resetButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("smooth_active")); - resetButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("smooth_inactive")); - resetButton->setToolTip(tr("RESET_A_TODO")); - resetButton->resize(13, 48); - resetButton->move(300, 100); - - auto curGraph = new VectorGraphView(this, 300, 200, 10, 1024); - curGraph->setModel(&controls->m_graphModel); - curGraph->move(100, 240); -/* - auto swapInputs = new LedCheckBox("Swap inputs", this, tr("Swap inputs"), LedCheckBox::LedColor::Green); - swapInputs->move( 20, 275 ); - swapInputs->setModel( & controls->m_swapInputs ); - swapInputs->setToolTip(tr("Swap left and right input channels for reflections")); - */ - /* - auto = new Knob(KnobType::Bright26, this); - ->setModel(&_controls->m_volumeModel); - ->setLabel(tr("INPUT")); - ->setCheckable(true); - ->setHintText(tr("Input gain:"),""); - ->setVolumeKnob(true); - ->setVolumeRatio(1.0); - ->move(26, 223); - */ -} - -} // namespace lmms::gui diff --git a/plugins/FFTFilter/FFTFilterControlDialog.h b/plugins/FFTFilter/FFTFilterControlDialog.h deleted file mode 100644 index 1bb14ec4f31..00000000000 --- a/plugins/FFTFilter/FFTFilterControlDialog.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * FFTFilterControlDialog.h - control dialog for FFTFilter effect - * - * Copyright (c) 2024 Szeli1 TODO - * - * 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 LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H -#define LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H - -#include "EffectControlDialog.h" - -namespace lmms -{ - -class FFTFilterControls; -class FloatModel; - -namespace gui -{ - -class Knob; - -class FFTFilterControlDialog : public EffectControlDialog -{ - Q_OBJECT -public: - FFTFilterControlDialog(FFTFilterControls* controls); - ~FFTFilterControlDialog() override = default; -}; - -} // namespace gui - -} // namespace lmms - -#endif // LMMS_GUI_FFTFILTER_CONTROL_DIALOG_H diff --git a/plugins/FFTFilter/FFTFilterControls.cpp b/plugins/FFTFilter/FFTFilterControls.cpp deleted file mode 100644 index 2062e8e1c81..00000000000 --- a/plugins/FFTFilter/FFTFilterControls.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * FFTFilterCotnrols.cpp - controls for FFTFilter effect - * - * Copyright (c) 2024 Szeli1 TODO - * - * 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 - -#include "FFTFilterControls.h" -#include "FFTFilter.h" -#include "VectorGraph.h" - -namespace lmms -{ - -FFTFilterControls::FFTFilterControls(FFTFilterEffect* effect) : - EffectControls(effect), - m_effect(effect), - m_volumeModel(100.0f, 0.0f, 200.0f, 0.1f, this, tr("Volume")), - m_freqControlModel(100.0f, 0.0f, 200.0f, 0.1f, this, tr("Freq")), - m_effectControlModel(0.0f, -100.0f, 100.0f, 0.1f, this, tr("Effect")), - m_bufferModel(16, 2, 2048, this, "Quality"), - //m_filterModel(0.0f, 1.0f, 200, this), - m_displayFFTModel( true, this, tr("Display fft")), - m_graphModel(1024, this, false) -{ - /* - void setIsFixedSize(bool valueIn); - void setIsFixedX(bool valueIn); - void setIsFixedY(bool valueIn); - void setIsFixedEndPoints(bool valueIn); - void setIsSelectable(bool valueIn); - void setIsEditableAttrib(bool valueIn); - void setIsAutomatableEffectable(bool valueIn); - void setIsSaveable(bool valueIn); - void setNonNegative(bool valueIn); - */ - unsigned int arrayLocation = m_graphModel.addArray(); - //m_graphModel.getDataArray(arrayLocation)->setIsFixedSize(true); - //m_graphModel.getDataArray(arrayLocation)->setIsFixedX(true); - //m_graphModel.getDataArray(arrayLocation)->setIsFixedY(true); - //m_graphModel.getDataArray(arrayLocation)->setIsFixedEndPoints(true); - m_graphModel.getDataArray(arrayLocation)->setIsSelectable(true); - m_graphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); - m_graphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); - m_graphModel.getDataArray(arrayLocation)->setIsSaveable(true); - //m_graphModel.getDataArray(arrayLocation)->setIsNonNegative(true); - m_graphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); - m_graphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); - m_graphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); - m_graphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); - - unsigned int arrayLocationB = m_graphModel.addArray(); - m_graphModel.getDataArray(arrayLocationB)->setIsSelectable(true); - m_graphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); - m_graphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); - m_graphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); - m_graphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); - m_graphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); - m_graphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(10, 50, 255, 255)); - - // effectors: - // true -> m_graphModel will call update() -> paintEvent() - m_graphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); -} - - -void FFTFilterControls::loadSettings(const QDomElement& parent) -{ - m_volumeModel.loadSettings(parent, "volume"); - m_freqControlModel.loadSettings(parent, "freqcontrol"); - m_effectControlModel.loadSettings(parent, "effectcontrol"); - m_bufferModel.loadSettings(parent, "buffer"); - m_displayFFTModel.loadSettings(parent, "display"); - - - m_graphModel.loadSettings(parent, "VectorGraph"); -} - - -void FFTFilterControls::saveSettings(QDomDocument& doc, QDomElement& parent) -{ - m_volumeModel.saveSettings(doc, parent, "volume"); - m_freqControlModel.saveSettings(doc, parent, "freqcontrol"); - m_effectControlModel.saveSettings(doc, parent, "effectcontrol"); - m_bufferModel.saveSettings(doc, parent, "buffer"); - m_displayFFTModel.saveSettings(doc, parent, "display"); - - m_graphModel.saveSettings(doc, parent, "VectorGraph"); -} - -void FFTFilterControls::resetClicked() -{ - -} - -std::vector FFTFilterControls::getGraph(unsigned int sizeIn) -{ - std::vector output; - if (0 < m_graphModel.getDataArraySize()) - { - qDebug("FFTFilterControls: get graph"); - output = m_graphModel.getDataArray(0)->getValues(sizeIn); - } - return output; -} -void FFTFilterControls::setGraph(std::vector>* dataArrayIn) -{ - if (1 < m_graphModel.getDataArraySize()) - { - qDebug("FFTFilterControls: set graph"); - // void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); - m_graphModel.getDataArray(1)->setDataArray(dataArrayIn, true, false, false, true, false, false); - } -} - -} // namespace lmms diff --git a/plugins/FFTFilter/FFTFilterControls.h b/plugins/FFTFilter/FFTFilterControls.h deleted file mode 100644 index 86a238c3d87..00000000000 --- a/plugins/FFTFilter/FFTFilterControls.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * FFTFilterControls.h - FFTFilter controls - * - * Copyright (c) 2024 Szeli1 TODO - * - * 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 LMMS_FFTFILTER_CONTROLS_H -#define LMMS_FFTFILTER_CONTROLS_H - -#include "EffectControls.h" -#include "FFTFilterControlDialog.h" -#include "VectorGraph.h" - -namespace lmms -{ - -class FFTFilterEffect; - -namespace gui -{ -class FFTFilterControlDialog; -} - -class FFTFilterControls : public EffectControls -{ - Q_OBJECT -public: - FFTFilterControls(FFTFilterEffect* effect); - ~FFTFilterControls() override = default; - - void saveSettings(QDomDocument& doc, QDomElement& parent) override; - void loadSettings(const QDomElement& parent) override; - inline QString nodeName() const override - { - return "FFTFilterControls"; - } - gui::EffectControlDialog* createView() override - { - return new gui::FFTFilterControlDialog(this); - } - int controlCount() override { return 8; } - - std::vector getGraph(unsigned int sizeIn); - void setGraph(std::vector>* dataArrayIn); - -private slots: - void resetClicked(); - -private: - FFTFilterEffect* m_effect; - FloatModel m_volumeModel; - //FloatModel m_panModel; - //FloatModel m_leftModel; - //FloatModel m_rightModel; - FloatModel m_freqControlModel; - FloatModel m_effectControlModel; - IntModel m_bufferModel; - - BoolModel m_displayFFTModel; - BoolModel m_resetModel; - - VectorGraphModel m_graphModel; - - //graphModel m_filterModel; - - friend class gui::FFTFilterControlDialog; - friend class FFTFilterEffect; -}; - -} // namespace lmms - -#endif // LMMS_FFTFILTER_CONTROLS_H diff --git a/plugins/FFTFilter/FFTProcessor.cpp b/plugins/FFTFilter/FFTProcessor.cpp deleted file mode 100644 index 869cfe62151..00000000000 --- a/plugins/FFTFilter/FFTProcessor.cpp +++ /dev/null @@ -1,528 +0,0 @@ - - -#include -#include -#include -#include -#include - -#include "FFTProcessor.h" -#include "fft_helpers.h" -#include "lmms_basics.h" -#include "LocklessRingBuffer.h" - -// some parts of the code were copyed from SaProcessor.cpp -// credit: 2019 Martin Pavelek - -namespace lmms -{ - -FFTProcessor::FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWindow FFTWindowIn)// : - //m_reader(bufferSizeIn * 4) -{ - m_blockSize = bufferSizeIn; - m_isThreaded = isThreadedIn; - m_FFTWindowType = FFTWindowIn; - - m_terminate = true; - m_frameFillLoc = 0; - - m_samplesIn.resize(m_blockSize); - m_samplesOut.resize(m_blockSize); - m_normSpectrum.resize(binCount(m_blockSize)); - //m_complexMultiplier; - - /* - m_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * binCount(m_blockSize)); - // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); - // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); - m_plan = fftwf_plan_dft_r2c_1d(m_blockSize, m_samplesIn.data(), m_out, FFTW_ESTIMATE); - m_iplan = fftwf_plan_dft_c2r_1d(m_blockSize, m_out, m_samplesOut.data(), FFTW_ESTIMATE); - */ - - //m_fftWindow.resize(m_blockSize, 1.0); - //precomputeWindow(m_fftWindow.data(), m_blockSize, m_FFTWindowType); -} -FFTProcessor::~FFTProcessor() -{ - qDebug("FFTProcessor destrc -1"); - - threadedTerminate(); - /* - if (m_plan != nullptr) - { - fftwf_destroy_plan(m_plan); - } - if (m_iplan != nullptr) - { - fftwf_destroy_plan(m_iplan); - } - qDebug("FFTProcessor destrc 0"); - qDebug("FFTProcessor destrc 1"); - if (m_out != nullptr) - { - fftwf_free(m_out); - } - */ - - qDebug("FFTProcessor destrc 2"); - //m_out = nullptr; - qDebug("FFTProcessor destrc 3"); -} - -void FFTProcessor::analyze(sampleFrame* sampleBufferIn, unsigned int sizeIn, unsigned int sampLocIn) -{ - if (m_isThreaded == false) - { - /* - while (frameIn < frameCount && m_frameFillLoc < blockSizeIn) - { - //qDebug("analyzeB 2"); - samples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; - frameIn++; - frameFillLoc++; - } - */ - - } -} - -void FFTProcessor::threadedStartThread(LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, bool computeSpectrum, bool computeInverse) -{ - qDebug("analyze threaded start"); - if (m_isThreaded == true && m_terminate == true && ringBufferIn != nullptr && - (computeSpectrum == true || computeInverse == true)) - { - qDebug("analyze threaded thread init"); - m_terminate = false; - unsigned int blockSize = m_blockSize; - m_FFTThread = std::thread(FFTProcessor::threadedAnalyze, &m_terminate, &m_samplesOut, &m_samplesOut, &m_outputSpectrumChanged, &m_outputSamplesChanged, - ringBufferIn, &m_complexMultiplier, sampLocIn, blockSize, &m_normSpectrum, &m_outputAccess); - qDebug("analyze threaded thread running"); - } -} - -std::vector FFTProcessor::getNormSpectrum() -{ - m_outputAccess.lock(); - std::vector output = m_normSpectrum; - m_outputAccess.unlock(); - return output; -} -std::vector FFTProcessor::getSample() -{ - m_outputAccess.lock(); - std::vector output = m_samplesOut; - m_outputAccess.unlock(); - return output; -} -bool FFTProcessor::getOutputSpectrumChanged() -{ - bool output = m_outputSpectrumChanged; - m_outputSpectrumChanged = false; - return output; -} -bool FFTProcessor::getOutputSamplesChanged() -{ - bool output = m_outputSamplesChanged; - m_outputSamplesChanged = false; - return output; -} -void FFTProcessor::setComplexMultiplier(std::vector* complexMultiplierIn) -{ - m_complexMultiplier = *complexMultiplierIn; -} - -void FFTProcessor::threadedAnalyze(std::atomic* terminateIn, std::vector* samplesInB, std::vector* samplesOutB, - std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, - LocklessRingBuffer* ringBufferIn, std::vector* filterSpectrumIn, unsigned int sampLocIn, unsigned int blockSizeIn, - std::vector* spectrumOut, std::mutex* outputAccessIn) -{ - LocklessRingBufferReader reader(*ringBufferIn); - - std::vector samplesIn(blockSizeIn); - //std::vector samplesInBuffer(blockSizeIn); - std::vector samplesOut(blockSizeIn); - std::vector samplesOutBufferA(blockSizeIn); - std::vector samplesOutBufferB(blockSizeIn); - std::vector absSpectrum(blockSizeIn); - std::vector outputSpectrum(blockSizeIn); - - fftwf_complex* fftComplex = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * binCount(blockSizeIn)); - // fftwf_plan fftwf_plan_dft_r2c_1d(int n, float *in, fftwf_complex *out, unsigned flags); - // fftwf_plan fftwf_plan_dft_c2r_1d(int n, fftwf_complex *in, float *out, unsigned flags); - fftwf_plan plan = fftwf_plan_dft_r2c_1d(blockSizeIn, samplesIn.data(), fftComplex, FFTW_ESTIMATE); - fftwf_plan iplan = fftwf_plan_dft_c2r_1d(blockSizeIn, fftComplex, samplesOut.data(), FFTW_ESTIMATE); - - // TODO might not be the correct size - float pi = 3.141592654f; - std::vector hanningWindow(blockSizeIn); - precomputeWindow(hanningWindow.data(), blockSizeIn, FFTWindow::Hanning); - float maxWindow = 0.0f; - /* - for (int i = 0; i < blockSizeIn; i++) - { - // applying sinc function - float sincVal = pi * 0.25f * (i - (static_cast(blockSizeIn) / 2.0f)); - if (sincVal != 0) - { - hanningWindow[i] = hanningWindow[i] * std::sin(sincVal) / sincVal; - } - sumWindow = sumWindow + hanningWindow[i]; - qDebug("FFTProcessor final window [%d]: %f, %f", i, hanningWindow[i], sumWindow); - } - */ - for (int i = 0; i < blockSizeIn; i++) - { - maxWindow = maxWindow < hanningWindow[i] ? hanningWindow[i] : maxWindow; - } - for (int i = 0; i < blockSizeIn; i++) - { - // normalise - hanningWindow[i] = hanningWindow[i] / maxWindow; - qDebug("FFTProcessor sumWindow [%d]: %f, %f", i, hanningWindow[i], maxWindow); - } - - - fpp_t frameFillLoc = blockSizeIn / 2; - //fpp_t frameFillLoc = 0; - int outFillLoc = 0; - - bool writeSamplesOut = true; - bool writeToBufferA = true; - int runFFTCount = 0; - qDebug("analyzeB 0"); - while (*terminateIn == false) - { - if (reader.empty() == false) - { - reader.waitForData(); - } - - auto bufferIn = reader.read_max(ringBufferIn->capacity()); - size_t frameCount = bufferIn.size(); - - if (frameCount > 0) - { - qDebug("analyzeB 0.5 DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG count: %ld", frameCount); - } - - fpp_t frameIn = 0; - - while (frameIn < frameCount) - { - qDebug("analyzeB 1"); - while (frameIn < frameCount && frameFillLoc < blockSizeIn) - //while (frameIn < frameCount && frameFillLoc < blockSizeIn / 2) - { - //qDebug("analyzeB 2"); - //samplesInBuffer[frameFillLoc] = bufferIn[frameIn][sampLocIn]; - samplesIn[frameFillLoc - blockSizeIn / 2] = samplesIn[frameFillLoc]; - samplesIn[frameFillLoc] = bufferIn[frameIn][sampLocIn]; - - //samplesIn[frameFillLoc + blockSizeIn / 2] = bufferIn[frameIn][sampLocIn]; - //samplesIn[frameFillLoc] = storedSamples[frameFillLoc]; - //storedSamples[frameFillLoc] = bufferIn[frameIn][sampLocIn]; - frameIn++; - frameFillLoc++; - } - - if (frameFillLoc < blockSizeIn) - //if (frameFillLoc < blockSizeIn / 2) - { - break; - } - frameFillLoc = blockSizeIn / 2; - //frameFillLoc = 0; - /* - runFFTCount = 2; - } - while (runFFTCount > 0) - { - runFFTCount--; - int readStartLocation = runFFTCount == 1 ? 0 : blockSizeIn / 2; - for (unsigned int i = 0; i < blockSizeIn / 2; i++) - { - samplesIn[i] = samplesIn[i + blockSizeIn / 2]; - samplesIn[i + blockSizeIn / 2] = samplesInBuffer[i + readStartLocation]; - } - */ - - - qDebug("analyzeB run"); - - for (unsigned int i = 0; i < blockSizeIn; i++) - { - qDebug("FFTProcessor analyze samplesIn [%d]: %f", i, samplesIn[i]); - } - qDebug("analyzeB run2 size: %ld", samplesIn.size()); - - // applying window - // this is needed to attenuate the reverse complex correctly - for (unsigned int i = 0; i < blockSizeIn; i++) - { - //qDebug("FFTProcessor analyze samplesIn before window [%d]: %f", i, samplesIn->operator[](i)); - //samplesIn[i] = samplesIn[i] * hanningWindow[i]; - //qDebug("FFTProcessor analyze samplesOut after window [%d]: %f", i, samplesIn->operator[](i)); - } - - - //unsigned int reverseSize = blockSizeIn / 2; - - - fftwf_execute(plan); - - qDebug("analyzeB run3"); - - absspec(fftComplex, absSpectrum.data(), binCount(blockSizeIn)); - normalize(absSpectrum, outputSpectrum, blockSizeIn); - - /* - for (unsigned int i = 0; i < blockSizeIn; i++) - { - qDebug("[%d] %f, %f, %f, - %f, %f", i, complexIn[i][0], complexIn[i][1], samplesIn->operator[](i), absSpectrum[i], outputSpectrum[i]); - } - */ - - qDebug("analyzeB run4"); - outputAccessIn->lock(); - for (unsigned int i = 0; i < binCount(blockSizeIn); i++) - { - spectrumOut->operator[](i) = outputSpectrum[i]; - } - outputAccessIn->unlock(); - *spectrumChangedOut = true; - - qDebug("analyzeB try inverse"); - if (filterSpectrumIn->size() == blockSizeIn) - { - /* - for (unsigned int i = 0; i < binCount(blockSizeIn); i++) - { - inverseOldReal[i] = complexIn[i][0]; - inverseOldImg[i] = complexIn[i][1]; - //qDebug("analyzeB complex %d, %f, %f", i, inverseOldReal[i], inverseOldImg[i]); - } - - qDebug("analyzeB inverse"); - //int inverseabsspec(const fftwf_complex *complex_buffer, float *absspec_buffer, unsigned int compl_length) - // the input filter spectrum gets copyed in 2 halfs (rotation part) - // and then it gets run througth an fft - for (unsigned int i = 0; i < blockSizeIn / 2; i++) - { - - complexIn[i][0] = complexIn[i][0] * complexMultiplierIn->operator[](i); - complexIn[i][1] = complexIn[i][1] * complexMultiplierIn->operator[](i); - - samplesIn->operator[](i) = filterSpectrumIn->operator[](i + blockSizeIn / 2); - //changedAbsSpectum[i] = absSpectrum[i]; - //qDebug("FFTProcessor analyze complexMultiplier [%d]: %f", i, complexMultiplierIn->operator[](i)); - } - for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) - { - samplesIn->operator[](i) = filterSpectrumIn->operator[](i); - } - for (unsigned int i = 0; i < blockSizeIn; i++) - { - //qDebug("FFTProcessor filterIn [%d]: %f %f", i, samplesIn->operator[](i), filterSpectrumIn->operator[](i)); - } - fftwf_execute(*planIn); - - outputAccessIn->lock(); - //inverseabsspec(complexIn, changedAbsSpectum.data(), binCount(blockSizeIn)); - for (unsigned int i = 0; i < binCount(blockSizeIn); i++) - { - //qDebug("analyzeB complex %d, %f, %f, multiply: %f, %f", i, inverseOldReal[i], inverseOldImg[i], complexIn[i][0], complexIn[i][1]); - complexIn[i][0] = inverseOldReal[i] * complexIn[i][0]; - complexIn[i][1] = inverseOldImg[i] * complexIn[i][1]; - //complexIn[i][0] = inverseOldReal[i];// * complexIn[i][0]; - //complexIn[i][1] = inverseOldImg[i];// * complexIn[i][1]; - } - */ - /* - for (unsigned int i = 0; i < binCount(blockSizeIn); i++) - { - qDebug("analyzeB complex start %d, %f, %f", i, fftComplex[i][0], fftComplex[i][1]); - } - */ - std::vector absSpectrumB(blockSizeIn); - for (unsigned int i = 0; i < blockSizeIn; i++) - { - absSpectrumB[i] = absSpectrum[i] * filterSpectrumIn->operator[](i); - } - inverseAbsspec(fftComplex, absSpectrumB.data(), 44100, binCount(blockSizeIn)); - /* - for (unsigned int i = 0; i < binCount(blockSizeIn); i++) - { - qDebug("analyzeB complex end %d, %f, %f", i, fftComplex[i][0], fftComplex[i][1]); - } - */ - fftwf_execute(iplan); - - for (unsigned int i = 0; i < blockSizeIn; i++) - { - samplesOut[i] = samplesOut[i] / blockSizeIn * hanningWindow[i]; - //samplesOut[i] = samplesOut[i] / blockSizeIn; - //qDebug("FFTProcessor analyze 0. samplesOut convert_back: [%d]:%f", i, samplesOut[i]); - } - /* - if (writeSamplesOut == false) - { - if (writeToBufferA == true) - { - samplesOutBufferA = samplesOut; - qDebug("FFTProcessor analyze A reset reset reset reset reset reset reset reset reset reset reset reset reset"); - } - else - { - samplesOutBufferB = samplesOut; - qDebug("FFTProcessor analyze B reset reset reset reset reset reset reset reset reset reset reset reset reset"); - } - writeToBufferA = !writeToBufferA; - writeSamplesOut = true; - } - */ - //else - //{ - outputAccessIn->lock(); - float lastDebug = samplesOutB->operator[](samplesOutB->size() - 1); - /* - if (writeToBufferA == true) - { - for (unsigned int i = 0; i < blockSizeIn / 2; i++) - { - samplesOutB->operator[](i) = samplesOutBufferA[i + blockSizeIn / 2]; - qDebug("FFTProcessor analyze 1.A samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i + blockSizeIn / 2], i + blockSizeIn / 2); - } - for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) - { - samplesOutB->operator[](i) = samplesOutBufferB[i - blockSizeIn / 2]; - qDebug("FFTProcessor analyze 3.B samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferB[i - blockSizeIn / 2], i - blockSizeIn / 2); - } - } - else - { - for (unsigned int i = 0; i < blockSizeIn / 2; i++) - { - samplesOutB->operator[](i) = samplesOutBufferB[i + blockSizeIn / 2]; - qDebug("FFTProcessor analyze 1.B samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferB[i + blockSizeIn / 2], i + blockSizeIn / 2); - } - for (unsigned int i = blockSizeIn / 2; i < blockSizeIn; i++) - { - samplesOutB->operator[](i) = samplesOutBufferA[i - blockSizeIn / 2]; - qDebug("FFTProcessor analyze 3.A samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i - blockSizeIn / 2], i - blockSizeIn / 2); - } - } - - for (unsigned int i = 0; i < blockSizeIn; i++) - { - //qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i], i); - samplesOutB->operator[](i) += samplesOut[i]; - qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i], i); - } - */ - - if (outFillLoc == 0) - { - for (unsigned int i = 0; i < blockSizeIn; i++) - { - samplesOutB->operator[](i) = 0.0f; - } - for (unsigned int i = 0; i < blockSizeIn / 2; i++) - { - samplesOutB->operator[](i) = samplesOutBufferA[i + blockSizeIn / 2]; - //qDebug("FFTProcessor analyze 1. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOutBufferA[i + blockSizeIn / 2], i + blockSizeIn / 2); - } - } - for (unsigned int i = outFillLoc; i < blockSizeIn; i++) - { - samplesOutB->operator[](i) += samplesOut[i - outFillLoc]; - //samplesOutB->operator[](i) = samplesOut[i - outFillLoc]; - //qDebug("FFTProcessor analyze 2. samplesOut [%d]: %f, %f, %d", i, samplesOutB->operator[](i), samplesOut[i - outFillLoc], i - outFillLoc); - } - outputAccessIn->unlock(); - - outFillLoc += blockSizeIn / 2; - if (outFillLoc + 1 >= blockSizeIn) - { - qDebug("FFTProcessor analyze write out, samplesOut copyed"); - samplesOutBufferA = samplesOut; - *samplesChangedOut = true; - outFillLoc = 0; - } - - /* - if (std::abs(samplesOutB->operator[](0) - lastDebug) > 0.08f && lastDebug != 0.0f) - { - qDebug("FFTProcessor analyze break 2"); - int* debugval = nullptr; - // *debugval = 1; - } - - for (unsigned int i = 0; i < blockSizeIn; i++) - { - qDebug("FFTProcessor analyze end samplesOut [%d]: %f", i, samplesOutB->operator[](i)); - if (i > 0 && std::abs(samplesOutB->operator[](i - 1) - samplesOutB->operator[](i)) > 0.15f && std::abs(samplesOutB->operator[](i)) >= 0.01f && std::abs(samplesOutB->operator[](i - 1)) >= 0.01f) - { - - qDebug("FFTProcessor analyze break 1"); - int* debugval = nullptr; - // *debugval = 1; - - } - } - */ - writeSamplesOut = false; - //} - } - } - } - - if (plan != nullptr) - { - fftwf_destroy_plan(plan); - } - if (iplan != nullptr) - { - fftwf_destroy_plan(iplan); - } - qDebug("FFTProcessor destrc 0"); - qDebug("FFTProcessor destrc 1"); - if (fftComplex != nullptr) - { - fftwf_free(fftComplex); - } - - qDebug("analyzeB end"); -} - -// TODO -void FFTProcessor::reverse(std::vector processedDataIn) -{ - -} - -void FFTProcessor::threadedTerminate() -{ - m_terminate = true; - if (m_isThreaded == true) - { - m_FFTThread.join(); - } -} - -// TODO multithread -void FFTProcessor::rebuildWindow(FFTWindow FFTWindowIn) -{ - //m_FFTWindowType = FFTWindowIn; - //precomputeWindow(m_fftWindow.data(), m_blockSize, FFTWindowIn); -} - -// TODO multithread - -unsigned int FFTProcessor::binCount(unsigned int blockSizeIn) -{ - return blockSizeIn / 2 + 1; -} - -} // namespace lmms diff --git a/plugins/FFTFilter/FFTProcessor.h b/plugins/FFTFilter/FFTProcessor.h deleted file mode 100644 index b961ad69fc1..00000000000 --- a/plugins/FFTFilter/FFTProcessor.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * FFTFilter.h - FFTFilter effect for lmms - * - * Copyright (c) 2019 Martin Pavelek - * Copyright (c) 2024 Szeli1 TODO - * - * 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 LMMS_FFTPROCESSOR_H -#define LMMS_FFTPROCESSOR_H - -#include -#include -#include -#include -#include - -#include "lmms_basics.h" -#include "fft_helpers.h" -#include "LocklessRingBuffer.h" - -namespace lmms -{ - -template -class LocklessRingBuffer; - -class FFTProcessor -{ -public: - - FFTProcessor(unsigned int bufferSizeIn, bool isThreadedIn, FFTWindow FFTWindowIn); - ~FFTProcessor(); - - //void analyze(LocklessRingBuffer &ringBufferIn); - // if m_isThreaded and termilnate == false -> block, else start thread or run on current thread - void analyze(sampleFrame* sampleBufferIn, unsigned int sizeIn, unsigned int sampLocIn); - //void analyze(std::vector* inputArrayIn, unsigned int readStartIn, bool isStereoIn); - - void threadedStartThread(LocklessRingBuffer* ringBufferIn, unsigned int sampLocIn, bool computeSpectrum, bool computeInverse); - void threadedTerminate(); - - // getters - std::vector getNormSpectrum(); - std::vector getSample(); - bool getOutputSpectrumChanged(); - bool getOutputSamplesChanged(); - void setComplexMultiplier(std::vector* complexMultiplierIn); - - void reverse(std::vector processedDataIn); - - void rebuildWindow(FFTWindow FFTWindowIn); - - static unsigned int binCount(unsigned int blockSizeIn); - - -private: - static void threadedAnalyze(std::atomic* terminateIn, std::vector* samplesInB, std::vector* samplesOutB, - std::atomic* spectrumChangedOut, std::atomic* samplesChangedOut, - LocklessRingBuffer* ringBufferIn, std::vector* filterSpectrumIn, unsigned int sampLocIn, unsigned int blockSizeIn, - std::vector* spectrumOut, std::mutex* outputAccessIn); - - // Thread: - // terminates the thread - std::atomic m_terminate; - std::atomic m_outputSpectrumChanged; - std::atomic m_outputSamplesChanged; - // it analyze gets ran on a different thread - bool m_isThreaded; - // worker thread if m_isThreaded is enabled - std::thread m_FFTThread; - std::mutex m_outputAccess; - - - unsigned int m_frameFillLoc; - - // fft - //fftwf_complex* m_out; - - //fftwf_plan m_plan; - //fftwf_plan m_iplan; //inverse - - std::atomic m_blockSize; - - std::vector m_samplesIn; - std::vector m_samplesOut; - std::vector m_normSpectrum; - - std::vector m_complexMultiplier; - - //std::vector m_fftWindow; - FFTWindow m_FFTWindowType; -}; - -} // namespace lmms - -#endif // LMMS_FFTPROCESSOR_H diff --git a/plugins/FFTFilter/artwork.png b/plugins/FFTFilter/artwork.png deleted file mode 100644 index 5598b32db47134819b686a2f2e282c297fe78c06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7739 zcmV-B9>n2^P)0000PbVXQnLvL+uWo~o;Lvm$dbY)~9 zcWHEJAV*0}P*;Ht7XSbqwMj%lRCwC$UCWMT$&C{)YS%M>fdS_Kf6`lX7WYI1NhwaI z#~Ux)Mz<@o?jue-6cR;I_}l;dFY7=5{M-EV(I2?~^RN8#Z@RvmM@Ihk3GUBD{tB7=3&<)|J^%UXv)TT<2gS=PbhYipoIf)^C*I2T-wXpJ=oZ zub%*3b~XBlxCX=V`97>F5(V@}v3Y~e25g|z2m5}|_vQKuoTuUQV%GY9pKbCxdtC43 zdA2o9$T$$Qk6~U&{d?>Yl2sr}MzJ69c@!C+JP-Ao;q#<7hDKKM2u>jORy51c8)_l?}U{dvgeNoeQe zc^INd?(bg{M?Q0kXV*QC$Y&=3-_O7rJbAWe@py~ee(_awod+yV)CGMP65qePf z1MJ`J@zlA*$~18iQ_c`b)1183ahv&AU|Y%E{5 z7uEgt?e2~7)ev6!Jmh=%60E}S@bMpvV_*xaAphojAx9XOG2OyB#tLHyYw;GDbABGM z2ezMLj~3@2yZs+RqaQ&7TwsUaydG0zPM;k87imhXNBQ~icmpMdg=oK{NBh&W@Z}jl z_t`r4z&6~?{ahC#uZx;bx9#q12m8?`#Zws`3AgvM#cCXvr!4Akn=s7>TcqRW0dkcg zM>d&L+6MXD*B@uk0JF)#vUhMGNVh#Wpq6mtfprJKrtelLf$ZfE`nV+JOU5QA}I+Xk;8EzN!Ui*e+^?yNkVVxZ$MZF2ip%#m;2oaV`GZ zsPGtNxsu%AB9CuEQczooB@kBOiN2^4wFga`Z(qsdf0G!j(D!p-cp7Dq*FnafUp(VG zv4gz!pxnL=8}EcqFa#}F*c7^LH7mOAQS5kphtM0Vl8vfC;0m&IzWy*F13hsNn+wW8 zV%aLKpW*SsMx*v;%C20Cq@%$B$4lUqwKzz#7N!C1>Ut*jte(3E3*srcSD?@c16En9+z8$l=&}rGOaAf+!@=K55#P4)Y z%dsHt1cgS_eW9V>r~?FgYllGEG%7%tZr^u>GiVNKn<%{|r&xo1k?a()6C^M!Ucx%BG@u*UmQiU7q@h_m zh0&Lzfflf1V!>RHMMz|e44mlzCoecd=IbkMzLF<&HsLUG;$Q9n(VRbbc(_y7j{h+> z>KBgrq^k=mMn3^?LVZ~mB+|Y0U=oox0c0AfnRy?udM%pmJ9h#`j?>rM8(>el`R!Eh zbTF>Cm3N$iMPa$-8q+}0+BdqFC}W;k@I$I*dtU*5H|sF#1o!`&%x!! z!p=R#d7$ks?1+{FkO#}6@?dNRx_NqaL~N#ffqIX)kj{>$us=It70dDSFkqUi4Avh! z4{dA@vn>uT9)`t*$o2$@P!0h(y9anl91xKb4lHa(>u_vp%4}E;RVYM6H&5h_VYaUi zM4CE3kB()fdqDRZdCSnT>a($y^cOkYT>6Ev!w<|bAgBmRplxd?d@NBldytB1zL8%} zHMk9k_v`V}-JP(%nvFo6(eJ;^rI+AyT+a&xX-*c?;ddo;!BcqZHtDg?)Ej;0mXhxX z2L~w_5RV^Z*p=ll7&p4EiAQqWd@y=I!HArANEPlrR>z?11hNz3u+RoJnyKfaX}{`b z__@@XU(z-ggl&*n;A7HA*aVJwZb`xe5R8g~48t>Tdct_%crFM7ba+RZ5GdnI9hig0 zdZCy~Zb+WtQjS?C4=}-oWHN$30Eey=FZk?>nx0eOCX*dPSAKb#G}sr!)fWCP5djE? z2t}=#F4A%>`2aDUB>0W~nNHaEJqIVNjVGz;z($eLcYI~0Q$B06KRpYGb}cd-x&zIB zEE=+$@NqMNZZW2amY1N-xxnh0=3P6*$~`8c!1%$A9TRq#wsa)cFhC>-j+jxE7@2s+ zXH9XH@Xrt%Wx3rS4gp`=v_B;4`4;V8m>%sqn8?a{b?~H+@H*jrLrf7e8&f8qf#btt zc-_R%xy=zfP-vg@Ii{IcDh($*hBMaH_*5029Y>{|Ja+a5hDe-zsSi?2;=57rV}MgaY$ge#qxbLP$ysrFcdI z8d@f>Vp5It#$k6#Ny1@<4-3dCW7kcOh9IOA$Cxn*vjVgV1pnm3*QH2I=pN1*rOL7B_TCJuz>d1y4d$ z6Gs-*no;P`!H!JfIF1onfbfV;Y(b&IL)rR}T>LX8l0o@gEc_EW!_o^p6KTalzO|8g zG94}`3>snH@RS&k@D#;5A(pze{BE)pA-0=-qXDt%XS5mM+KsPUGpI3Eld)DDcp(@c;utXS-i)<1u_kD7%N3 zELQAo;b<)ncLkvz%OD{rHijvnnGOR4*A!(UUy65VhF0;j;ie|rb7{nXie`dxqo$$P zD)^+Py{Td1Do(ad_(6l`KumA@K!+(NO;+{OU5>n=g8a{l8-g`b&@f~7^TEfPz1EuUad{%C7LFFj*t_b&{C?Z=4jLqHOCmPW$EcSc)f1G?=0T{lM94eyS2|DTd=3K-M zc(FS1Jd^vI01=lZN4SSq0PBV&UAGcz1Sa1mHJ!vs943p3P`^`uS?>9VbaEOm{47M$ zh)nFO*A-fsw33N3`G%F3pt;wbI|aWA#yiC)ify8fU;v3`%Ga|^fZ>Mb(aL>drEWi9jQtv6$vSJ^f{&9dkhC=*%mDTwIU*x zxwSCnN5`Nb|EtCwL%WPyNjNwYR!U-}(roGp8o_l!BG<$~C@t-%*V^`>>3pP!Whk?{ zt9?b|#DE@|NWkmI14EDpjCh3;mx6~c99SIF@j!=5kdB%qx0EjMAa!sn(uglB#SI9D zjrAwFL|+XMC=m0=Qn)vCk~&J9F3(YG(LB}rLC=+}F&I$IXXb zEOb<8VJq}liHa`tnM6V}dYYH7*fb%Xp*9rqT|A$;YmRgy3MsC|J%FG5wd{QE!e{sI zvS&y#Kv?s%BaFxG)eVH6tU0g@t)6qGIE!)QRfee!I;;1OUGWc$z@{n1qd+8RXjZtK z`V4IF(@j*O_)!G~_w<;Tzr_JU2LkOxT4~*$gY#U_@nCjvzThI!DMAe`!RXo&a}@1< zp^L{w6#T_UEs^{&EoWEkL?NIj8OurkC>Dpy;ND8Dqi4^A7AwY+34lX{N2myU)eZ(Lv{X{XM0Y_ z-~ayi!F$N~6Z4OZ_OcUwaNW?j$V9{yGCV&D6b>N6pZ*LK)E7N zikhi%4^7&+ogT;PfFU4BF+ol>^}BQ_XDwu^-1_k*x6M2+EErVe^B(^OAa9Ydp* zSX2m$YR-LEP~EC76|1A@4^m2zCB!$@B2JaIFUgXUI1|5=9rmP}YmO5$EJ_jt_{3QZ zQ;Zgnky<^^^&Rk%2`SB1gGta3>wf=4t{%=0!%{;HTwKexkBDcTj3E!|;lbFR3|a~l zc@?6JVy{)&4T`3s!A@1|xKs%MN5i1VVAIPF(9|%3+y}HGrCr)kdFraPj2jwl^N=_8 z$=SRytsvG-;}_w9TE4&fV-l{4$UZwbFENHLid|SJ+f}VBTC@_CIHZctDG~q#L$Lyh zh6+I++3<|6H@u?TQ;U~Y%_I+71u6(&g`YeDGefPFes_YYY)avf&~rav{b6`4Onuv$ zOM;nSyiHk@w%z#T5oJO>IUMDKy)z}n0|6xMw8&=R7@RWHErboD=>pRH84AtGNEP~X z-b;#c@w`_pgqLb?(STr%kNZ6@X;RR1KCDQkk*^2Eg@F@HKO!@3wq=}PCsfr+n^4dY z7GokUWYE0;%V6eU=<_8UOJ7_mw%5=J%b5G5y`=mB!M%rk_8UmtFcRtSlp6s+vw+bw?V@WhCB& zAVFk~Crm06bDe49E6CSEA+~zQ3GVq^xlU2K&a23BXInLgU;+^_gL90EADZ4eYXn1C z(^Ox;%UHHo!C`jiJ`Ix?OX!vnZd%`WWX58I?M`V26}LWJ(p1d@)KlZ71;M zoWB5bxIojUm*^2Tr`mUOBkRpT8vS+J4l`*z%eB$w;bX2>D^He;en1V>8gLHk459zw z60y8^0T>>(t1GO!bk=W;b=Ob=(SbYFNy)M{hK>_Lf-Wn{xaeGjD z7levNB(^?i7jdsm=A5rkduUvlsc2M-biC7osxx!~HeBQ@y%wHl$3;xpBY60!mb5i0 zNF1p)(U|c5=%029G228_OjVh16`d*9=-rYi=-!)}Lt+rP*=>}hrhC_az@vO6Xe(o6 zB8xNNngEWKL#9GB+Oz^#^>KNyMF_z^a#+IU$0FF13q3DgBV3b#K<@M;Wqku^6VA zUhu+!9Zs3p!+b>UR+uQ*B>JVQ6VO6Vc8>>nYj2E<2b0n93^0k-Q(84v35#88G;!E1 zTZ%nQeP}?OV7DIKUJS_qx;l|J$dbs9t4>eZj*FjEYO8BQ@5b>8ZCfoItWh zStZz5k8YW|#k)=5fn{V-O%zG8qTm*qUI@8k;y)sKXR)O|!FyAgmaDDA_EasK z4QOotkJh`a;c3Qzlm)=e8E5ZZ;>=8E+?NN267UU#ke6V#!qdN`fxUDg9j&QjP1A=C zsg0~VF>+gRgmG>mB8QET&`W-H8#jMKEBd@lDy<(*eLbcV5wHYaSRM?Unli3Qlv|0W zl%B51+az{%7=XVVUs@(D2e;XnOy-YQ?@7AG$vA(U753Vv>rEcI~S4;O`x4?_`NoWb#CepPb!rb z{J}{MZL`VpOhU!O2#c@wrH=Bh2T&RiYb-CuXvlfALl7-xbkYr^ zM8A32iE5^V5bDbgU(?Zo#F2Ord9SETOe_oh;W7x3gzU9dFnyG&VNs;zMmoZ44nGzl zCoDax><^sDw2NciKqx>YVAooci-1d$Rz;V($ii_%)sl%ez)eXoYNX|7@0_W*c=#1f za1=7I^kWKoMvmmeNVGT2UW=2;m+EhRbgczd5R#QViRe}|6GRM+7S@sM_>nxpZ_WL<#nA}JZ2kSzU zVmhq8x}`uC#8V5H>JS1k@Vy;rO^h8wJkDQ~3rda)Wky}ESUWFVR z23s#Hc~J3XOlK9#!8F5^19Z8W^5?BE^{p0tV8wi#f00?g(e2^)#W5 z1KyyxT1uB=Ql7g0u>55h+dl}L&sfq)8|v~3f}X2fa?|EEQ5-{3)Kt(@ zg9wl}mcRh3Fdz#KgolgV|FuVNPY6m=vyoHAIg8uE*^UNam}6X`{!fRUJX>h}9P8fA zMrR9G_C_5Obpf{&ruIceI!fJx<}8k*I}+14tFG;ilpKAb>%qsd#z?DosH}Qop^Cu!`j)JSi&b+rUFg z6PgTNRGC7}7O%i6U-)ZWeGFYUH}p03r1VY)v_MdZ#~GKPArq1|&E6WK0a8c0L)rF6 z!WK=tWZQdszd~yAO-l}lPncdp3Vgu z(~9z5loau|K5|+xEUq5TWkki8%zQ-qQ=(jI0GW;5`Xxt01QI^*M9vhJ$Zj@J=J{~g z%I1rhaIfH8chU1TQR8@Gxr=UqqHM|0^YZ>I8?FGfZR!WKw3mva5~aqC$ER7oIYAx585r^Tf5)LW9dkH7vBc;Olo=Tc5goZ(>Wl zgn>AH-W!Vi{QYN`tN1hTon2~fW*ku0HUB*Z`r~VT2Qr)1U!&=swbXXyg&sFtRYrLG zrnd)RJ0&nouA70+O*8ndprtMw=?y~o36~lU`TS)ZdWQToF?`o^;f1VGJp(b$=WcxhDbli6i(zH_4xf=_VirZ9(c6Q9`V>Q&qhfSh$!tA2lCMi!w-9d*#ic4#uNs(Vg2&sPOqDEwQH4aPvWO0}ABPrWC(j8@7(pZ`UU zQ)0J9i@uvVvA1z)H>>!(q4u zi1rd}*pR^SILf3oq*c}QDcf+z3DQzE6SCGV?Lj5cdVJv2vuKQhxX4+RxkbN^(0K%y zkpxXWlk__EmYUgOz}`BWL2+;LW!JyEln&bo%kl(4C!8o8sH>m81HCKd2=4s|ymA}| zx_I-e^R7uQRHoS-g@9A3hSo}7w-?cGkGRC4&TqYi*th{t(M)WNW!Q`T(}%zM-d2v? zxwncyBNF`98_RU8>SYlspc!#c=r`E})?x_zzd3cz%|`IvG37PdoOTpnG*f;;A4V`Y zs+9X*{;UXkBWv&mK28BG(xYUf+qH*51{CL?{{so%c^XFLhl~IK002ovPDHLkV1mrw Bz%u{< diff --git a/plugins/FFTFilter/logo.png b/plugins/FFTFilter/logo.png deleted file mode 100644 index 9340da708dd79ed97111eb535f51b81a91d6a15b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 774 zcmV+h1Nr=kP)7WEc)VQ)zLm`B#lSD% z0Wg;#IH?7|3b0p&fj_`2;A{cm@zx+(Ge?s$@EN$6LtMjg>;+(boCbaXw;ja=b6mQ?gRp67Yf18(18niCN0v&eY^{Cr&#;#IcF{ks?!* z&o!_q>9xbSw`QytRI!M?zP_o#K-8ExJaV?vi znPt?~0KhTu23U+Gy8^Tw;^SzWSet9n Date: Mon, 15 Apr 2024 21:02:53 +0200 Subject: [PATCH 066/184] VectorGraph_style_css_implemented_partially --- data/themes/default/style.css | 10 ++++++++++ include/VectorGraph.h | 27 +++++++++++++++++++++---- src/gui/widgets/VectorGraph.cpp | 35 ++++++++++++++++++++++++++------- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index e3e2eec6a96..bdf5d0f0938 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -51,6 +51,16 @@ lmms--gui--Knob { qproperty-arcInactiveColor: rgba(120, 120, 120, 70); } +lmms--gui--VectorGraph { + qproperty-vectorGraphDefaultAutomatedColor: rgba(69,42,153,180); + qproperty-vectorGraphDefaultLineColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphDefaultActiveColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphDefaultFillColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphSecondaryLineColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphSecondaryActiveColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphSecondaryFillColor: rgba(120, 120, 120, 255); +} + lmms--gui--AutomationEditor { color: #ffffff; background-color: #141616; diff --git a/include/VectorGraph.h b/include/VectorGraph.h index e9010cf7821..87191fd2761 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -50,16 +50,24 @@ namespace gui class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView { Q_OBJECT + // set default VectorGraph css colors and styles + Q_PROPERTY(QColor vectorGraphDefaultAutomatedColor MEMBER m_vectorGraphDefaultAutomatedColor) + Q_PROPERTY(QColor vectorGraphDefaultLineColor MEMBER m_vectorGraphDefaultLineColor) + Q_PROPERTY(QColor vectorGraphDefaultActiveColor MEMBER m_vectorGraphDefaultActiveColor) + Q_PROPERTY(QColor vectorGraphDefaultFillColor MEMBER m_vectorGraphDefaultFillColor) + Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor) + Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor) + Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor) public: - VectorGraphView(QWidget * parentIn, - int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn); + VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, + unsigned int pointSizeIn, unsigned int maxLengthIn, bool shouldApplyDefaultVectorGraphColorsIn); ~VectorGraphView(); void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); void setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn); + void applyDefaultColors(); inline VectorGraphModel* model() { @@ -198,6 +206,18 @@ protected slots: std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; + + + // default VectorGraphDataArray colors + // applyed in constructor + QColor m_vectorGraphDefaultAutomatedColor; + + QColor m_vectorGraphDefaultLineColor; + QColor m_vectorGraphDefaultActiveColor; + QColor m_vectorGraphDefaultFillColor; + QColor m_vectorGraphSecondaryLineColor; + QColor m_vectorGraphSecondaryActiveColor; + QColor m_vectorGraphSecondaryFillColor; }; } // namespace gui @@ -280,7 +300,6 @@ public slots: // block threads that want to access // a dataArray's getValues() at the same time std::mutex m_getValuesAccess; - //friend class gui::VectorGraphView; }; class LMMS_EXPORT VectorGraphDataArray diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 444a30b4348..d3484891bf4 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -55,9 +55,8 @@ namespace lmms namespace gui { -VectorGraphView::VectorGraphView(QWidget * parentIn, - int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn) : +VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, + unsigned int pointSizeIn, unsigned int maxLengthIn, bool shouldApplyDefaultVectorGraphColorsIn) : QWidget(parentIn), ModelView(new VectorGraphModel(maxLengthIn, nullptr, false), this) { @@ -114,6 +113,10 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, setCursor(Qt::CrossCursor); modelChanged(); + if (shouldApplyDefaultVectorGraphColorsIn == true) + { + applyDefaultColors(); + } } VectorGraphView::~VectorGraphView() { @@ -129,7 +132,7 @@ void VectorGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocatio if (model()->getDataArraySize() > dataArrayLocationIn) { model()->getDataArray(dataArrayLocationIn)->setLineColor(colorIn); - update(); + updateGraph(); } } void VectorGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -137,7 +140,7 @@ void VectorGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocat if (model()->getDataArraySize() > dataArrayLocationIn) { model()->getDataArray(dataArrayLocationIn)->setActiveColor(colorIn); - update(); + updateGraph(); } } void VectorGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -145,7 +148,7 @@ void VectorGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocatio if (model()->getDataArraySize() > dataArrayLocationIn) { model()->getDataArray(dataArrayLocationIn)->setFillColor(colorIn); - update(); + updateGraph(); } } void VectorGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn) @@ -153,7 +156,25 @@ void VectorGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLo if (model()->getDataArraySize() > dataArrayLocationIn) { model()->getDataArray(dataArrayLocationIn)->setAutomatedColor(colorIn); - update(); + updateGraph(); + } +} +void VectorGraphView::applyDefaultColors() +{ + unsigned int size = model()->getDataArraySize(); + if (size > 0) + { + setLineColor(m_vectorGraphDefaultLineColor, 0); + setActiveColor(m_vectorGraphDefaultActiveColor, 0); + setFillColor(m_vectorGraphDefaultFillColor, 0); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); + if (size > 1) + { + setLineColor(m_vectorGraphSecondaryLineColor, 1); + setActiveColor(m_vectorGraphSecondaryActiveColor, 1); + setFillColor(m_vectorGraphSecondaryFillColor, 1); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 1); + } } } From 208ab9d3833c29ff5c2f45d8fa91b790d3ab4eeb Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:04:05 +0200 Subject: [PATCH 067/184] WaveShaper_VectorGraph_default_colors_applyed --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 95af4939207..c7f9d682a0f 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -49,9 +49,10 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); - auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024); + auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024, false); curGraph->setModel(&_controls->m_vectorGraphModel); curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); + curGraph->applyDefaultColors(); curGraph->move(10, 6); auto inputKnob = new Knob(KnobType::Bright26, this); From abe78a7354b7de3c48573aea3b275382734068c4 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:05:28 +0200 Subject: [PATCH 068/184] fft_helpers_reverted --- include/fft_helpers.h | 30 ------------ src/core/fft_helpers.cpp | 98 ---------------------------------------- 2 files changed, 128 deletions(-) diff --git a/include/fft_helpers.h b/include/fft_helpers.h index 521a65b2030..80c69a0a35a 100644 --- a/include/fft_helpers.h +++ b/include/fft_helpers.h @@ -96,36 +96,6 @@ int LMMS_EXPORT absspec(const fftwf_complex *complex_buffer, float *absspec_buff unsigned int compl_length); -/** TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * @return 0 on success, else -1 - */ -int LMMS_EXPORT getPhase(const fftwf_complex *complex_buffer, float *phaseBufferOut, unsigned int compl_length); - - -/** TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * @return 0 on success, else -1 - */ -int LMMS_EXPORT inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, const float *phaseBufferIn, - unsigned int sampleRateIn, unsigned int compl_length); -int LMMS_EXPORT inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, unsigned int sampleRateIn, unsigned int compl_length); - - -/** TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * @return 0 on success, else -1 - */ -int LMMS_EXPORT getFreq(float *freqBufferOut, unsigned int sampleRateIn, unsigned int compl_length); -float LMMS_EXPORT getFreq(unsigned int locationIn, unsigned int sampleRateIn, unsigned int compl_length); - - /** Build fewer subbands from many absolute spectrum values. * Take care that - compressedbands[] array num_new elements long * - num_old > num_new diff --git a/src/core/fft_helpers.cpp b/src/core/fft_helpers.cpp index 1345b13097f..c2431034170 100644 --- a/src/core/fft_helpers.cpp +++ b/src/core/fft_helpers.cpp @@ -26,10 +26,7 @@ #include "fft_helpers.h" -#include - #include -#include #include "lmms_constants.h" namespace lmms @@ -182,101 +179,6 @@ int absspec(const fftwf_complex *complex_buffer, float *absspec_buffer, unsigned } -/* TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * return 0 on success, else -1 - */ -int getPhase(const fftwf_complex *complex_buffer, float *phaseBufferOut, unsigned int compl_length) -{ - if (complex_buffer == nullptr || phaseBufferOut == nullptr) {return -1;} - if (compl_length == 0) {return -1;} - - for (unsigned int i = 0; i < compl_length; i++) - { - phaseBufferOut[i] = std::atan(complex_buffer[i][1] / complex_buffer[i][0]); - } - - return 0; -} - - -/* TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * return 0 on success, else -1 - */ -int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, const float *phaseBufferIn, - unsigned int sampleRateIn, unsigned int compl_length) -{ - if (complex_buffer == nullptr || absspec_buffer == nullptr || phaseBufferIn == nullptr) {return -1;} - if (compl_length == 0) {return -1;} - /* - for a complex number $c$ of magnitude $m$ and phase offset $\theta$ - [ - c = me^{j(2\pi f + \theta)} = m\cos(2\pi f + \theta) + jm\sin(2\pi f + \theta) - ] - */ - // 2 / pi - float twoDivPi = 1.570796327f; - for (unsigned int i = 0; i < compl_length; i++) - { - float curFreq = getFreq(i, sampleRateIn, compl_length); - //std::cout << "inverseAbsspec i: " << i << " freq: " << curFreq << " amp: " << absspec_buffer[i] << " phase: " << phaseBufferIn[i] << std::endl; - //complex_buffer[i][0] = absspec_buffer[i] / std::cos(twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][1] = absspec_buffer[i] / std::sin(twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][0] = std::pow(absspec_buffer[i] * 2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][1] = std::pow(absspec_buffer[i] * 2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][0] = absspec_buffer[i] * std::cos(twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][1] = absspec_buffer[i] * std::sin(twoDivPi * curFreq + phaseBufferIn[i]); - //complex_buffer[i][0] = absspec_buffer[i] * std::cos(phaseBufferIn[i]); - //complex_buffer[i][1] = absspec_buffer[i] * std::sin(phaseBufferIn[i]); - - //complex_buffer[i][0] = absspec_buffer[i] * 2.718281828f; - //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, phaseBufferIn[i]); - //complex_buffer[i][1] = absspec_buffer[i] * std::pow(2.718281828f, twoDivPi * curFreq + phaseBufferIn[i]); - complex_buffer[i][0] = absspec_buffer[i] * std::acos(twoDivPi * curFreq / phaseBufferIn[i]); - complex_buffer[i][1] = absspec_buffer[i] * std::asin(twoDivPi * curFreq / phaseBufferIn[i]); - } - return 0; -} -int inverseAbsspec(fftwf_complex *complex_buffer, const float *absspec_buffer, unsigned int sampleRateIn, unsigned int compl_length) -{ - if (complex_buffer == nullptr || absspec_buffer == nullptr) {return -1;} - if (compl_length == 0) {return -1;} - - std::vector phaseInput(compl_length); - getPhase(complex_buffer, phaseInput.data(), compl_length); - return inverseAbsspec(complex_buffer, absspec_buffer, phaseInput.data(), sampleRateIn, compl_length); -} - - -/* TODO - * Take care that - compl_len is not bigger than complex_buffer! - * - absspec buffer is big enough! - * - * return 0 on success, else -1 - */ -int getFreq(float *freqBufferOut, unsigned int sampleRateIn, unsigned int compl_length) -{ - if (freqBufferOut == nullptr) {return -1;} - if (compl_length == 0) {return -1;} - - for (unsigned int i = 0; i < compl_length; i++) - { - freqBufferOut[i] = getFreq(i, sampleRateIn, compl_length); - } - - return 0; -} -float getFreq(unsigned int locationIn, unsigned int sampleRateIn, unsigned int compl_length) -{ - return locationIn * sampleRateIn / static_cast(compl_length) / 2.0f; -} - - /* Build fewer subbands from many absolute spectrum values. * Take care that - compressedbands[] array num_new elements long * - num_old > num_new From 63f7092be4c9359ee39b7334aff277844fe79438 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:40:24 +0200 Subject: [PATCH 069/184] VectorGraph_style_css_implemented_partially2 --- data/themes/default/style.css | 10 +++++----- src/gui/widgets/VectorGraph.cpp | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index bdf5d0f0938..8702dc98068 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -51,11 +51,11 @@ lmms--gui--Knob { qproperty-arcInactiveColor: rgba(120, 120, 120, 70); } -lmms--gui--VectorGraph { - qproperty-vectorGraphDefaultAutomatedColor: rgba(69,42,153,180); - qproperty-vectorGraphDefaultLineColor: rgba(120, 120, 120, 255); - qproperty-vectorGraphDefaultActiveColor: rgba(120, 120, 120, 255); - qproperty-vectorGraphDefaultFillColor: rgba(120, 120, 120, 255); +lmms--gui--VectorGraphView { + qproperty-vectorGraphDefaultAutomatedColor: rgba(69, 42, 153, 180); + qproperty-vectorGraphDefaultLineColor: rgb(55, 10, 250); + qproperty-vectorGraphDefaultActiveColor: #452a99; + qproperty-vectorGraphDefaultFillColor: #452a99; qproperty-vectorGraphSecondaryLineColor: rgba(120, 120, 120, 255); qproperty-vectorGraphSecondaryActiveColor: rgba(120, 120, 120, 255); qproperty-vectorGraphSecondaryFillColor: rgba(120, 120, 120, 255); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d3484891bf4..7d530e5f917 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -164,6 +164,7 @@ void VectorGraphView::applyDefaultColors() unsigned int size = model()->getDataArraySize(); if (size > 0) { + qDebug("applyDefaultColors lineColor: %d, %d, %d, %d", m_vectorGraphDefaultLineColor.red(), m_vectorGraphDefaultLineColor.green(), m_vectorGraphDefaultLineColor.blue(), m_vectorGraphDefaultLineColor.alpha()); setLineColor(m_vectorGraphDefaultLineColor, 0); setActiveColor(m_vectorGraphDefaultActiveColor, 0); setFillColor(m_vectorGraphDefaultFillColor, 0); From 29b0377b910b155c129600c08974866f3314e807 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 17 Apr 2024 22:24:40 +0200 Subject: [PATCH 070/184] VectorGraph_default_colors_loaded_correctly --- include/VectorGraph.h | 21 +++++++++++++-------- src/gui/widgets/VectorGraph.cpp | 16 +++++++++++++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 87191fd2761..6a25cce9b4c 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -1,7 +1,7 @@ /* * VecorGraph.h - Vector graph widget and model implementation * - * Copyright (c) 2024 Szeli1 TODO + * Copyright (c) 2024 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -51,14 +51,15 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView { Q_OBJECT // set default VectorGraph css colors and styles - Q_PROPERTY(QColor vectorGraphDefaultAutomatedColor MEMBER m_vectorGraphDefaultAutomatedColor) - Q_PROPERTY(QColor vectorGraphDefaultLineColor MEMBER m_vectorGraphDefaultLineColor) - Q_PROPERTY(QColor vectorGraphDefaultActiveColor MEMBER m_vectorGraphDefaultActiveColor) - Q_PROPERTY(QColor vectorGraphDefaultFillColor MEMBER m_vectorGraphDefaultFillColor) - Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor) - Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor) - Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor) + Q_PROPERTY(QColor vectorGraphDefaultAutomatedColor MEMBER m_vectorGraphDefaultAutomatedColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultLineColor MEMBER m_vectorGraphDefaultLineColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultActiveColor MEMBER m_vectorGraphDefaultActiveColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultFillColor MEMBER m_vectorGraphDefaultFillColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor NOTIFY changedDefaultColors) public: + VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, unsigned int maxLengthIn, bool shouldApplyDefaultVectorGraphColorsIn); ~VectorGraphView(); @@ -95,6 +96,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView signals: // emited after paintEvent void drawn(); + void changedDefaultColors(); protected: void paintEvent(QPaintEvent* pe) override; void mousePressEvent(QMouseEvent* me) override; @@ -104,6 +106,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView protected slots: void updateGraph(); void updateGraph(bool shouldUseGetLastValuesIn); + void updateDefaultColors(); void execConnectionDialog(); void removeAutomation(); @@ -178,6 +181,8 @@ protected slots: unsigned int m_fontSize; // draw simplified lines bool m_isSimplified; + // true when applyDefaultColors is called, used when defaultColors are loading + bool m_isDefaultColorsApplyed; QPixmap m_background; // for 1 draw, it will use the VectorGraphDataArray // m_bakedValues without calling GetValues() diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 7d530e5f917..e5da7c06273 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1,7 +1,7 @@ /* * VectorGraph.cpp - Vector graph widget, model, helper class implementation * - * Copyright (c) 2024 Szeli1 TODO + * Copyright (c) 2024 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -68,6 +68,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_pointSize = pointSizeIn; m_fontSize = 12; m_isSimplified = false; + m_isDefaultColorsApplyed = false; //m_background; m_useGetLastValues = false; @@ -113,6 +114,11 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, setCursor(Qt::CrossCursor); modelChanged(); + + // connect default loading of default colors to applyDefaultColors + QObject::connect(this, SIGNAL(changedDefaultColors()), + this, SLOT(updateDefaultColors())); + if (shouldApplyDefaultVectorGraphColorsIn == true) { applyDefaultColors(); @@ -161,6 +167,7 @@ void VectorGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLo } void VectorGraphView::applyDefaultColors() { + m_isDefaultColorsApplyed = true; unsigned int size = model()->getDataArraySize(); if (size > 0) { @@ -841,6 +848,13 @@ void VectorGraphView::updateGraph(bool shouldUseGetLastValuesIn) m_useGetLastValues = shouldUseGetLastValuesIn; update(); } +void VectorGraphView::updateDefaultColors() +{ + if (m_isDefaultColorsApplyed == true) + { + applyDefaultColors(); + } +} void VectorGraphView::execConnectionDialog() { if (m_isSelected == true) From b503d1e3691f5ba612010ffb56d16aab9b417c01 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:11:39 +0200 Subject: [PATCH 071/184] style_finalized_default_colors_1 --- data/themes/default/style.css | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 8702dc98068..42c959a210e 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -52,13 +52,13 @@ lmms--gui--Knob { } lmms--gui--VectorGraphView { - qproperty-vectorGraphDefaultAutomatedColor: rgba(69, 42, 153, 180); - qproperty-vectorGraphDefaultLineColor: rgb(55, 10, 250); - qproperty-vectorGraphDefaultActiveColor: #452a99; - qproperty-vectorGraphDefaultFillColor: #452a99; - qproperty-vectorGraphSecondaryLineColor: rgba(120, 120, 120, 255); - qproperty-vectorGraphSecondaryActiveColor: rgba(120, 120, 120, 255); - qproperty-vectorGraphSecondaryFillColor: rgba(120, 120, 120, 255); + qproperty-vectorGraphDefaultAutomatedColor: rgba(74, 59, 186, 200); + qproperty-vectorGraphDefaultLineColor: rgba(11, 213, 86, 255); + qproperty-vectorGraphDefaultActiveColor: rgba(29, 226, 118, 255); + qproperty-vectorGraphDefaultFillColor: rgba(23, 121, 59, 100); + qproperty-vectorGraphSecondaryLineColor: rgba(209, 216, 228, 255); + qproperty-vectorGraphSecondaryActiveColor: rgba(255, 255, 255, 255); + qproperty-vectorGraphSecondaryFillColor: rgba(209, 216, 228, 100); } lmms--gui--AutomationEditor { From 1f6c20bb1cb5124b00e788c2cc0d9029a574d1a3 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:40:14 +0200 Subject: [PATCH 072/184] WaveShaper_finalized_implementation_1 --- plugins/WaveShaper/WaveShaper.cpp | 3 +- .../WaveShaper/WaveShaperControlDialog.cpp | 6 +++ plugins/WaveShaper/WaveShaperControls.cpp | 39 ++++++++----------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index 18a2beaeb9f..8fe7727a69b 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -78,8 +78,9 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ const float w = wetLevel(); float input = m_wsControls.m_inputModel.value(); float output = m_wsControls.m_outputModel.value(); + // getting the current graph samples (size: 200) + // getting the graph samples this often can cause lagg with bigger sample count (if automated or effected) std::vector graphSamples = m_wsControls.getGraphSamples(); - //const float * samples = m_wsControls.m_wavegraphModel.samples(); const bool clip = m_wsControls.m_clipModel.value(); ValueBuffer *inputBuffer = m_wsControls.m_inputModel.valueBuffer(); diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index c7f9d682a0f..0aef81776b2 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -52,7 +52,13 @@ WaveShaperControlDialog::WaveShaperControlDialog( auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024, false); curGraph->setModel(&_controls->m_vectorGraphModel); curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); + // this can cause problems with custom colors curGraph->applyDefaultColors(); + // custom colors can be set this way (but this garph uses applyDefaultColros()): + //curGraph->setLineColor(QColor(210, 50, 50, 255), arrayLocation); + //curGraph->setActiveColor(QColor(210, 50, 50, 255), arrayLocation); + //curGraph->setFillColor(QColor(210, 50, 50, 255), arrayLocation); + //curGraph->setAutomatedColor(QColor(210, 50, 50, 255), arrayLocation); curGraph->move(10, 6); auto inputKnob = new Knob(KnobType::Bright26, this); diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 818f32abe92..566647a6668 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -50,6 +50,12 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_clipModel( false, this ) { + unsigned int arrayLocationB = m_vectorGraphModel.addArray(); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); + unsigned int arrayLocation = m_vectorGraphModel.addArray(); //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedSize(true); //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedX(true); @@ -60,22 +66,8 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); - m_vectorGraphModel.getDataArray(arrayLocation)->setLineColor(QColor(210, 50, 50, 255)); - m_vectorGraphModel.getDataArray(arrayLocation)->setActiveColor(QColor(255, 30, 20, 255)); - m_vectorGraphModel.getDataArray(arrayLocation)->setFillColor(QColor(170, 25, 25, 40)); - m_vectorGraphModel.getDataArray(arrayLocation)->setAutomatedColor(QColor(144, 107, 255, 255)); - unsigned int arrayLocationB = m_vectorGraphModel.addArray(); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setLineColor(QColor(10, 50, 210, 255)); - m_vectorGraphModel.getDataArray(arrayLocationB)->setActiveColor(QColor(70, 170, 255, 255)); - m_vectorGraphModel.getDataArray(arrayLocationB)->setFillColor(QColor(70, 100, 180, 40)); - m_vectorGraphModel.getDataArray(arrayLocationB)->setAutomatedColor(QColor(144, 107, 255, 255)); - - // connect VectorGraphDataArrays so the 2. will be able to effect the 1.: + // connect VectorGraphDataArrays so the 1. VectorGraphDataArray will be able to effect the 2.: m_vectorGraphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); // draw default shape setDefaultShape(); @@ -117,9 +109,10 @@ void WaveShaperControls::saveSettings( QDomDocument & _doc, std::vector WaveShaperControls::getGraphSamples() { - if (m_vectorGraphModel.getDataArraySize() > 0) + if (m_vectorGraphModel.getDataArraySize() > 1) { - std::vector output = m_vectorGraphModel.getDataArray(0)->getValues(200); + // get 200 samples from the 1. VectorGraphDataArray + std::vector output = m_vectorGraphModel.getDataArray(1)->getValues(200); emit vectorGraphUpdateView(true); return output; } @@ -139,22 +132,22 @@ void WaveShaperControls::setDefaultShape() if (m_vectorGraphModel.getDataArraySize() > 1) { - int addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.0f); + int addedLocation = m_vectorGraphModel.getDataArray(1)->add(0.0f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(0)->setY(addedLocation, -1.0f); + m_vectorGraphModel.getDataArray(1)->setY(addedLocation, -1.0f); } - addedLocation = m_vectorGraphModel.getDataArray(0)->add(1.0f); + addedLocation = m_vectorGraphModel.getDataArray(1)->add(1.0f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(0)->setY(addedLocation, 1.0f); + m_vectorGraphModel.getDataArray(1)->setY(addedLocation, 1.0f); } - addedLocation = m_vectorGraphModel.getDataArray(1)->add(0.5f); + addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.5f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(1)->setY(addedLocation, -1.0f); + m_vectorGraphModel.getDataArray(0)->setY(addedLocation, -1.0f); } } } From 02847b689e8995f7018821eced1139872f99f5f6 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:47:46 +0200 Subject: [PATCH 073/184] VectorGraph_style_changes --- include/VectorGraph.h | 2 ++ src/gui/widgets/VectorGraph.cpp | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 6a25cce9b4c..3a7d0d1a529 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -58,6 +58,8 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor NOTIFY changedDefaultColors) Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor NOTIFY changedDefaultColors) Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor NOTIFY changedDefaultColors) + + Q_PROPERTY(int fontSize MEMBER m_fontSize) public: VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index e5da7c06273..d3f63e4d2a1 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -66,7 +66,8 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_addition = false; m_pointSize = pointSizeIn; - m_fontSize = 12; + // gets set in style + //m_fontSize = 12; m_isSimplified = false; m_isDefaultColorsApplyed = false; //m_background; @@ -171,18 +172,25 @@ void VectorGraphView::applyDefaultColors() unsigned int size = model()->getDataArraySize(); if (size > 0) { - qDebug("applyDefaultColors lineColor: %d, %d, %d, %d", m_vectorGraphDefaultLineColor.red(), m_vectorGraphDefaultLineColor.green(), m_vectorGraphDefaultLineColor.blue(), m_vectorGraphDefaultLineColor.alpha()); - setLineColor(m_vectorGraphDefaultLineColor, 0); - setActiveColor(m_vectorGraphDefaultActiveColor, 0); - setFillColor(m_vectorGraphDefaultFillColor, 0); - setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); if (size > 1) { - setLineColor(m_vectorGraphSecondaryLineColor, 1); - setActiveColor(m_vectorGraphSecondaryActiveColor, 1); - setFillColor(m_vectorGraphSecondaryFillColor, 1); + setLineColor(m_vectorGraphSecondaryLineColor, 0); + setActiveColor(m_vectorGraphSecondaryActiveColor, 0); + setFillColor(m_vectorGraphSecondaryFillColor, 0); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); + + setLineColor(m_vectorGraphDefaultLineColor, 1); + setActiveColor(m_vectorGraphDefaultActiveColor, 1); + setFillColor(m_vectorGraphDefaultFillColor, 1); setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 1); } + else + { + setLineColor(m_vectorGraphDefaultLineColor, 0); + setActiveColor(m_vectorGraphDefaultActiveColor, 0); + setFillColor(m_vectorGraphDefaultFillColor, 0); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); + } } } From f129c7206d406630f92e751b112e0f31e3331369 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:48:04 +0200 Subject: [PATCH 074/184] style_added_font_size --- data/themes/default/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 42c959a210e..1d8759c44b2 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -59,6 +59,7 @@ lmms--gui--VectorGraphView { qproperty-vectorGraphSecondaryLineColor: rgba(209, 216, 228, 255); qproperty-vectorGraphSecondaryActiveColor: rgba(255, 255, 255, 255); qproperty-vectorGraphSecondaryFillColor: rgba(209, 216, 228, 100); + qproperty-fontSize: 10; } lmms--gui--AutomationEditor { From 85510ed6f2dc29442fb7870167dfa300dcfd39f2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 16:31:00 +0200 Subject: [PATCH 075/184] style_classic_updated --- data/themes/classic/style.css | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index 1667ea5fe61..91c7b2c4a49 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -16,6 +16,17 @@ lmms--gui--Knob { qproperty-arcInactiveColor: rgba(120, 120, 120, 70); } +lmms--gui--VectorGraphView { + qproperty-vectorGraphDefaultAutomatedColor: rgba(74, 59, 186, 200); + qproperty-vectorGraphDefaultLineColor: rgba(11, 213, 86, 255); + qproperty-vectorGraphDefaultActiveColor: rgba(29, 226, 118, 255); + qproperty-vectorGraphDefaultFillColor: rgba(23, 121, 59, 100); + qproperty-vectorGraphSecondaryLineColor: rgba(209, 216, 228, 255); + qproperty-vectorGraphSecondaryActiveColor: rgba(255, 255, 255, 255); + qproperty-vectorGraphSecondaryFillColor: rgba(209, 216, 228, 100); + qproperty-fontSize: 10; +} + lmms--gui--AutomationEditor { background-color: rgb(0, 0, 0); color: #e0e0e0; From 3b01f158e654ecf69a9e8713fccabb188b6b3414 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:28:49 +0200 Subject: [PATCH 076/184] VectorGraph_getValues_vector_usage_reworked --- include/VectorGraph.h | 7 ++- src/gui/widgets/VectorGraph.cpp | 98 ++++++++++++++++++++------------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 3a7d0d1a529..216b3a285a3 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -285,6 +285,8 @@ Q_OBJECT //int readLoc(unsigned int startIn, QString dataIn); void lockGetValuesAccess(); void unlockGetValuesAccess(); + void lockBakedValuesAccess(); + void unlockBakedValuesAccess(); signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); @@ -307,6 +309,7 @@ public slots: // block threads that want to access // a dataArray's getValues() at the same time std::mutex m_getValuesAccess; + std::mutex m_bakedValuesAccess; }; class LMMS_EXPORT VectorGraphDataArray @@ -439,7 +442,7 @@ class LMMS_EXPORT VectorGraphDataArray // countIn is the retuned vector's size std::vector getValues(unsigned int countIn); // returns m_bakedValues without updating - std::vector getLastValues(); + void getLastValues(std::vector* copyBufferOut); std::vector getEffectorArrayLocations(); @@ -711,6 +714,8 @@ class LMMS_EXPORT VectorGraphDataArray bool m_isDataChanged; // array containing output final float values for optimalization std::vector m_bakedValues; + // used for updating m_bakedValues fast + std::vector m_updatingBakedValues; // unsorted array of locations in m_dataArray // that need to be updated // sorted in getUpdatingOriginals() because some functions need this to be sorted diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d3f63e4d2a1..069ad9f5a78 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -606,7 +606,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve std::vector dataArrayValues; if (m_useGetLastValues == true) { - dataArrayValues = dataArray->getLastValues(); + dataArray->getLastValues(&dataArrayValues); } else { @@ -633,7 +633,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve } else { - dataArrayValues = dataArray->getLastValues(); + dataArray->getLastValues(&dataArrayValues); } } @@ -1668,7 +1668,7 @@ VectorGraphModel::VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bo Model(parentIn, tr("VectorGraphModel"), defaultConstructedIn) { m_maxLength = maxLengthIn; - m_dataArrays = {}; + //m_dataArrays } VectorGraphModel::~VectorGraphModel() @@ -1903,6 +1903,14 @@ void VectorGraphModel::unlockGetValuesAccess() { m_getValuesAccess.unlock(); } +void VectorGraphModel::lockBakedValuesAccess() +{ + m_bakedValuesAccess.lock(); +} +void VectorGraphModel::unlockBakedValuesAccess() +{ + m_bakedValuesAccess.unlock(); +} void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) { saveSettings(doc, element, QString("")); @@ -1953,6 +1961,7 @@ VectorGraphDataArray::VectorGraphDataArray() // m_dataArray m_isDataChanged = false; // m_bakedValues; + // m_updatingBakedValues // m_needsUpdating; // m_automationModelArray; @@ -1985,6 +1994,7 @@ VectorGraphDataArray::VectorGraphDataArray( // m_dataArray; m_isDataChanged = false; // m_bakedValues; + // m_updatingBakedValues // m_needsUpdating; // m_automationModelArray; @@ -1995,9 +2005,9 @@ VectorGraphDataArray::VectorGraphDataArray( VectorGraphDataArray::~VectorGraphDataArray() { qDebug("VectorGraphDataArray dstc"); - m_dataArray.clear(); - m_bakedValues.clear(); - m_needsUpdating.clear(); + //m_dataArray.clear(); + //m_bakedValues.clear(); + //m_needsUpdating.clear(); for (unsigned int i = 0; i < m_automationModelArray.size(); i++) { @@ -2492,9 +2502,11 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn) qDebug("getValuesA3 finished"); return output; } -std::vector VectorGraphDataArray::getLastValues() +void VectorGraphDataArray::getLastValues(std::vector* copyBufferOut) { - return m_bakedValues; + m_parent->lockBakedValuesAccess(); + *copyBufferOut = m_bakedValues; + m_parent->unlockBakedValuesAccess(); } std::vector VectorGraphDataArray::getEffectorArrayLocations() { @@ -3636,13 +3648,9 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, &effectorUpdatingValues); } - else - { - effectorOutput.resize(countIn); - } qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); - m_isDataChanged = m_isDataChanged || countIn != m_bakedValues.size(); + m_isDataChanged = m_isDataChanged || countIn != m_updatingBakedValues.size(); // deciding if the whole dataArray should be updated // if the whole effectorDataArray was updated @@ -3660,7 +3668,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } // updating m_needsUpdating - if (m_isDataChanged == false && countIn == m_bakedValues.size()) + if (m_isDataChanged == false && countIn == m_updatingBakedValues.size()) { if (isEffected == true && effectorUpdatingValues.size() > 0 && (effectorIsChanged == false || effectedCount > 0)) @@ -3678,10 +3686,16 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i } else { + m_parent->lockBakedValuesAccess(); if (countIn != m_bakedValues.size()) { m_bakedValues.resize(countIn); } + m_parent->unlockBakedValuesAccess(); + if (countIn != m_updatingBakedValues.size()) + { + m_updatingBakedValues.resize(countIn); + } m_needsUpdating.resize(m_dataArray.size()); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { @@ -3692,10 +3706,13 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i float stepSize = 1.0f / static_cast(countIn); // calculating point data and lines - if (m_needsUpdating.size() > 0 && m_bakedValues.size() > 0) + if (m_needsUpdating.size() > 0 && m_updatingBakedValues.size() > 0) { + effectorOutput.resize(countIn); // calculating relative X locations (in lines) of the output values // for later use in the line calculations + // outputXLocations[sample_location] is equal to 0.0f if it is at the start of a line, + // it is equal to 1.0f if it is at the end of a line for (unsigned int i = 0; i < m_dataArray.size(); i++) { unsigned int start = static_cast @@ -3734,7 +3751,10 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i { getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); } - //effectorData.clear(); + + m_parent->lockBakedValuesAccess(); + m_bakedValues = m_updatingBakedValues; + m_parent->unlockBakedValuesAccess(); } // setting outputs @@ -3866,9 +3886,9 @@ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn if (m_needsUpdating[iIn] + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray - for (int j = end; j < m_bakedValues.size(); j++) + for (int j = end; j < m_updatingBakedValues.size(); j++) { - m_bakedValues[j] = curY; + m_updatingBakedValues[j] = curY; } } if (m_needsUpdating[iIn] == 0) @@ -3876,7 +3896,7 @@ void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn // if this point is at the 0 location in m_dataArray for (int j = 0; j < start; j++) { - m_bakedValues[j] = curY; + m_updatingBakedValues[j] = curY; } } @@ -3890,7 +3910,7 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // calculate curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // no line type } @@ -3899,13 +3919,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArraySine(outputXLocationsIn, start, end, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; } } else if (type == 2) @@ -3913,13 +3933,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; } } else if (type == 3) @@ -3927,13 +3947,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; } } else if (type == 4) @@ -3941,13 +3961,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_bakedValues, curValA, curValB, fadeInStart); + std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_updatingBakedValues, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; } } else if (type == 5) @@ -3955,46 +3975,46 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_bakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_bakedValues[j] = m_bakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; } } if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) { int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedValues.size() : end; // process line effect // if it is enabled qDebug("getValues run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { - m_bakedValues[j] = processEffect(m_needsUpdating[iIn], m_bakedValues[j], 0, effectorOutputIn->operator[](j)); + m_updatingBakedValues[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedValues[j], 0, effectorOutputIn->operator[](j)); } } // clamp for (int j = start; j < end; j++) { - if (m_bakedValues[j] > 1.0f) + if (m_updatingBakedValues[j] > 1.0f) { - m_bakedValues[j] = 1.0f; + m_updatingBakedValues[j] = 1.0f; } - else if (m_bakedValues[j] < -1.0f) + else if (m_updatingBakedValues[j] < -1.0f) { - m_bakedValues[j] = -1.0f; + m_updatingBakedValues[j] = -1.0f; } } if (m_isNonNegative == true) { int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_bakedValues.size() : end; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedValues.size() : end; for (int j = startB; j < endB; j++) { - m_bakedValues[j] = m_bakedValues[j] / 2.0f + 0.5f; + m_updatingBakedValues[j] = m_updatingBakedValues[j] / 2.0f + 0.5f; } } } From 4dcfe8c41acbe2f52d120f9395d2a721a1636c10 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:30:00 +0200 Subject: [PATCH 077/184] WaveShaper_getGraphSamples_reworked --- plugins/WaveShaper/WaveShaper.cpp | 10 +++++----- plugins/WaveShaper/WaveShaperControls.cpp | 15 ++++++--------- plugins/WaveShaper/WaveShaperControls.h | 3 ++- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index 8fe7727a69b..3ca84fae323 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -80,7 +80,7 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ float output = m_wsControls.m_outputModel.value(); // getting the current graph samples (size: 200) // getting the graph samples this often can cause lagg with bigger sample count (if automated or effected) - std::vector graphSamples = m_wsControls.getGraphSamples(); + std::vector* graphSamples = m_wsControls.getGraphSamples(); const bool clip = m_wsControls.m_clipModel.value(); ValueBuffer *inputBuffer = m_wsControls.m_inputModel.valueBuffer(); @@ -117,17 +117,17 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ if( lookup < 1 ) { - s[i] = frac * graphSamples[0] * posneg; + s[i] = frac * graphSamples->operator[](0) * posneg; } else if( lookup < 200 ) { - s[i] = linearInterpolate(graphSamples[lookup - 1], - graphSamples[lookup], frac) + s[i] = linearInterpolate(graphSamples->operator[](lookup - 1), + graphSamples->operator[](lookup), frac) * posneg; } else { - s[i] *= graphSamples[199]; + s[i] *= graphSamples->operator[](199); } } diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 566647a6668..82dfe37edd8 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -47,7 +47,8 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_inputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Input gain" ) ), m_outputModel( 1.0f, 0.0f, 5.0f, 0.01f, this, tr( "Output gain" ) ), m_vectorGraphModel(1024, this, false), - m_clipModel( false, this ) + m_clipModel( false, this ), + m_vectorGraphSampleBuffer(200) { unsigned int arrayLocationB = m_vectorGraphModel.addArray(); @@ -107,19 +108,15 @@ void WaveShaperControls::saveSettings( QDomDocument & _doc, m_vectorGraphModel.saveSettings(_doc, _this, "VectorGraph"); } -std::vector WaveShaperControls::getGraphSamples() +std::vector* WaveShaperControls::getGraphSamples() { if (m_vectorGraphModel.getDataArraySize() > 1) { - // get 200 samples from the 1. VectorGraphDataArray - std::vector output = m_vectorGraphModel.getDataArray(1)->getValues(200); + // get m_vectorGraphSampleBuffer.size (200) samples from the 1. VectorGraphDataArray + m_vectorGraphSampleBuffer = m_vectorGraphModel.getDataArray(1)->getValues(m_vectorGraphSampleBuffer.size()); emit vectorGraphUpdateView(true); - return output; - } - else - { - return std::vector(200); } + return &m_vectorGraphSampleBuffer; } void WaveShaperControls::setDefaultShape() diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 7c59f90e51c..214b73a3640 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -65,7 +65,7 @@ class WaveShaperControls : public EffectControls return( new gui::WaveShaperControlDialog( this ) ); } - std::vector getGraphSamples(); + std::vector* getGraphSamples(); @@ -89,6 +89,7 @@ private slots: friend class gui::WaveShaperControlDialog; friend class WaveShaperEffect; + std::vector m_vectorGraphSampleBuffer; } ; From ce49bc8a6721686ad4eace398b3525dc38a9e230 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:40:28 +0200 Subject: [PATCH 078/184] VectorGraph_added_new_setDataArray_function --- include/VectorGraph.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 216b3a285a3..f55e79f6fa6 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -457,6 +457,7 @@ class LMMS_EXPORT VectorGraphDataArray // callDataChangedIn -> call dataChanged() after -> paintEvent() void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); + void setDataArray(float* dataArrayIn, unsigned int sizeIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); // set attribute: ------------------- From 853eff77a9ccc3cb4c121cc50d86d70da45940ff Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:40:46 +0200 Subject: [PATCH 079/184] VectorGraph_added_new_setDataArray_function2 --- src/gui/widgets/VectorGraph.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 069ad9f5a78..c7e62d9b348 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2597,6 +2597,18 @@ void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, } setDataArray(&convertedDataArray, isCurvedIn, clearIn, clampIn, rescaleIn, false, callDataChangedIn); } +void VectorGraphDataArray::setDataArray(float* dataArrayIn, unsigned int sizeIn, + bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) +{ + std::vector> convertedDataArray(sizeIn); + float stepSize = 1.0f / static_cast(sizeIn); + for (unsigned int i = 0; i < sizeIn; i++) + { + convertedDataArray[i].first = i * stepSize; + convertedDataArray[i].second = dataArrayIn[i]; + } + setDataArray(&convertedDataArray, isCurvedIn, clearIn, clampIn, rescaleIn, false, callDataChangedIn); +} unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) { From 808fd7799411c4d1f95f87131e65cca08f464e32 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:42:26 +0200 Subject: [PATCH 080/184] WaveShaper_added_backwards_compatibility --- plugins/WaveShaper/WaveShaperControls.cpp | 27 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 82dfe37edd8..0f0889ab903 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -27,13 +27,12 @@ #include #include -#include - #include "WaveShaperControls.h" #include "WaveShaper.h" #include "VectorGraph.h" #include "Engine.h" #include "Song.h" +#include "base64.h" namespace lmms { @@ -88,8 +87,26 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) m_clipModel.loadSettings( _this, "clipInput" ); - // loading VectorGraph - m_vectorGraphModel.loadSettings(_this, "VectorGraph"); + if (_this.hasAttribute("waveShape") == true) + { + if (m_vectorGraphModel.getDataArraySize() > 1) + { + int size = 0; + char * dst = 0; + base64::decode(_this.attribute("waveShape"), &dst, &size); + float* graphSampleArray = (float*)dst; + + // loading old graph data into new vectorGraph + m_vectorGraphModel.getDataArray(1)->setDataArray(graphSampleArray, 200, false, false, false, true, true); + + delete[] dst; + } + } + else + { + // loading VectorGraph + m_vectorGraphModel.loadSettings(_this, "VectorGraph1"); + } } @@ -105,7 +122,7 @@ void WaveShaperControls::saveSettings( QDomDocument & _doc, m_clipModel.saveSettings( _doc, _this, "clipInput" ); // saving VectorGraph - m_vectorGraphModel.saveSettings(_doc, _this, "VectorGraph"); + m_vectorGraphModel.saveSettings(_doc, _this, "VectorGraph1"); } std::vector* WaveShaperControls::getGraphSamples() From e323abecf574e49a3153208c117f24aa7d16119b Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:54:08 +0200 Subject: [PATCH 081/184] VectorGraph_style_chagnes --- include/VectorGraph.h | 2 +- src/gui/widgets/VectorGraph.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f55e79f6fa6..04cdd46e1c4 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -132,7 +132,7 @@ protected slots: int mapControlInputX(float inputValueIn, unsigned int displayLengthIn); float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); - float getDistance(float xAIn, float yAIn, float xBIn, float yBIn); + float getDistanceF(float xAIn, float yAIn, float xBIn, float yBIn); // adds point to the selected VectorGraphDataArray bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index c7e62d9b348..7b266a1ff7f 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -117,8 +117,8 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, modelChanged(); // connect default loading of default colors to applyDefaultColors - QObject::connect(this, SIGNAL(changedDefaultColors()), - this, SLOT(updateDefaultColors())); + QObject::connect(this, &VectorGraphView::changedDefaultColors, + this, vectorGraphView::updateDefaultColors); if (shouldApplyDefaultVectorGraphColorsIn == true) { @@ -958,7 +958,7 @@ float VectorGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) { return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); } -float VectorGraphView::getDistance(float xAIn, float yAIn, float xBIn, float yBIn) +float VectorGraphView::getDistanceF(float xAIn, float yAIn, float xBIn, float yBIn) { return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); } @@ -1588,7 +1588,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance if (std::abs(dataX - transformedMouse.first) <= maxDistance) { // calculate real distance (x and y) - float curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, + float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); //qDebug("selected full distance: %f (%d, %d)", curDistance, location, (location - curvedBefore)); @@ -1644,7 +1644,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance dataY = curvedDataCoords.second; } } - curDistance = getDistance(transformedMouse.first * 2.0f, transformedMouse.second, + curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); //qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); if (curDistance <= maxDistance) From 76408e08fa3bf616390d1b30f6bb725381c47f40 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:54:29 +0200 Subject: [PATCH 082/184] WaveShaper_style_changes --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 2 +- plugins/WaveShaper/WaveShaperControls.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 0aef81776b2..085aa9df634 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -78,7 +78,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( outputKnob->setHintText( tr( "Output gain:" ), "" ); auto resetButton = new PixmapButton(this, tr("Reset wavegraph")); - resetButton -> move( 142, 225 ); + resetButton -> move(142, 225); resetButton -> resize( 13, 46 ); resetButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_active" ) ); resetButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_inactive" ) ); diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 0f0889ab903..d2c575f95e3 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -72,10 +72,8 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : // draw default shape setDefaultShape(); - connect(&m_vectorGraphModel, SIGNAL(dataChanged()), - this, SLOT(vectorGraphChanged())); - connect(this, SIGNAL(vectorGraphUpdateView(bool)), - &m_vectorGraphModel, SLOT(updateGraphModel(bool))); + connect(&m_vectorGraphModel, SIGNAL(dataChanged()), this, SLOT(vectorGraphChanged())); + connect(this, SIGNAL(vectorGraphUpdateView(bool)), &m_vectorGraphModel, SLOT(updateGraphModel(bool))); } From 60804ee5a5da6607e4bcaf2519558142b35f2e19 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:31:06 +0200 Subject: [PATCH 083/184] VectorGraph_gui_changes --- include/VectorGraph.h | 6 +++--- src/gui/widgets/VectorGraph.cpp | 27 ++++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 04cdd46e1c4..4af3fd484d9 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -62,8 +62,8 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView Q_PROPERTY(int fontSize MEMBER m_fontSize) public: - VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn, bool shouldApplyDefaultVectorGraphColorsIn); + VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, + unsigned int controlHeightIn, unsigned int controlDisplayCountIn, bool shouldApplyDefaultVectorGraphColorsIn); ~VectorGraphView(); void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); @@ -123,7 +123,7 @@ protected slots: // calculate graph coords from screen space coords std::pair mapMousePos(int xIn, int yIn); // calculate gui curve point's position - std::pair mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); + std::pair mapDataCurvePosF(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); // calculate screen space coords from graph coords // isNonNegativeIn can only be true when graph line / getValues() is mapped diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 7b266a1ff7f..31ff033a66e 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -54,11 +54,10 @@ namespace lmms namespace gui { - -VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, - unsigned int pointSizeIn, unsigned int maxLengthIn, bool shouldApplyDefaultVectorGraphColorsIn) : +VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, + unsigned int controlHeightIn, unsigned int controlDisplayCountIn, bool shouldApplyDefaultVectorGraphColorsIn) : QWidget(parentIn), - ModelView(new VectorGraphModel(maxLengthIn, nullptr, false), this) + ModelView(new VectorGraphModel(2048, nullptr, false), this) { resize(widthIn, heightIn); @@ -80,8 +79,8 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_isLastSelectedArray = false; m_graphHeight = height(); - m_controlHeight = 30; - m_controlDisplayCount = 4; + m_controlHeight = controlHeightIn; + m_controlDisplayCount = controlDisplayCountIn; m_controlDisplayPage = 0; m_isEditingActive = false; m_controlText = { @@ -116,9 +115,9 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, modelChanged(); - // connect default loading of default colors to applyDefaultColors + // connect loading of default colors to applyDefaultColors QObject::connect(this, &VectorGraphView::changedDefaultColors, - this, vectorGraphView::updateDefaultColors); + this, &VectorGraphView::updateDefaultColors); if (shouldApplyDefaultVectorGraphColorsIn == true) { @@ -680,6 +679,8 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve { posA = startPos; + int squareSize = m_pointSize; + QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; bool resetColor = false; @@ -719,8 +720,8 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve if (dataArray->getIsEditableAttrib() == true) { std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - pIn->drawRect(posC.first - m_pointSize / 4 - m_pointSize / 2, - m_graphHeight - posC.second - m_pointSize / 4 - m_pointSize / 2, m_pointSize, m_pointSize); + pIn->drawRect(posC.first - squareSize / 2, + m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); } } } @@ -937,7 +938,7 @@ std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool isNon static_cast((yIn + 1.0f) * static_cast(m_graphHeight) / 2.0f)); } } -std::pair VectorGraphView::mapDataCurvePos(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) +std::pair VectorGraphView::mapDataCurvePosF(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) { return std::pair( (xAIn + xBIn) / 2.0f, @@ -1575,7 +1576,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance } if (location - curvedBefore < arrayIn->size() - 1) { - std::pair curvedDataCoords = mapDataCurvePos( + std::pair curvedDataCoords = mapDataCurvePosF( arrayIn->getX(location - curvedBefore), arrayIn->getY(location - curvedBefore), arrayIn->getX(location - curvedBefore + 1), arrayIn->getY(location - curvedBefore + 1), arrayIn->getC(location - curvedBefore)); @@ -1637,7 +1638,7 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance { if (arrayIn->size() - 1 > i) { - std::pair curvedDataCoords = mapDataCurvePos( + std::pair curvedDataCoords = mapDataCurvePosF( arrayIn->getX(i), arrayIn->getY(i), arrayIn->getX(i + 1), arrayIn->getY(i + 1), arrayIn->getC(i)); dataX = curvedDataCoords.first; From af51f399b619b7cd233018a9adcf2ddfc7d16ea2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:31:38 +0200 Subject: [PATCH 084/184] WaveShaper_updated_VectorGraphView_constructor --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 085aa9df634..ab75293de95 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -49,7 +49,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); - auto curGraph = new VectorGraphView(this, 204, 205, 10, 1024, false); + auto curGraph = new VectorGraphView(this, 204, 205, 10, 30, 3, false); curGraph->setModel(&_controls->m_vectorGraphModel); curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); // this can cause problems with custom colors From cbcf1ec37d4bd7868065aacbec7ebf131ee82a55 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:33:40 +0200 Subject: [PATCH 085/184] WaveShaper_changed_VectorGraph_point_size --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index ab75293de95..8a98ca81ee5 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -49,7 +49,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); - auto curGraph = new VectorGraphView(this, 204, 205, 10, 30, 3, false); + auto curGraph = new VectorGraphView(this, 204, 205, 8, 30, 3, false); curGraph->setModel(&_controls->m_vectorGraphModel); curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); // this can cause problems with custom colors From 265b6d55da102553934f52bcbccffee2d52633f8 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:16:03 +0200 Subject: [PATCH 086/184] VectorGraph_fixed_drawing_order --- include/VectorGraph.h | 2 +- src/gui/widgets/VectorGraph.cpp | 99 +++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 4af3fd484d9..fb16242d779 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -114,7 +114,7 @@ protected slots: void removeAutomation(); void removeController(); private: - void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* alreadyUpdatedDataArraysIn); + void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastValuesIn); void paintEditing(QPainter* pIn); void modelChanged() override; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 31ff033a66e..a94954c6ee9 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -569,11 +569,58 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) p.drawLine(0, height() - 1, width() - 1, height() - 1); p.drawLine(0, 0, 0, height() - 1); - std::vector alreadyUpdatedDataArrays; + std::vector effectArrays; + std::vector sampleBuffer; + // getting arrays that effect other arrays for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - paintGraph(&p, i, &alreadyUpdatedDataArrays); + // getting the current array's effector array + int curArrayEffector = model()->getDataArray(i)->getEffectorArrayLocation(); + + if (curArrayEffector != -1) + { + bool found = false; + // checking if it is already in the list + for (unsigned int k = 0; k < effectArrays.size(); k++) + { + if (curArrayEffector == effectArrays[k]) + { + found = true; + break; + } + } + if (found == false) + { + effectArrays.push_back(curArrayEffector); + } + } + } + + // updating arrays that do not effect other arrays first + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + bool found = false; + for (unsigned int j = 0; j < effectArrays.size(); j++) + { + if (i == effectArrays[j]) + { + found = true; + break; + } + } + if (found == false) + { + paintGraph(&p, i, &sampleBuffer, false); + } + } + + // updating arrays that effect other arrays + // without calling getValues() for optimization + // (they were updated during the previous step) + for (unsigned int i = 0; i < effectArrays.size(); i++) + { + paintGraph(&p, i, &sampleBuffer, true); } paintEditing(&p); @@ -583,7 +630,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) emit drawn(); } -void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* alreadyUpdatedDataArraysIn) +void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastValuesIn) { VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); unsigned int length = dataArray->size(); @@ -602,47 +649,23 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve posA = startPos; pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - std::vector dataArrayValues; - if (m_useGetLastValues == true) + if (m_useGetLastValues == true || shouldUseGetLastValuesIn == true) { - dataArray->getLastValues(&dataArrayValues); + qDebug("paintEvent getLastValues2 [%d]", locationIn); + dataArray->getLastValues(sampleBufferIn); } else { - // getting most updated dataArray values - // if this dataArray has not been updated by - // an other dataArray while paintEvent is happening - bool found = false; - for (unsigned int j = 0; j < alreadyUpdatedDataArraysIn->size(); j++) - { - if (locationIn == alreadyUpdatedDataArraysIn->operator[](j)) - { - found = true; - break; - } - } - if (found == false) - { - dataArrayValues = dataArray->getValues(width()); - std::vector updatedArrays = dataArray->getEffectorArrayLocations(); - for (unsigned int j = 0; j < updatedArrays.size(); j++) - { - alreadyUpdatedDataArraysIn->push_back(updatedArrays[j]); - } - } - else - { - dataArray->getLastValues(&dataArrayValues); - } + *sampleBufferIn = dataArray->getValues(width()); } - qDebug("paint dataArrayValues size: %ld", dataArrayValues.size()); - for (unsigned int j = 0; j < dataArrayValues.size(); j++) + qDebug("paint sampleBufferIn size: %ld", sampleBufferIn->size()); + for (unsigned int j = 0; j < sampleBufferIn->size(); j++) { // if nonNegative then only the dataArray output (getDataValues) // is bigger than 0 so it matters only here - posB = mapDataPos(0, dataArrayValues[j], dataArray->getIsNonNegative()); - posB.first = static_cast((j * width()) / static_cast(dataArrayValues.size())); + posB = mapDataPos(0, sampleBufferIn->operator[](j), dataArray->getIsNonNegative()); + posB.first = static_cast((j * width()) / static_cast(sampleBufferIn->size())); if (posA.first != posB.first) { @@ -3721,7 +3744,11 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // calculating point data and lines if (m_needsUpdating.size() > 0 && m_updatingBakedValues.size() > 0) { - effectorOutput.resize(countIn); + if (effectorOutput.size() != countIn) + { + effectorOutput.resize(countIn); + } + // calculating relative X locations (in lines) of the output values // for later use in the line calculations // outputXLocations[sample_location] is equal to 0.0f if it is at the start of a line, From 71d22a3883fee6f341b0350af9eb53efb6be6348 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:19:09 +0200 Subject: [PATCH 087/184] WaveShaper_added_comment --- plugins/WaveShaper/WaveShaperControls.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index d2c575f95e3..f89c2ae7deb 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -85,6 +85,8 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) m_clipModel.loadSettings( _this, "clipInput" ); + // if this is an old save that still has + // a normal graph saved if (_this.hasAttribute("waveShape") == true) { if (m_vectorGraphModel.getDataArraySize() > 1) @@ -95,7 +97,7 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) float* graphSampleArray = (float*)dst; // loading old graph data into new vectorGraph - m_vectorGraphModel.getDataArray(1)->setDataArray(graphSampleArray, 200, false, false, false, true, true); + m_vectorGraphModel.getDataArray(1)->setDataArray(graphSampleArray, 200, false, false, false, false, true); delete[] dst; } From 65dd19bbfb6d7ea9de66c1e4c28c31f53d4e93cd Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:05:30 +0200 Subject: [PATCH 088/184] VectorGraph_getValues_renamed_and_made_void --- include/VectorGraph.h | 52 ++++++++++++------------- src/gui/widgets/VectorGraph.cpp | 67 +++++++++++++++++---------------- 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index fb16242d779..e3df41ae5f8 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -77,7 +77,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView return castModel(); } - // draws estimated line, does not call getValues() + // draws estimated line, does not call getSamples() // does not fill graphs with VectorGraphDataArray FillColor void setIsSimplified(bool isSimplifiedIn); @@ -91,10 +91,10 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void setBackground(const QPixmap backgoundIn); // if this function is called - // paintEvent will not call getValues() (optimization) - // insted calls getLastValues + // paintEvent will not call getSamples() (optimization) + // insted calls getLastSamples // resets after every paint event - void useGetLastValues(); + void useGetLastSamples(); signals: // emited after paintEvent void drawn(); @@ -107,14 +107,14 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void mouseDoubleClickEvent(QMouseEvent* me) override; protected slots: void updateGraph(); - void updateGraph(bool shouldUseGetLastValuesIn); + void updateGraph(bool shouldUseGetLastSamplesIn); void updateDefaultColors(); void execConnectionDialog(); void removeAutomation(); void removeController(); private: - void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastValuesIn); + void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastSamplesIn); void paintEditing(QPainter* pIn); void modelChanged() override; @@ -126,7 +126,7 @@ protected slots: std::pair mapDataCurvePosF(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); // calculate screen space coords from graph coords - // isNonNegativeIn can only be true when graph line / getValues() is mapped + // isNonNegativeIn can only be true when graph line / getSamples() is mapped std::pair mapDataPos(float xIn, float yIn, bool isNonNegativeIn); // map where each Control is displayed when m_isEdtitingActive is true int mapControlInputX(float inputValueIn, unsigned int displayLengthIn); @@ -187,8 +187,8 @@ protected slots: bool m_isDefaultColorsApplyed; QPixmap m_background; // for 1 draw, it will use the VectorGraphDataArray - // m_bakedValues without calling GetValues() - bool m_useGetLastValues; + // m_bakedValues without calling getSamples() + bool m_useGetLastSamples; // if m_isLastSelectedArray == true then // m_selectedArray can be used @@ -283,14 +283,14 @@ Q_OBJECT virtual void loadSettings(const QDomElement& element); // read locations from saved data attributes unused but implemeted //int readLoc(unsigned int startIn, QString dataIn); - void lockGetValuesAccess(); - void unlockGetValuesAccess(); + void lockGetSamplesAccess(); + void unlockGetSamplesAccess(); void lockBakedValuesAccess(); void unlockBakedValuesAccess(); signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); - void updateGraphView(bool shouldUseGetLastValuesIn); + void updateGraphView(bool shouldUseGetLastSamplesIn); // signals when a dataArray gets to 0 element size // locationIn is the location of the VectorGraphDataArray // locationIn can be -1 @@ -299,7 +299,7 @@ Q_OBJECT void styleChanged(); public slots: void dataArrayChanged(); - void updateGraphModel(bool shouldUseGetLastValuesIn); + void updateGraphModel(bool shouldUseGetLastSamplesIn); void dataArrayClearedEvent(int idIn); void dataArrayStyleChanged(); private: @@ -307,8 +307,8 @@ public slots: unsigned int m_maxLength; // block threads that want to access - // a dataArray's getValues() at the same time - std::mutex m_getValuesAccess; + // a dataArray's getSamples() at the same time + std::mutex m_getSamplesAccess; std::mutex m_bakedValuesAccess; }; @@ -440,9 +440,9 @@ class LMMS_EXPORT VectorGraphDataArray // returns the latest updated graph values // countIn is the retuned vector's size - std::vector getValues(unsigned int countIn); + void getSamples(unsigned int countIn, std::vector* sampleBufferOut); // returns m_bakedValues without updating - void getLastValues(std::vector* copyBufferOut); + void getLastSamples(std::vector* sampleBufferOut); std::vector getEffectorArrayLocations(); @@ -649,12 +649,12 @@ class LMMS_EXPORT VectorGraphDataArray // every point is in there only once void getUpdatingOriginals(); - // real getValues processing - std::vector getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut); + // real getSamples processing + void getSamples(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); // gets every m_needsUpdating point's line's start and end effector point's location in the effector dataArray // .first = start, .second = line end location (effector dataArray) - //void getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); - void getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, + //void getSamplesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); + void getSamplesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn); bool isEffectedPoint(unsigned int locationIn); @@ -701,17 +701,17 @@ class LMMS_EXPORT VectorGraphDataArray // baking - // getValues() will return m_bakedValues if a line is unchanged + // getSamples() will return m_bakedValues if a line is unchanged // else it will recalculate the line's values, update m_bakedValues - // getValues() needs to know where did lines change so it updates + // getSamples() needs to know where did lines change so it updates // m_needsUpdating by running getUpdatingFromEffector() - // if m_isDataChanged is true, then getValues adds all the points + // if m_isDataChanged is true, then getSamples adds all the points // to m_needsUpdating before running - // getValues() clears m_needsUpdating after it has run + // getSamples() clears m_needsUpdating after it has run // every change is only applyed to the point's line (line started by the point) // changes in position will cause multiple points to update - // if we want to update all (the full line in getValues()) + // if we want to update all (the full line in getSamples()) bool m_isDataChanged; // array containing output final float values for optimalization std::vector m_bakedValues; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index a94954c6ee9..37c3257aaa9 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -70,7 +70,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_isSimplified = false; m_isDefaultColorsApplyed = false; //m_background; - m_useGetLastValues = false; + m_useGetLastSamples = false; m_selectedLocation = 0; m_selectedArray = 0; @@ -231,9 +231,9 @@ void VectorGraphView::setBackground(const QPixmap backgroundIn) { m_background = backgroundIn; } -void VectorGraphView::useGetLastValues() +void VectorGraphView::useGetLastSamples() { - m_useGetLastValues = true; + m_useGetLastSamples = true; } void VectorGraphView::mousePressEvent(QMouseEvent* me) @@ -616,7 +616,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) } // updating arrays that effect other arrays - // without calling getValues() for optimization + // without calling getSamples() for optimization // (they were updated during the previous step) for (unsigned int i = 0; i < effectArrays.size(); i++) { @@ -625,12 +625,12 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) paintEditing(&p); - m_useGetLastValues = false; + m_useGetLastSamples = false; qDebug("paint event end"); emit drawn(); } -void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastValuesIn) +void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastSamplesIn) { VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); unsigned int length = dataArray->size(); @@ -649,14 +649,14 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve posA = startPos; pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - if (m_useGetLastValues == true || shouldUseGetLastValuesIn == true) + if (m_useGetLastSamples == true || shouldUseGetLastSamplesIn == true) { - qDebug("paintEvent getLastValues2 [%d]", locationIn); - dataArray->getLastValues(sampleBufferIn); + qDebug("paintEvent SamplestValues2 [%d]", locationIn); + dataArray->getLastSamples(sampleBufferIn); } else { - *sampleBufferIn = dataArray->getValues(width()); + dataArray->getSamples(width(), sampleBufferIn); } qDebug("paint sampleBufferIn size: %ld", sampleBufferIn->size()); @@ -875,9 +875,9 @@ void VectorGraphView::updateGraph() { update(); } -void VectorGraphView::updateGraph(bool shouldUseGetLastValuesIn) +void VectorGraphView::updateGraph(bool shouldUseGetLastSamplesIn) { - m_useGetLastValues = shouldUseGetLastValuesIn; + m_useGetLastSamples = shouldUseGetLastSamplesIn; update(); } void VectorGraphView::updateDefaultColors() @@ -1754,10 +1754,10 @@ void VectorGraphModel::dataArrayChanged() emit dataChanged(); emit updateGraphView(false); } -void VectorGraphModel::updateGraphModel(bool shouldUseGetLastValuesIn) +void VectorGraphModel::updateGraphModel(bool shouldUseGetLastSamplesIn) { // connects to external update signal - emit updateGraphView(shouldUseGetLastValuesIn); + emit updateGraphView(shouldUseGetLastSamplesIn); } void VectorGraphModel::dataArrayClearedEvent(int idIn) { @@ -1919,13 +1919,13 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n } } } -void VectorGraphModel::lockGetValuesAccess() +void VectorGraphModel::lockGetSamplesAccess() { - m_getValuesAccess.lock(); + m_getSamplesAccess.lock(); } -void VectorGraphModel::unlockGetValuesAccess() +void VectorGraphModel::unlockGetSamplesAccess() { - m_getValuesAccess.unlock(); + m_getSamplesAccess.unlock(); } void VectorGraphModel::lockBakedValuesAccess() { @@ -2516,20 +2516,18 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is return -1; } -std::vector VectorGraphDataArray::getValues(unsigned int countIn) +void VectorGraphDataArray::getSamples(unsigned int countIn, std::vector* sampleBufferOut) { qDebug("getValuesA1"); - m_parent->lockGetValuesAccess(); - std::vector output = getValues(countIn, nullptr, nullptr); - m_parent->unlockGetValuesAccess(); - qDebug("getValuesA2, size: %ld", output.size()); + m_parent->lockGetSamplesAccess(); + getSamples(countIn, nullptr, nullptr, sampleBufferOut); + m_parent->unlockGetSamplesAccess(); qDebug("getValuesA3 finished"); - return output; } -void VectorGraphDataArray::getLastValues(std::vector* copyBufferOut) +void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) { m_parent->lockBakedValuesAccess(); - *copyBufferOut = m_bakedValues; + *sampleBufferOut = m_bakedValues; m_parent->unlockBakedValuesAccess(); } std::vector VectorGraphDataArray::getEffectorArrayLocations() @@ -3645,7 +3643,7 @@ void VectorGraphDataArray::getUpdatingOriginals() // sorting the array // this is done to optimize the functions that use - // m_needsUpdating in getValues() + // m_needsUpdating in getSamples() std::sort(originalValues.begin(), originalValues.end(), [](unsigned int a, unsigned int b) { @@ -3672,7 +3670,7 @@ void VectorGraphDataArray::getUpdatingOriginals() } */ } -std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut) +void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); @@ -3682,7 +3680,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { - effectorOutput = m_parent->getDataArray(m_effectorLocation)->getValues(countIn, &effectorIsChanged, &effectorUpdatingValues); + m_parent->getDataArray(m_effectorLocation)->getSamples(countIn, &effectorIsChanged, &effectorUpdatingValues, &effectorOutput); } qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); @@ -3789,7 +3787,7 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - getValuesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); + getSamplesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); } m_parent->lockBakedValuesAccess(); @@ -3812,10 +3810,15 @@ std::vector VectorGraphDataArray::getValues(unsigned int countIn, bool* i // clearing the updated values m_needsUpdating.clear(); } + if (sampleBufferOut != nullptr) + { + m_parent->lockBakedValuesAccess(); + *sampleBufferOut = m_bakedValues; + m_parent->unlockBakedValuesAccess(); + } m_isDataChanged = false; qDebug("getValuesB9"); - return m_bakedValues; } // unused function, might be useful later /* @@ -3874,7 +3877,7 @@ qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); } } */ -void VectorGraphDataArray::getValuesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, +void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn) { qDebug("getValuesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); From 4921c89b50786267cdcc184417c13f13d768bf06 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:12:39 +0200 Subject: [PATCH 089/184] VectorGraph_bakedValues_rendamed_to_bakedSamples --- include/VectorGraph.h | 22 ++--- src/gui/widgets/VectorGraph.cpp | 142 ++++++++++++++++---------------- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index e3df41ae5f8..f0b29d160eb 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -187,7 +187,7 @@ protected slots: bool m_isDefaultColorsApplyed; QPixmap m_background; // for 1 draw, it will use the VectorGraphDataArray - // m_bakedValues without calling getSamples() + // m_bakedSamples without calling getSamples() bool m_useGetLastSamples; // if m_isLastSelectedArray == true then @@ -285,8 +285,8 @@ Q_OBJECT //int readLoc(unsigned int startIn, QString dataIn); void lockGetSamplesAccess(); void unlockGetSamplesAccess(); - void lockBakedValuesAccess(); - void unlockBakedValuesAccess(); + void lockBakedSamplesAccess(); + void unlockBakedSamplesAccess(); signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); @@ -309,7 +309,7 @@ public slots: // block threads that want to access // a dataArray's getSamples() at the same time std::mutex m_getSamplesAccess; - std::mutex m_bakedValuesAccess; + std::mutex m_bakedSamplesAccess; }; class LMMS_EXPORT VectorGraphDataArray @@ -441,7 +441,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns the latest updated graph values // countIn is the retuned vector's size void getSamples(unsigned int countIn, std::vector* sampleBufferOut); - // returns m_bakedValues without updating + // returns m_bakedSamples without updating void getLastSamples(std::vector* sampleBufferOut); std::vector getEffectorArrayLocations(); @@ -638,7 +638,7 @@ class LMMS_EXPORT VectorGraphDataArray // ONLY WORKS IN SORTED ARRAYS void getUpdatingFromEffector(std::vector* updatingValuesIn); // if locationIn >= 0 -> adds the location to m_needsUpdating - // else it will update the whole m_dataArray and m_bakedValues + // else it will update the whole m_dataArray and m_bakedSamples // changes in the size of m_dataArray (addtition, deletion, ect.) // should to cause a full update void getUpdatingFromPoint(int locationIn); @@ -701,8 +701,8 @@ class LMMS_EXPORT VectorGraphDataArray // baking - // getSamples() will return m_bakedValues if a line is unchanged - // else it will recalculate the line's values, update m_bakedValues + // getSamples() will return m_bakedSamples if a line is unchanged + // else it will recalculate the line's values, update m_bakedSamples // getSamples() needs to know where did lines change so it updates // m_needsUpdating by running getUpdatingFromEffector() // if m_isDataChanged is true, then getSamples adds all the points @@ -714,9 +714,9 @@ class LMMS_EXPORT VectorGraphDataArray // if we want to update all (the full line in getSamples()) bool m_isDataChanged; // array containing output final float values for optimalization - std::vector m_bakedValues; - // used for updating m_bakedValues fast - std::vector m_updatingBakedValues; + std::vector m_bakedSamples; + // used for updating m_bakedSamples fast + std::vector m_updatingBakedSamples; // unsorted array of locations in m_dataArray // that need to be updated // sorted in getUpdatingOriginals() because some functions need this to be sorted diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 37c3257aaa9..5d4ade60e74 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -27,7 +27,7 @@ #include // sort #include // rand #include // unintptr_t -#include // locking when getValues +#include // locking when getSamples #include #include #include @@ -1927,13 +1927,13 @@ void VectorGraphModel::unlockGetSamplesAccess() { m_getSamplesAccess.unlock(); } -void VectorGraphModel::lockBakedValuesAccess() +void VectorGraphModel::lockBakedSamplesAccess() { - m_bakedValuesAccess.lock(); + m_bakedSamplesAccess.lock(); } -void VectorGraphModel::unlockBakedValuesAccess() +void VectorGraphModel::unlockBakedSamplesAccess() { - m_bakedValuesAccess.unlock(); + m_bakedSamplesAccess.unlock(); } void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) { @@ -1984,8 +1984,8 @@ VectorGraphDataArray::VectorGraphDataArray() // m_dataArray m_isDataChanged = false; - // m_bakedValues; - // m_updatingBakedValues + // m_bakedSamples; + // m_updatingBakedSamples // m_needsUpdating; // m_automationModelArray; @@ -2017,8 +2017,8 @@ VectorGraphDataArray::VectorGraphDataArray( // m_dataArray; m_isDataChanged = false; - // m_bakedValues; - // m_updatingBakedValues + // m_bakedSamples; + // m_updatingBakedSamples // m_needsUpdating; // m_automationModelArray; @@ -2030,7 +2030,7 @@ VectorGraphDataArray::~VectorGraphDataArray() { qDebug("VectorGraphDataArray dstc"); //m_dataArray.clear(); - //m_bakedValues.clear(); + //m_bakedSamples.clear(); //m_needsUpdating.clear(); for (unsigned int i = 0; i < m_automationModelArray.size(); i++) @@ -2518,17 +2518,17 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is void VectorGraphDataArray::getSamples(unsigned int countIn, std::vector* sampleBufferOut) { - qDebug("getValuesA1"); + qDebug("getSamplesA1"); m_parent->lockGetSamplesAccess(); getSamples(countIn, nullptr, nullptr, sampleBufferOut); m_parent->unlockGetSamplesAccess(); - qDebug("getValuesA3 finished"); + qDebug("getSamplesA3 finished"); } void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) { - m_parent->lockBakedValuesAccess(); - *sampleBufferOut = m_bakedValues; - m_parent->unlockBakedValuesAccess(); + m_parent->lockBakedSamplesAccess(); + *sampleBufferOut = m_bakedSamples; + m_parent->unlockBakedSamplesAccess(); } std::vector VectorGraphDataArray::getEffectorArrayLocations() { @@ -3682,9 +3682,9 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, { m_parent->getDataArray(m_effectorLocation)->getSamples(countIn, &effectorIsChanged, &effectorUpdatingValues, &effectorOutput); } - qDebug("getValuesB1, size: %ld - id: %d", outputXLocations.size(), m_id); + qDebug("getSamplesB1, size: %ld - id: %d", outputXLocations.size(), m_id); - m_isDataChanged = m_isDataChanged || countIn != m_updatingBakedValues.size(); + m_isDataChanged = m_isDataChanged || countIn != m_updatingBakedSamples.size(); // deciding if the whole dataArray should be updated // if the whole effectorDataArray was updated @@ -3702,7 +3702,7 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, } // updating m_needsUpdating - if (m_isDataChanged == false && countIn == m_updatingBakedValues.size()) + if (m_isDataChanged == false && countIn == m_updatingBakedSamples.size()) { if (isEffected == true && effectorUpdatingValues.size() > 0 && (effectorIsChanged == false || effectedCount > 0)) @@ -3711,36 +3711,36 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, // before use (in this case it is already sorted) getUpdatingFromEffector(&effectorUpdatingValues); } - qDebug("getValuesB2"); + qDebug("getSamplesB2"); getUpdatingFromAutomation(); // sort and select only original // values getUpdatingOriginals(); - qDebug("getValuesB3"); + qDebug("getSamplesB3"); } else { - m_parent->lockBakedValuesAccess(); - if (countIn != m_bakedValues.size()) + m_parent->lockBakedSamplesAccess(); + if (countIn != m_bakedSamples.size()) { - m_bakedValues.resize(countIn); + m_bakedSamples.resize(countIn); } - m_parent->unlockBakedValuesAccess(); - if (countIn != m_updatingBakedValues.size()) + m_parent->unlockBakedSamplesAccess(); + if (countIn != m_updatingBakedSamples.size()) { - m_updatingBakedValues.resize(countIn); + m_updatingBakedSamples.resize(countIn); } m_needsUpdating.resize(m_dataArray.size()); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { m_needsUpdating[i] = i; } - qDebug("getValuesB4, needsUpdating size: %ld", m_needsUpdating.size()); + qDebug("getSamplesB4, needsUpdating size: %ld", m_needsUpdating.size()); } float stepSize = 1.0f / static_cast(countIn); // calculating point data and lines - if (m_needsUpdating.size() > 0 && m_updatingBakedValues.size() > 0) + if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) { if (effectorOutput.size() != countIn) { @@ -3762,7 +3762,7 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, for (unsigned int j = start; j < end; j++) { outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - //qDebug("getValuesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); + //qDebug("getSamplesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); } } } @@ -3775,14 +3775,14 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, //std::vector> effectorData; - //getValuesLocations(effector, &effectorData); + //getSamplesLocations(effector, &effectorData); /* for (unsigned int j = 0; j < effectorData.size(); j++) { - qDebug("getValuesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); + qDebug("getSamplesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); } */ - qDebug("getValuesB6, updatingsize: %ld", m_needsUpdating.size()); + qDebug("getSamplesB6, updatingsize: %ld", m_needsUpdating.size()); // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) @@ -3790,9 +3790,9 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, getSamplesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); } - m_parent->lockBakedValuesAccess(); - m_bakedValues = m_updatingBakedValues; - m_parent->unlockBakedValuesAccess(); + m_parent->lockBakedSamplesAccess(); + m_bakedSamples = m_updatingBakedSamples; + m_parent->unlockBakedSamplesAccess(); } // setting outputs @@ -3812,17 +3812,17 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, } if (sampleBufferOut != nullptr) { - m_parent->lockBakedValuesAccess(); - *sampleBufferOut = m_bakedValues; - m_parent->unlockBakedValuesAccess(); + m_parent->lockBakedSamplesAccess(); + *sampleBufferOut = m_bakedSamples; + m_parent->unlockBakedSamplesAccess(); } m_isDataChanged = false; - qDebug("getValuesB9"); + qDebug("getSamplesB9"); } // unused function, might be useful later /* -void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) +void VectorGraphDataArray::getSamplesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) { if (effectorIn != nullptr) { @@ -3837,18 +3837,18 @@ void VectorGraphDataArray::getValuesLocations(VectorGraphDataArray* effectorIn, curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; // location effectorDataOut->operator[](i).first = curLocation; -qDebug("getValuesC5.1, [%d] set to: %d", i, curLocation); +qDebug("getSamplesC5.1, [%d] set to: %d", i, curLocation); // next location effectorDataOut->operator[](i).second = curLocation; // if the location of this is the next location for before this if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) { -qDebug("getValuesC5.2, [%d - 1] changed to: %d", i, curLocation); +qDebug("getSamplesC5.2, [%d - 1] changed to: %d", i, curLocation); effectorDataOut->operator[](i- 1).second = curLocation; } } } -qDebug("getValuesC5"); +qDebug("getSamplesC5"); // getting the missing next location values for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { @@ -3864,7 +3864,7 @@ qDebug("getValuesC5"); { curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; // next location -qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); +qDebug("getSamplesC5.3, [%d] set after to: %d", i, curLocation); effectorDataOut->operator[](i).second = curLocation; } } @@ -3880,10 +3880,10 @@ qDebug("getValuesC5.3, [%d] set after to: %d", i, curLocation); void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn) { - qDebug("getValuesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); + qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); unsigned int effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSizeIn)); - qDebug("getValuesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutputIn->size()); + qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutputIn->size()); // current effector output Y near m_needsUpdating[iIn] point float curEffectY = effectorOutputIn->operator[](effectYLocation); float nextEffectY = effectorOutputIn->operator[](effectYLocation); @@ -3929,9 +3929,9 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorI if (m_needsUpdating[iIn] + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray - for (int j = end; j < m_updatingBakedValues.size(); j++) + for (int j = end; j < m_updatingBakedSamples.size(); j++) { - m_updatingBakedValues[j] = curY; + m_updatingBakedSamples[j] = curY; } } if (m_needsUpdating[iIn] == 0) @@ -3939,13 +3939,13 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorI // if this point is at the 0 location in m_dataArray for (int j = 0; j < start; j++) { - m_updatingBakedValues[j] = curY; + m_updatingBakedSamples[j] = curY; } } float fadeInStart = 0.05f; unsigned int type = m_dataArray[m_needsUpdating[iIn]].m_type; -qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", iIn, start, end, type, curY, nextY, curC, curValA, curValB); +qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", iIn, start, end, type, curY, nextY, curC, curValA, curValB); // calculate final updated line if (type == 0) @@ -3953,7 +3953,7 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // calculate curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // no line type } @@ -3962,13 +3962,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArraySine(outputXLocationsIn, start, end, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } else if (type == 2) @@ -3976,13 +3976,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } else if (type == 3) @@ -3990,13 +3990,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } else if (type == 4) @@ -4004,13 +4004,13 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_updatingBakedValues, curValA, curValB, fadeInStart); + std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } else if (type == 5) @@ -4018,46 +4018,46 @@ qDebug("getValuesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f // curve for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); } // line type std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] + lineTypeOutput[j - start]; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) { int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedValues.size() : end; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; // process line effect // if it is enabled - qDebug("getValues run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); + qDebug("getSamples run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { - m_updatingBakedValues[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedValues[j], 0, effectorOutputIn->operator[](j)); + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedSamples[j], 0, effectorOutputIn->operator[](j)); } } // clamp for (int j = start; j < end; j++) { - if (m_updatingBakedValues[j] > 1.0f) + if (m_updatingBakedSamples[j] > 1.0f) { - m_updatingBakedValues[j] = 1.0f; + m_updatingBakedSamples[j] = 1.0f; } - else if (m_updatingBakedValues[j] < -1.0f) + else if (m_updatingBakedSamples[j] < -1.0f) { - m_updatingBakedValues[j] = -1.0f; + m_updatingBakedSamples[j] = -1.0f; } } if (m_isNonNegative == true) { int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedValues.size() : end; + int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; for (int j = startB; j < endB; j++) { - m_updatingBakedValues[j] = m_updatingBakedValues[j] / 2.0f + 0.5f; + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; } } } From 734effd932b6edb8de35dabb652bc5600361b83c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:36:14 +0200 Subject: [PATCH 090/184] VectorGraph_paintEvent_graph_drawing_order_fixed --- include/VectorGraph.h | 2 +- src/gui/widgets/VectorGraph.cpp | 83 ++++++++++++++++----------------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f0b29d160eb..c93a7dd61de 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -114,7 +114,7 @@ protected slots: void removeAutomation(); void removeController(); private: - void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastSamplesIn); + void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn); void paintEditing(QPainter* pIn); void modelChanged() override; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 5d4ade60e74..a496ee2ea86 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -572,19 +572,41 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) std::vector effectArrays; std::vector sampleBuffer; - // getting arrays that effect other arrays - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + // updating the VectorGraphDataArray samples before draw + if (m_useGetLastSamples == false) { - // getting the current array's effector array - int curArrayEffector = model()->getDataArray(i)->getEffectorArrayLocation(); + // getting arrays that effect other arrays + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + // getting the current array's effector array + int curArrayEffector = model()->getDataArray(i)->getEffectorArrayLocation(); - if (curArrayEffector != -1) + if (curArrayEffector != -1) + { + bool found = false; + // checking if it is already in the list + for (unsigned int k = 0; k < effectArrays.size(); k++) + { + if (curArrayEffector == effectArrays[k]) + { + found = true; + break; + } + } + if (found == false) + { + effectArrays.push_back(curArrayEffector); + } + } + } + + // updating arrays that do not effect other arrays first + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { bool found = false; - // checking if it is already in the list - for (unsigned int k = 0; k < effectArrays.size(); k++) + for (unsigned int j = 0; j < effectArrays.size(); j++) { - if (curArrayEffector == effectArrays[k]) + if (i == effectArrays[j]) { found = true; break; @@ -592,35 +614,20 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) } if (found == false) { - effectArrays.push_back(curArrayEffector); + // this updates the array and its effector arrays + // with width() sample count + model()->getDataArray(i)->getSamples(width(), nullptr); } } } - // updating arrays that do not effect other arrays first - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + // draw the updated VectorGraphDataArray samples in order + // sometimes an other getSamples() call elsewhere can + // change the sample count between updating and drawing + // causing badly drawn output (if sample count is low) + for (int i = model()->getDataArraySize() - 1; i >= 0; i--) { - bool found = false; - for (unsigned int j = 0; j < effectArrays.size(); j++) - { - if (i == effectArrays[j]) - { - found = true; - break; - } - } - if (found == false) - { - paintGraph(&p, i, &sampleBuffer, false); - } - } - - // updating arrays that effect other arrays - // without calling getSamples() for optimization - // (they were updated during the previous step) - for (unsigned int i = 0; i < effectArrays.size(); i++) - { - paintGraph(&p, i, &sampleBuffer, true); + paintGraph(&p, i, &sampleBuffer); } paintEditing(&p); @@ -630,7 +637,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) emit drawn(); } -void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn, bool shouldUseGetLastSamplesIn) +void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn) { VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); unsigned int length = dataArray->size(); @@ -649,15 +656,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve posA = startPos; pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - if (m_useGetLastSamples == true || shouldUseGetLastSamplesIn == true) - { - qDebug("paintEvent SamplestValues2 [%d]", locationIn); - dataArray->getLastSamples(sampleBufferIn); - } - else - { - dataArray->getSamples(width(), sampleBufferIn); - } + dataArray->getLastSamples(sampleBufferIn); qDebug("paint sampleBufferIn size: %ld", sampleBufferIn->size()); for (unsigned int j = 0; j < sampleBufferIn->size(); j++) From 49cc3ed4c01485783ad8c02e269d7403d0ccef9f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:38:06 +0200 Subject: [PATCH 091/184] VectorGraph_default_colors_flipped --- src/gui/widgets/VectorGraph.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index a496ee2ea86..bd8639ba4c2 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -171,25 +171,17 @@ void VectorGraphView::applyDefaultColors() unsigned int size = model()->getDataArraySize(); if (size > 0) { + setLineColor(m_vectorGraphDefaultLineColor, 0); + setActiveColor(m_vectorGraphDefaultActiveColor, 0); + setFillColor(m_vectorGraphDefaultFillColor, 0); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); if (size > 1) { - setLineColor(m_vectorGraphSecondaryLineColor, 0); - setActiveColor(m_vectorGraphSecondaryActiveColor, 0); - setFillColor(m_vectorGraphSecondaryFillColor, 0); - setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); - - setLineColor(m_vectorGraphDefaultLineColor, 1); - setActiveColor(m_vectorGraphDefaultActiveColor, 1); - setFillColor(m_vectorGraphDefaultFillColor, 1); + setLineColor(m_vectorGraphSecondaryLineColor, 1); + setActiveColor(m_vectorGraphSecondaryActiveColor, 1); + setFillColor(m_vectorGraphSecondaryFillColor, 1); setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 1); } - else - { - setLineColor(m_vectorGraphDefaultLineColor, 0); - setActiveColor(m_vectorGraphDefaultActiveColor, 0); - setFillColor(m_vectorGraphDefaultFillColor, 0); - setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); - } } } From 94587b89c12e8322f3d38c8ca311654e8a990e8f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:42:50 +0200 Subject: [PATCH 092/184] WaveShaper_flipped_VectorGraphDataArrays --- plugins/WaveShaper/WaveShaperControls.cpp | 31 +++++++++++------------ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index f89c2ae7deb..98c5da6df84 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -49,13 +49,6 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_clipModel( false, this ), m_vectorGraphSampleBuffer(200) { - - unsigned int arrayLocationB = m_vectorGraphModel.addArray(); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); - unsigned int arrayLocation = m_vectorGraphModel.addArray(); //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedSize(true); //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedX(true); @@ -67,7 +60,13 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); - // connect VectorGraphDataArrays so the 1. VectorGraphDataArray will be able to effect the 2.: + unsigned int arrayLocationB = m_vectorGraphModel.addArray(); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); + + // connect VectorGraphDataArrays so the 2. VectorGraphDataArray will be able to effect the 1.: m_vectorGraphModel.getDataArray(arrayLocation)->setEffectorArrayLocation(arrayLocationB, true); // draw default shape setDefaultShape(); @@ -127,10 +126,10 @@ void WaveShaperControls::saveSettings( QDomDocument & _doc, std::vector* WaveShaperControls::getGraphSamples() { - if (m_vectorGraphModel.getDataArraySize() > 1) + if (m_vectorGraphModel.getDataArraySize() > 0) { // get m_vectorGraphSampleBuffer.size (200) samples from the 1. VectorGraphDataArray - m_vectorGraphSampleBuffer = m_vectorGraphModel.getDataArray(1)->getValues(m_vectorGraphSampleBuffer.size()); + m_vectorGraphModel.getDataArray(0)->getSamples(m_vectorGraphSampleBuffer.size(), &m_vectorGraphSampleBuffer); emit vectorGraphUpdateView(true); } return &m_vectorGraphSampleBuffer; @@ -146,22 +145,22 @@ void WaveShaperControls::setDefaultShape() if (m_vectorGraphModel.getDataArraySize() > 1) { - int addedLocation = m_vectorGraphModel.getDataArray(1)->add(0.0f); + int addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.0f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(1)->setY(addedLocation, -1.0f); + m_vectorGraphModel.getDataArray(0)->setY(addedLocation, -1.0f); } - addedLocation = m_vectorGraphModel.getDataArray(1)->add(1.0f); + addedLocation = m_vectorGraphModel.getDataArray(0)->add(1.0f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(1)->setY(addedLocation, 1.0f); + m_vectorGraphModel.getDataArray(0)->setY(addedLocation, 1.0f); } - addedLocation = m_vectorGraphModel.getDataArray(0)->add(0.5f); + addedLocation = m_vectorGraphModel.getDataArray(1)->add(0.5f); if (addedLocation >= 0) { - m_vectorGraphModel.getDataArray(0)->setY(addedLocation, -1.0f); + m_vectorGraphModel.getDataArray(1)->setY(addedLocation, -1.0f); } } } From ec6c92f8ad30c4cda9e97050d67d4280a37ab777 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 11:27:54 +0200 Subject: [PATCH 093/184] WaveShaper_removed_In_in_functinons --- plugins/WaveShaper/WaveShaperControls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 214b73a3640..a6f472e9af8 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -77,7 +77,7 @@ private slots: // connected to dataArrayChanged() // shouldUseGetLastValuesIn: when the graph is redrawn // should it use the last updated values instead of updating again - void vectorGraphUpdateView(bool shouldUseGetLastValuesIn); + void vectorGraphUpdateView(bool shouldUseGetLastValues); private: WaveShaperEffect * m_effect; FloatModel m_inputModel; From 53a3cc8cc4fe56af0bd3c68950f1fdbad9f77fc2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:53:32 +0200 Subject: [PATCH 094/184] VectorGraph_replaced_mutex_with_QMutex --- include/VectorGraph.h | 6 +++--- src/gui/widgets/VectorGraph.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index c93a7dd61de..a46e42cf5c1 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -26,11 +26,11 @@ #define LMMS_GUI_VECTORGRAPH_H #include -#include #include #include #include #include +#include #include "Model.h" #include "ModelView.h" @@ -308,8 +308,8 @@ public slots: // block threads that want to access // a dataArray's getSamples() at the same time - std::mutex m_getSamplesAccess; - std::mutex m_bakedSamplesAccess; + QMutex m_getSamplesAccess; + QMutex m_bakedSamplesAccess; }; class LMMS_EXPORT VectorGraphDataArray diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index bd8639ba4c2..c4e882b31ce 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -27,12 +27,12 @@ #include // sort #include // rand #include // unintptr_t -#include // locking when getSamples #include #include #include #include // showInputDialog() #include // context menu +#include // locking when getSamples #include "VectorGraph.h" @@ -216,7 +216,7 @@ void VectorGraphView::setSelectedData(std::pair dataIn) model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, dataIn.second); qDebug("set value done"); m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, dataIn.first); - qDebug("set position done"); + qDebug("set position done (%f)", dataIn.first); } } void VectorGraphView::setBackground(const QPixmap backgroundIn) @@ -2497,7 +2497,7 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is //*isBeforeOut = false; } //qDebug("getNearestLocation, outputDif: %d", outputDif); - *foundOut = false; + *foundOut = xIn == m_dataArray[mid + outputDif].m_x; *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } From c4e5ce1f11b341c462b011193b06662c747121ff Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:58:37 +0200 Subject: [PATCH 095/184] VectorGraph_added_setters_for_gui_settings --- include/VectorGraph.h | 3 +++ src/gui/widgets/VectorGraph.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index a46e42cf5c1..011d7ba02ea 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -71,6 +71,9 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); void setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn); void applyDefaultColors(); + void setPointSize(unsigned int pointSizeIn); + void setControlHeight(unsigned int controlHeightIn); + void setControlDisplayCount(unsigned int controlDisplayCountIn); inline VectorGraphModel* model() { diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index c4e882b31ce..0f133490231 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -184,6 +184,21 @@ void VectorGraphView::applyDefaultColors() } } } +void VectorGraphView::setPointSize(unsigned int pointSizeIn) +{ + m_pointSize = pointSizeIn; + updateGraph(); +} +void VectorGraphView::setControlHeight(unsigned int controlHeightIn) +{ + m_controlHeight = controlHeightIn; + updateGraph(); +} +void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCountIn) +{ + m_controlDisplayCount = controlDisplayCountIn; + updateGraph(); +} void VectorGraphView::setIsSimplified(bool isSimplifiedIn) { From fad3d5ee9f244b3c0de7b4fab31af761100d342f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 13:22:25 +0200 Subject: [PATCH 096/184] VectorGraph_context_menu_updated --- src/gui/widgets/VectorGraph.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 0f133490231..b053be8ce6a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1102,7 +1102,7 @@ void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bo } // show context menu CaptionMenu contextMenu(model()->displayName() + QString(" - ") + controlDisplayText); - addDefaultActions(&contextMenu, QString("(") + m_controlText[location] + QString(")")); + addDefaultActions(&contextMenu, m_controlText[location]); contextMenu.exec(QCursor::pos()); } else if (isDraggingIn == false && m_controlIsFloat[location] == false) @@ -1415,7 +1415,10 @@ void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayTextI { // context menu settings menu->addAction(embed::getIconPixmap("reload"), - controlDisplayTextIn + tr(" remove automation") , + tr("name: ") + controlDisplayTextIn, + this, SLOT(updateGraph())); + menu->addAction(embed::getIconPixmap("reload"), + tr("remove automation"), this, SLOT(removeAutomation())); menu->addSeparator(); From a72a0b9cff91c6440282f33a98642116471982a7 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:49:28 +0200 Subject: [PATCH 097/184] VectorGraph_In_removed_from_functions --- include/VectorGraph.h | 311 ++++---- src/gui/widgets/VectorGraph.cpp | 1247 +++++++++++++++---------------- 2 files changed, 778 insertions(+), 780 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 011d7ba02ea..acbcaac3b85 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -62,18 +62,18 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView Q_PROPERTY(int fontSize MEMBER m_fontSize) public: - VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, - unsigned int controlHeightIn, unsigned int controlDisplayCountIn, bool shouldApplyDefaultVectorGraphColorsIn); + VectorGraphView(QWidget * parent, int widthIn, int heightIn, unsigned int pointSize, + unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors); ~VectorGraphView(); - void setLineColor(QColor colorIn, unsigned int dataArrayLocationIn); - void setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn); - void setFillColor(QColor colorIn, unsigned int dataArrayLocationIn); - void setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn); + void setLineColor(QColor color, unsigned int dataArrayLocation); + void setActiveColor(QColor color, unsigned int dataArrayLocation); + void setFillColor(QColor color, unsigned int dataArrayLocation); + void setAutomatedColor(QColor color, unsigned int dataArrayLocation); void applyDefaultColors(); - void setPointSize(unsigned int pointSizeIn); - void setControlHeight(unsigned int controlHeightIn); - void setControlDisplayCount(unsigned int controlDisplayCountIn); + void setPointSize(unsigned int pointSize); + void setControlHeight(unsigned int controlHeight); + void setControlDisplayCount(unsigned int controlDisplayCount); inline VectorGraphModel* model() { @@ -82,16 +82,16 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView // draws estimated line, does not call getSamples() // does not fill graphs with VectorGraphDataArray FillColor - void setIsSimplified(bool isSimplifiedIn); + void setIsSimplified(bool isSimplified); // returns -1.0f at .first when nothing is selected std::pair getSelectedData(); // returns -1 it can not return an array location int getLastSelectedArray(); // sets the position of the currently selected point - void setSelectedData(std::pair dataIn); + void setSelectedData(std::pair data); // sets the background pixmap - void setBackground(const QPixmap backgoundIn); + void setBackground(const QPixmap backgound); // if this function is called // paintEvent will not call getSamples() (optimization) @@ -110,71 +110,71 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void mouseDoubleClickEvent(QMouseEvent* me) override; protected slots: void updateGraph(); - void updateGraph(bool shouldUseGetLastSamplesIn); + void updateGraph(bool shouldUseGetLastSamples); void updateDefaultColors(); void execConnectionDialog(); void removeAutomation(); void removeController(); private: - void paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn); - void paintEditing(QPainter* pIn); + void paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer); + void paintEditing(QPainter* p); void modelChanged() override; // utility // calculate graph coords from screen space coords - std::pair mapMousePos(int xIn, int yIn); + std::pair mapMousePos(int x, int y); // calculate gui curve point's position - std::pair mapDataCurvePosF(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn); - std::pairmapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn); + std::pair mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); + std::pairmapDataCurvePos(int xA, int yA, int xB, int yB, float curve); // calculate screen space coords from graph coords - // isNonNegativeIn can only be true when graph line / getSamples() is mapped - std::pair mapDataPos(float xIn, float yIn, bool isNonNegativeIn); + // isNonNegative can only be true when graph line / getSamples() is mapped + std::pair mapDataPos(float x, float y, bool isNonNegative); // map where each Control is displayed when m_isEdtitingActive is true - int mapControlInputX(float inputValueIn, unsigned int displayLengthIn); + int mapControlInputX(float inputValue, unsigned int displayLength); - float getDistance(int xAIn, int yAIn, int xBIn, int yBIn); - float getDistanceF(float xAIn, float yAIn, float xBIn, float yBIn); + float getDistance(int xA, int yA, int xB, int yB); + float getDistanceF(float xA, float yA, float xB, float yB); // adds point to the selected VectorGraphDataArray - bool addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn); + bool addPoint(unsigned int arrayLocation, int mouseX, int mouseY); // editing menu / controls // returns true if the graph was clicked - bool isGraphPressed(int mouseXIn, int mouseYIn); + bool isGraphPressed(int mouseX, int mouseY); // returns true if the control window was clicked while in editing mode - bool isControlWindowPressed(int mouseYIn); - void processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn); + bool isControlWindowPressed(int mouseY); + void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving, int curX, int curY); // returns -1 if no control / input was clicked - // returns displayed absolute control / input location based on inputCountIn - int getPressedControlInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn); + // returns displayed absolute control / input location based on inputCount + int getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount); // returns a float attrib value, valueOut = attrib value if it is a bool - float getInputAttribValue(unsigned int controlArrayLocationIn, bool* valueOut); - // sets the selected point's attrib to floatValueIn it it is float, else it sets the attrib to boolValueIn - void setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn); + float getInputAttribValue(unsigned int controlArrayLocation, bool* valueOut); + // sets the selected point's attrib to floatValue it it is float, else it sets the attrib to boolValue + void setInputAttribValue(unsigned int controlArrayLocation, float floatValue, bool boolValue); // calculates the ideal text color - QColor getTextColorFromBaseColor(QColor baseColorIn); + QColor getTextColorFromBaseColor(QColor baseColor); // calculates a replacement background fill color - QColor getFillColorFromBaseColor(QColor baseColorIn); + QColor getFillColorFromBaseColor(QColor baseColor); // cuts the string to displayedLength(in px) size (estimated) - QString getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn); + QString getTextFromDisplayLength(QString text, unsigned int displayLength); // context menu actions - void addDefaultActions(QMenu* menu, QString controlDisplayTextIn); + void addDefaultActions(QMenu* menu, QString controlDisplayText); // inputDialog std::pair showCoordInputDialog(); - float showInputDialog(float curInputValueIn); + float showInputDialog(float curInputValue); // selection // searches VectorGraphDataArray-s to select // near clicked location - void selectData(int mouseXIn, int mouseYIn); + void selectData(int mouseX, int mouseY); // searches for point in a given VectorGraphDataArray // returns found location, when a point // was found in the given distance // else it returns -1 - int searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn); + int searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved); // if the mouse is not moved bool m_mousePress; @@ -236,35 +236,35 @@ class LMMS_EXPORT VectorGraphModel : public Model, public JournallingObject { Q_OBJECT public: - VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn); + VectorGraphModel(unsigned int arrayMaxLength, Model* parentIn, bool defaultConstructed); ~VectorGraphModel(); inline size_t getDataArraySize() { return m_dataArrays.size(); } - inline VectorGraphDataArray* getDataArray(unsigned int locationIn) + inline VectorGraphDataArray* getDataArray(unsigned int arrayLocation) { - return &m_dataArrays[locationIn]; + return &m_dataArrays[arrayLocation]; } inline unsigned int getMaxLength() { return m_maxLength; } - inline void setMaxLength(unsigned int maxLengthIn) + inline void setMaxLength(unsigned int arrayMaxLength) { - if (m_maxLength != maxLengthIn) + if (m_maxLength != arrayMaxLength) { - m_maxLength = maxLengthIn; + m_maxLength = arrayMaxLength; emit dataChanged(); emit updateGraphView(false); } } // returns added VectorGraphDataArray location unsigned int addArray(); - // deletes VectorGraphDataArray at locationIn + // deletes VectorGraphDataArray at arrayLocation // preservs the order - void delArray(unsigned int locationIn); + void delArray(unsigned int arrayLocation); inline void clearArray() { m_dataArrays.clear(); @@ -272,7 +272,7 @@ Q_OBJECT emit updateGraphView(false); } // if the id is not found then it will return 0 - int getDataArrayLocationFromId(int idIn); + int getDataArrayLocationFromId(int arrayId); int getDataArrayNewId(); // save, load @@ -285,7 +285,7 @@ Q_OBJECT virtual void saveSettings(QDomDocument& doc, QDomElement& element); virtual void loadSettings(const QDomElement& element); // read locations from saved data attributes unused but implemeted - //int readLoc(unsigned int startIn, QString dataIn); + //int readLoc(unsigned int start, QString data); void lockGetSamplesAccess(); void unlockGetSamplesAccess(); void lockBakedSamplesAccess(); @@ -293,17 +293,17 @@ Q_OBJECT signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); - void updateGraphView(bool shouldUseGetLastSamplesIn); + void updateGraphView(bool shouldUseGetLastSamples); // signals when a dataArray gets to 0 element size - // locationIn is the location of the VectorGraphDataArray - // locationIn can be -1 - void clearedEvent(int locationIn); + // arrayLocation is the location of the VectorGraphDataArray + // arrayLocation can be -1 + void clearedEvent(int arrayLocation); // style changed inside m_dataArray void styleChanged(); public slots: void dataArrayChanged(); - void updateGraphModel(bool shouldUseGetLastSamplesIn); - void dataArrayClearedEvent(int idIn); + void updateGraphModel(bool shouldUseGetLastSamples); + void dataArrayClearedEvent(int arrayId); void dataArrayStyleChanged(); private: std::vector m_dataArrays; @@ -322,31 +322,31 @@ class LMMS_EXPORT VectorGraphDataArray // avoid using this or run updateConnections() after initialization VectorGraphDataArray(); VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool isNonNegativeIn, - bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, VectorGraphModel* parentIn, int idIn); + bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, + bool isSaveable, VectorGraphModel* parentIn, int arrayId); ~VectorGraphDataArray(); void updateConnections(VectorGraphModel* parentIn); // see descriptions in privete - void setIsFixedSize(bool valueIn); - void setIsFixedX(bool valueIn); - void setIsFixedY(bool valueIn); - void setIsFixedEndPoints(bool valueIn); - void setIsSelectable(bool valueIn); - void setIsEditableAttrib(bool valueIn); - void setIsAutomatableEffectable(bool valueIn); - void setIsSaveable(bool valueIn); - void setIsNonNegative(bool valueIn); - void setLineColor(QColor colorIn); - void setActiveColor(QColor colorIn); - void setFillColor(QColor colorIn); - void setAutomatedColor(QColor colorIn); + void setIsFixedSize(bool bValue); + void setIsFixedX(bool bValue); + void setIsFixedY(bool bValue); + void setIsFixedEndPoints(bool bValue); + void setIsSelectable(bool bValue); + void setIsEditableAttrib(bool bValue); + void setIsAutomatableEffectable(bool bValue); + void setIsSaveable(bool bValue); + void setIsNonNegative(bool bValue); + void setLineColor(QColor color); + void setActiveColor(QColor color); + void setFillColor(QColor color); + void setAutomatedColor(QColor color); // returns true if successful - // if callDataChangedIn then it will call dataChanged() --> paintEvent() - bool setEffectorArrayLocation(int locationIn, bool callDataChangedIn); + // if callDataChanged then it will call dataChanged() --> paintEvent() + bool setEffectorArrayLocation(int arrayLocation, bool callDataChanged); bool getIsFixedSize(); bool getIsFixedX(); @@ -369,9 +369,9 @@ class LMMS_EXPORT VectorGraphDataArray // array: ------------------- // returns the location of added/found point, -1 if not found or can not be added - int add(float xIn); - // deletes the point in locationIn location if m_isFixedSize is disabled - void del(unsigned int locationIn); + int add(float newX); + // deletes the point in pointLocation location if m_isFixedSize is disabled + void del(unsigned int pointLocation); // clears m_dataArray without any checks inline void clear() { @@ -387,63 +387,63 @@ class LMMS_EXPORT VectorGraphDataArray return m_dataArray.size(); } // clamps down the values to 0 - 1, -1 - 1 - // sorts array, removes duplicated positions, calls dataChanged() if callDataChangedIn - // clampIn: should clamp, sortIn: should sort - void formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); + // sorts array, removes duplicated positions, calls dataChanged() if callDataChanged + // clamp: should clamp, sort: should sort + void formatArray(std::vector>* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); // get attribute: ------------------- - inline float getX(unsigned int locationIn) + inline float getX(unsigned int pointLocation) { - return m_dataArray[locationIn].m_x; + return m_dataArray[pointLocation].m_x; } - inline float getY(unsigned int locationIn) + inline float getY(unsigned int pointLocation) { - return m_dataArray[locationIn].m_y; + return m_dataArray[pointLocation].m_y; } - inline float getC(unsigned int locationIn) + inline float getC(unsigned int pointLocation) { - return m_dataArray[locationIn].m_c; + return m_dataArray[pointLocation].m_c; } - inline float getValA(unsigned int locationIn) + inline float getValA(unsigned int pointLocation) { - return m_dataArray[locationIn].m_valA; + return m_dataArray[pointLocation].m_valA; } - inline float getValB(unsigned int locationIn) + inline float getValB(unsigned int pointLocation) { - return m_dataArray[locationIn].m_valB; + return m_dataArray[pointLocation].m_valB; } - inline unsigned int getType(unsigned int locationIn) + inline unsigned int getType(unsigned int pointLocation) { - return m_dataArray[locationIn].m_type; + return m_dataArray[pointLocation].m_type; } // returns attribLocation: 0 = m_y, 1 = m_c, 2 = m_valA, 3 = m_valB (int VectorGraphPoint) - unsigned int getAutomatedAttribLocation(unsigned int locationIn); - unsigned int getEffectedAttribLocation(unsigned int locationIn); + unsigned int getAutomatedAttribLocation(unsigned int pointLocation); + unsigned int getEffectedAttribLocation(unsigned int pointLocation); // returns true when m_effectOnlyPoints is true or // when getEffectedAttribLocation > 0 (y is uneffected) // -> when the current point CAN effect lines before it - bool getEffectOnlyPoints(unsigned int locationIn); - // returns if the effectNumberIn-th effect is active - bool getEffect(unsigned int locationIn, unsigned int effectNumberIn); + bool getEffectOnlyPoints(unsigned int pointLocation); + // returns if the effectId-th effect is active + bool getEffect(unsigned int pointLocation, unsigned int effectId); // true when the automationModel's value changed since last check - bool getIsAutomationValueChanged(unsigned int locationIn); + bool getIsAutomationValueChanged(unsigned int pointLocation); // can return nullptr - inline FloatModel* getAutomationModel(unsigned int locationIn); + inline FloatModel* getAutomationModel(unsigned int pointLocation); // get: ------------------- // returns -1 when position is not found - int getLocation(float xIn); + int getLocation(float searchX); // gets the nearest data location to the position, - // foundOut is true when the nearest position = posIn, + // foundOut is true when the nearest position = searchXIn, // reurns -1 when search failed - int getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut); + int getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut); // returns the latest updated graph values - // countIn is the retuned vector's size - void getSamples(unsigned int countIn, std::vector* sampleBufferOut); + // targetSizeIn is the retuned vector's size + void getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut); // returns m_bakedSamples without updating void getLastSamples(std::vector* sampleBufferOut); std::vector getEffectorArrayLocations(); @@ -458,33 +458,34 @@ class LMMS_EXPORT VectorGraphDataArray // rescaleIn -> scale input positions // sortIn -> sort input positions // callDataChangedIn -> call dataChanged() after -> paintEvent() - void setDataArray(std::vector>* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn); - void setDataArray(std::vector* dataArrayIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); - void setDataArray(float* dataArrayIn, unsigned int sizeIn, bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn); + void setDataArray(std::vector>* dataArrayIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + void setDataArray(std::vector* dataArrayIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); + void setDataArray(float* dataArrayIn, unsigned int sizeIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); // set attribute: ------------------- // sets position when m_isFixedX is disabled, returns final location - unsigned int setX(unsigned int locationIn, float xIn); + unsigned int setX(unsigned int pointLocation, float newX); // sets value when m_isFixedY is disabled - void setY(unsigned int locationIn, float yIn); + void setY(unsigned int pointLocation, float newY); // sets value when m_isEditableAttrib is enabled - void setC(unsigned int locationIn, float cIn); + void setC(unsigned int pointLocation, float newC); // sets value when m_isEditableAttrib is enabled - void setValA(unsigned int locationIn, float valueIn); + void setValA(unsigned int pointLocation, float fValue); // sets value when m_isEditableAttrib is enabled - void setValB(unsigned int locationIn, float valueIn); + void setValB(unsigned int pointLocation, float fValue); // sets value when m_isEditableAttrib is enabled - void setType(unsigned int locationIn, unsigned int typeIn); - // sets attribute settings when m_isEditableAttrib and m_isAutomatableEffectable is enabled - void setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn); - void setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn); - void setEffectOnlyPoints(unsigned int locationIn, bool boolIn); - void setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn); - // if isAutomatedIn is true then make a new FloatModel and connect it, else delete + void setType(unsigned int pointLocation, unsigned int newType); + // sets what attribute gets automated when m_isEditableAttrib and m_isAutomatableEffectable is enabled + void setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation); + // sets what attribute gets effected when m_isEditableAttrib and m_isAutomatableEffectable is enabled + void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); + void setEffectOnlyPoints(unsigned int pointLocation, bool bValue); + void setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue); + // if bValue is true then make a new FloatModel and connect it, else delete // the currently used FloatModel // runs if m_isAutomatableEffectable is enabled - void setAutomated(unsigned int locationIn, bool isAutomatedIn); + void setAutomated(unsigned int pointLocation, bool bValue); // signals: // not qt @@ -500,7 +501,7 @@ class LMMS_EXPORT VectorGraphDataArray // that are not used by points (there should be 0 cases like this) void delUnusedAutomation(); QString getSavedDataArray(); - void loadDataArray(QString dataIn, unsigned int sizeIn); + void loadDataArray(QString data, unsigned int arraySize); private: class VectorGraphPoint { @@ -529,10 +530,10 @@ class LMMS_EXPORT VectorGraphDataArray m_bufferedAutomationValue = 0.0f; m_automationModel = -1; } - inline VectorGraphPoint(float xIn, float yIn) + inline VectorGraphPoint(float x, float y) { - m_x = xIn; - m_y = yIn; + m_x = x; + m_y = y; m_c = 0.0f; m_valA = 0.0f; m_valB = 0.0f; @@ -601,50 +602,50 @@ class LMMS_EXPORT VectorGraphDataArray int m_automationModel; }; // deletes the point's automation model - // if locationIn == point location - void delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn); + // if modelLocation == point location + void delAutomationModel(unsigned int modelLocation, bool callDataChanged); // swapping values, "slide" moves the values (between) once left or right // handle m_isFixedEndPoints when using this - void swap(unsigned int locationAIn, unsigned int locationBIn, bool slide); + void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool slide); // returns the curve value at a given x coord, does clamp - float processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn); + float processCurve(float yBefore, float yAfter, float curve, float xIn); // applys the effect on a given value, does clamp - float processEffect(unsigned int locationIn, float attribValueIn, unsigned int attribLocationIn, float effectValueIn); + float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); // returns a VectorGraphPoint with modified attributes, does clamp - float processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn); + float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); // line effects / types, m_type is used for this - // valA: amp, valB: freq, fadeInStartIn: from what xIn value should the line type fade out - //float processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn); - std::vector processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float fadeInStartIn); - // curveIn: phase - //float processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); - std::vector processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn); + // valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out + //float processLineTypeSine(float xIn, float valA, float valB, float fadeInStartLoc); + std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float fadeInStartLoc); + // curve: phase + //float processLineTypeSineB(float xIn, float valA, float valB, float curve, float fadeInStartLoc); + std::vector processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc); // valA: amp, valB: x coord, curve: width - //float processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); - std::vector processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn); + //float processLineTypePeak(float xIn, float valA, float valB, float curve, float fadeInStartLoc); + std::vector processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc); // y: calculate steps from, valA: y count, valB: curve - //float processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeInStartIn); - std::vector processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, - std::vector* yIn, float valAIn, float valBIn, float fadeInStartIn); - // valA: amp, valB: random number count, curveIn: seed - //float processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn); - std::vector processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn); + //float processLineTypeSteps(float xIn, float yIn, float valA, float valBIn, float fadeInStartLoc); + std::vector processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + std::vector* yArray, float valA, float valB, float fadeInStartLoc); + // valA: amp, valB: random number count, curve: seed + //float processLineTypeRandom(float xIn, float valA, float valB, float curve, float fadeInStartLoc); + std::vector processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc); // updating // adds the points that are // effected by the effector's values changing // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::vector* updatingValuesIn); - // if locationIn >= 0 -> adds the location to m_needsUpdating + void getUpdatingFromEffector(std::vector* updatingPointLocations); + // if pointLocation >= 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedSamples // changes in the size of m_dataArray (addtition, deletion, ect.) // should to cause a full update - void getUpdatingFromPoint(int locationIn); + void getUpdatingFromPoint(int pointLocation); // adds the points that are changed because their // automation is changed void getUpdatingFromAutomation(); @@ -653,13 +654,13 @@ class LMMS_EXPORT VectorGraphDataArray void getUpdatingOriginals(); // real getSamples processing - void getSamples(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); + void getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); // gets every m_needsUpdating point's line's start and end effector point's location in the effector dataArray // .first = start, .second = line end location (effector dataArray) - //void getSamplesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut); - void getSamplesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, - std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn); - bool isEffectedPoint(unsigned int locationIn); + //void getSamplesLocations(VectorGraphDataArray* effector, std::vector>* effectorDataOut); + void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, + std::vector* outputXLocations, unsigned int iIn, float stepSize); + bool isEffectedPoint(unsigned int pointLocation); // checks m_isFixedEndPoints, does not call dataChanged() void formatDataArrayEndPoints(); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index b053be8ce6a..bfce14373d5 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -54,9 +54,9 @@ namespace lmms namespace gui { -VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, unsigned int pointSizeIn, - unsigned int controlHeightIn, unsigned int controlDisplayCountIn, bool shouldApplyDefaultVectorGraphColorsIn) : - QWidget(parentIn), +VectorGraphView::VectorGraphView(QWidget * parent, int widthIn, int heightIn, unsigned int pointSize, + unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors) : + QWidget(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this) { resize(widthIn, heightIn); @@ -64,7 +64,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_mousePress = false; m_addition = false; - m_pointSize = pointSizeIn; + m_pointSize = pointSize; // gets set in style //m_fontSize = 12; m_isSimplified = false; @@ -79,8 +79,8 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, m_isLastSelectedArray = false; m_graphHeight = height(); - m_controlHeight = controlHeightIn; - m_controlDisplayCount = controlDisplayCountIn; + m_controlHeight = controlHeight; + m_controlDisplayCount = controlDisplayCount; m_controlDisplayPage = 0; m_isEditingActive = false; m_controlText = { @@ -119,7 +119,7 @@ VectorGraphView::VectorGraphView(QWidget * parentIn, int widthIn, int heightIn, QObject::connect(this, &VectorGraphView::changedDefaultColors, this, &VectorGraphView::updateDefaultColors); - if (shouldApplyDefaultVectorGraphColorsIn == true) + if (shouldApplyDefaultVectorGraphColors == true) { applyDefaultColors(); } @@ -133,35 +133,35 @@ VectorGraphView::~VectorGraphView() qDebug("VectorGraphView dstc end"); } -void VectorGraphView::setLineColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) { - if (model()->getDataArraySize() > dataArrayLocationIn) + if (model()->getDataArraySize() > dataArrayLocation) { - model()->getDataArray(dataArrayLocationIn)->setLineColor(colorIn); + model()->getDataArray(dataArrayLocation)->setLineColor(color); updateGraph(); } } -void VectorGraphView::setActiveColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setActiveColor(QColor color, unsigned int dataArrayLocation) { - if (model()->getDataArraySize() > dataArrayLocationIn) + if (model()->getDataArraySize() > dataArrayLocation) { - model()->getDataArray(dataArrayLocationIn)->setActiveColor(colorIn); + model()->getDataArray(dataArrayLocation)->setActiveColor(color); updateGraph(); } } -void VectorGraphView::setFillColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setFillColor(QColor color, unsigned int dataArrayLocation) { - if (model()->getDataArraySize() > dataArrayLocationIn) + if (model()->getDataArraySize() > dataArrayLocation) { - model()->getDataArray(dataArrayLocationIn)->setFillColor(colorIn); + model()->getDataArray(dataArrayLocation)->setFillColor(color); updateGraph(); } } -void VectorGraphView::setAutomatedColor(QColor colorIn, unsigned int dataArrayLocationIn) +void VectorGraphView::setAutomatedColor(QColor color, unsigned int dataArrayLocation) { - if (model()->getDataArraySize() > dataArrayLocationIn) + if (model()->getDataArraySize() > dataArrayLocation) { - model()->getDataArray(dataArrayLocationIn)->setAutomatedColor(colorIn); + model()->getDataArray(dataArrayLocation)->setAutomatedColor(color); updateGraph(); } } @@ -184,25 +184,25 @@ void VectorGraphView::applyDefaultColors() } } } -void VectorGraphView::setPointSize(unsigned int pointSizeIn) +void VectorGraphView::setPointSize(unsigned int pointSize) { - m_pointSize = pointSizeIn; + m_pointSize = pointSize; updateGraph(); } -void VectorGraphView::setControlHeight(unsigned int controlHeightIn) +void VectorGraphView::setControlHeight(unsigned int controlHeight) { - m_controlHeight = controlHeightIn; + m_controlHeight = controlHeight; updateGraph(); } -void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCountIn) +void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCount) { - m_controlDisplayCount = controlDisplayCountIn; + m_controlDisplayCount = controlDisplayCount; updateGraph(); } -void VectorGraphView::setIsSimplified(bool isSimplifiedIn) +void VectorGraphView::setIsSimplified(bool isSimplified) { - m_isSimplified = isSimplifiedIn; + m_isSimplified = isSimplified; } std::pair VectorGraphView::getSelectedData() @@ -223,20 +223,20 @@ int VectorGraphView::getLastSelectedArray() } return -1; } -void VectorGraphView::setSelectedData(std::pair dataIn) +void VectorGraphView::setSelectedData(std::pair data) { if (m_isSelected == true) { qDebug("setSelectedData"); - model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, dataIn.second); + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, data.second); qDebug("set value done"); - m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, dataIn.first); - qDebug("set position done (%f)", dataIn.first); + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, data.first); + qDebug("set position done (%f)", data.first); } } -void VectorGraphView::setBackground(const QPixmap backgroundIn) +void VectorGraphView::setBackground(const QPixmap background) { - m_background = backgroundIn; + m_background = background; } void VectorGraphView::useGetLastSamples() { @@ -644,14 +644,14 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) emit drawn(); } -void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::vector* sampleBufferIn) +void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer) { - VectorGraphDataArray* dataArray = model()->getDataArray(locationIn); + VectorGraphDataArray* dataArray = model()->getDataArray(arrayLocation); unsigned int length = dataArray->size(); if (length > 0) { - pIn->setPen(QPen(*dataArray->getLineColor(), 2)); - pIn->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); std::pair posA(0, 0); std::pair posB(0, 0); @@ -663,21 +663,21 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve posA = startPos; pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - dataArray->getLastSamples(sampleBufferIn); + dataArray->getLastSamples(sampleBuffer); - qDebug("paint sampleBufferIn size: %ld", sampleBufferIn->size()); - for (unsigned int j = 0; j < sampleBufferIn->size(); j++) + qDebug("paint sampleBuffer size: %ld", sampleBuffer->size()); + for (unsigned int j = 0; j < sampleBuffer->size(); j++) { // if nonNegative then only the dataArray output (getDataValues) // is bigger than 0 so it matters only here - posB = mapDataPos(0, sampleBufferIn->operator[](j), dataArray->getIsNonNegative()); - posB.first = static_cast((j * width()) / static_cast(sampleBufferIn->size())); + posB = mapDataPos(0, sampleBuffer->operator[](j), dataArray->getIsNonNegative()); + posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); if (posA.first != posB.first) { pt.lineTo(posB.first, m_graphHeight - posB.second); // pt replaces drawing with path - //pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + //p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } posA = posB; } @@ -693,13 +693,13 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve pt.lineTo(startPos.first + 1, m_graphHeight - 1); pt.lineTo(startPos.first + 1, startPos.second); // draw fill - pIn->fillPath(pt, QBrush(*dataArray->getFillColor())); + p->fillPath(pt, QBrush(*dataArray->getFillColor())); // draw line - pIn->drawPath(ptline); + p->drawPath(ptline); } else { - pIn->drawPath(pt); + p->drawPath(pt); } } @@ -723,24 +723,24 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve if (dataArray->getAutomationModel(j) != nullptr) { // if automated - pIn->setPen(QPen(*dataArray->getAutomatedColor(), 2)); - pIn->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); + p->setPen(QPen(*dataArray->getAutomatedColor(), 2)); + p->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); resetColor = true; } - else if (m_isSelected == true && m_selectedArray == locationIn && m_selectedLocation == j) + else if (m_isSelected == true && m_selectedArray == arrayLocation && m_selectedLocation == j) { // if selected - pIn->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); + p->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); resetColor = true; } - pIn->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + p->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); // reset point color if (resetColor == true) { - pIn->setPen(QPen(*dataArray->getLineColor(), 2)); - pIn->setBrush(Qt::NoBrush); + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(Qt::NoBrush); resetColor = false; } @@ -749,7 +749,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve if (dataArray->getIsEditableAttrib() == true) { std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - pIn->drawRect(posC.first - squareSize / 2, + p->drawRect(posC.first - squareSize / 2, m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); } } @@ -758,7 +758,7 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve // draw simplified line if (m_isSimplified == true) { - pIn->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } posA = posB; } @@ -766,13 +766,13 @@ void VectorGraphView::paintGraph(QPainter* pIn, unsigned int locationIn, std::ve // draw last simplified line if (m_isSimplified == true) { - pIn->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); + p->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); } } } -void VectorGraphView::paintEditing(QPainter* pIn) +void VectorGraphView::paintEditing(QPainter* p) { - pIn->setFont(QFont("Arial", m_fontSize)); + p->setFont(QFont("Arial", m_fontSize)); if (m_isEditingActive == true) { VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); @@ -799,7 +799,7 @@ void VectorGraphView::paintEditing(QPainter* pIn) int segmentLength = width() / (m_controlDisplayCount + 1); // draw inputs - pIn->setPen(QPen(textColor, 1)); + p->setPen(QPen(textColor, 1)); for (unsigned int i = 0; i < m_controlDisplayCount; i++) { int controlLocation = m_controlDisplayCount * m_controlDisplayPage + i; @@ -822,9 +822,9 @@ void VectorGraphView::paintEditing(QPainter* pIn) curForeColor = *dataArray->getActiveColor(); curBackColor = getFillColorFromBaseColor(curForeColor); } - pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curBackColor); - pIn->fillRect(i * segmentLength, m_graphHeight, mapControlInputX(inputValue, segmentLength), m_controlHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, + p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curBackColor); + p->fillRect(i * segmentLength, m_graphHeight, mapControlInputX(inputValue, segmentLength), m_controlHeight, curForeColor); + p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); } else @@ -836,35 +836,35 @@ void VectorGraphView::paintEditing(QPainter* pIn) { curForeColor = *dataArray->getActiveColor(); } - pIn->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); - pIn->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, + p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); + p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); } } } // draw "next page" button - pIn->fillRect(m_controlDisplayCount * segmentLength, m_graphHeight, segmentLength, m_controlHeight, *dataArray->getFillColor()); - pIn->setPen(textColor); - pIn->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, ">>"); + p->fillRect(m_controlDisplayCount * segmentLength, m_graphHeight, segmentLength, m_controlHeight, *dataArray->getFillColor()); + p->setPen(textColor); + p->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, ">>"); // draw selected array display outline - pIn->setPen(*dataArray->getLineColor()); - pIn->drawRect(0, 0, m_controlHeight, m_controlHeight); + p->setPen(*dataArray->getLineColor()); + p->drawRect(0, 0, m_controlHeight, m_controlHeight); // draw outline - pIn->drawLine(0, m_graphHeight, width(), m_graphHeight); + p->drawLine(0, m_graphHeight, width(), m_graphHeight); for (unsigned int i = 1; i < m_controlDisplayCount + 1; i++) { if (m_controlDisplayCount * m_controlDisplayPage + i < controlTextCount || i >= m_controlDisplayCount) { - pIn->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); + p->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); } } } if (m_isLastSelectedArray == true) { // draw selected array number - pIn->setPen(QPen(QColor(127, 127, 127, 255), 2)); - pIn->drawText(2, (m_controlHeight - m_fontSize) / 2 + m_fontSize, QString::number(m_selectedArray)); + p->setPen(QPen(QColor(127, 127, 127, 255), 2)); + p->drawText(2, (m_controlHeight - m_fontSize) / 2 + m_fontSize, QString::number(m_selectedArray)); } } @@ -881,9 +881,9 @@ void VectorGraphView::updateGraph() { update(); } -void VectorGraphView::updateGraph(bool shouldUseGetLastSamplesIn) +void VectorGraphView::updateGraph(bool shouldUseGetLastSamples) { - m_useGetLastSamples = shouldUseGetLastSamplesIn; + m_useGetLastSamples = shouldUseGetLastSamples; update(); } void VectorGraphView::updateDefaultColors() @@ -944,117 +944,117 @@ void VectorGraphView::removeController() removeAutomation(); } -std::pair VectorGraphView::mapMousePos(int xIn, int yIn) +std::pair VectorGraphView::mapMousePos(int x, int y) { // mapping the position to 0 - 1, -1 - 1 using qWidget width and height return std::pair( - static_cast(xIn / (float)width()), - static_cast(yIn) * 2.0f / static_cast(m_graphHeight) - 1.0f); + static_cast(x / (float)width()), + static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); } -std::pair VectorGraphView::mapDataPos(float xIn, float yIn, bool isNonNegativeIn) +std::pair VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) { // mapping the point/sample positon to mouse/view position - if (isNonNegativeIn == true) + if (isNonNegative == true) { return std::pair( - static_cast(xIn * width()), - static_cast(yIn * m_graphHeight)); + static_cast(x * width()), + static_cast(y * m_graphHeight)); } else { return std::pair( - static_cast(xIn * width()), - static_cast((yIn + 1.0f) * static_cast(m_graphHeight) / 2.0f)); + static_cast(x * width()), + static_cast((y + 1.0f) * static_cast(m_graphHeight) / 2.0f)); } } -std::pair VectorGraphView::mapDataCurvePosF(float xAIn, float yAIn, float xBIn, float yBIn, float curveIn) +std::pair VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve) { return std::pair( - (xAIn + xBIn) / 2.0f, - yAIn + (curveIn / 2.0f + 0.5f) * (yBIn - yAIn)); + (xA + xB) / 2.0f, + yA + (curve / 2.0f + 0.5f) * (yB - yA)); } -std::pair VectorGraphView::mapDataCurvePos(int xAIn, int yAIn, int xBIn, int yBIn, float curveIn) +std::pair VectorGraphView::mapDataCurvePos(int xA, int yA, int xB, int yB, float curve) { return std::pair( - (xAIn + xBIn) / 2, - yAIn + static_cast((curveIn / 2.0f + 0.5f) * (yBIn - yAIn))); + (xA + xB) / 2, + yA + static_cast((curve / 2.0f + 0.5f) * (yB - yA))); } -int VectorGraphView::mapControlInputX(float inputValueIn, unsigned int displayLengthIn) +int VectorGraphView::mapControlInputX(float inputValue, unsigned int displayLength) { - return (inputValueIn / 2.0f + 0.5f) * displayLengthIn; + return (inputValue / 2.0f + 0.5f) * displayLength; } -float VectorGraphView::getDistance(int xAIn, int yAIn, int xBIn, int yBIn) +float VectorGraphView::getDistance(int xA, int yA, int xB, int yB) { - return std::sqrt(static_cast((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn))); + return std::sqrt(static_cast((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB))); } -float VectorGraphView::getDistanceF(float xAIn, float yAIn, float xBIn, float yBIn) +float VectorGraphView::getDistanceF(float xA, float yA, float xB, float yB) { - return std::sqrt((xAIn - xBIn) * (xAIn - xBIn) + (yAIn - yBIn) * (yAIn - yBIn)); + return std::sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB)); } -bool VectorGraphView::addPoint(unsigned int locationIn, int mouseXIn, int mouseYIn) +bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouseY) { - // mouseYIn is calculated like this: + // mouseY is calculated like this: // m_graphHeight - y bool output = false; - std::pair curMouseCoords = mapMousePos(mouseXIn, mouseYIn); + std::pair curMouseCoords = mapMousePos(mouseX, mouseY); curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); - int location = model()->getDataArray(locationIn)->add(curMouseCoords.first); + int location = model()->getDataArray(arrayLocation)->add(curMouseCoords.first); // if adding was successful if (location >= 0) { output = true; - qDebug("addPoint point added: array: %d location: %d %f,%d", locationIn, location, curMouseCoords.second, m_graphHeight); - model()->getDataArray(locationIn)->setY(location, curMouseCoords.second); + qDebug("addPoint point added: array: %d location: %d %f,%d", arrayLocation, location, curMouseCoords.second, m_graphHeight); + model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); } - qDebug("addPoint LocationIn: %d", locationIn); + qDebug("addPoint Location: %d", location); return output; } -bool VectorGraphView::isGraphPressed(int mouseXIn, int mouseYIn) +bool VectorGraphView::isGraphPressed(int mouseX, int mouseY) { bool output = true; - // mouseYIn is calculated like this: + // mouseY is calculated like this: // m_graphHeight - y - if (m_isEditingActive == true && m_graphHeight - mouseYIn < m_controlHeight && mouseXIn < m_controlHeight) + if (m_isEditingActive == true && m_graphHeight - mouseY < m_controlHeight && mouseX < m_controlHeight) { // if switch selected data array was pressed //qDebug("isGraphPressed switch selected dataArray"); output = false; } - else if (isControlWindowPressed(mouseYIn) == true) + else if (isControlWindowPressed(mouseY) == true) { // if the control window was pressed output = false; } return output; } -bool VectorGraphView::isControlWindowPressed(int mouseYIn) +bool VectorGraphView::isControlWindowPressed(int mouseY) { bool output = false; - // mouseYIn is calculated like this: + // mouseY is calculated like this: // m_graphHeight - y - if (m_isEditingActive == true && mouseYIn <= 0) + if (m_isEditingActive == true && mouseY <= 0) { //qDebug("isGraphPressed control window was pressed"); output = true; } return output; } -void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bool isDraggingIn, bool startMovingIn, int curXIn, int curYIn) +void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving, int curX, int curY) { - // mouseYIn is calculated like this: + // mouseY is calculated like this: // m_graphHeight - y setCursor(Qt::ArrowCursor); qDebug("mouseMove 7: %d", m_lastTrackPoint.first); if (m_isEditingActive == true) { - int pressLocation = getPressedControlInput(mouseXIn, m_graphHeight - mouseYIn, m_controlDisplayCount + 1); + int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount + 1); int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; - if (isDraggingIn == false && pressLocation == m_controlDisplayCount) + if (isDragging == false && pressLocation == m_controlDisplayCount) { // if the last button was pressed @@ -1105,7 +1105,7 @@ void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bo addDefaultActions(&contextMenu, m_controlText[location]); contextMenu.exec(QCursor::pos()); } - else if (isDraggingIn == false && m_controlIsFloat[location] == false) + else if (isDragging == false && m_controlIsFloat[location] == false) { // if the input type is a bool @@ -1119,50 +1119,50 @@ void VectorGraphView::processControlWindowPressed(int mouseXIn, int mouseYIn, bo } setInputAttribValue(location, 0.0f, curBoolValue); } - else if (isDraggingIn == true && m_controlIsFloat[location] == true) + else if (isDragging == true && m_controlIsFloat[location] == true) { // if the input type is a float // if the user just started to move the mouse it is pressed - if (startMovingIn == true) + if (startMoving == true) { // unused bool bool isTrue = false; // set m_lastScndTrackPoint.first to the current input value m_lastScndTrackPoint.first = mapControlInputX(getInputAttribValue(location, &isTrue), m_graphHeight); - m_lastTrackPoint.first = curXIn; - m_lastTrackPoint.second = curYIn; - qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, curXIn, (curYIn), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); + m_lastTrackPoint.first = curX; + m_lastTrackPoint.second = curY; + qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, curX, (curY), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); } std::pair convertedCoords = mapMousePos(0, - m_lastScndTrackPoint.first + static_cast(curYIn - m_lastTrackPoint.second) / 2); - qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curYIn - m_lastTrackPoint.second) / 2), convertedCoords.second); + m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); + qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2), convertedCoords.second); setInputAttribValue(location, convertedCoords.second, false); } } } } -int VectorGraphView::getPressedControlInput(int mouseXIn, int mouseYIn, unsigned int inputCountIn) +int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount) { int output = -1; - if (m_isEditingActive == true && mouseYIn > m_graphHeight) + if (m_isEditingActive == true && mouseY > m_graphHeight) { - output = mouseXIn * inputCountIn / width(); + output = mouseX * controlCount / width(); } - if (output > inputCountIn) + if (output > controlCount) { - output = inputCountIn; -qDebug("getPressedControlInput x location ERRROR: %d", mouseXIn); + output = controlCount; +qDebug("getPressedControlInput x location ERRROR: %d", mouseX); } return output; } -float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocationIn, bool* valueOut) +float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bool* valueOut) { float output = 0.0f; if (m_isSelected == true) { - switch (controlArrayLocationIn) + switch (controlArrayLocation) { case 0: *valueOut = false; @@ -1233,14 +1233,14 @@ float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocationIn, } return output; } -void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, float floatValueIn, bool boolValueIn) +void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue, bool boolValue) { qDebug("setInputAttribValue started"); if (m_isSelected == true) { - float clampedValue = std::clamp(floatValueIn, -1.0f, 1.0f); + float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); unsigned int clampedValueB = 0; - switch (controlArrayLocationIn) + switch (controlArrayLocation) { case 0: m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); @@ -1260,7 +1260,7 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f case 5: // type clampedValueB = 0; - if (boolValueIn == true) + if (boolValue == true) { clampedValueB = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation) + 1; if (clampedValueB > 5) @@ -1270,14 +1270,14 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 5.0f)); + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); } model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); break; case 6: // automation location clampedValueB = 0; - if (boolValueIn == true) + if (boolValue == true) { clampedValueB = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation) + 1; if (clampedValueB > 4) @@ -1287,14 +1287,14 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 4.0f)); + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); } model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); break; case 7: // effect location clampedValueB = 0; - if (boolValueIn == true) + if (boolValue == true) { clampedValueB = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation) + 1; if (clampedValueB > 4) @@ -1304,48 +1304,48 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocationIn, f } else { - clampedValueB = static_cast(std::clamp(floatValueIn, 0.0f, 4.0f)); + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); } model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); break; case 8: - model()->getDataArray(m_selectedArray)->setEffectOnlyPoints(m_selectedLocation, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffectOnlyPoints(m_selectedLocation, boolValue); break; case 9: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); break; case 10: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); break; case 11: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); break; case 12: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); break; case 13: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); break; case 14: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); break; case 15: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); break; case 16: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); break; case 17: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValueIn); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValue); break; } } qDebug("setInputAttribValue finished"); } -QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColorIn) +QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColor) { QColor output(255, 255, 255, 255); - int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); + int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); // > 127 * 3 if (colorSum > 382) { @@ -1353,12 +1353,12 @@ QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColorIn) } return output; } -QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColorIn) +QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColor) { QColor output; - int colorSum = baseColorIn.red() + baseColorIn.green() + baseColorIn.blue(); + int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); int brighten = 0; - int alpha = baseColorIn.alpha(); + int alpha = baseColor.alpha(); if (alpha == 0) { alpha = 255; @@ -1372,32 +1372,32 @@ QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColorIn) { // (red * 0.6f + avg * 0.4f / 3.0f) * 0.7 //qDebug("getFillColorFromBaseColor bigger, %d", brighten); - output = QColor(static_cast(static_cast(baseColorIn.red()) * 0.42f + colorSum * 0.09f) - brighten, - static_cast(static_cast(baseColorIn.green()) * 0.42f + colorSum * 0.09f) - brighten, - static_cast(static_cast(baseColorIn.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); + output = QColor(static_cast(static_cast(baseColor.red()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColor.green()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColor.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); } else { // (red * 0.6f + avg * 0.4f / 3.0f) * 1.3 - output = QColor(static_cast(static_cast(baseColorIn.red()) * 0.78f + colorSum * 0.17f) + brighten, - static_cast(static_cast(baseColorIn.green()) * 0.78f + colorSum * 0.17f) + brighten, - static_cast(static_cast(baseColorIn.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); + output = QColor(static_cast(static_cast(baseColor.red()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColor.green()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColor.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); } return output; } -QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int displayLengthIn) +QString VectorGraphView::getTextFromDisplayLength(QString text, unsigned int displayLength) { // estimating text length int charLength = static_cast(m_fontSize * 0.65f); QString output = ""; - int targetSize = displayLengthIn / charLength < textIn.size() ? displayLengthIn / charLength : textIn.size(); - if (targetSize != textIn.size()) + int targetSize = displayLength / charLength < text.size() ? displayLength / charLength : text.size(); + if (targetSize != text.size()) { for (unsigned int i = 0; i < targetSize; i++) { if (i + 2 < targetSize) { - output = output + textIn[i]; + output = output + text[i]; } else { @@ -1407,15 +1407,15 @@ QString VectorGraphView::getTextFromDisplayLength(QString textIn, unsigned int d } else { - output = textIn; + output = text; } return output; } -void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayTextIn) +void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayText) { // context menu settings menu->addAction(embed::getIconPixmap("reload"), - tr("name: ") + controlDisplayTextIn, + tr("name: ") + controlDisplayText, this, SLOT(updateGraph())); menu->addAction(embed::getIconPixmap("reload"), tr("remove automation"), @@ -1480,14 +1480,14 @@ std::pair VectorGraphView::showCoordInputDialog() } return curData; } -float VectorGraphView::showInputDialog(float curInputValueIn) +float VectorGraphView::showInputDialog(float curInputValue) { float output = 0.0f; bool ok; double changedPos = QInputDialog::getDouble(this, tr("Set value"), tr("Please enter a new value between -100 and 100"), - static_cast(curInputValueIn * 100.0f), + static_cast(curInputValue * 100.0f), -100.0, 100.0, 2, &ok); if (ok == true) { @@ -1497,7 +1497,7 @@ float VectorGraphView::showInputDialog(float curInputValueIn) return output; } -void VectorGraphView::selectData(int mouseXIn, int mouseYIn) +void VectorGraphView::selectData(int mouseX, int mouseY) { qDebug("selectData"); @@ -1507,7 +1507,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) if (m_isLastSelectedArray == true) { VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); - int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); if (location > -1) { m_selectedLocation = location; @@ -1534,7 +1534,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) VectorGraphDataArray* dataArray = model()->getDataArray(i); if (dataArray->getIsSelectable() == true) { - int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, false); + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); if (location > -1) { //qDebug("selected data!"); @@ -1556,7 +1556,7 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) VectorGraphDataArray* dataArray = model()->getDataArray(i); if (dataArray->getIsSelectable() == true) { - int location = searchForData(mouseXIn, mouseYIn, static_cast(m_pointSize) / width(), dataArray, true); + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, true); if (location > -1) { //qDebug("selected data curve!"); @@ -1576,42 +1576,42 @@ void VectorGraphView::selectData(int mouseXIn, int mouseYIn) qDebug("selectDataEnd, Arr: %d, location: %d", m_selectedArray, m_selectedLocation); } -int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistanceIn, VectorGraphDataArray* arrayIn, bool curvedIn) +int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved) { int output = -1; - float maxDistance = maxDistanceIn * 2.0f; + maxDistance = maxDistance * 2.0f; qDebug("searchData"); - std::pair transformedMouse = mapMousePos(mouseXIn, mouseYIn); + std::pair transformedMouse = mapMousePos(mouseX, mouseY); // unused bool bool found = false; bool isBefore = false; // get the nearest data to the mouse pos (x) in an optimalized way - int location = arrayIn->getNearestLocation(transformedMouse.first, &found, &isBefore); + int location = dataArray->getNearestLocation(transformedMouse.first, &found, &isBefore); //qDebug("selected location: %d", location); // if getNearestLocation was successful if (location >= 0) { - float dataX = arrayIn->getX(location); - float dataY = arrayIn->getY(location); - // this is set to one when curveIn == true + float dataX = dataArray->getX(location); + float dataY = dataArray->getY(location); + // this is set to one when isCurved == true // and isBefore == false int curvedBefore = 0; - // if curved then get the closest curved coord - if (curvedIn == true && arrayIn->size() > 1) + // if isCurved then get the closest curved coord + if (isCurved == true && dataArray->size() > 1) { if (isBefore == false && 1 < location) { curvedBefore = 1; } - if (location - curvedBefore < arrayIn->size() - 1) + if (location - curvedBefore < dataArray->size() - 1) { std::pair curvedDataCoords = mapDataCurvePosF( - arrayIn->getX(location - curvedBefore), arrayIn->getY(location - curvedBefore), - arrayIn->getX(location - curvedBefore + 1), arrayIn->getY(location - curvedBefore + 1), - arrayIn->getC(location - curvedBefore)); + dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), + dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), + dataArray->getC(location - curvedBefore)); dataX = curvedDataCoords.first; dataY = curvedDataCoords.second; } @@ -1636,25 +1636,25 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance // coordinates are close but the y coords are not // calculating and testing all near by point distances int searchStart = 0; - int searchEnd = arrayIn->size() - 1; + int searchEnd = dataArray->size() - 1; // from where we need to search the data for (int i = location - curvedBefore - 1; i > 0; i--) { - if (std::abs(arrayIn->getX(i) - transformedMouse.first) > maxDistance) + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) { - // if it is curved, then subtract 1 - // add 1 to i because [i] > maxDistanceIn - searchStart = i + 1 - (i > 0 && curvedIn == true ? 1 : 0); + // if it is isCurved, then subtract 1 + // add 1 to i because [i] > maxDistance + searchStart = i + 1 - (i > 0 && isCurved == true ? 1 : 0); break; } } //qDebug("search V2AAA temp, start: %d, end: %d", searchStart, searchEnd); // getting where the search needs to end - for (int i = location - curvedBefore + 1; i < arrayIn->size(); i++) + for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) { - if (std::abs(arrayIn->getX(i) - transformedMouse.first) > maxDistance) + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) { - searchEnd = i - 1 - (i > 0 && curvedIn == true ? 1 : 0); + searchEnd = i - 1 - (i > 0 && isCurved == true ? 1 : 0); break; } } @@ -1664,22 +1664,22 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance { if (i != location) { - dataX = arrayIn->getX(i); - dataY = arrayIn->getY(i); - if (curvedIn == true && arrayIn->size() > 1) + dataX = dataArray->getX(i); + dataY = dataArray->getY(i); + if (isCurved == true && dataArray->size() > 1) { - if (arrayIn->size() - 1 > i) + if (dataArray->size() - 1 > i) { std::pair curvedDataCoords = mapDataCurvePosF( - arrayIn->getX(i), arrayIn->getY(i), arrayIn->getX(i + 1), arrayIn->getY(i + 1), - arrayIn->getC(i)); + dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), + dataArray->getC(i)); dataX = curvedDataCoords.first; dataY = curvedDataCoords.second; } } curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - //qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, arrayIn->getY(i), arrayIn->size()); + //qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, dataArray->getY(i), dataArray->size()); if (curDistance <= maxDistance) { //qDebug("search successful V2"); @@ -1697,10 +1697,10 @@ int VectorGraphView::searchForData(int mouseXIn, int mouseYIn, float maxDistance } // namespace gui -VectorGraphModel::VectorGraphModel(unsigned int maxLengthIn, Model* parentIn, bool defaultConstructedIn) : - Model(parentIn, tr("VectorGraphModel"), defaultConstructedIn) +VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parentIn, bool defaultConstructed) : + Model(parentIn, tr("VectorGraphModel"), defaultConstructed) { - m_maxLength = maxLengthIn; + m_maxLength = arrayMaxLength; //m_dataArrays } @@ -1722,11 +1722,11 @@ unsigned int VectorGraphModel::addArray() return m_dataArrays.size() - 1; } -void VectorGraphModel::delArray(unsigned int locationIn) +void VectorGraphModel::delArray(unsigned int arrayLocation) { qDebug("delArray"); std::vector effectorArrayLocations(m_dataArrays.size()); - for (unsigned int i = locationIn; i < m_dataArrays.size() - 1; i++) + for (unsigned int i = arrayLocation; i < m_dataArrays.size() - 1; i++) { //qDebug("copyed [%d] to [%d]", i + 1, i); m_dataArrays[i] = m_dataArrays[i + 1]; @@ -1736,11 +1736,11 @@ void VectorGraphModel::delArray(unsigned int locationIn) for (unsigned int i = 0; i < m_dataArrays.size(); i++) { effectorArrayLocations[i] = m_dataArrays[i].getEffectorArrayLocation(); - if (m_dataArrays[i].getEffectorArrayLocation() == static_cast(locationIn)) + if (m_dataArrays[i].getEffectorArrayLocation() == static_cast(arrayLocation)) { effectorArrayLocations[i] = -1; } - else if (effectorArrayLocations[i] >= static_cast(locationIn)) + else if (effectorArrayLocations[i] >= static_cast(arrayLocation)) { effectorArrayLocations[i]--; } @@ -1763,15 +1763,15 @@ void VectorGraphModel::dataArrayChanged() emit dataChanged(); emit updateGraphView(false); } -void VectorGraphModel::updateGraphModel(bool shouldUseGetLastSamplesIn) +void VectorGraphModel::updateGraphModel(bool shouldUseGetLastSamples) { // connects to external update signal - emit updateGraphView(shouldUseGetLastSamplesIn); + emit updateGraphView(shouldUseGetLastSamples); } -void VectorGraphModel::dataArrayClearedEvent(int idIn) +void VectorGraphModel::dataArrayClearedEvent(int arrayId) { // TODO needs testing - int location = getDataArrayLocationFromId(idIn); + int location = getDataArrayLocationFromId(arrayId); emit clearedEvent(location); emit dataChanged(); emit updateGraphView(false); @@ -1781,14 +1781,14 @@ void VectorGraphModel::dataArrayStyleChanged() { emit styleChanged(); } -int VectorGraphModel::getDataArrayLocationFromId(int idIn) +int VectorGraphModel::getDataArrayLocationFromId(int arrayId) { int output = -1; - if (idIn >= 0) + if (arrayId >= 0) { for (unsigned int i = 0; i < m_dataArrays.size(); i++) { - if (m_dataArrays[i].getId() == idIn) + if (m_dataArrays[i].getId() == arrayId) { output = i; break; @@ -1953,14 +1953,14 @@ void VectorGraphModel::loadSettings(const QDomElement& element) loadSettings(element, QString("")); } /* -int VectorGraphModel::readLoc(unsigned int startIn, QString dataIn) +int VectorGraphModel::readLoc(unsigned int start, QString data) { int output = -1; - for (unsigned int i = startIn; i < dataIn.size(); i++) + for (unsigned int i = start; i < data.size(); i++) { - if (dataIn[i] == QString("-")) + if (data[i] == QString("-")) { - output = dataIn.left(i - 1).toInt(); + output = data.left(i - 1).toInt(); break; } } @@ -2002,19 +2002,19 @@ VectorGraphDataArray::VectorGraphDataArray() } VectorGraphDataArray::VectorGraphDataArray( - bool isFixedSizeIn, bool isFixedXIn, bool isFixedYIn, bool isNonNegativeIn, - bool isFixedEndPointsIn, bool isSelectableIn, bool isEditableAttribIn, bool isAutomatableEffectableIn, - bool isSaveableIn, VectorGraphModel* parentIn, int idIn) -{ - m_isFixedSize = isFixedSizeIn; - m_isFixedY = isFixedXIn; - m_isFixedX = isFixedYIn; - m_isFixedEndPoints = isFixedEndPointsIn; - m_isSelectable = isSelectableIn; - m_isEditableAttrib = isEditableAttribIn; - m_isAutomatableEffectable = isAutomatableEffectableIn; - m_isSaveable = isSaveableIn; - m_isNonNegative = isNonNegativeIn; + bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, + bool isSaveable, VectorGraphModel* parentIn, int arrayId) +{ + m_isFixedSize = isFixedSize; + m_isFixedY = isFixedX; + m_isFixedX = isFixedY; + m_isFixedEndPoints = isFixedEndPoints; + m_isSelectable = isSelectable; + m_isEditableAttrib = isEditableAttrib; + m_isAutomatableEffectable = isAutomatableEffectable; + m_isSaveable = isSaveable; + m_isNonNegative = isNonNegative; m_lineColor = QColor(200, 200, 200, 255); m_activeColor = QColor(255, 255, 255, 255); @@ -2031,7 +2031,7 @@ VectorGraphDataArray::VectorGraphDataArray( // m_needsUpdating; // m_automationModelArray; - m_id = idIn; + m_id = arrayId; updateConnections(parentIn); } @@ -2063,47 +2063,47 @@ void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) setEffectorArrayLocation(-1, true); } -void VectorGraphDataArray::setIsFixedSize(bool valueIn) +void VectorGraphDataArray::setIsFixedSize(bool bValue) { - m_isFixedSize = valueIn; + m_isFixedSize = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsFixedX(bool valueIn) +void VectorGraphDataArray::setIsFixedX(bool bValue) { - m_isFixedX = valueIn; + m_isFixedX = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsFixedY(bool valueIn) +void VectorGraphDataArray::setIsFixedY(bool bValue) { - m_isFixedY = valueIn; + m_isFixedY = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsFixedEndPoints(bool valueIn) +void VectorGraphDataArray::setIsFixedEndPoints(bool bValue) { - m_isFixedEndPoints = valueIn; + m_isFixedEndPoints = bValue; formatDataArrayEndPoints(); getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsSelectable(bool valueIn) +void VectorGraphDataArray::setIsSelectable(bool bValue) { - m_isSelectable = valueIn; + m_isSelectable = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsEditableAttrib(bool valueIn) +void VectorGraphDataArray::setIsEditableAttrib(bool bValue) { - m_isEditableAttrib = valueIn; + m_isEditableAttrib = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) +void VectorGraphDataArray::setIsAutomatableEffectable(bool bValue) { - m_isAutomatableEffectable = valueIn; - if (valueIn == false) + m_isAutomatableEffectable = bValue; + if (bValue == false) { // setEffectorArray will call dataChanged() setEffectorArrayLocation(-1, true); @@ -2114,41 +2114,41 @@ void VectorGraphDataArray::setIsAutomatableEffectable(bool valueIn) dataChanged(); } } -void VectorGraphDataArray::setIsSaveable(bool valueIn) +void VectorGraphDataArray::setIsSaveable(bool bValue) { - m_isSaveable = valueIn; + m_isSaveable = bValue; } -void VectorGraphDataArray::setIsNonNegative(bool valueIn) +void VectorGraphDataArray::setIsNonNegative(bool bValue) { - m_isNonNegative = valueIn; + m_isNonNegative = bValue; getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setLineColor(QColor colorIn) +void VectorGraphDataArray::setLineColor(QColor bValue) { - m_lineColor = colorIn; + m_lineColor = bValue; styleChanged(); } -void VectorGraphDataArray::setActiveColor(QColor colorIn) +void VectorGraphDataArray::setActiveColor(QColor color) { - m_activeColor = colorIn; + m_activeColor = color; styleChanged(); } -void VectorGraphDataArray::setFillColor(QColor colorIn) +void VectorGraphDataArray::setFillColor(QColor color) { - m_fillColor = colorIn; + m_fillColor = color; styleChanged(); } -void VectorGraphDataArray::setAutomatedColor(QColor colorIn) +void VectorGraphDataArray::setAutomatedColor(QColor color) { - m_automatedColor = colorIn; + m_automatedColor = color; styleChanged(); } -bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDataChangedIn) +bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool callDataChanged) { qDebug("setEffectorArrayLocation start"); bool found = true; - if (locationIn >= 0) + if (arrayLocation >= 0) { // if there is no valid id if (m_id < 0) @@ -2156,19 +2156,19 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat m_id = m_parent->getDataArrayNewId(); } qDebug("setEffectorArrayLocation cur_id %d", m_id); - int arrayLocation = locationIn; + int searchArrayLocation = arrayLocation; found = false; // checking if the effector chain has this dataArray in it for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) { - int arrayId = m_parent->getDataArray(arrayLocation)->getId(); - arrayLocation = m_parent->getDataArray(arrayLocation)->getEffectorArrayLocation(); + int arrayId = m_parent->getDataArray(searchArrayLocation)->getId(); + searchArrayLocation = m_parent->getDataArray(searchArrayLocation)->getEffectorArrayLocation(); if(arrayId == m_id) { found = true; break; } - if (arrayLocation == -1) + if (searchArrayLocation == -1) { break; } @@ -2176,9 +2176,9 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat // if the effector chain does not contain this dataArray if (found == false) { - m_effectorLocation = locationIn; + m_effectorLocation = arrayLocation; getUpdatingFromPoint(-1); - if (callDataChangedIn == true) + if (callDataChanged == true) { dataChanged(); } @@ -2190,7 +2190,7 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int locationIn, bool callDat { m_effectorLocation = -1; getUpdatingFromPoint(-1); - if (callDataChangedIn == true) + if (callDataChanged == true) { dataChanged(); } @@ -2263,7 +2263,7 @@ int VectorGraphDataArray::getId() // array: -int VectorGraphDataArray::add(float xIn) +int VectorGraphDataArray::add(float newX) { int location = -1; if (m_isFixedSize == false && m_dataArray.size() < m_parent->getMaxLength()) @@ -2271,7 +2271,7 @@ int VectorGraphDataArray::add(float xIn) qDebug("add 1. success"); bool found = false; bool isBefore = false; - location = getNearestLocation(xIn, &found, &isBefore); + location = getNearestLocation(newX, &found, &isBefore); if (found == false) { qDebug("add 2. success, nearest: %d", location); @@ -2292,7 +2292,7 @@ int VectorGraphDataArray::add(float xIn) targetLocation++; } } - m_dataArray.push_back(VectorGraphPoint(xIn, 0.0f)); + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); qDebug("add 4. success, target: %d", targetLocation); swap(m_dataArray.size() - 1, targetLocation, true); dataChangedVal = true; @@ -2300,7 +2300,7 @@ int VectorGraphDataArray::add(float xIn) else if (m_dataArray.size() <= 0) { qDebug("add 5. success"); - m_dataArray.push_back(VectorGraphPoint(xIn, 0.0f)); + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); targetLocation = 0; dataChangedVal = true; } @@ -2324,17 +2324,17 @@ int VectorGraphDataArray::add(float xIn) return location; } -void VectorGraphDataArray::del(unsigned int locationIn) +void VectorGraphDataArray::del(unsigned int pointLocation) { - if (m_isFixedSize == false && locationIn < m_dataArray.size()) + if (m_isFixedSize == false && pointLocation < m_dataArray.size()) { // deleting the points automationModel - delAutomationModel(m_dataArray[locationIn].m_automationModel, true); + delAutomationModel(m_dataArray[pointLocation].m_automationModel, true); // swaping the point to the last location // in m_dataArray - swap(locationIn, m_dataArray.size() - 1, true); + swap(pointLocation, m_dataArray.size() - 1, true); m_dataArray.pop_back(); - if (locationIn == 0 || locationIn == m_dataArray.size()) + if (pointLocation == 0 || pointLocation == m_dataArray.size()) { formatDataArrayEndPoints(); } @@ -2350,32 +2350,32 @@ void VectorGraphDataArray::del(unsigned int locationIn) } } -void VectorGraphDataArray::formatArray(std::vector>* dataArrayIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) +void VectorGraphDataArray::formatArray(std::vector>* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { - if (rescaleIn == true) + if (shouldRescale == true) { // scale float minX = 0.0f; float maxX = 1.0f; float minY = -1.0f; float maxY = 1.0f; - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - if (dataArrayIn->operator[](i).first < minX) + if (dataArrayOut->operator[](i).first < minX) { - minX = dataArrayIn->operator[](i).first; + minX = dataArrayOut->operator[](i).first; } - if (dataArrayIn->operator[](i).first > maxX) + if (dataArrayOut->operator[](i).first > maxX) { - maxX = dataArrayIn->operator[](i).first; + maxX = dataArrayOut->operator[](i).first; } - if (dataArrayIn->operator[](i).second < minY) + if (dataArrayOut->operator[](i).second < minY) { - minY = dataArrayIn->operator[](i).second; + minY = dataArrayOut->operator[](i).second; } - if (dataArrayIn->operator[](i).second > maxY) + if (dataArrayOut->operator[](i).second > maxY) { - maxY = dataArrayIn->operator[](i).second; + maxY = dataArrayOut->operator[](i).second; } } //qDebug("formatArray 1: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); @@ -2386,48 +2386,48 @@ void VectorGraphDataArray::formatArray(std::vector>* dat //qDebug("formatArray 2: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); if (minX != 0.0f || maxX != 1.0f) { - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - dataArrayIn->operator[](i).first = (dataArrayIn->operator[](i).first + minX) / maxX; + dataArrayOut->operator[](i).first = (dataArrayOut->operator[](i).first + minX) / maxX; } } if (minY != -1.0f || maxY != 1.0f) { - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - dataArrayIn->operator[](i).second = (dataArrayIn->operator[](i).second + minY) / maxY - 1.0f; + dataArrayOut->operator[](i).second = (dataArrayOut->operator[](i).second + minY) / maxY - 1.0f; } } } - if (clampIn == true || rescaleIn == true) + if (shouldClamp == true || shouldRescale == true) { // clamp - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - if (dataArrayIn->operator[](i).first < 0.0f) + if (dataArrayOut->operator[](i).first < 0.0f) { - dataArrayIn->operator[](i).first = 0.0f; + dataArrayOut->operator[](i).first = 0.0f; } - if (dataArrayIn->operator[](i).first > 1.0f) + if (dataArrayOut->operator[](i).first > 1.0f) { - dataArrayIn->operator[](i).first = 1.0f; + dataArrayOut->operator[](i).first = 1.0f; } - if (dataArrayIn->operator[](i).second < -1.0f) + if (dataArrayOut->operator[](i).second < -1.0f) { - dataArrayIn->operator[](i).second = -1.0f; + dataArrayOut->operator[](i).second = -1.0f; } - if (dataArrayIn->operator[](i).second > 1.0f) + if (dataArrayOut->operator[](i).second > 1.0f) { - dataArrayIn->operator[](i).second = 1.0f; + dataArrayOut->operator[](i).second = 1.0f; } } formatDataArrayEndPoints(); } // sort - if (sortIn == true) + if (shouldSort == true) { - std::sort(dataArrayIn->begin(), dataArrayIn->end(), + std::sort(dataArrayOut->begin(), dataArrayOut->end(), [](std::pair a, std::pair b) { return a.first < b.first; @@ -2436,35 +2436,35 @@ void VectorGraphDataArray::formatArray(std::vector>* dat // delete duplicates float lastPos = -1.0f; - if (dataArrayIn->size() > 0) + if (dataArrayOut->size() > 0) { - lastPos = dataArrayIn->operator[](0).first; + lastPos = dataArrayOut->operator[](0).first; } - for (unsigned int i = 1; i < dataArrayIn->size(); i++) + for (unsigned int i = 1; i < dataArrayOut->size(); i++) { - if (dataArrayIn->operator[](i).first == lastPos) + if (dataArrayOut->operator[](i).first == lastPos) { del(i); } else { - lastPos = dataArrayIn->operator[](i).first; + lastPos = dataArrayOut->operator[](i).first; } } // calling clearedEvent is not needed // because all of the values can not be cleared here getUpdatingFromPoint(-1); - if (callDataChangedIn == true) + if (callDataChanged == true) { dataChanged(); } } -int VectorGraphDataArray::getLocation(float xIn) +int VectorGraphDataArray::getLocation(float searchX) { bool found = false; bool isBefore = false; - int location = getNearestLocation(xIn, &found, &isBefore); + int location = getNearestLocation(searchX, &found, &isBefore); if (found == false) { return -1; @@ -2472,7 +2472,7 @@ int VectorGraphDataArray::getLocation(float xIn) return location; } -int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* isBeforeOut) +int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut) { // modified binary search if (m_dataArray.size() > 0) @@ -2485,14 +2485,14 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is { mid = start + (end - start) / 2; //qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); - //qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, xIn); - if (m_dataArray[mid].m_x == xIn) + //qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, searchXIn); + if (m_dataArray[mid].m_x == searchXIn) { *foundOut = true; *isBeforeOut = false; return mid; } - else if (m_dataArray[mid].m_x < xIn) + else if (m_dataArray[mid].m_x < searchXIn) { start = mid + 1; } @@ -2503,33 +2503,33 @@ int VectorGraphDataArray::getNearestLocation(float xIn, bool* foundOut, bool* is } int outputDif = 0; mid = start + (end - start) / 2; - if (m_dataArray[mid].m_x > xIn && mid > 0) + if (m_dataArray[mid].m_x > searchXIn && mid > 0) { mid = mid - 1; } if (mid + 1 < m_dataArray.size() && - std::abs(m_dataArray[mid].m_x - xIn) > - std::abs(m_dataArray[mid + 1].m_x - xIn)) + std::abs(m_dataArray[mid].m_x - searchXIn) > + std::abs(m_dataArray[mid + 1].m_x - searchXIn)) { outputDif = 1; //*isBeforeOut = false; } //qDebug("getNearestLocation, outputDif: %d", outputDif); - *foundOut = xIn == m_dataArray[mid + outputDif].m_x; - *isBeforeOut = xIn >= m_dataArray[mid + outputDif].m_x; + *foundOut = searchXIn == m_dataArray[mid + outputDif].m_x; + *isBeforeOut = searchXIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } - //qDebug("getNearestLocation, xIn: %f", xIn); + //qDebug("getNearestLocation, searchXIn: %f", searchXIn); *foundOut = false; *isBeforeOut = false; return -1; } -void VectorGraphDataArray::getSamples(unsigned int countIn, std::vector* sampleBufferOut) +void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut) { qDebug("getSamplesA1"); m_parent->lockGetSamplesAccess(); - getSamples(countIn, nullptr, nullptr, sampleBufferOut); + getSamples(targetSizeIn, nullptr, nullptr, sampleBufferOut); m_parent->unlockGetSamplesAccess(); qDebug("getSamplesA3 finished"); } @@ -2560,10 +2560,10 @@ std::vector VectorGraphDataArray::getEffectorArrayLocations() } void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, - bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool sortIn, bool callDataChangedIn) + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { qDebug("setDataArray size: %ld", dataArrayIn->size()); - if (clearIn == true) + if (shouldClear == true) { m_dataArray.clear(); } @@ -2572,9 +2572,9 @@ void VectorGraphDataArray::setDataArray(std::vector>* da { clearedEvent(); } - if (clampIn == true || rescaleIn == true || sortIn == true) + if (shouldClamp == true || shouldRescale == true || shouldSort == true) { - formatArray(dataArrayIn, clampIn, rescaleIn, sortIn, false); + formatArray(dataArrayIn, shouldClamp, shouldRescale, shouldSort, false); } bool noneBefore = true; bool isNegativeBefore = false; @@ -2584,7 +2584,7 @@ void VectorGraphDataArray::setDataArray(std::vector>* da m_dataArray[i].m_x = dataArrayIn->operator[](i).first; m_dataArray[i].m_y = dataArrayIn->operator[](i).second; // calculating curves - if (isCurvedIn == true && i > 0) + if (shouldCurve == true && i > 0) { // TODO take in to account x coords float diff = m_dataArray[i - 1].m_y - m_dataArray[i].m_y; @@ -2611,13 +2611,13 @@ void VectorGraphDataArray::setDataArray(std::vector>* da } // the whole m_dataArray needs to be updated getUpdatingFromPoint(-1); - if (callDataChangedIn == true) + if (callDataChanged == true) { dataChanged(); } } void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, - bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { std::vector> convertedDataArray(dataArrayIn->size()); float stepSize = 1.0f / static_cast(convertedDataArray.size()); @@ -2626,10 +2626,10 @@ void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, convertedDataArray[i].first = i * stepSize; convertedDataArray[i].second = dataArrayIn->operator[](i); } - setDataArray(&convertedDataArray, isCurvedIn, clearIn, clampIn, rescaleIn, false, callDataChangedIn); + setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); } void VectorGraphDataArray::setDataArray(float* dataArrayIn, unsigned int sizeIn, - bool isCurvedIn, bool clearIn, bool clampIn, bool rescaleIn, bool callDataChangedIn) + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { std::vector> convertedDataArray(sizeIn); float stepSize = 1.0f / static_cast(sizeIn); @@ -2638,21 +2638,21 @@ void VectorGraphDataArray::setDataArray(float* dataArrayIn, unsigned int sizeIn, convertedDataArray[i].first = i * stepSize; convertedDataArray[i].second = dataArrayIn[i]; } - setDataArray(&convertedDataArray, isCurvedIn, clearIn, clampIn, rescaleIn, false, callDataChangedIn); + setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); } -unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) +unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) { - int location = locationIn; - if (m_isFixedX == false && xIn <= 1.0f) + int location = pointLocation; + if (m_isFixedX == false && newX <= 1.0f) { bool found = false; bool isBefore = false; - location = getNearestLocation(xIn, &found, &isBefore); - // if an other point was not found exactly at xIn + location = getNearestLocation(newX, &found, &isBefore); + // if an other point was not found exactly at newX // and if dataArray end points are changeable if (found == false && ((m_isFixedEndPoints == true && - locationIn < m_dataArray.size() - 1 && locationIn > 0) || + pointLocation < m_dataArray.size() - 1 && pointLocation > 0) || m_isFixedEndPoints == false)) { int targetLocation = location; @@ -2661,14 +2661,14 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) if (location >= 0) { qDebug("set 3. success, location: %d", targetLocation); - if (location < locationIn && isBefore == true) + if (location < pointLocation && isBefore == true) { if (targetLocation + 1 < m_dataArray.size()) { targetLocation++; } } - else if (location > locationIn && isBefore == false) + else if (location > pointLocation && isBefore == false) { if (targetLocation > 0) { @@ -2676,8 +2676,8 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) } } qDebug("set 4. success, target: %d", targetLocation); - m_dataArray[locationIn].m_x = xIn; - swap(locationIn, targetLocation, true); + m_dataArray[pointLocation].m_x = newX; + swap(pointLocation, targetLocation, true); location = targetLocation; getUpdatingFromPoint(-1); @@ -2691,31 +2691,31 @@ unsigned int VectorGraphDataArray::setX(unsigned int locationIn, float xIn) } else { - location = locationIn; + location = pointLocation; } } else { - location = locationIn; + location = pointLocation; } } return location; } -void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) +void VectorGraphDataArray::setY(unsigned int pointLocation, float newY) { if (m_isFixedY == false) { - m_dataArray[locationIn].m_y = yIn; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_y = newY; + getUpdatingFromPoint(pointLocation); // changes in the position can change lines before // so the point before this is updated - if (locationIn > 0) + if (pointLocation > 0) { - getUpdatingFromPoint(locationIn - 1); + getUpdatingFromPoint(pointLocation - 1); } if (m_isFixedEndPoints == true && - (locationIn <= 0 || locationIn >= m_dataArray.size() - 1)) + (pointLocation <= 0 || pointLocation >= m_dataArray.size() - 1)) { formatDataArrayEndPoints(); getUpdatingFromPoint(0); @@ -2725,53 +2725,53 @@ void VectorGraphDataArray::setY(unsigned int locationIn, float yIn) } } -void VectorGraphDataArray::setC(unsigned int locationIn, float cIn) +void VectorGraphDataArray::setC(unsigned int pointLocation, float newC) { if (m_isEditableAttrib == true) { - m_dataArray[locationIn].m_c = cIn; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_c = newC; + getUpdatingFromPoint(pointLocation); dataChanged(); } } -void VectorGraphDataArray::setValA(unsigned int locationIn, float valueIn) +void VectorGraphDataArray::setValA(unsigned int pointLocation, float fValue) { if (m_isEditableAttrib == true) { - m_dataArray[locationIn].m_valA = valueIn; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_valA = fValue; + getUpdatingFromPoint(pointLocation); dataChanged(); } } -void VectorGraphDataArray::setValB(unsigned int locationIn, float valueIn) +void VectorGraphDataArray::setValB(unsigned int pointLocation, float fValue) { if (m_isEditableAttrib == true) { - m_dataArray[locationIn].m_valB = valueIn; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_valB = fValue; + getUpdatingFromPoint(pointLocation); dataChanged(); } } -void VectorGraphDataArray::setType(unsigned int locationIn, unsigned int typeIn) +void VectorGraphDataArray::setType(unsigned int pointLocation, unsigned int newType) { if (m_isEditableAttrib == true) { // set the type without changing the automated attribute location - m_dataArray[locationIn].m_type = typeIn; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_type = newType; + getUpdatingFromPoint(pointLocation); dataChanged(); } } -void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned int attribLocationIn) +void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation) { if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; + attribLocation = attribLocation > 3 ? 0 : attribLocation; // set automated location correctly (effected_location = automatedEffectedLocation % 4) - m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn * 4 + getEffectedAttribLocation(locationIn); + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation * 4 + getEffectedAttribLocation(pointLocation); - getUpdatingFromPoint(locationIn); + getUpdatingFromPoint(pointLocation); // the line before this can get added later // in getUpdatingFromAutomation // so the point before this is not updated here @@ -2779,165 +2779,165 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int locationIn, unsigned dataChanged(); } } -void VectorGraphDataArray::setEffectedAttrib(unsigned int locationIn, unsigned int attribLocationIn) +void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation) { if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocationIn = attribLocationIn > 3 ? 0 : attribLocationIn; + attribLocation = attribLocation > 3 ? 0 : attribLocation; // set effected location correctly - m_dataArray[locationIn].m_automatedEffectedAttribLocations = attribLocationIn + getAutomatedAttribLocation(locationIn); + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation); - getUpdatingFromPoint(locationIn); + getUpdatingFromPoint(pointLocation); // if the current point can effect line before it // update the point before it - if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + if (getEffectOnlyPoints(pointLocation) == false && pointLocation > 0) { - getUpdatingFromPoint(locationIn - 1); + getUpdatingFromPoint(pointLocation - 1); } dataChanged(); } } -unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int locationIn) +unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int pointLocation) { - return m_dataArray[locationIn].m_automatedEffectedAttribLocations / 4; + return m_dataArray[pointLocation].m_automatedEffectedAttribLocations / 4; } -unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int locationIn) +unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int pointLocation) { - return m_dataArray[locationIn].m_automatedEffectedAttribLocations % 4; + return m_dataArray[pointLocation].m_automatedEffectedAttribLocations % 4; } -bool VectorGraphDataArray::getEffectOnlyPoints(unsigned int locationIn) +bool VectorGraphDataArray::getEffectOnlyPoints(unsigned int pointLocation) { - return (m_dataArray[locationIn].m_effectOnlyPoints == true || getEffectedAttribLocation(locationIn) > 0); + return (m_dataArray[pointLocation].m_effectOnlyPoints == true || getEffectedAttribLocation(pointLocation) > 0); } -void VectorGraphDataArray::setEffectOnlyPoints(unsigned int locationIn, bool boolIn) +void VectorGraphDataArray::setEffectOnlyPoints(unsigned int pointLocation, bool bValue) { if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { - if (m_dataArray[locationIn].m_effectOnlyPoints != boolIn) + if (m_dataArray[pointLocation].m_effectOnlyPoints != bValue) { // getEffectOnlyPoints does not return m_effecteOnlyPoints - bool dataChangedValue = getEffectOnlyPoints(locationIn); - m_dataArray[locationIn].m_effectOnlyPoints = boolIn; + bool dataChangedValue = getEffectOnlyPoints(pointLocation); + m_dataArray[pointLocation].m_effectOnlyPoints = bValue; // this change does effect the main output if this // data array is an effector of an other so dataChanged() // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectOnlyPoints(locationIn)) + if (dataChangedValue != getEffectOnlyPoints(pointLocation)) { - getUpdatingFromPoint(locationIn); + getUpdatingFromPoint(pointLocation); // if the current point can effect line before it // update the point before it - if (getEffectedAttribLocation(locationIn) <= 0&& locationIn > 0) + if (getEffectedAttribLocation(pointLocation) <= 0&& pointLocation > 0) { - getUpdatingFromPoint(locationIn - 1); + getUpdatingFromPoint(pointLocation - 1); } } dataChanged(); } } } -bool VectorGraphDataArray::getEffect(unsigned int locationIn, unsigned int effectNumberIn) +bool VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectId) { - switch (effectNumberIn) + switch (effectId) { case 0: - return m_dataArray[locationIn].m_effectAdd; + return m_dataArray[pointLocation].m_effectAdd; break; case 1: - return m_dataArray[locationIn].m_effectSubtract; + return m_dataArray[pointLocation].m_effectSubtract; break; case 2: - return m_dataArray[locationIn].m_effectMultiply; + return m_dataArray[pointLocation].m_effectMultiply; break; case 3: - return m_dataArray[locationIn].m_effectDivide; + return m_dataArray[pointLocation].m_effectDivide; break; case 4: - return m_dataArray[locationIn].m_effectPower; + return m_dataArray[pointLocation].m_effectPower; break; case 5: - return m_dataArray[locationIn].m_effectLog; + return m_dataArray[pointLocation].m_effectLog; break; case 6: - return m_dataArray[locationIn].m_effectSine; + return m_dataArray[pointLocation].m_effectSine; break; case 7: - return m_dataArray[locationIn].m_effectClampLower; + return m_dataArray[pointLocation].m_effectClampLower; break; case 8: - return m_dataArray[locationIn].m_effectClampUpper; + return m_dataArray[pointLocation].m_effectClampUpper; break; } return false; } -void VectorGraphDataArray::setEffect(unsigned int locationIn, unsigned int effectNumberIn, bool boolIn) +void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue) { if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { - switch (effectNumberIn) + switch (effectId) { case 0: - m_dataArray[locationIn].m_effectAdd = boolIn; + m_dataArray[pointLocation].m_effectAdd = bValue; break; case 1: - m_dataArray[locationIn].m_effectSubtract = boolIn; + m_dataArray[pointLocation].m_effectSubtract = bValue; break; case 2: - m_dataArray[locationIn].m_effectMultiply = boolIn; + m_dataArray[pointLocation].m_effectMultiply = bValue; break; case 3: - m_dataArray[locationIn].m_effectDivide = boolIn; + m_dataArray[pointLocation].m_effectDivide = bValue; break; case 4: - m_dataArray[locationIn].m_effectPower = boolIn; + m_dataArray[pointLocation].m_effectPower = bValue; break; case 5: - m_dataArray[locationIn].m_effectLog = boolIn; + m_dataArray[pointLocation].m_effectLog = bValue; break; case 6: - m_dataArray[locationIn].m_effectSine = boolIn; + m_dataArray[pointLocation].m_effectSine = bValue; break; case 7: - m_dataArray[locationIn].m_effectClampLower = boolIn; + m_dataArray[pointLocation].m_effectClampLower = bValue; break; case 8: - m_dataArray[locationIn].m_effectClampUpper = boolIn; + m_dataArray[pointLocation].m_effectClampUpper = bValue; break; } - getUpdatingFromPoint(locationIn); + getUpdatingFromPoint(pointLocation); // if the current point can effect line before it // update the point before it - if (getEffectOnlyPoints(locationIn) == false && locationIn > 0) + if (getEffectOnlyPoints(pointLocation) == false && pointLocation > 0) { - getUpdatingFromPoint(locationIn - 1); + getUpdatingFromPoint(pointLocation - 1); } dataChanged(); } } -bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int locationIn) +bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int pointLocation) { - if (getAutomationModel(locationIn) != nullptr && - m_dataArray[locationIn].m_bufferedAutomationValue != getAutomationModel(locationIn)->value()) + if (getAutomationModel(pointLocation) != nullptr && + m_dataArray[pointLocation].m_bufferedAutomationValue != getAutomationModel(pointLocation)->value()) { - m_dataArray[locationIn].m_bufferedAutomationValue = getAutomationModel(locationIn)->value(); + m_dataArray[pointLocation].m_bufferedAutomationValue = getAutomationModel(pointLocation)->value(); return true; } return false; } -void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomatedIn) +void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) { qDebug("setAutomated start"); if (m_isAutomatableEffectable == true) { - if (isAutomatedIn == true) + if (bValue == true) { qDebug("setAutomated make"); // if it is not already automated - if (m_dataArray[locationIn].m_automationModel == -1) + if (m_dataArray[pointLocation].m_automationModel == -1) { m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); - m_dataArray[locationIn].m_automationModel = m_automationModelArray.size() - 1; - getUpdatingFromPoint(locationIn); + m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; + getUpdatingFromPoint(pointLocation); dataChanged(); } } @@ -2947,16 +2947,16 @@ void VectorGraphDataArray::setAutomated(unsigned int locationIn, bool isAutomate // dataChanged() is called in this function // this function check if the current point has an automationModel - delAutomationModel(m_dataArray[locationIn].m_automationModel, true); + delAutomationModel(m_dataArray[pointLocation].m_automationModel, true); } } qDebug("setAutomated end"); } -FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int locationIn) +FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) { - if (m_dataArray[locationIn].m_automationModel != -1) + if (m_dataArray[pointLocation].m_automationModel != -1) { - return m_automationModelArray[m_dataArray[locationIn].m_automationModel]; + return m_automationModelArray[m_dataArray[pointLocation].m_automationModel]; } return nullptr; } @@ -3008,19 +3008,19 @@ QString VectorGraphDataArray::getSavedDataArray() m_dataArray.size() * sizeof(VectorGraphPoint), output); return output; } -void VectorGraphDataArray::loadDataArray(QString dataIn, unsigned int sizeIn) +void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize) { qDebug("loadDatatArray start"); int size = 0; char* dst = 0; - base64::decode(dataIn, &dst, &size); + base64::decode(data, &dst, &size); - if (size == sizeIn * sizeof(VectorGraphPoint)) + if (size == arraySize * sizeof(VectorGraphPoint)) { - m_dataArray.resize(sizeIn); + m_dataArray.resize(arraySize); VectorGraphPoint* points = (VectorGraphPoint*)dst; - for (unsigned int i = 0; i < sizeIn; i++) + for (unsigned int i = 0; i < arraySize; i++) { m_dataArray[i] = points[i]; } @@ -3031,14 +3031,14 @@ void VectorGraphDataArray::loadDataArray(QString dataIn, unsigned int sizeIn) } // private: -void VectorGraphDataArray::delAutomationModel(unsigned int modelLocationIn, bool callDataChangedIn) +void VectorGraphDataArray::delAutomationModel(unsigned int modelLocation, bool callDataChanged) { - if (modelLocationIn != -1) + if (modelLocation != -1) { - FloatModel* curModel = m_automationModelArray[modelLocationIn]; + FloatModel* curModel = m_automationModelArray[modelLocation]; // copy the last FloatModel* to the current location - m_automationModelArray[modelLocationIn] = + m_automationModelArray[modelLocation] = m_automationModelArray[m_automationModelArray.size() - 1]; m_automationModelArray.pop_back(); @@ -3049,14 +3049,14 @@ void VectorGraphDataArray::delAutomationModel(unsigned int modelLocationIn, bool // all of them are checked for (unsigned int i = 0; i < m_dataArray.size(); i++) { - if (m_dataArray[i].m_automationModel == modelLocationIn) + if (m_dataArray[i].m_automationModel == modelLocation) { m_dataArray[i].m_automationModel = -1; getUpdatingFromPoint(i); } if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) { - m_dataArray[i].m_automationModel = modelLocationIn; + m_dataArray[i].m_automationModel = modelLocation; } } if (curModel != nullptr) @@ -3065,21 +3065,21 @@ void VectorGraphDataArray::delAutomationModel(unsigned int modelLocationIn, bool curModel = nullptr; } - if (callDataChangedIn == true) + if (callDataChanged == true) { dataChanged(); } } } -void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationBIn, bool slide) +void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool slide) { - if (locationAIn != locationBIn) + if (pointLocationA != pointLocationB) { if (slide == true) { qDebug("swap: -------"); - qDebug("first.: %d, second.: %d", locationAIn, locationBIn); + qDebug("first.: %d, second.: %d", pointLocationA, pointLocationB); /* for (unsigned int i = 0; i < m_dataArray.size(); i++) @@ -3088,23 +3088,23 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB } */ - if (locationAIn < locationBIn) + if (pointLocationA < pointLocationB) { - VectorGraphPoint swap = m_dataArray[locationAIn]; - for (unsigned int i = locationAIn; i < locationBIn; i++) + VectorGraphPoint swap = m_dataArray[pointLocationA]; + for (unsigned int i = pointLocationA; i < pointLocationB; i++) { m_dataArray[i] = m_dataArray[i + 1]; } - m_dataArray[locationBIn] = swap; + m_dataArray[pointLocationB] = swap; } else { - VectorGraphPoint swap = m_dataArray[locationAIn]; - for (unsigned int i = locationAIn; i > locationBIn; i--) + VectorGraphPoint swap = m_dataArray[pointLocationA]; + for (unsigned int i = pointLocationA; i > pointLocationB; i--) { m_dataArray[i] = m_dataArray[i - 1]; } - m_dataArray[locationBIn] = swap; + m_dataArray[pointLocationB] = swap; } /* @@ -3118,94 +3118,93 @@ void VectorGraphDataArray::swap(unsigned int locationAIn, unsigned int locationB else { // normal swap - VectorGraphPoint swap = m_dataArray[locationAIn]; - m_dataArray[locationAIn] = m_dataArray[locationBIn]; - m_dataArray[locationBIn] = swap; - } - getUpdatingFromPoint(locationBIn - 1 > 0 ? locationBIn - 1 : 0); - getUpdatingFromPoint(locationAIn - 1 > 0 ? locationAIn - 1 : 0); - getUpdatingFromPoint(locationAIn); - getUpdatingFromPoint(locationBIn); + VectorGraphPoint swap = m_dataArray[pointLocationA]; + m_dataArray[pointLocationA] = m_dataArray[pointLocationB]; + m_dataArray[pointLocationB] = swap; + } + getUpdatingFromPoint(pointLocationB - 1 > 0 ? pointLocationB - 1 : 0); + getUpdatingFromPoint(pointLocationA - 1 > 0 ? pointLocationA - 1 : 0); + getUpdatingFromPoint(pointLocationA); + getUpdatingFromPoint(pointLocationB); dataChanged(); } } -float VectorGraphDataArray::processCurve(float valueBeforeIn, float valueAfterIn, float curveIn, float xIn) +float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float xIn) { // calculating line curve - float absCurveIn = std::abs(curveIn); - float pow = curveIn < 0.0f ? 1.0f - xIn : xIn; + float absCurveIn = std::abs(curve); + float pow = curve < 0.0f ? 1.0f - xIn : xIn; pow = std::pow(pow, 1.0f - absCurveIn) - pow; - float output = valueBeforeIn + (valueAfterIn - valueBeforeIn) * xIn; - output = curveIn > 0.0f ? output + pow * (valueAfterIn - valueBeforeIn) : output - pow * (valueAfterIn - valueBeforeIn); + float output = yBefore + (yAfter - yBefore) * xIn; + output = curve > 0.0f ? output + pow * (yAfter - yBefore) : output - pow * (yAfter - yBefore); // clamp - if (valueBeforeIn > valueAfterIn) + if (yBefore > yAfter) { - output = std::clamp(output, valueAfterIn, valueBeforeIn); + output = std::clamp(output, yAfter, yBefore); } else { - output = std::clamp(output, valueBeforeIn, valueAfterIn); + output = std::clamp(output, yBefore, yAfter); } return output; } -float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribValueIn, - unsigned int attribLocationIn, float effectValueIn) +float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attribValue, + unsigned int attribLocation, float effectValue) { - // calculating an effect on attribValueIn - float output = attribValueIn; - unsigned int attribLocation = getEffectedAttribLocation(locationIn); + // calculating an effect on attribValue + float output = attribValue; // effects - if (attribLocationIn == attribLocation) + if (getEffectedAttribLocation(pointLocation) == attribLocation) { - if (getEffect(locationIn, 6) == true) + if (getEffect(pointLocation, 6) == true) { // sine - output = output + std::sin(effectValueIn * 100.0f); + output = output + std::sin(effectValue * 100.0f); } - if (getEffect(locationIn, 4) == true && output > 0.0f) + if (getEffect(pointLocation, 4) == true && output > 0.0f) { // power - output = std::pow(output, effectValueIn); + output = std::pow(output, effectValue); } - else if (getEffect(locationIn, 5) == true && output > 0.0f && effectValueIn != 0.0f) + else if (getEffect(pointLocation, 5) == true && output > 0.0f && effectValue != 0.0f) { // log - output = std::log(output) / std::log(effectValueIn); + output = std::log(output) / std::log(effectValue); } - if (getEffect(locationIn, 2) == true) + if (getEffect(pointLocation, 2) == true) { // multiply - output = output * 5.0f * effectValueIn; + output = output * 5.0f * effectValue; } - else if (getEffect(locationIn, 3) == true && effectValueIn != 0.0f) + else if (getEffect(pointLocation, 3) == true && effectValue != 0.0f) { // divide - output = output / 5.0f / effectValueIn; + output = output / 5.0f / effectValue; } - if (getEffect(locationIn, 0) == true) + if (getEffect(pointLocation, 0) == true) { // add - output += effectValueIn; + output += effectValue; } - else if (getEffect(locationIn, 1) == true) + else if (getEffect(pointLocation, 1) == true) { // subtract - output -= effectValueIn; + output -= effectValue; } - if (getEffect(locationIn, 7) == true) + if (getEffect(pointLocation, 7) == true) { // clamp lower - output = std::max(effectValueIn, output); + output = std::max(effectValue, output); } - else if (getEffect(locationIn, 8) == true) + else if (getEffect(pointLocation, 8) == true) { // clamp upper - output = std::min(effectValueIn, output); + output = std::min(effectValue, output); } // clamp @@ -3213,21 +3212,20 @@ float VectorGraphDataArray::processEffect(unsigned int locationIn, float attribV } return output; } -float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int locationIn, unsigned int attribLocationIn) +float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation) { - // adding the automation value to attribValueIn + // adding the automation value to attribValue float output = 0.0f; // if automated - FloatModel* automationModel = getAutomationModel(locationIn); + FloatModel* automationModel = getAutomationModel(pointLocation); if (automationModel != nullptr) { - unsigned int attribLocation = getAutomatedAttribLocation(locationIn); - if (attribLocation == attribLocationIn) + if (getAutomatedAttribLocation(pointLocation) == attribLocation) { output += automationModel->value(); } } - output += attribValueIn; + output += attribValue; output = std::clamp(output, -1.0f, 1.0f); return output; @@ -3235,53 +3233,53 @@ float VectorGraphDataArray::processAutomation(float attribValueIn, unsigned int // line type effects: /* -float VectorGraphDataArray::processLineTypeSine(float xIn, float valAIn, float valBIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeSine(float xIn, float valA, float valB, float fadeInStartLoc) { - return processLineTypeSineB(xIn, valAIn, valBIn, 0.0f, fadeInStartIn); + return processLineTypeSineB(xIn, valA, valB, 0.0f, fadeInStartLoc); } */ -// valA: amp, valB: freq, fadeInStartIn: from what xIn value should the line type fade out -std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float fadeInStartIn) +// valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out +std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float fadeInStartLoc) { - return VectorGraphDataArray::processLineTypeArraySineB(xIn, startIn, endIn, - valAIn, valBIn, 0.0f, fadeInStartIn); + return VectorGraphDataArray::processLineTypeArraySineB(xArray, startLoc, endLoc, + valA, valB, 0.0f, fadeInStartLoc); } /* -float VectorGraphDataArray::processLineTypeSineB(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeSineB(float xIn, float valA, float valB, float curve, float fadeInStartLoc) { // sine // 628.318530718f = 100.0f * 2.0f * pi - float output = valAIn * std::sin(xIn * 628.318530718f * valBIn + curveIn * 100.0f); + float output = valA * std::sin(xIn * 628.318530718f * valB + curve * 100.0f); // fade in - if (xIn < fadeInStartIn) + if (xIn < fadeInStartLoc) { - output = output * xIn / fadeInStartIn; + output = output * xIn / fadeInStartLoc; } // fade out - if (xIn > 1.0f - fadeInStartIn) + if (xIn > 1.0f - fadeInStartLoc) { - output = output * (1.0f - xIn) / fadeInStartIn; + output = output * (1.0f - xIn) / fadeInStartLoc; } return output; } */ -// valA: amp, valB: freq, curveIn: phase -std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn) +// valA: amp, valB: freq, curve: phase +std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc) { - int count = static_cast(endIn) - static_cast(startIn); + int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } - float valB = 0.001f + ((valBIn + 1.0f) / 2.0f) * 0.999f; + float tValB = 0.001f + ((valB + 1.0f) / 2.0f) * 0.999f; std::vector output(count); // calculating how many samples are needed to 1 complete wave - // we have "count" amount of samples and "valB * 100.0f" amount of waves - int end = static_cast(std::floor(count / (valB * 100.0f))); - //qDebug("sineB_1, %f, %d", (count / (valB * 100.0f)), end); + // we have "count" amount of samples and "tValB * 100.0f" amount of waves + int end = static_cast(std::floor(count / (tValB * 100.0f))); + //qDebug("sineB_1, %f, %d", (count / (tValB * 100.0f)), end); if (count <= 0) { end = 0; @@ -3295,9 +3293,9 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vectoroperator[](startIn + i) * 628.318531f * valB + curveIn * 100.0f); + // (1 sine wave is 2pi long and we have 1 * 100 * valB waves) + output[i] = valA * std::sin( + xArray->operator[](startLoc + i) * 628.318531f * tValB + curve * 100.0f); } //qDebug("sineB_2"); // copy the first wave until the end @@ -3310,52 +3308,52 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vectoroperator[](startIn + i); - if (x > fadeInStartIn) + float x = xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } //qDebug("sineB_4"); // fade out for (unsigned int i = count - 1; i >= 0; i--) { - float x = 1.0f - xIn->operator[](startIn + i); - if (x > fadeInStartIn) + float x = 1.0f - xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } //qDebug("sineB_5"); return output; } /* -float VectorGraphDataArray::processLineTypePeak(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypePeak(float xIn, float valA, float valB, float curve, float fadeInStartLoc) { // peak - float output = std::pow((curveIn + 1.0f) * 0.2f + 0.01f, std::abs(xIn - (valBIn + 1.0f) * 0.5f) * 10.0f) * valAIn; + float output = std::pow((curve + 1.0f) * 0.2f + 0.01f, std::abs(xIn - (valB + 1.0f) * 0.5f) * 10.0f) * valA; // fade in - if (xIn < fadeInStartIn) + if (xIn < fadeInStartLoc) { - output = output * xIn / fadeInStartIn; + output = output * xIn / fadeInStartLoc; } // fade out - if (xIn > 1.0f - fadeInStartIn) + if (xIn > 1.0f - fadeInStartLoc) { - output = output * (1.0f - xIn) / fadeInStartIn; + output = output * (1.0f - xIn) / fadeInStartLoc; } return output; } */ // valA: amp, valB: x coord, curve: width -std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn) +std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc) { - int count = static_cast(endIn) - static_cast(startIn); + int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; @@ -3363,97 +3361,97 @@ std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector output(count); for (unsigned int i = 0; i < count; i++) { - output[i] = std::pow((curveIn + 1.0f) * 0.2f + 0.01f, - std::abs(xIn->operator[](startIn + i) - (valBIn + 1.0f) * 0.5f) * 10.0f) * valAIn; + output[i] = std::pow((curve + 1.0f) * 0.2f + 0.01f, + std::abs(xArray->operator[](startLoc + i) - (valB + 1.0f) * 0.5f) * 10.0f) * valA; } // fade in for (unsigned int i = 0; i < count; i++) { - float x = xIn->operator[](startIn + i); - if (x > fadeInStartIn) + float x = xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } // fade out for (unsigned int i = count - 1; i >= 0; i--) { - float x = 1.0f - xIn->operator[](startIn + i); - if (x > fadeInStartIn) + float x = 1.0f - xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } return output; } /* -float VectorGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valAIn, float valBIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeSteps(float xIn, float yIn, float valA, float valB, float fadeInStartLoc) { } */ // y: calculate steps from, valA: y count, valB: curve -std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xIn, unsigned int startIn, unsigned int endIn, - std::vector* yIn, float valAIn, float valBIn, float fadeInStartIn) +std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + std::vector* yArray, float valA, float valB, float fadeInStartLoc) { - int count = static_cast(endIn) - static_cast(startIn); + int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } std::vector output(count); - float stepCount = (1.0f + valAIn) / 2.0f * 19.0f + 1.0f; + float stepCount = (1.0f + valA) / 2.0f * 19.0f + 1.0f; //qDebug("stepsA - stepCount = %f", stepCount); for (unsigned int i = 0; i < count; i++) { - float y = yIn->operator[](startIn + i) + 1.0f; + float y = yArray->operator[](startLoc + i) + 1.0f; float diff = std::round(y * stepCount) - y * stepCount; - float smooth = 1.0f - std::abs(diff) * (1.0f - (valBIn + 1.0f) / 2.0f) * 2.0f; + float smooth = 1.0f - std::abs(diff) * (1.0f - (valB + 1.0f) / 2.0f) * 2.0f; output[i] = diff / stepCount * smooth; } // fade in for (unsigned int i = 0; i < count; i++) { - float x = xIn->operator[](startIn + i); - if (x > fadeInStartIn) + float x = xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } // fade out for (unsigned int i = count - 1; i >= 0; i--) { - float x = 1.0f - xIn->operator[](startIn + i); - if (x > fadeInStartIn) + float x = 1.0f - xArray->operator[](startLoc + i); + if (x > fadeInStartLoc) { break; } - output[i] = output[i] * x / fadeInStartIn; + output[i] = output[i] * x / fadeInStartLoc; } return output; } /* -float VectorGraphDataArray::processLineTypeRandom(float xIn, float valAIn, float valBIn, float curveIn, float fadeInStartIn) +float VectorGraphDataArray::processLineTypeRandom(float xIn, float valA, float valB, float curve, float fadeInStartLoc) { } */ -// valA: amp, valB: random number count, curveIn: seed -std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xIn, unsigned int startIn, unsigned int endIn, - float valAIn, float valBIn, float curveIn, float fadeInStartIn) +// valA: amp, valB: random number count, curve: seed +std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float valA, float valB, float curve, float fadeInStartLoc) { - int count = static_cast(endIn) - static_cast(startIn); + int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } std::vector output(count); - std::vector randomValues(static_cast(50.0f * (valBIn + 1.0f)) * 2); + std::vector randomValues(static_cast(50.0f * (valB + 1.0f)) * 2); - float blend = 10.0f + curveIn * 10.0f; + float blend = 10.0f + curve * 10.0f; int randomSeed = static_cast(blend); blend = blend - randomSeed; std::srand(randomSeed); @@ -3477,40 +3475,39 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< float size = static_cast(randomValues.size() / 2); for (unsigned int i = 0; i < count; i++) { - float randomValueX = xIn->operator[](startIn + i) * size; + float randomValueX = xArray->operator[](startLoc + i) * size; float randomValueLocation = std::floor(randomValueX); output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * - valAIn; + (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * valA; } } return output; } -void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingValuesIn) +void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) { VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); - for (unsigned int i = 0; i < updatingValuesIn->size(); i++) + for (unsigned int i = 0; i < updatingPointLocations->size(); i++) { - // since updatingValuesIn is a sorted list, we can get the end + // since updatingPointLocations is a sorted list, we can get the end // location and update everithing between them // starting effector location is i, end effector location is updatingEnd unsigned int updatingEnd = i; - for (unsigned int j = i + 1; j < updatingValuesIn->size(); j++) + for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) { // we can not skip gaps because - // every updatingValuesIn point effects their line only + // every updatingPointLocations point effects their line only // (the line that starts with the point) - if (updatingValuesIn->operator[](updatingEnd) + 1 >= - updatingValuesIn->operator[](j)) + if (updatingPointLocations->operator[](updatingEnd) + 1 >= + updatingPointLocations->operator[](j)) { updatingEnd = j; qDebug("getUpdatingFromEffector new updatingEnd: %d, i: %d", updatingEnd, i); } else { - qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, (updatingValuesIn->operator[](updatingEnd) + 1), updatingValuesIn->operator[](j), j); + qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, (updatingPointLocations->operator[](updatingEnd) + 1), updatingPointLocations->operator[](j), j); break; } } @@ -3525,7 +3522,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // translating the effector data array locations to m_dataArray locations bool found = false; bool isBefore = false; - int locationBefore = getNearestLocation(effector->getX(updatingValuesIn->operator[](i)), &found, &isBefore); + int locationBefore = getNearestLocation(effector->getX(updatingPointLocations->operator[](i)), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); if (isBefore == false && locationBefore >= 0 && getEffectOnlyPoints(locationBefore) == true) { @@ -3541,8 +3538,8 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - int locationAfter = getNearestLocation(effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); - qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX(updatingValuesIn->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); + int locationAfter = getNearestLocation(effector->getX(updatingPointLocations->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); + qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX(updatingPointLocations->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); if (isBefore == false) { qDebug("getUpdatingFromEffector locationAfter = %d - 1", locationAfter); @@ -3550,14 +3547,14 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationAfter--; } // updating everything before if i -> 0 - if (updatingValuesIn->operator[](i) == 0) + if (updatingPointLocations->operator[](i) == 0) { qDebug("getUpdatingFromEffector updating everything before"); locationBefore = 0; } // if updatingEnd is the last point in effecor, then // update everithing after - if (updatingValuesIn->operator[](updatingEnd) + updatingEndSlide + 1 >= effector->size()) + if (updatingPointLocations->operator[](updatingEnd) + updatingEndSlide + 1 >= effector->size()) { qDebug("getUpdatingFromEffector updating everything after"); locationAfter = m_dataArray.size() - 1; @@ -3582,19 +3579,19 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up } } } -void VectorGraphDataArray::getUpdatingFromPoint(int locationIn) +void VectorGraphDataArray::getUpdatingFromPoint(int pointLocation) { // changes in position need to cause updates before the changed point // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) - if (m_isDataChanged == false && locationIn >= 0) + if (m_isDataChanged == false && pointLocation >= 0) { - m_needsUpdating.push_back(locationIn); + m_needsUpdating.push_back(pointLocation); if (m_needsUpdating.size() > m_dataArray.size() * 3) { m_isDataChanged = true; } } - else if (locationIn < 0) + else if (pointLocation < 0) { m_isDataChanged = true; } @@ -3679,21 +3676,21 @@ void VectorGraphDataArray::getUpdatingOriginals() } */ } -void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) +void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); std::vector effectorUpdatingValues; std::vector effectorOutput; - std::vector outputXLocations(countIn); + std::vector outputXLocations(targetSizeIn); bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { - m_parent->getDataArray(m_effectorLocation)->getSamples(countIn, &effectorIsChanged, &effectorUpdatingValues, &effectorOutput); + m_parent->getDataArray(m_effectorLocation)->getSamples(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, &effectorOutput); } qDebug("getSamplesB1, size: %ld - id: %d", outputXLocations.size(), m_id); - m_isDataChanged = m_isDataChanged || countIn != m_updatingBakedSamples.size(); + m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); // deciding if the whole dataArray should be updated // if the whole effectorDataArray was updated @@ -3711,7 +3708,7 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, } // updating m_needsUpdating - if (m_isDataChanged == false && countIn == m_updatingBakedSamples.size()) + if (m_isDataChanged == false && targetSizeIn == m_updatingBakedSamples.size()) { if (isEffected == true && effectorUpdatingValues.size() > 0 && (effectorIsChanged == false || effectedCount > 0)) @@ -3730,14 +3727,14 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, else { m_parent->lockBakedSamplesAccess(); - if (countIn != m_bakedSamples.size()) + if (targetSizeIn != m_bakedSamples.size()) { - m_bakedSamples.resize(countIn); + m_bakedSamples.resize(targetSizeIn); } m_parent->unlockBakedSamplesAccess(); - if (countIn != m_updatingBakedSamples.size()) + if (targetSizeIn != m_updatingBakedSamples.size()) { - m_updatingBakedSamples.resize(countIn); + m_updatingBakedSamples.resize(targetSizeIn); } m_needsUpdating.resize(m_dataArray.size()); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) @@ -3747,13 +3744,13 @@ void VectorGraphDataArray::getSamples(unsigned int countIn, bool* isChangedOut, qDebug("getSamplesB4, needsUpdating size: %ld", m_needsUpdating.size()); } - float stepSize = 1.0f / static_cast(countIn); + float stepSize = 1.0f / static_cast(targetSizeIn); // calculating point data and lines if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) { - if (effectorOutput.size() != countIn) + if (effectorOutput.size() != targetSizeIn) { - effectorOutput.resize(countIn); + effectorOutput.resize(targetSizeIn); } // calculating relative X locations (in lines) of the output values @@ -3886,23 +3883,23 @@ qDebug("getSamplesC5.3, [%d] set after to: %d", i, curLocation); } } */ -void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorIn, std::vector* effectorOutputIn, - std::vector* outputXLocationsIn, unsigned int iIn, float stepSizeIn) +void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, + std::vector* outputXLocations, unsigned int iIn, float stepSize) { qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSizeIn)); - qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorOutputIn->size()); + (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSize)); + qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorSamples->size()); // current effector output Y near m_needsUpdating[iIn] point - float curEffectY = effectorOutputIn->operator[](effectYLocation); - float nextEffectY = effectorOutputIn->operator[](effectYLocation); + float curEffectY = effectorSamples->operator[](effectYLocation); + float nextEffectY = effectorSamples->operator[](effectYLocation); // getting the final automatable / effectable point values - float curY = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_y, m_needsUpdating[iIn], 0); - float curC = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_c, m_needsUpdating[iIn], 1); - float curValA = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valA, m_needsUpdating[iIn], 2); - float curValB = processAutomation(m_dataArray[m_needsUpdating[iIn]].m_valB, m_needsUpdating[iIn], 3); - if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) + float curY = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_y, 0); + float curC = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_c, 1); + float curValA = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_valA, 2); + float curValB = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_valB, 3); + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) { curY = processEffect(m_needsUpdating[iIn], curY, 0, curEffectY); curC = processEffect(m_needsUpdating[iIn], curC, 1, curEffectY); @@ -3918,19 +3915,19 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effectorI if (m_needsUpdating[iIn] + 1 < m_dataArray.size()) { effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSizeIn)); + (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSize)); // where updating line ends (+1) end = effectYLocation; - nextY = processAutomation(m_dataArray[m_needsUpdating[iIn] + 1].m_y, m_needsUpdating[iIn] + 1, 0); + nextY = processAutomation(m_needsUpdating[iIn] + 1, m_dataArray[m_needsUpdating[iIn] + 1].m_y, 0); // if the current point can only be effected (and not its line) // and the next point can only be effected - // this is done to avoid adding effectorOutputIn to the line and to the next point (line's end point) at the same time - if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn] + 1) == true && + // this is done to avoid adding effectorSamples to the line and to the next point (line's end point) at the same time + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn] + 1) == true && ((getEffectOnlyPoints(m_needsUpdating[iIn]) == true && isEffectedPoint(m_needsUpdating[iIn]) == true) || isEffectedPoint(m_needsUpdating[iIn]) == false)) { - nextEffectY = effectorOutputIn->operator[](effectYLocation); + nextEffectY = effectorSamples->operator[](effectYLocation); nextY = processEffect(m_needsUpdating[iIn] + 1, nextY, 0, nextEffectY); } } @@ -3962,7 +3959,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // calculate curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); } // no line type } @@ -3971,10 +3968,10 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySine(outputXLocationsIn, start, end, curValA, curValB, fadeInStart); + std::vector lineTypeOutput = processLineTypeArraySine(outputXLocations, start, end, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; @@ -3985,10 +3982,10 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; @@ -3999,10 +3996,10 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; @@ -4013,10 +4010,10 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocationsIn, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); + std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); for (int j = start; j < end; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; @@ -4027,16 +4024,16 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocationsIn->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocationsIn, start, end, curValA, curValB, curC, fadeInStart); + std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); for (int j = start; j < end; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } - if (effectorIn != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) { int startB = m_needsUpdating[iIn] == 0 ? 0 : start; int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; @@ -4045,7 +4042,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % qDebug("getSamples run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { - m_updatingBakedSamples[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedSamples[j], 0, effectorOutputIn->operator[](j)); + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedSamples[j], 0, effectorSamples->operator[](j)); } } // clamp @@ -4071,14 +4068,14 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % } } -bool VectorGraphDataArray::isEffectedPoint(unsigned int locationIn) +bool VectorGraphDataArray::isEffectedPoint(unsigned int pointLocation) { // loops througth all the effects // return true when 1 or more effects are active bool output = false; for (unsigned int i = 0; i <= 8; i++) { - if (getEffect(locationIn, i) == true) + if (getEffect(pointLocation, i) == true) { output = true; break; From da1c8de866064473ea7739f4f00e2c66ee76ac82 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:51:11 +0200 Subject: [PATCH 098/184] WaveShaper_removed_example_functions --- plugins/WaveShaper/WaveShaperControls.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 98c5da6df84..bc39024270b 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -50,10 +50,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphSampleBuffer(200) { unsigned int arrayLocation = m_vectorGraphModel.addArray(); - //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedSize(true); - //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedX(true); - //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedY(true); - //m_vectorGraphModel.getDataArray(arrayLocation)->setIsFixedEndPoints(true); + // see other settings avalible for VectorGraphDataArray in VectorGraph.h m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); From f44f9265e59615cea5a399c0ac4705f468559a2a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 21 Apr 2024 10:50:56 +0200 Subject: [PATCH 099/184] VectorGraph_log_effect_limited --- src/gui/widgets/VectorGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index bfce14373d5..634888e1a09 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3168,7 +3168,7 @@ float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attr // power output = std::pow(output, effectValue); } - else if (getEffect(pointLocation, 5) == true && output > 0.0f && effectValue != 0.0f) + else if (getEffect(pointLocation, 5) == true && output > 0.0f && effectValue > 0.0f) { // log output = std::log(output) / std::log(effectValue); From ab64838e51871ad0d181f8ca04277f7dfa8baded Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 10:04:11 +0200 Subject: [PATCH 100/184] VectorGraph_gui_text_vector_replaced_with_array --- include/VectorGraph.h | 27 ++++++++++++++++++++++--- src/gui/widgets/VectorGraph.cpp | 36 ++++++++------------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index acbcaac3b85..f6c53d5019a 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -26,6 +26,7 @@ #define LMMS_GUI_VECTORGRAPH_H #include +#include #include #include #include @@ -210,9 +211,29 @@ protected slots: unsigned int m_controlDisplayCount; unsigned int m_controlDisplayPage; bool m_isEditingActive; - std::vector m_controlText; - std::vector m_controlLineEffectText; - std::vector m_controlIsFloat; + std::array m_controlText = + { + tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), + tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), + tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), + tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), + tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") + }; + std::array m_controlLineEffectText = { + tr("none"), + tr("sine"), + tr("phase changable sine"), + tr("peak"), + tr("steps"), + tr("random") + }; + std::array m_controlIsFloat = { + true, true, true, true, + true, false, false, + false, false, false, false, + false, false, false, false, + false, false, false + }; std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 634888e1a09..147b60fa659 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -22,11 +22,13 @@ * */ +#include "VectorGraph.h" + #include +#include #include // sine #include // sort #include // rand -#include // unintptr_t #include #include #include @@ -35,7 +37,6 @@ #include // locking when getSamples -#include "VectorGraph.h" #include "StringPairDrag.h" #include "CaptionMenu.h" // context menu #include "embed.h" // context menu @@ -66,7 +67,7 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widthIn, int heightIn, un m_pointSize = pointSize; // gets set in style - //m_fontSize = 12; + //m_fontSize = 12; // set in css m_isSimplified = false; m_isDefaultColorsApplyed = false; //m_background; @@ -83,28 +84,10 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widthIn, int heightIn, un m_controlDisplayCount = controlDisplayCount; m_controlDisplayPage = 0; m_isEditingActive = false; - m_controlText = { - tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), - tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), - tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), - tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), - tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") - }; - m_controlLineEffectText = { - tr("none"), - tr("sine"), - tr("phase changable sine"), - tr("peak"), - tr("steps"), - tr("random") - }; - m_controlIsFloat = { - true, true, true, true, - true, false, false, - false, false, false, false, - false, false, false, false, - false, false, false - }; + // set in .h + //m_controlText + //m_controlLineEffectText + //m_controlIsFloat m_lastTrackPoint.first = -1; m_lastTrackPoint.second = 0; @@ -127,9 +110,6 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widthIn, int heightIn, un VectorGraphView::~VectorGraphView() { qDebug("VectorGraphView dstc"); - m_controlText.clear(); - m_controlIsFloat.clear(); - m_controlLineEffectText.clear(); qDebug("VectorGraphView dstc end"); } From 61a1c4c1eb6dc281bc5fe844df4110a3c3856d7a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 11:00:06 +0200 Subject: [PATCH 101/184] VectorGraph_rewrote_comments --- include/VectorGraph.h | 69 ++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index f6c53d5019a..0a9de596775 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -197,7 +197,7 @@ protected slots: // if m_isLastSelectedArray == true then // m_selectedArray can be used // else if m_isSelected == false then - // m_selectedLocation amd m_selectedArray should not be used + // m_selectedLocation and m_selectedArray should not be used unsigned int m_selectedLocation; unsigned int m_selectedArray; bool m_isSelected; @@ -389,16 +389,19 @@ class LMMS_EXPORT VectorGraphDataArray // array: ------------------- - // returns the location of added/found point, -1 if not found or can not be added + // checks m_isFixedSize (== false) and m_maxLength + // returns the location of added point, -1 if not found or can not be added + // returns the location of found point if there is a point already at newX int add(float newX); - // deletes the point in pointLocation location if m_isFixedSize is disabled + // checks m_isFixedSize (== false) + // deletes the point in pointLocation location void del(unsigned int pointLocation); // clears m_dataArray without any checks inline void clear() { m_dataArray.clear(); m_needsUpdating.clear(); - // m_automationModelArray sould not be cleared without destruction + // m_automationModelArray should not be cleared without FloatModel destruction clearedEvent(); getUpdatingFromPoint(-1); dataChanged(); @@ -408,7 +411,7 @@ class LMMS_EXPORT VectorGraphDataArray return m_dataArray.size(); } // clamps down the values to 0 - 1, -1 - 1 - // sorts array, removes duplicated positions, calls dataChanged() if callDataChanged + // sorts array, removes duplicated x positions, calls dataChanged() if callDataChanged // clamp: should clamp, sort: should sort void formatArray(std::vector>* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); @@ -485,27 +488,40 @@ class LMMS_EXPORT VectorGraphDataArray // set attribute: ------------------- - // sets position when m_isFixedX is disabled, returns final location + // checks m_isFixedX (== false) + // sets x position, returns final location + // returns the location of found point if there is a point already at newX unsigned int setX(unsigned int pointLocation, float newX); - // sets value when m_isFixedY is disabled + // checks m_isFixedY (== false) + // sets y position void setY(unsigned int pointLocation, float newY); - // sets value when m_isEditableAttrib is enabled + // checks m_isEditableAttrib + // sets curve void setC(unsigned int pointLocation, float newC); - // sets value when m_isEditableAttrib is enabled + // checks m_isEditableAttrib + // sets 1. attribute value void setValA(unsigned int pointLocation, float fValue); - // sets value when m_isEditableAttrib is enabled + // checks m_isEditableAttrib + // sets 2. attribute value void setValB(unsigned int pointLocation, float fValue); - // sets value when m_isEditableAttrib is enabled + // checks m_isEditableAttrib + // sets line type void setType(unsigned int pointLocation, unsigned int newType); - // sets what attribute gets automated when m_isEditableAttrib and m_isAutomatableEffectable is enabled + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets what attribute gets automated (by point's FloatModel) void setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation); - // sets what attribute gets effected when m_isEditableAttrib and m_isAutomatableEffectable is enabled + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets what attribute gets effected (by effector array) void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // if bValue is true then the effector array will not effect the line's individual samples void setEffectOnlyPoints(unsigned int pointLocation, bool bValue); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets the point's effect type void setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue); + // checks m_isAutomatableEffectable // if bValue is true then make a new FloatModel and connect it, else delete // the currently used FloatModel - // runs if m_isAutomatableEffectable is enabled void setAutomated(unsigned int pointLocation, bool bValue); @@ -521,7 +537,9 @@ class LMMS_EXPORT VectorGraphDataArray // delete automationModels in m_automationModelArray // that are not used by points (there should be 0 cases like this) void delUnusedAutomation(); + // encodes m_dataArray to QString QString getSavedDataArray(); + // decodes and sets m_dataArray from QString void loadDataArray(QString data, unsigned int arraySize); private: class VectorGraphPoint @@ -630,12 +648,13 @@ class LMMS_EXPORT VectorGraphDataArray void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool slide); // returns the curve value at a given x coord, does clamp float processCurve(float yBefore, float yAfter, float curve, float xIn); - // applys the effect on a given value, does clamp + // returns effected attribute value from base attribValue (input attribute value), does clamp + // this function applies the point Effects (like m_effectAdd) based on attribValue and effectValue float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); - // returns a VectorGraphPoint with modified attributes, does clamp + // returns automated attribute value from base attribValue (input attribute value), does clamp float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); - // line effects / types, m_type is used for this + // line types, m_type is used for this // valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out //float processLineTypeSine(float xIn, float valA, float valB, float fadeInStartLoc); std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, @@ -692,7 +711,7 @@ class LMMS_EXPORT VectorGraphDataArray bool m_isFixedX; // can the values be changed bool m_isFixedY; - // if true then it makes the last position coordinate 1, 1, the first point coordinate to -1 (ot 0), 0 + // if true then it makes the last point coordinate 1, 1, the first point coordinate -1, 0 bool m_isFixedEndPoints; // can VectorGraphView select this bool m_isSelectable; @@ -726,15 +745,17 @@ class LMMS_EXPORT VectorGraphDataArray // baking - // getSamples() will return m_bakedSamples if a line is unchanged - // else it will recalculate the line's values, update m_bakedSamples + // getSamples() will return m_bakedSamples if lines are unchanged + // else it will recalculate the changed line's values, update m_bakedSamples // getSamples() needs to know where did lines change so it updates // m_needsUpdating by running getUpdatingFromEffector() - // if m_isDataChanged is true, then getSamples adds all the points - // to m_needsUpdating before running + // if m_isDataChanged is true, then getSamples recalculates all the lines/samples // getSamples() clears m_needsUpdating after it has run - // every change is only applyed to the point's line (line started by the point) - // changes in position will cause multiple points to update + // updating a line means recalculating m_bakedSamples in getSamples() + // based on the changed points (stored in m_needsUpdating) + // changes in a point will causes its line to update (line started by the point) + // changes in position needs to cause multiple lines to update + // addition or deletion needs to cause all the lines to update // if we want to update all (the full line in getSamples()) bool m_isDataChanged; From 2d6002f909863a2e4d6ca356c44c667487a34123 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 11:08:07 +0200 Subject: [PATCH 102/184] VectorGraph_reworked_VectorGraphPoint_constructor --- include/VectorGraph.h | 93 ++++++++++++------------------------------- 1 file changed, 25 insertions(+), 68 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 0a9de596775..7859748b038 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -547,65 +547,22 @@ class LMMS_EXPORT VectorGraphDataArray public: inline VectorGraphPoint() { - m_x = 0.0f; - m_y = 0.0f; - m_c = 0.0f; - m_valA = 0.0f; - m_valB = 0.0f; - m_type = 0; - m_automatedEffectedAttribLocations = 0; - - m_effectOnlyPoints = false; - m_effectAdd = false; - m_effectSubtract = false; - m_effectMultiply = false; - m_effectDivide = false; - m_effectPower = false; - m_effectLog = false; - m_effectSine = false; - m_effectClampLower = false; - m_effectClampUpper = false; - - m_bufferedAutomationValue = 0.0f; - m_automationModel = -1; } inline VectorGraphPoint(float x, float y) { m_x = x; m_y = y; - m_c = 0.0f; - m_valA = 0.0f; - m_valB = 0.0f; - m_type = 0; - m_automatedEffectedAttribLocations = 0; - - m_effectOnlyPoints = false; - m_effectAdd = false; - m_effectSubtract = false; - m_effectMultiply = false; - m_effectDivide = false; - m_effectPower = false; - m_effectLog = false; - m_effectSine = false; - m_effectClampLower = false; - m_effectClampUpper = false; - - m_bufferedAutomationValue = 0.0f; - m_automationModel = -1; - } - inline ~VectorGraphPoint() - { } // 0 - 1 - float m_x; - // 0 (or -1) - 1, getAutomatedAttrib() -> 0 - float m_y; + float m_x = 0.0f; + // -1 - 1, getAutomatedAttrib() -> 0 + float m_y = 0.0f; // curve, -1 - 1, getAutomatedAttrib() -> 1 - float m_c; + float m_c = 0.0f; // valueA, -1 - 1, getAutomatedAttrib() -> 2 - float m_valA; + float m_valA = 0.0f; // valueB, -1 - 1, getAutomatedAttrib() -> 3 - float m_valB; + float m_valB = 0.0f; // line type: // 0 - none // 1 - sine @@ -613,32 +570,32 @@ class LMMS_EXPORT VectorGraphDataArray // 3 - peak // 4 - steps // 5 - random - unsigned int m_type; + unsigned int m_type = 0; // the automated attrib location and // the effected attrib location is // stored here // use getAutomatedAttrib or getEffectedAttrib to get it - unsigned int m_automatedEffectedAttribLocations; + unsigned int m_automatedEffectedAttribLocations = 0; - // if the point's line should effect only points + // if the point's line should effect only pointss // getEffectOnlyPoints() will return true when // effected attrib location > 0 - bool m_effectOnlyPoints; - - bool m_effectAdd; - bool m_effectSubtract; - bool m_effectMultiply; - bool m_effectDivide; - bool m_effectPower; - bool m_effectLog; - bool m_effectSine; - bool m_effectClampLower; - bool m_effectClampUpper; - - // stores m_automationModel->value(), used in updating - float m_bufferedAutomationValue; - // automation: connecting to floatmodels, -1 when it isn't conntected' - int m_automationModel; + bool m_effectOnlyPoints = false; + + bool m_effectAdd = false; + bool m_effectSubtract = false; + bool m_effectMultiply = false; + bool m_effectDivide = false; + bool m_effectPower = false; + bool m_effectLog = false; + bool m_effectSine = false; + bool m_effectClampLower = false; + bool m_effectClampUpper = false; + + // stores m_automationModel->value(), used in getSamples() when updating + float m_bufferedAutomationValue = 0.0f; + // automation: connecting to floatmodels, -1 when it isn't conntected + int m_automationModel = -1; }; // deletes the point's automation model // if modelLocation == point location From a6bef80c8d0ca18b68d59310c821240f8e07ee21 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 11:29:57 +0200 Subject: [PATCH 103/184] VectorGraph_removed_unused_functions --- include/VectorGraph.h | 11 +-- src/gui/widgets/VectorGraph.cpp | 138 -------------------------------- 2 files changed, 1 insertion(+), 148 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 7859748b038..446cefd03de 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -305,8 +305,6 @@ Q_OBJECT virtual void loadSettings(const QDomElement& element, const QString& name); virtual void saveSettings(QDomDocument& doc, QDomElement& element); virtual void loadSettings(const QDomElement& element); - // read locations from saved data attributes unused but implemeted - //int readLoc(unsigned int start, QString data); void lockGetSamplesAccess(); void unlockGetSamplesAccess(); void lockBakedSamplesAccess(); @@ -613,23 +611,18 @@ class LMMS_EXPORT VectorGraphDataArray // line types, m_type is used for this // valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out - //float processLineTypeSine(float xIn, float valA, float valB, float fadeInStartLoc); std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float fadeInStartLoc); // curve: phase - //float processLineTypeSineB(float xIn, float valA, float valB, float curve, float fadeInStartLoc); std::vector processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc); // valA: amp, valB: x coord, curve: width - //float processLineTypePeak(float xIn, float valA, float valB, float curve, float fadeInStartLoc); std::vector processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc); // y: calculate steps from, valA: y count, valB: curve - //float processLineTypeSteps(float xIn, float yIn, float valA, float valBIn, float fadeInStartLoc); std::vector processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float valA, float valB, float fadeInStartLoc); // valA: amp, valB: random number count, curve: seed - //float processLineTypeRandom(float xIn, float valA, float valB, float curve, float fadeInStartLoc); std::vector processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc); @@ -652,9 +645,7 @@ class LMMS_EXPORT VectorGraphDataArray // real getSamples processing void getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); - // gets every m_needsUpdating point's line's start and end effector point's location in the effector dataArray - // .first = start, .second = line end location (effector dataArray) - //void getSamplesLocations(VectorGraphDataArray* effector, std::vector>* effectorDataOut); + // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, std::vector* outputXLocations, unsigned int iIn, float stepSize); bool isEffectedPoint(unsigned int pointLocation); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 147b60fa659..6f1ef69344c 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1932,21 +1932,6 @@ void VectorGraphModel::loadSettings(const QDomElement& element) { loadSettings(element, QString("")); } -/* -int VectorGraphModel::readLoc(unsigned int start, QString data) -{ - int output = -1; - for (unsigned int i = start; i < data.size(); i++) - { - if (data[i] == QString("-")) - { - output = data.left(i - 1).toInt(); - break; - } - } - return output; -} -*/ // VectorGraphDataArray ------ @@ -3211,13 +3196,6 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float return output; } -// line type effects: -/* -float VectorGraphDataArray::processLineTypeSine(float xIn, float valA, float valB, float fadeInStartLoc) -{ - return processLineTypeSineB(xIn, valA, valB, 0.0f, fadeInStartLoc); -} -*/ // valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float fadeInStartLoc) @@ -3225,26 +3203,6 @@ std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector 1.0f - fadeInStartLoc) - { - output = output * (1.0f - xIn) / fadeInStartLoc; - } - return output; -} -*/ // valA: amp, valB: freq, curve: phase std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc) @@ -3309,26 +3267,6 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector 1.0f - fadeInStartLoc) - { - output = output * (1.0f - xIn) / fadeInStartLoc; - } - return output; -} -*/ - // valA: amp, valB: x coord, curve: width std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc) @@ -3366,11 +3304,6 @@ std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float valA, float valB, float fadeInStartLoc) @@ -3414,11 +3347,6 @@ std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float curve, float fadeInStartLoc) @@ -3759,15 +3687,6 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged effector = m_parent->getDataArray(m_effectorLocation); } - // m_dataArray[i] location in effecor m_dataArray, next location in effecor m_dataArray, - //std::vector> effectorData; - //getSamplesLocations(effector, &effectorData); - /* - for (unsigned int j = 0; j < effectorData.size(); j++) - { - qDebug("getSamplesB6.4, [%d] %d, %d", j, effectorData[j].first, effectorData[j].second); - } - */ qDebug("getSamplesB6, updatingsize: %ld", m_needsUpdating.size()); // calculate final lines @@ -3806,63 +3725,6 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged m_isDataChanged = false; qDebug("getSamplesB9"); } -// unused function, might be useful later -/* -void VectorGraphDataArray::getSamplesLocations(VectorGraphDataArray* effectorIn, std::vector>* effectorDataOut) -{ - if (effectorIn != nullptr) - { - effectorDataOut->resize(m_needsUpdating.size()); - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - bool found = false; - bool isBefore = false; - int curLocation = effectorIn->getNearestLocation(m_dataArray[m_needsUpdating[i]].m_x, &found, &isBefore); - if (curLocation >= 0) - { - curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; - // location - effectorDataOut->operator[](i).first = curLocation; -qDebug("getSamplesC5.1, [%d] set to: %d", i, curLocation); - // next location - effectorDataOut->operator[](i).second = curLocation; - // if the location of this is the next location for before this - if (i > 0 && m_needsUpdating[i - 1] == m_needsUpdating[i] - 1) - { -qDebug("getSamplesC5.2, [%d - 1] changed to: %d", i, curLocation); - effectorDataOut->operator[](i- 1).second = curLocation; - } - } - } -qDebug("getSamplesC5"); - // getting the missing next location values - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - // if there is a gap in m_needsUpdating - // (next needsUpdating point is not the point after this one in m_dataArray) - if (i + 1 < m_needsUpdating.size() && m_needsUpdating[i] + 1 < m_dataArray.size() && - m_needsUpdating[i + 1] != m_needsUpdating[i] + 1) - { - bool found = false; - bool isBefore = false; - int curLocation = effectorIn->getNearestLocation(m_dataArray[m_needsUpdating[i] + 1].m_x, &found, &isBefore); - if (curLocation >= 0) - { - curLocation = isBefore == false ? (curLocation > 0 ? curLocation - 1 : curLocation) : curLocation; - // next location -qDebug("getSamplesC5.3, [%d] set after to: %d", i, curLocation); - effectorDataOut->operator[](i).second = curLocation; - } - } - } - // getting the last updated point's next location value - if (m_needsUpdating[m_needsUpdating.size() - 1] + 1 >= m_dataArray.size()) - { - effectorDataOut->operator[](m_needsUpdating.size() - 1).second = effectorIn->size() - 1; - } - } -} -*/ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, std::vector* outputXLocations, unsigned int iIn, float stepSize) { From 082fba77515529ebb249ec2ba64c782dd2801682 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 12:13:23 +0200 Subject: [PATCH 104/184] VectorGraph_renamded_variables_and_functions --- include/VectorGraph.h | 44 +++++----- src/gui/widgets/VectorGraph.cpp | 150 ++++++++++++++++---------------- 2 files changed, 99 insertions(+), 95 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 446cefd03de..12f69d48c64 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -63,7 +63,7 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView Q_PROPERTY(int fontSize MEMBER m_fontSize) public: - VectorGraphView(QWidget * parent, int widthIn, int heightIn, unsigned int pointSize, + VectorGraphView(QWidget* parent, int widgetWidth, int widgetHeight, unsigned int pointSize, unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors); ~VectorGraphView(); @@ -211,7 +211,7 @@ protected slots: unsigned int m_controlDisplayCount; unsigned int m_controlDisplayPage; bool m_isEditingActive; - std::array m_controlText = + std::array m_controlText = { tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), @@ -227,7 +227,7 @@ protected slots: tr("steps"), tr("random") }; - std::array m_controlIsFloat = { + std::array m_controlIsFloat = { true, true, true, true, true, false, false, false, false, false, false, @@ -257,7 +257,7 @@ class LMMS_EXPORT VectorGraphModel : public Model, public JournallingObject { Q_OBJECT public: - VectorGraphModel(unsigned int arrayMaxLength, Model* parentIn, bool defaultConstructed); + VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed); ~VectorGraphModel(); inline size_t getDataArraySize() @@ -343,10 +343,10 @@ class LMMS_EXPORT VectorGraphDataArray VectorGraphDataArray( bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parentIn, int arrayId); + bool isSaveable, VectorGraphModel* parent, int arrayId); ~VectorGraphDataArray(); - void updateConnections(VectorGraphModel* parentIn); + void updateConnections(VectorGraphModel* parent); // see descriptions in privete void setIsFixedSize(bool bValue); @@ -393,7 +393,7 @@ class LMMS_EXPORT VectorGraphDataArray int add(float newX); // checks m_isFixedSize (== false) // deletes the point in pointLocation location - void del(unsigned int pointLocation); + void deletePoint(unsigned int pointLocation); // clears m_dataArray without any checks inline void clear() { @@ -474,15 +474,15 @@ class LMMS_EXPORT VectorGraphDataArray // set: ------------------- // sets / adds m_dataArray points // .first = x, .second = y coords - // isCurvedIn -> should set curve automatically - // clearIn -> clear m_dataArray before setting - // clampIn -> clamp input positions - // rescaleIn -> scale input positions - // sortIn -> sort input positions - // callDataChangedIn -> call dataChanged() after -> paintEvent() - void setDataArray(std::vector>* dataArrayIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); - void setDataArray(std::vector* dataArrayIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); - void setDataArray(float* dataArrayIn, unsigned int sizeIn, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); + // isCurved -> should set curve automatically + // clear -> clear m_dataArray before setting + // clamp -> clamp input positions + // rescale -> scale input positions + // sort -> sort input positions + // callDataChanged -> call dataChanged() after -> paintEvent() + void setDataArray(std::vector>* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); + void setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); // set attribute: ------------------- @@ -534,7 +534,7 @@ class LMMS_EXPORT VectorGraphDataArray std::vector* getAutomationModelArray(); // delete automationModels in m_automationModelArray // that are not used by points (there should be 0 cases like this) - void delUnusedAutomation(); + void deleteUnusedAutomation(); // encodes m_dataArray to QString QString getSavedDataArray(); // decodes and sets m_dataArray from QString @@ -597,10 +597,10 @@ class LMMS_EXPORT VectorGraphDataArray }; // deletes the point's automation model // if modelLocation == point location - void delAutomationModel(unsigned int modelLocation, bool callDataChanged); - // swapping values, "slide" moves the values (between) once left or right + void deleteAutomationModel(unsigned int modelLocation, bool callDataChanged); + // swapping values, "shouldShiftBetween" moves the values (between) once left or right to keep the order // handle m_isFixedEndPoints when using this - void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool slide); + void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween); // returns the curve value at a given x coord, does clamp float processCurve(float yBefore, float yAfter, float curve, float xIn); // returns effected attribute value from base attribValue (input attribute value), does clamp @@ -610,7 +610,7 @@ class LMMS_EXPORT VectorGraphDataArray float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); // line types, m_type is used for this - // valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out + // valA: amp, valB: freq, fadeInStartLoc: from what relative x value should the line type fade out std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float fadeInStartLoc); // curve: phase @@ -647,7 +647,7 @@ class LMMS_EXPORT VectorGraphDataArray void getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* outputXLocations, unsigned int iIn, float stepSize); + std::vector* outputXLocations, unsigned int pointLocation, float stepSize); bool isEffectedPoint(unsigned int pointLocation); // checks m_isFixedEndPoints, does not call dataChanged() diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 6f1ef69344c..ef7523677c3 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -55,12 +55,12 @@ namespace lmms namespace gui { -VectorGraphView::VectorGraphView(QWidget * parent, int widthIn, int heightIn, unsigned int pointSize, +VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors) : QWidget(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this) { - resize(widthIn, heightIn); + resize(widgetWidth, widgetHeight); m_mousePress = false; m_addition = false; @@ -350,7 +350,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) selectData(x, m_graphHeight - y); if (m_isSelected == true) { - model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); m_isSelected = false; m_isEditingActive = false; } @@ -443,7 +443,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) else if (m_isSelected == true && m_addition == false) { // if selection was successful -> deletion - model()->getDataArray(m_selectedArray)->del(m_selectedLocation); + model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); m_isSelected = false; m_isEditingActive = false; } @@ -1427,7 +1427,7 @@ void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayText) contMenu->addAction(embed::getIconPixmap("cancel"), tr("Remove connection"), - this, SLOT(removeConnection())); + this, SLOT(removeAutomation())); } } @@ -1677,8 +1677,8 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } // namespace gui -VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parentIn, bool defaultConstructed) : - Model(parentIn, tr("VectorGraphModel"), defaultConstructed) +VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed) : + Model(parent, tr("VectorGraphModel"), defaultConstructed) { m_maxLength = arrayMaxLength; //m_dataArrays @@ -1816,7 +1816,7 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con } // delete automation that is in the automationModelArray // but not used by a point (there should be 0 cases like this) - m_dataArrays[i].delUnusedAutomation(); + m_dataArrays[i].deleteUnusedAutomation(); // getting the start of the attribute name QString readLocation = "a" + QString::number(i) + "-"; @@ -1969,7 +1969,7 @@ VectorGraphDataArray::VectorGraphDataArray() VectorGraphDataArray::VectorGraphDataArray( bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parentIn, int arrayId) + bool isSaveable, VectorGraphModel* parent, int arrayId) { m_isFixedSize = isFixedSize; m_isFixedY = isFixedX; @@ -1997,7 +1997,7 @@ VectorGraphDataArray::VectorGraphDataArray( // m_automationModelArray; m_id = arrayId; - updateConnections(parentIn); + updateConnections(parent); } VectorGraphDataArray::~VectorGraphDataArray() @@ -2019,10 +2019,10 @@ VectorGraphDataArray::~VectorGraphDataArray() qDebug("VectorGraphDataArray dstc end"); } -void VectorGraphDataArray::updateConnections(VectorGraphModel* parentIn) +void VectorGraphDataArray::updateConnections(VectorGraphModel* parent) { // call VectorGraphModel signals without qt - m_parent = parentIn; + m_parent = parent; m_id = m_parent->getDataArrayNewId(); // reseting effectors setEffectorArrayLocation(-1, true); @@ -2247,7 +2247,7 @@ int VectorGraphDataArray::add(float newX) { qDebug("add 3. success, nearest: %d", location); targetLocation = location; - // slide the new data if the closest data x is bigger + // shift the new data if the closest data x is bigger // (done for swaping) if (isBefore == true) { @@ -2289,12 +2289,12 @@ int VectorGraphDataArray::add(float newX) return location; } -void VectorGraphDataArray::del(unsigned int pointLocation) +void VectorGraphDataArray::deletePoint(unsigned int pointLocation) { if (m_isFixedSize == false && pointLocation < m_dataArray.size()) { // deleting the points automationModel - delAutomationModel(m_dataArray[pointLocation].m_automationModel, true); + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); // swaping the point to the last location // in m_dataArray swap(pointLocation, m_dataArray.size() - 1, true); @@ -2409,7 +2409,7 @@ void VectorGraphDataArray::formatArray(std::vector>* dat { if (dataArrayOut->operator[](i).first == lastPos) { - del(i); + deletePoint(i); } else { @@ -2524,30 +2524,30 @@ std::vector VectorGraphDataArray::getEffectorArrayLocations() return output; } -void VectorGraphDataArray::setDataArray(std::vector>* dataArrayIn, +void VectorGraphDataArray::setDataArray(std::vector>* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { - qDebug("setDataArray size: %ld", dataArrayIn->size()); + qDebug("setDataArray size: %ld", inputDataArray->size()); if (shouldClear == true) { m_dataArray.clear(); } - m_dataArray.resize(dataArrayIn->size()); + m_dataArray.resize(inputDataArray->size()); if (m_dataArray.size() == 0) { clearedEvent(); } if (shouldClamp == true || shouldRescale == true || shouldSort == true) { - formatArray(dataArrayIn, shouldClamp, shouldRescale, shouldSort, false); + formatArray(inputDataArray, shouldClamp, shouldRescale, shouldSort, false); } bool noneBefore = true; bool isNegativeBefore = false; for (unsigned int i = 0; i < m_dataArray.size(); i++) { - //qDebug("setDataArray 1, x: %f, y: %f", dataArrayIn->operator[](i).first, dataArrayIn->operator[](i).second); - m_dataArray[i].m_x = dataArrayIn->operator[](i).first; - m_dataArray[i].m_y = dataArrayIn->operator[](i).second; + //qDebug("setDataArray 1, x: %f, y: %f", inputDataArray->operator[](i).first, inputDataArray->operator[](i).second); + m_dataArray[i].m_x = inputDataArray->operator[](i).first; + m_dataArray[i].m_y = inputDataArray->operator[](i).second; // calculating curves if (shouldCurve == true && i > 0) { @@ -2581,27 +2581,27 @@ void VectorGraphDataArray::setDataArray(std::vector>* da dataChanged(); } } -void VectorGraphDataArray::setDataArray(std::vector* dataArrayIn, +void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { - std::vector> convertedDataArray(dataArrayIn->size()); + std::vector> convertedDataArray(inputDataArray->size()); float stepSize = 1.0f / static_cast(convertedDataArray.size()); - for (unsigned int i = 0; i < dataArrayIn->size(); i++) + for (unsigned int i = 0; i < inputDataArray->size(); i++) { convertedDataArray[i].first = i * stepSize; - convertedDataArray[i].second = dataArrayIn->operator[](i); + convertedDataArray[i].second = inputDataArray->operator[](i); } setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); } -void VectorGraphDataArray::setDataArray(float* dataArrayIn, unsigned int sizeIn, +void VectorGraphDataArray::setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { - std::vector> convertedDataArray(sizeIn); - float stepSize = 1.0f / static_cast(sizeIn); - for (unsigned int i = 0; i < sizeIn; i++) + std::vector> convertedDataArray(size); + float stepSize = 1.0f / static_cast(size); + for (unsigned int i = 0; i < size; i++) { convertedDataArray[i].first = i * stepSize; - convertedDataArray[i].second = dataArrayIn[i]; + convertedDataArray[i].second = inputDataArray[i]; } setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); } @@ -2912,7 +2912,7 @@ void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) // dataChanged() is called in this function // this function check if the current point has an automationModel - delAutomationModel(m_dataArray[pointLocation].m_automationModel, true); + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); } } qDebug("setAutomated end"); @@ -2931,7 +2931,7 @@ std::vector* VectorGraphDataArray::getAutomationModelArray() { return &m_automationModelArray; } -void VectorGraphDataArray::delUnusedAutomation() +void VectorGraphDataArray::deleteUnusedAutomation() { bool dataChangedVal = false; std::vector usedAutomation; @@ -2956,11 +2956,11 @@ void VectorGraphDataArray::delUnusedAutomation() if (found == false) { dataChangedVal = true; - delAutomationModel(i, false); + deleteAutomationModel(i, false); } } - // getUpdatingFromPoint() is called in delAutomationModel() + // getUpdatingFromPoint() is called in deleteAutomationModel() if (dataChangedVal == true) { dataChanged(); @@ -2996,7 +2996,7 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize) } // private: -void VectorGraphDataArray::delAutomationModel(unsigned int modelLocation, bool callDataChanged) +void VectorGraphDataArray::deleteAutomationModel(unsigned int modelLocation, bool callDataChanged) { if (modelLocation != -1) { @@ -3018,6 +3018,10 @@ void VectorGraphDataArray::delAutomationModel(unsigned int modelLocation, bool c { m_dataArray[i].m_automationModel = -1; getUpdatingFromPoint(i); + if (i > 0) + { + getUpdatingFromPoint(i - 1); + } } if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) { @@ -3037,11 +3041,11 @@ void VectorGraphDataArray::delAutomationModel(unsigned int modelLocation, bool c } } -void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool slide) +void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween) { if (pointLocationA != pointLocationB) { - if (slide == true) + if (shouldShiftBetween == true) { qDebug("swap: -------"); qDebug("first.: %d, second.: %d", pointLocationA, pointLocationB); @@ -3094,14 +3098,14 @@ void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointL dataChanged(); } } -float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float xIn) +float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float x) { // calculating line curve float absCurveIn = std::abs(curve); - float pow = curve < 0.0f ? 1.0f - xIn : xIn; + float pow = curve < 0.0f ? 1.0f - x : x; pow = std::pow(pow, 1.0f - absCurveIn) - pow; - float output = yBefore + (yAfter - yBefore) * xIn; + float output = yBefore + (yAfter - yBefore) * x; output = curve > 0.0f ? output + pow * (yAfter - yBefore) : output - pow * (yAfter - yBefore); // clamp if (yBefore > yAfter) @@ -3196,7 +3200,7 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float return output; } -// valA: amp, valB: freq, fadeInStartLoc: from what xIn value should the line type fade out +// valA: amp, valB: freq, fadeInStartLoc: from what x relative position should the line type fade out std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float valA, float valB, float fadeInStartLoc) { @@ -3726,27 +3730,27 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged qDebug("getSamplesB9"); } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* outputXLocations, unsigned int iIn, float stepSize) + std::vector* outputXLocations, unsigned int pointLocation, float stepSize) { - qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", iIn, m_needsUpdating[iIn]); + qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", pointLocation, m_needsUpdating[pointLocation]); unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[iIn]].m_x / stepSize)); + (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorSamples->size()); - // current effector output Y near m_needsUpdating[iIn] point + // current effector output Y near m_needsUpdating[pointLocation] point float curEffectY = effectorSamples->operator[](effectYLocation); float nextEffectY = effectorSamples->operator[](effectYLocation); // getting the final automatable / effectable point values - float curY = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_y, 0); - float curC = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_c, 1); - float curValA = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_valA, 2); - float curValB = processAutomation(m_needsUpdating[iIn], m_dataArray[m_needsUpdating[iIn]].m_valB, 3); - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == true) + float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); + float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); + float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); + float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation]) == true) { - curY = processEffect(m_needsUpdating[iIn], curY, 0, curEffectY); - curC = processEffect(m_needsUpdating[iIn], curC, 1, curEffectY); - curValA = processEffect(m_needsUpdating[iIn], curValA, 2, curEffectY); - curValB = processEffect(m_needsUpdating[iIn], curValB, 3, curEffectY); + curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); + curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); + curValA = processEffect(m_needsUpdating[pointLocation], curValA, 2, curEffectY); + curValB = processEffect(m_needsUpdating[pointLocation], curValB, 3, curEffectY); } // from where to update line int start = effectYLocation; @@ -3754,27 +3758,27 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, float nextY = curY; - if (m_needsUpdating[iIn] + 1 < m_dataArray.size()) + if (m_needsUpdating[pointLocation] + 1 < m_dataArray.size()) { effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[iIn] + 1].m_x / stepSize)); + (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); // where updating line ends (+1) end = effectYLocation; - nextY = processAutomation(m_needsUpdating[iIn] + 1, m_dataArray[m_needsUpdating[iIn] + 1].m_y, 0); + nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); // if the current point can only be effected (and not its line) // and the next point can only be effected // this is done to avoid adding effectorSamples to the line and to the next point (line's end point) at the same time - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn] + 1) == true && - ((getEffectOnlyPoints(m_needsUpdating[iIn]) == true && isEffectedPoint(m_needsUpdating[iIn]) == true) || - isEffectedPoint(m_needsUpdating[iIn]) == false)) + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation] + 1) == true && + ((getEffectOnlyPoints(m_needsUpdating[pointLocation]) == true && isEffectedPoint(m_needsUpdating[pointLocation]) == true) || + isEffectedPoint(m_needsUpdating[pointLocation]) == false)) { nextEffectY = effectorSamples->operator[](effectYLocation); - nextY = processEffect(m_needsUpdating[iIn] + 1, nextY, 0, nextEffectY); + nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); } } // calculating line ends - if (m_needsUpdating[iIn] + 1 >= m_dataArray.size()) + if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray for (int j = end; j < m_updatingBakedSamples.size(); j++) @@ -3782,7 +3786,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, m_updatingBakedSamples[j] = curY; } } - if (m_needsUpdating[iIn] == 0) + if (m_needsUpdating[pointLocation] == 0) { // if this point is at the 0 location in m_dataArray for (int j = 0; j < start; j++) @@ -3792,8 +3796,8 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, } float fadeInStart = 0.05f; - unsigned int type = m_dataArray[m_needsUpdating[iIn]].m_type; -qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", iIn, start, end, type, curY, nextY, curC, curValA, curValB); + unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; +qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); // calculate final updated line if (type == 0) @@ -3875,16 +3879,16 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; } } - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[iIn]) == false) + if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation]) == false) { - int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; // process line effect // if it is enabled qDebug("getSamples run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { - m_updatingBakedSamples[j] = processEffect(m_needsUpdating[iIn], m_updatingBakedSamples[j], 0, effectorSamples->operator[](j)); + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, effectorSamples->operator[](j)); } } // clamp @@ -3901,8 +3905,8 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % } if (m_isNonNegative == true) { - int startB = m_needsUpdating[iIn] == 0 ? 0 : start; - int endB = m_needsUpdating[iIn] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; for (int j = startB; j < endB; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; From 10e5f998f1a0cc987576a7075f54ccb64ed55090 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 12:56:55 +0200 Subject: [PATCH 105/184] VectorGraph_processLineType_variables_renamed --- include/VectorGraph.h | 19 ++++++------- src/gui/widgets/VectorGraph.cpp | 49 ++++++++++++++++----------------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 12f69d48c64..4a4d673a6e0 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -128,7 +128,7 @@ protected slots: std::pair mapMousePos(int x, int y); // calculate gui curve point's position std::pair mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); - std::pairmapDataCurvePos(int xA, int yA, int xB, int yB, float curve); + std::pair mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); // calculate screen space coords from graph coords // isNonNegative can only be true when graph line / getSamples() is mapped std::pair mapDataPos(float x, float y, bool isNonNegative); @@ -610,25 +610,24 @@ class LMMS_EXPORT VectorGraphDataArray float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); // line types, m_type is used for this - // valA: amp, valB: freq, fadeInStartLoc: from what relative x value should the line type fade out + // fadeInStartLoc: from what relative x value should the line type fade out std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float fadeInStartLoc); - // curve: phase + float sineAmp, float sineFreq, float fadeInStartLoc); std::vector processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc); + float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc); // valA: amp, valB: x coord, curve: width std::vector processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc); + float peakAmp, float peakX, float peakWidth, float fadeInStartLoc); // y: calculate steps from, valA: y count, valB: curve std::vector processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float valA, float valB, float fadeInStartLoc); + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc); // valA: amp, valB: random number count, curve: seed std::vector processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc); + float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc); // updating - // adds the points that are - // effected by the effector's values changing + // adds the m_dataArray points that are + // effected by the changed effector array points. // ONLY WORKS IN SORTED ARRAYS void getUpdatingFromEffector(std::vector* updatingPointLocations); // if pointLocation >= 0 -> adds the location to m_needsUpdating diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index ef7523677c3..62a8651e7f9 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3200,23 +3200,21 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float return output; } -// valA: amp, valB: freq, fadeInStartLoc: from what x relative position should the line type fade out std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float fadeInStartLoc) + float sineAmp, float sineFreq, float fadeInStartLoc) { return VectorGraphDataArray::processLineTypeArraySineB(xArray, startLoc, endLoc, - valA, valB, 0.0f, fadeInStartLoc); + sineAmp, sineFreq, 0.0f, fadeInStartLoc); } -// valA: amp, valB: freq, curve: phase std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc) + float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc) { int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } - float tValB = 0.001f + ((valB + 1.0f) / 2.0f) * 0.999f; + float tValB = 0.001f + ((sineFreq + 1.0f) / 2.0f) * 0.999f; std::vector output(count); // calculating how many samples are needed to 1 complete wave // we have "count" amount of samples and "tValB * 100.0f" amount of waves @@ -3235,9 +3233,9 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vectoroperator[](startLoc + i) * 628.318531f * tValB + curve * 100.0f); + // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) + output[i] = sineAmp * std::sin( + xArray->operator[](startLoc + i) * 628.318531f * tValB + sinePhase * 100.0f); } //qDebug("sineB_2"); // copy the first wave until the end @@ -3271,9 +3269,8 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc) + float peakAmp, float peakX, float peakWidth, float fadeInStartLoc) { int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) @@ -3283,8 +3280,8 @@ std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector output(count); for (unsigned int i = 0; i < count; i++) { - output[i] = std::pow((curve + 1.0f) * 0.2f + 0.01f, - std::abs(xArray->operator[](startLoc + i) - (valB + 1.0f) * 0.5f) * 10.0f) * valA; + output[i] = std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, + std::abs(xArray->operator[](startLoc + i) - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; } // fade in for (unsigned int i = 0; i < count; i++) @@ -3310,7 +3307,7 @@ std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float valA, float valB, float fadeInStartLoc) + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc) { int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) @@ -3319,14 +3316,14 @@ std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector output(count); - float stepCount = (1.0f + valA) / 2.0f * 19.0f + 1.0f; + float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; //qDebug("stepsA - stepCount = %f", stepCount); for (unsigned int i = 0; i < count; i++) { float y = yArray->operator[](startLoc + i) + 1.0f; - float diff = std::round(y * stepCount) - y * stepCount; - float smooth = 1.0f - std::abs(diff) * (1.0f - (valB + 1.0f) / 2.0f) * 2.0f; - output[i] = diff / stepCount * smooth; + float diff = std::round(y * stepCountB) - y * stepCountB; + float smooth = 1.0f - std::abs(diff) * (1.0f - (stepCurve + 1.0f) / 2.0f) * 2.0f; + output[i] = diff / stepCountB * smooth; } // fade in @@ -3353,7 +3350,7 @@ std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float valA, float valB, float curve, float fadeInStartLoc) + float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc) { int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) @@ -3361,12 +3358,12 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< count = 0; } std::vector output(count); - std::vector randomValues(static_cast(50.0f * (valB + 1.0f)) * 2); + std::vector randomValues(static_cast(50.0f * (randomCount + 1.0f)) * 2); - float blend = 10.0f + curve * 10.0f; - int randomSeed = static_cast(blend); - blend = blend - randomSeed; - std::srand(randomSeed); + float blend = 10.0f + randomSeed * 10.0f; + int randomSeedB = static_cast(blend); + blend = blend - randomSeedB; + std::srand(randomSeedB); // getting the random values // generating 2 seeds and blending in between them @@ -3374,7 +3371,7 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< { randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; } - std::srand(randomSeed + 1); + std::srand(randomSeedB + 1); for (unsigned int i = randomValues.size() / 2; i < randomValues.size(); i++) { randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; @@ -3390,7 +3387,7 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< float randomValueX = xArray->operator[](startLoc + i) * size; float randomValueLocation = std::floor(randomValueX); output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * valA; + (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * randomAmp; } } From 1b1b01b5f8feebec8425f652e4ba95b4199177b0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 14:07:31 +0200 Subject: [PATCH 106/184] VectorGraph_line_types_rewrite --- include/VectorGraph.h | 18 +++-- src/gui/widgets/VectorGraph.cpp | 133 ++++++++++++++------------------ 2 files changed, 67 insertions(+), 84 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 4a4d673a6e0..38669f57f5c 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -611,18 +611,20 @@ class LMMS_EXPORT VectorGraphDataArray // line types, m_type is used for this // fadeInStartLoc: from what relative x value should the line type fade out - std::vector processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + // linking: valA: sineAmp, valB: sineFreq + void processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float fadeInStartLoc); - std::vector processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + // linking: valA: sineAmp, valB: sineFreq, curve: sinePhase + void processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc); - // valA: amp, valB: x coord, curve: width - std::vector processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + // linking: valA: amp, valB: x coord, curve: width + void processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float peakAmp, float peakX, float peakWidth, float fadeInStartLoc); - // y: calculate steps from, valA: y count, valB: curve - std::vector processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + // linking: y: yArray, valA: stepCount, valB: stepCurve + void processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc); - // valA: amp, valB: random number count, curve: seed - std::vector processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + // linking: valA: randomAmp, valB: randomCount, curve: randomSeed + void processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc); // updating diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 62a8651e7f9..5fd56bfae71 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3200,26 +3200,27 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float return output; } -std::vector VectorGraphDataArray::processLineTypeArraySine(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, +void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float fadeInStartLoc) { - return VectorGraphDataArray::processLineTypeArraySineB(xArray, startLoc, endLoc, + processLineTypeArraySineB(samplesOut, xArray, startLoc, endLoc, sineAmp, sineFreq, 0.0f, fadeInStartLoc); } -std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, +void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc) { + float startLocVal = samplesOut->operator[](startLoc); + float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } float tValB = 0.001f + ((sineFreq + 1.0f) / 2.0f) * 0.999f; - std::vector output(count); // calculating how many samples are needed to 1 complete wave // we have "count" amount of samples and "tValB * 100.0f" amount of waves int end = static_cast(std::floor(count / (tValB * 100.0f))); - //qDebug("sineB_1, %f, %d", (count / (tValB * 100.0f)), end); + qDebug("sineB_1, %f, %d", (count / (tValB * 100.0f)), end); if (count <= 0) { end = 0; @@ -3228,93 +3229,98 @@ std::vector VectorGraphDataArray::processLineTypeArraySineB(std::vector count ? count : end + 1; } + std::vector oneWave(end); // calculate 1 wave of sine for (unsigned int i = 0; i < end; i++) { // 628.318531f = 100.0f * 2.0f * pi // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) - output[i] = sineAmp * std::sin( + oneWave[i] = sineAmp * std::sin( xArray->operator[](startLoc + i) * 628.318531f * tValB + sinePhase * 100.0f); } //qDebug("sineB_2"); // copy the first wave until the end - for (unsigned int i = end; i < count; i++) + for (int i = 0; i < count; i += end) { - //qDebug("sineB_2.5: i: %d, %d, %d", (i - end), end, i); - output[i] = output[i - end]; + //qDebug("sineB_2.4: i: %d, end: %d count - i: %d, count: %d", i, end, count - i, count); + int endB = i + end >= count ? count - i : end; + for (unsigned int j = 0; j < endB; j++) + { + //qDebug("sineB_2.5: i: %d, %d, %d", endB, j, i + j); + samplesOut->operator[](startLoc + j + i) += oneWave[j]; + } } + //qDebug("sineB_3"); // fade in - for (unsigned int i = 0; i < count; i++) + for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = xArray->operator[](i) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); } - //qDebug("sineB_4"); // fade out - for (unsigned int i = count - 1; i >= 0; i--) + for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = 1.0f - xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); } - //qDebug("sineB_5"); - return output; } -std::vector VectorGraphDataArray::processLineTypeArrayPeak(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, +void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float peakAmp, float peakX, float peakWidth, float fadeInStartLoc) { + float startLocVal = samplesOut->operator[](startLoc); + float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } - std::vector output(count); for (unsigned int i = 0; i < count; i++) { - output[i] = std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, + samplesOut->operator[](startLoc + i) += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, std::abs(xArray->operator[](startLoc + i) - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; } + // fade in - for (unsigned int i = 0; i < count; i++) + for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = xArray->operator[](i) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); } // fade out - for (unsigned int i = count - 1; i >= 0; i--) + for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = 1.0f - xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); } - return output; } -// y: calculate steps from, valA: y count, valB: curve -std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, +void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc) { + float startLocVal = samplesOut->operator[](startLoc); + float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { count = 0; } - std::vector output(count); float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; //qDebug("stepsA - stepCount = %f", stepCount); @@ -3323,33 +3329,31 @@ std::vector VectorGraphDataArray::processLineTypeArraySteps(std::vectoroperator[](startLoc + i) + 1.0f; float diff = std::round(y * stepCountB) - y * stepCountB; float smooth = 1.0f - std::abs(diff) * (1.0f - (stepCurve + 1.0f) / 2.0f) * 2.0f; - output[i] = diff / stepCountB * smooth; + samplesOut->operator[](startLoc + i) += diff / stepCountB * smooth; } // fade in - for (unsigned int i = 0; i < count; i++) + for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = xArray->operator[](i) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); } // fade out - for (unsigned int i = count - 1; i >= 0; i--) + for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = 1.0f - xArray->operator[](startLoc + i); - if (x > fadeInStartLoc) + float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + if (x > 1.0f) { break; } - output[i] = output[i] * x / fadeInStartLoc; + samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); } - return output; } -// valA: amp, valB: random number count, curve: seed -std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector* xArray, unsigned int startLoc, unsigned int endLoc, +void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc) { int count = static_cast(endLoc) - static_cast(startLoc); @@ -3357,7 +3361,6 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< { count = 0; } - std::vector output(count); std::vector randomValues(static_cast(50.0f * (randomCount + 1.0f)) * 2); float blend = 10.0f + randomSeed * 10.0f; @@ -3386,12 +3389,10 @@ std::vector VectorGraphDataArray::processLineTypeArrayRandom(std::vector< { float randomValueX = xArray->operator[](startLoc + i) * size; float randomValueLocation = std::floor(randomValueX); - output[i] = -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + samplesOut->operator[](startLoc + i) += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * randomAmp; } } - - return output; } void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) @@ -3814,11 +3815,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySine(outputXLocations, start, end, curValA, curValB, fadeInStart); - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; - } + processLineTypeArraySine(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, fadeInStart); } else if (type == 2) { @@ -3828,11 +3825,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySineB(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; - } + processLineTypeArraySineB(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); } else if (type == 3) { @@ -3842,11 +3835,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArrayPeak(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; - } + processLineTypeArrayPeak(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); } else if (type == 4) { @@ -3856,11 +3845,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArraySteps(outputXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; - } + processLineTypeArraySteps(&m_updatingBakedSamples, outputXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); } else if (type == 5) { @@ -3870,11 +3855,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); } // line type - std::vector lineTypeOutput = processLineTypeArrayRandom(outputXLocations, start, end, curValA, curValB, curC, fadeInStart); - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] + lineTypeOutput[j - start]; - } + processLineTypeArrayRandom(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); } if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation]) == false) { From 945fffa3d78752080231b35f700f68023e19e708 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 14:10:08 +0200 Subject: [PATCH 107/184] WaveShaper_changed_comment --- plugins/WaveShaper/WaveShaperControls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index a6f472e9af8..664cfc8d6bc 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -75,7 +75,7 @@ private slots: void vectorGraphChanged(); signals: // connected to dataArrayChanged() - // shouldUseGetLastValuesIn: when the graph is redrawn + // shouldUseGetLastValues: when the graph is redrawn // should it use the last updated values instead of updating again void vectorGraphUpdateView(bool shouldUseGetLastValues); private: From 7af38723cf6736c54e77ebb65c9564477d22f482 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 15:38:58 +0200 Subject: [PATCH 108/184] VectorGraph_replaced_pair_with_PointF --- include/VectorGraph.h | 17 +++++++------ src/gui/widgets/VectorGraph.cpp | 44 ++++++++++++++++----------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 38669f57f5c..6003d8034bc 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -46,6 +46,8 @@ class VectorGraphModel; class VectorGraphDataArray; class FloatModel; +using PointF = std::pair; + namespace gui { class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView @@ -86,11 +88,11 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void setIsSimplified(bool isSimplified); // returns -1.0f at .first when nothing is selected - std::pair getSelectedData(); + PointF getSelectedData(); // returns -1 it can not return an array location int getLastSelectedArray(); // sets the position of the currently selected point - void setSelectedData(std::pair data); + void setSelectedData(PointF data); // sets the background pixmap void setBackground(const QPixmap backgound); @@ -125,9 +127,9 @@ protected slots: // utility // calculate graph coords from screen space coords - std::pair mapMousePos(int x, int y); + PointF mapMousePos(int x, int y); // calculate gui curve point's position - std::pair mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); + PointF mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); std::pair mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); // calculate screen space coords from graph coords // isNonNegative can only be true when graph line / getSamples() is mapped @@ -164,7 +166,7 @@ protected slots: void addDefaultActions(QMenu* menu, QString controlDisplayText); // inputDialog - std::pair showCoordInputDialog(); + PointF showCoordInputDialog(); float showInputDialog(float curInputValue); // selection @@ -411,7 +413,7 @@ class LMMS_EXPORT VectorGraphDataArray // clamps down the values to 0 - 1, -1 - 1 // sorts array, removes duplicated x positions, calls dataChanged() if callDataChanged // clamp: should clamp, sort: should sort - void formatArray(std::vector>* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + void formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); // get attribute: ------------------- @@ -480,7 +482,8 @@ class LMMS_EXPORT VectorGraphDataArray // rescale -> scale input positions // sort -> sort input positions // callDataChanged -> call dataChanged() after -> paintEvent() - void setDataArray(std::vector>* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + // PointF = std::pair + void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); void setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 5fd56bfae71..16f139c789c 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -185,9 +185,9 @@ void VectorGraphView::setIsSimplified(bool isSimplified) m_isSimplified = isSimplified; } -std::pair VectorGraphView::getSelectedData() +PointF VectorGraphView::getSelectedData() { - std::pair output(-1.0f, 0.00); + PointF output(-1.0f, 0.00); if (m_isSelected == true) { output.first = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); @@ -203,7 +203,7 @@ int VectorGraphView::getLastSelectedArray() } return -1; } -void VectorGraphView::setSelectedData(std::pair data) +void VectorGraphView::setSelectedData(PointF data) { if (m_isSelected == true) { @@ -323,7 +323,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) if (m_isCurveSelected == false) { // dragging point - std::pair convertedCoords = mapMousePos(x, m_graphHeight - y); + PointF convertedCoords = mapMousePos(x, m_graphHeight - y); convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); setSelectedData(convertedCoords); @@ -331,7 +331,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { // dragging curve - std::pair convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); + PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; curveValue = std::clamp(curveValue, -1.0f, 1.0f); model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); @@ -511,7 +511,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) if (m_isSelected == true && me->button() == Qt::LeftButton) { // display dialog - std::pair curData = showCoordInputDialog(); + PointF curData = showCoordInputDialog(); // change data setSelectedData(curData); } @@ -924,10 +924,10 @@ void VectorGraphView::removeController() removeAutomation(); } -std::pair VectorGraphView::mapMousePos(int x, int y) +PointF VectorGraphView::mapMousePos(int x, int y) { // mapping the position to 0 - 1, -1 - 1 using qWidget width and height - return std::pair( + return PointF( static_cast(x / (float)width()), static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); } @@ -947,9 +947,9 @@ std::pair VectorGraphView::mapDataPos(float x, float y, bool isNonNega static_cast((y + 1.0f) * static_cast(m_graphHeight) / 2.0f)); } } -std::pair VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve) +PointF VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve) { - return std::pair( + return PointF( (xA + xB) / 2.0f, yA + (curve / 2.0f + 0.5f) * (yB - yA)); } @@ -978,7 +978,7 @@ bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouse // mouseY is calculated like this: // m_graphHeight - y bool output = false; - std::pair curMouseCoords = mapMousePos(mouseX, mouseY); + PointF curMouseCoords = mapMousePos(mouseX, mouseY); curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); int location = model()->getDataArray(arrayLocation)->add(curMouseCoords.first); @@ -1115,7 +1115,7 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i m_lastTrackPoint.second = curY; qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, curX, (curY), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); } - std::pair convertedCoords = mapMousePos(0, + PointF convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2), convertedCoords.second); setInputAttribValue(location, convertedCoords.second, false); @@ -1431,9 +1431,9 @@ void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayText) } } -std::pair VectorGraphView::showCoordInputDialog() +PointF VectorGraphView::showCoordInputDialog() { - std::pair curData(0.0f, 0.0f); + PointF curData(0.0f, 0.0f); if (m_isSelected == true) { curData = getSelectedData(); @@ -1562,7 +1562,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve maxDistance = maxDistance * 2.0f; qDebug("searchData"); - std::pair transformedMouse = mapMousePos(mouseX, mouseY); + PointF transformedMouse = mapMousePos(mouseX, mouseY); // unused bool bool found = false; @@ -1588,7 +1588,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } if (location - curvedBefore < dataArray->size() - 1) { - std::pair curvedDataCoords = mapDataCurvePosF( + PointF curvedDataCoords = mapDataCurvePosF( dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), dataArray->getC(location - curvedBefore)); @@ -1650,7 +1650,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve { if (dataArray->size() - 1 > i) { - std::pair curvedDataCoords = mapDataCurvePosF( + PointF curvedDataCoords = mapDataCurvePosF( dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), dataArray->getC(i)); dataX = curvedDataCoords.first; @@ -2315,7 +2315,7 @@ void VectorGraphDataArray::deletePoint(unsigned int pointLocation) } } -void VectorGraphDataArray::formatArray(std::vector>* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) +void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { if (shouldRescale == true) { @@ -2393,7 +2393,7 @@ void VectorGraphDataArray::formatArray(std::vector>* dat if (shouldSort == true) { std::sort(dataArrayOut->begin(), dataArrayOut->end(), - [](std::pair a, std::pair b) + [](PointF a, PointF b) { return a.first < b.first; }); @@ -2524,7 +2524,7 @@ std::vector VectorGraphDataArray::getEffectorArrayLocations() return output; } -void VectorGraphDataArray::setDataArray(std::vector>* inputDataArray, +void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { qDebug("setDataArray size: %ld", inputDataArray->size()); @@ -2584,7 +2584,7 @@ void VectorGraphDataArray::setDataArray(std::vector>* in void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { - std::vector> convertedDataArray(inputDataArray->size()); + std::vector convertedDataArray(inputDataArray->size()); float stepSize = 1.0f / static_cast(convertedDataArray.size()); for (unsigned int i = 0; i < inputDataArray->size(); i++) { @@ -2596,7 +2596,7 @@ void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, void VectorGraphDataArray::setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) { - std::vector> convertedDataArray(size); + std::vector convertedDataArray(size); float stepSize = 1.0f / static_cast(size); for (unsigned int i = 0; i < size; i++) { From dcb86dc0711937003850b442b3980982c40c2983 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 1 May 2024 15:42:37 +0200 Subject: [PATCH 109/184] WaveShaper_changed_old_graph_loading_location --- plugins/WaveShaper/WaveShaperControls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index bc39024270b..0a559bc03bf 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -85,7 +85,7 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) // a normal graph saved if (_this.hasAttribute("waveShape") == true) { - if (m_vectorGraphModel.getDataArraySize() > 1) + if (m_vectorGraphModel.getDataArraySize() > 0) { int size = 0; char * dst = 0; @@ -93,7 +93,7 @@ void WaveShaperControls::loadSettings( const QDomElement & _this ) float* graphSampleArray = (float*)dst; // loading old graph data into new vectorGraph - m_vectorGraphModel.getDataArray(1)->setDataArray(graphSampleArray, 200, false, false, false, false, true); + m_vectorGraphModel.getDataArray(0)->setDataArray(graphSampleArray, 200, false, false, false, false, true); delete[] dst; } From bebce626131d2c7256339468b27cbf42fbfe1c89 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 10:40:28 +0200 Subject: [PATCH 110/184] VectorGraph_replaced_operator[]() --- src/gui/widgets/VectorGraph.cpp | 144 ++++++++++++++++---------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 16f139c789c..1f1a15aef2c 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -650,7 +650,7 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v { // if nonNegative then only the dataArray output (getDataValues) // is bigger than 0 so it matters only here - posB = mapDataPos(0, sampleBuffer->operator[](j), dataArray->getIsNonNegative()); + posB = mapDataPos(0, (*sampleBuffer)[j], dataArray->getIsNonNegative()); posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); if (posA.first != posB.first) @@ -928,7 +928,7 @@ PointF VectorGraphView::mapMousePos(int x, int y) { // mapping the position to 0 - 1, -1 - 1 using qWidget width and height return PointF( - static_cast(x / (float)width()), + static_cast(x / static_cast(width())), static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); } std::pair VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) @@ -1836,7 +1836,7 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con { qDebug("saveSettings saved automatinModel %d, %d", i, j); QString readLocationB = QString::number(j) + "-"; - automationModels->operator[](j)->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); + (*automationModels)[j]->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); } } } @@ -2326,21 +2326,21 @@ void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool s float maxY = 1.0f; for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - if (dataArrayOut->operator[](i).first < minX) + if ((*dataArrayOut)[i].first < minX) { - minX = dataArrayOut->operator[](i).first; + minX = (*dataArrayOut)[i].first; } - if (dataArrayOut->operator[](i).first > maxX) + if ((*dataArrayOut)[i].first > maxX) { - maxX = dataArrayOut->operator[](i).first; + maxX = (*dataArrayOut)[i].first; } - if (dataArrayOut->operator[](i).second < minY) + if ((*dataArrayOut)[i].second < minY) { - minY = dataArrayOut->operator[](i).second; + minY = (*dataArrayOut)[i].second; } - if (dataArrayOut->operator[](i).second > maxY) + if ((*dataArrayOut)[i].second > maxY) { - maxY = dataArrayOut->operator[](i).second; + maxY = (*dataArrayOut)[i].second; } } //qDebug("formatArray 1: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); @@ -2353,14 +2353,14 @@ void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool s { for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - dataArrayOut->operator[](i).first = (dataArrayOut->operator[](i).first + minX) / maxX; + (*dataArrayOut)[i].first = ((*dataArrayOut)[i].first + minX) / maxX; } } if (minY != -1.0f || maxY != 1.0f) { for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - dataArrayOut->operator[](i).second = (dataArrayOut->operator[](i).second + minY) / maxY - 1.0f; + (*dataArrayOut)[i].second = ((*dataArrayOut)[i].second + minY) / maxY - 1.0f; } } } @@ -2369,21 +2369,21 @@ void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool s // clamp for (unsigned int i = 0; i < dataArrayOut->size(); i++) { - if (dataArrayOut->operator[](i).first < 0.0f) + if ((*dataArrayOut)[i].first < 0.0f) { - dataArrayOut->operator[](i).first = 0.0f; + (*dataArrayOut)[i].first = 0.0f; } - if (dataArrayOut->operator[](i).first > 1.0f) + if ((*dataArrayOut)[i].first > 1.0f) { - dataArrayOut->operator[](i).first = 1.0f; + (*dataArrayOut)[i].first = 1.0f; } - if (dataArrayOut->operator[](i).second < -1.0f) + if ((*dataArrayOut)[i].second < -1.0f) { - dataArrayOut->operator[](i).second = -1.0f; + (*dataArrayOut)[i].second = -1.0f; } - if (dataArrayOut->operator[](i).second > 1.0f) + if ((*dataArrayOut)[i].second > 1.0f) { - dataArrayOut->operator[](i).second = 1.0f; + (*dataArrayOut)[i].second = 1.0f; } } formatDataArrayEndPoints(); @@ -2403,17 +2403,17 @@ void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool s float lastPos = -1.0f; if (dataArrayOut->size() > 0) { - lastPos = dataArrayOut->operator[](0).first; + lastPos = (*dataArrayOut)[0].first; } for (unsigned int i = 1; i < dataArrayOut->size(); i++) { - if (dataArrayOut->operator[](i).first == lastPos) + if ((*dataArrayOut)[i].first == lastPos) { deletePoint(i); } else { - lastPos = dataArrayOut->operator[](i).first; + lastPos = (*dataArrayOut)[i].first; } } // calling clearedEvent is not needed @@ -2545,9 +2545,9 @@ void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool isNegativeBefore = false; for (unsigned int i = 0; i < m_dataArray.size(); i++) { - //qDebug("setDataArray 1, x: %f, y: %f", inputDataArray->operator[](i).first, inputDataArray->operator[](i).second); - m_dataArray[i].m_x = inputDataArray->operator[](i).first; - m_dataArray[i].m_y = inputDataArray->operator[](i).second; + //qDebug("setDataArray 1, x: %f, y: %f", (*inputDataArray)[i].first, (*inputDataArray)[i].second); + m_dataArray[i].m_x = (*inputDataArray)[i].first; + m_dataArray[i].m_y = (*inputDataArray)[i].second; // calculating curves if (shouldCurve == true && i > 0) { @@ -2589,7 +2589,7 @@ void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, for (unsigned int i = 0; i < inputDataArray->size(); i++) { convertedDataArray[i].first = i * stepSize; - convertedDataArray[i].second = inputDataArray->operator[](i); + convertedDataArray[i].second = (*inputDataArray)[i]; } setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); } @@ -3209,8 +3209,8 @@ void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesO void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc) { - float startLocVal = samplesOut->operator[](startLoc); - float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { @@ -3237,7 +3237,7 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples // 628.318531f = 100.0f * 2.0f * pi // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) oneWave[i] = sineAmp * std::sin( - xArray->operator[](startLoc + i) * 628.318531f * tValB + sinePhase * 100.0f); + (*xArray)[startLoc + i] * 628.318531f * tValB + sinePhase * 100.0f); } //qDebug("sineB_2"); // copy the first wave until the end @@ -3248,7 +3248,7 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples for (unsigned int j = 0; j < endB; j++) { //qDebug("sineB_2.5: i: %d, %d, %d", endB, j, i + j); - samplesOut->operator[](startLoc + j + i) += oneWave[j]; + (*samplesOut)[startLoc + j + i] += oneWave[j]; } } @@ -3256,29 +3256,29 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples // fade in for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](i) / fadeInStartLoc; + float x = (*xArray)[i] / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float peakAmp, float peakX, float peakWidth, float fadeInStartLoc) { - float startLocVal = samplesOut->operator[](startLoc); - float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { @@ -3286,36 +3286,36 @@ void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesO } for (unsigned int i = 0; i < count; i++) { - samplesOut->operator[](startLoc + i) += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, - std::abs(xArray->operator[](startLoc + i) - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; + (*samplesOut)[startLoc + i] += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, + std::abs((*xArray)[startLoc + i] - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; } // fade in for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](i) / fadeInStartLoc; + float x = (*xArray)[i] / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc) { - float startLocVal = samplesOut->operator[](startLoc); - float endLocVal = samplesOut->operator[](endLoc > 0 ? endLoc - 1 : 0); + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) { @@ -3326,31 +3326,31 @@ void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samples //qDebug("stepsA - stepCount = %f", stepCount); for (unsigned int i = 0; i < count; i++) { - float y = yArray->operator[](startLoc + i) + 1.0f; + float y = (*yArray)[startLoc + i] + 1.0f; float diff = std::round(y * stepCountB) - y * stepCountB; float smooth = 1.0f - std::abs(diff) * (1.0f - (stepCurve + 1.0f) / 2.0f) * 2.0f; - samplesOut->operator[](startLoc + i) += diff / stepCountB * smooth; + (*samplesOut)[startLoc + i] += diff / stepCountB * smooth; } // fade in for (unsigned int i = startLoc; i < endLoc; i++) { - float x = xArray->operator[](i) / fadeInStartLoc; + float x = (*xArray)[i] / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + startLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out for (unsigned int i = endLoc - 1; i > startLoc; i--) { - float x = (1.0f - xArray->operator[](i)) / fadeInStartLoc; + float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; if (x > 1.0f) { break; } - samplesOut->operator[](i) = samplesOut->operator[](i) * x + endLocVal * (1.0f - x); + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, @@ -3387,9 +3387,9 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample float size = static_cast(randomValues.size() / 2); for (unsigned int i = 0; i < count; i++) { - float randomValueX = xArray->operator[](startLoc + i) * size; + float randomValueX = (*xArray)[startLoc + i] * size; float randomValueLocation = std::floor(randomValueX); - samplesOut->operator[](startLoc + i) += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * randomAmp; } } @@ -3409,15 +3409,15 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // we can not skip gaps because // every updatingPointLocations point effects their line only // (the line that starts with the point) - if (updatingPointLocations->operator[](updatingEnd) + 1 >= - updatingPointLocations->operator[](j)) + if ((*updatingPointLocations)[updatingEnd] + 1 >= + (*updatingPointLocations)[j]) { updatingEnd = j; qDebug("getUpdatingFromEffector new updatingEnd: %d, i: %d", updatingEnd, i); } else { - qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, (updatingPointLocations->operator[](updatingEnd) + 1), updatingPointLocations->operator[](j), j); + qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); break; } } @@ -3432,7 +3432,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // translating the effector data array locations to m_dataArray locations bool found = false; bool isBefore = false; - int locationBefore = getNearestLocation(effector->getX(updatingPointLocations->operator[](i)), &found, &isBefore); + int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); if (isBefore == false && locationBefore >= 0 && getEffectOnlyPoints(locationBefore) == true) { @@ -3448,8 +3448,8 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - int locationAfter = getNearestLocation(effector->getX(updatingPointLocations->operator[](updatingEnd) + updatingEndSlide), &found, &isBefore); - qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX(updatingPointLocations->operator[](updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); + int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); + qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); if (isBefore == false) { qDebug("getUpdatingFromEffector locationAfter = %d - 1", locationAfter); @@ -3457,14 +3457,14 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationAfter--; } // updating everything before if i -> 0 - if (updatingPointLocations->operator[](i) == 0) + if ((*updatingPointLocations)[i] == 0) { qDebug("getUpdatingFromEffector updating everything before"); locationBefore = 0; } // if updatingEnd is the last point in effecor, then // update everithing after - if (updatingPointLocations->operator[](updatingEnd) + updatingEndSlide + 1 >= effector->size()) + if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) { qDebug("getUpdatingFromEffector updating everything after"); locationAfter = m_dataArray.size() - 1; @@ -3735,8 +3735,8 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorSamples->size()); // current effector output Y near m_needsUpdating[pointLocation] point - float curEffectY = effectorSamples->operator[](effectYLocation); - float nextEffectY = effectorSamples->operator[](effectYLocation); + float curEffectY = (*effectorSamples)[effectYLocation]; + float nextEffectY = (*effectorSamples)[effectYLocation]; // getting the final automatable / effectable point values float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); @@ -3771,7 +3771,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, ((getEffectOnlyPoints(m_needsUpdating[pointLocation]) == true && isEffectedPoint(m_needsUpdating[pointLocation]) == true) || isEffectedPoint(m_needsUpdating[pointLocation]) == false)) { - nextEffectY = effectorSamples->operator[](effectYLocation); + nextEffectY = (*effectorSamples)[effectYLocation]; nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); } } @@ -3803,7 +3803,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // calculate curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); } // no line type } @@ -3812,7 +3812,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); } // line type processLineTypeArraySine(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, fadeInStart); @@ -3822,7 +3822,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); } // line type processLineTypeArraySineB(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); @@ -3832,7 +3832,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); } // line type processLineTypeArrayPeak(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); @@ -3842,7 +3842,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); } // line type processLineTypeArraySteps(&m_updatingBakedSamples, outputXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); @@ -3852,7 +3852,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, outputXLocations->operator[](j)); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); } // line type processLineTypeArrayRandom(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); @@ -3866,7 +3866,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % qDebug("getSamples run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { - m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, effectorSamples->operator[](j)); + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); } } // clamp From 636c3502ee4012f18db3aded348bb673d4f7d274 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 10:41:03 +0200 Subject: [PATCH 111/184] WaveShaper_replaced_operator[]() --- plugins/WaveShaper/WaveShaper.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index 3ca84fae323..7fae145f28e 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -117,17 +117,17 @@ Effect::ProcessStatus WaveShaperEffect::processImpl(SampleFrame* buf, const fpp_ if( lookup < 1 ) { - s[i] = frac * graphSamples->operator[](0) * posneg; + s[i] = frac * (*graphSamples)[0] * posneg; } else if( lookup < 200 ) { - s[i] = linearInterpolate(graphSamples->operator[](lookup - 1), - graphSamples->operator[](lookup), frac) + s[i] = linearInterpolate((*graphSamples)[lookup - 1], + (*graphSamples)[lookup], frac) * posneg; } else { - s[i] *= graphSamples->operator[](199); + s[i] *= (*graphSamples)[199]; } } From 4e10a9730d72b84b90793946d3c7d0cbc01c8764 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 13:59:19 +0200 Subject: [PATCH 112/184] VectorGraph_new_view_base_class_added --- include/VectorGraph.h | 16 +- include/VectorGraphViewBase.h | 76 +++++++++ src/gui/CMakeLists.txt | 1 + src/gui/widgets/VectorGraph.cpp | 155 ++---------------- src/gui/widgets/VectorGraphViewBase.cpp | 203 ++++++++++++++++++++++++ 5 files changed, 300 insertions(+), 151 deletions(-) create mode 100644 include/VectorGraphViewBase.h create mode 100644 src/gui/widgets/VectorGraphViewBase.cpp diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 6003d8034bc..70622979053 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -33,6 +33,7 @@ #include #include +#include "VectorGraphViewBase.h" #include "Model.h" #include "ModelView.h" #include "lmms_basics.h" @@ -42,6 +43,7 @@ namespace lmms { +//class VectorGraphViewBase; class VectorGraphModel; class VectorGraphDataArray; class FloatModel; @@ -50,7 +52,7 @@ using PointF = std::pair; namespace gui { -class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView +class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView { Q_OBJECT // set default VectorGraph css colors and styles @@ -78,11 +80,13 @@ class LMMS_EXPORT VectorGraphView : public QWidget, public ModelView void setControlHeight(unsigned int controlHeight); void setControlDisplayCount(unsigned int controlDisplayCount); + inline VectorGraphModel* model() { return castModel(); } + // draws estimated line, does not call getSamples() // does not fill graphs with VectorGraphDataArray FillColor void setIsSimplified(bool isSimplified); @@ -116,9 +120,7 @@ protected slots: void updateGraph(bool shouldUseGetLastSamples); void updateDefaultColors(); - void execConnectionDialog(); - void removeAutomation(); - void removeController(); + void contextMenuRemoveAutomation(); private: void paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer); void paintEditing(QPainter* p); @@ -162,12 +164,6 @@ protected slots: QColor getFillColorFromBaseColor(QColor baseColor); // cuts the string to displayedLength(in px) size (estimated) QString getTextFromDisplayLength(QString text, unsigned int displayLength); - // context menu actions - void addDefaultActions(QMenu* menu, QString controlDisplayText); - - // inputDialog - PointF showCoordInputDialog(); - float showInputDialog(float curInputValue); // selection // searches VectorGraphDataArray-s to select diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h new file mode 100644 index 00000000000..2532d2c2fb9 --- /dev/null +++ b/include/VectorGraphViewBase.h @@ -0,0 +1,76 @@ +/* + * VecorGraph.h - Vector graph widget and model implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 LMMS_GUI_VECTORGRAPHVIEWBASE_H +#define LMMS_GUI_VECTORGRAPHVIEWBASE_H + +#include +#include +#include + +#include "ModelView.h" +#include "SimpleTextFloat.h" +#include "AutomatableModel.h" + +namespace lmms +{ + +class VectorGraphModel; +class FloatModel; + +namespace gui +{ +class LMMS_EXPORT VectorGraphViewBase : public QWidget +{ + Q_OBJECT +public: + VectorGraphViewBase(QWidget* parent); + ~VectorGraphViewBase(); + + +protected slots: + virtual void contextMenuRemoveAutomation() = 0; +protected: + void showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDesplay, int msecDisplayTime); + void hideHintText(); + void connectToAutomationTrack(QMouseEvent* me, FloatModel* automationModel, QWidget* thisWidget); + + // context menu + void showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName); + + // inputDialog + std::pair showCoordInputDialog(std::pair pointPosition); + float showInputDialog(float curInputValue); + +private slots: + void contextMenuExecConnectionDialog(FloatModel* automationModel); +private: + void addDefaultActions(QMenu* menu, FloatModel* automationModel, QString controlDisplayText); + + SimpleTextFloat* m_hintText; +}; +} // namespace gui +} // namespace lmms + +#endif // LMMS_GUI_VECTORGRAPHVIEWBASE_H diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index feafce25c2d..f9f6911c289 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -129,6 +129,7 @@ SET(LMMS_SRCS gui/widgets/TimeDisplayWidget.cpp gui/widgets/ToolButton.cpp gui/widgets/VectorGraph.cpp + gui/widgets/VectorGraphViewBase.cpp PARENT_SCOPE ) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1f1a15aef2c..d57fb34e6dd 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -37,6 +37,7 @@ #include // locking when getSamples +#include "VectorGraphViewBase.h" #include "StringPairDrag.h" #include "CaptionMenu.h" // context menu #include "embed.h" // context menu @@ -57,7 +58,8 @@ namespace gui { VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors) : - QWidget(parent), + VectorGraphViewBase(parent), + //QWidget(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this) { resize(widgetWidth, widgetHeight); @@ -235,16 +237,11 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) { qDebug("mousePress automation started"); - // connect to automation + // connect to AutomationTrack model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - // check if setAutomated is failed (like when isAutomatableEffecable is not enabled) - if (curFloatModel != nullptr) - { - qDebug("mousePress automation sent"); - new gui::StringPairDrag("automatable_model", QString::number(curFloatModel->id()), QPixmap(), widget()); - me->accept(); - } + // (VectorGraphViewBase method:) + connectToAutomationTrack(me, curFloatModel, widget()); } else { @@ -511,7 +508,7 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) if (m_isSelected == true && me->button() == Qt::LeftButton) { // display dialog - PointF curData = showCoordInputDialog(); + PointF curData = showCoordInputDialog(getSelectedData()); // change data setSelectedData(curData); } @@ -873,45 +870,7 @@ void VectorGraphView::updateDefaultColors() applyDefaultColors(); } } -void VectorGraphView::execConnectionDialog() -{ - if (m_isSelected == true) - { - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), curAutomationModel); - - if (dialog.exec() == 1) - { - // Actually chose something - if (curAutomationModel != nullptr && dialog.chosenController() != nullptr) - { - // Update - if (curAutomationModel->controllerConnection() != nullptr) - { - curAutomationModel->controllerConnection()->setController(dialog.chosenController()); - } - else - { - // New - auto cc = new ControllerConnection(dialog.chosenController()); - curAutomationModel->setControllerConnection(cc); - } - } - else - { - // no controller, so delete existing connection - removeController(); - } - } - else - { - // did not return 1 -> delete the created floatModel - removeController(); - } - } -} -void VectorGraphView::removeAutomation() +void VectorGraphView::contextMenuRemoveAutomation() { if (m_isSelected == true) { @@ -919,10 +878,6 @@ void VectorGraphView::removeAutomation() model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); } } -void VectorGraphView::removeController() -{ - removeAutomation(); -} PointF VectorGraphView::mapMousePos(int x, int y) { @@ -1080,10 +1035,13 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i controlDisplayText = controlDisplayText + QString(" (") + m_controlLineEffectText[typeVal] + QString(")"); } } + + // getting the currently selected point's FloatModel + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + // show context menu - CaptionMenu contextMenu(model()->displayName() + QString(" - ") + controlDisplayText); - addDefaultActions(&contextMenu, m_controlText[location]); - contextMenu.exec(QCursor::pos()); + showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); } else if (isDragging == false && m_controlIsFloat[location] == false) { @@ -1391,91 +1349,6 @@ QString VectorGraphView::getTextFromDisplayLength(QString text, unsigned int dis } return output; } -void VectorGraphView::addDefaultActions(QMenu* menu, QString controlDisplayText) -{ - // context menu settings - menu->addAction(embed::getIconPixmap("reload"), - tr("name: ") + controlDisplayText, - this, SLOT(updateGraph())); - menu->addAction(embed::getIconPixmap("reload"), - tr("remove automation"), - this, SLOT(removeAutomation())); - menu->addSeparator(); - - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - QString controllerTxt; - - menu->addAction(embed::getIconPixmap("controller"), - tr("Connect to controller..."), - this, SLOT(execConnectionDialog())); - if(curAutomationModel != nullptr && curAutomationModel->controllerConnection() != nullptr) - { - - Controller* cont = curAutomationModel->controllerConnection()->getController(); - if(cont) - { - controllerTxt = AutomatableModel::tr( "Connected to %1" ).arg( cont->name() ); - } - else - { - controllerTxt = AutomatableModel::tr( "Connected to controller" ); - } - - - QMenu* contMenu = menu->addMenu(embed::getIconPixmap("controller"), controllerTxt); - - contMenu->addAction(embed::getIconPixmap("cancel"), - tr("Remove connection"), - this, SLOT(removeAutomation())); - } -} - -PointF VectorGraphView::showCoordInputDialog() -{ - PointF curData(0.0f, 0.0f); - if (m_isSelected == true) - { - curData = getSelectedData(); - - // show position input dialog - bool ok; - double changedX = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between 0 and 100"), - static_cast(curData.first * 100.0f), - 0.0, 100.0, 2, &ok); - if (ok == true) - { - curData.first = static_cast(changedX) / 100.0f; - } - - double changedY = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between -100 and 100"), - static_cast(curData.second * 100.0f), - -100.0, 100.0, 2, &ok); - if (ok == true) - { - curData.second = static_cast(changedY) / 100.0f; - } - } - return curData; -} -float VectorGraphView::showInputDialog(float curInputValue) -{ - float output = 0.0f; - - bool ok; - double changedPos = QInputDialog::getDouble(this, tr("Set value"), - tr("Please enter a new value between -100 and 100"), - static_cast(curInputValue * 100.0f), - -100.0, 100.0, 2, &ok); - if (ok == true) - { - output = static_cast(changedPos) / 100.0f; - } - - return output; -} void VectorGraphView::selectData(int mouseX, int mouseY) { diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp new file mode 100644 index 00000000000..9fe2682059a --- /dev/null +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -0,0 +1,203 @@ +/* + * VectorGraph.cpp - Vector graph widget, model, helper class implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 "VectorGraphViewBase.h" + +#include +#include // showInputDialog() +#include // context menu + + +#include "StringPairDrag.h" +#include "CaptionMenu.h" // context menu +#include "embed.h" // context menu +#include "MainWindow.h" // getting main window for context menu +#include "GuiApplication.h" // getGUI +#include "SimpleTextFloat.h" +#include "AutomatableModel.h" +#include "ControllerConnectionDialog.h" +#include "ControllerConnection.h" + + +namespace lmms +{ + +namespace gui +{ +VectorGraphViewBase::VectorGraphViewBase(QWidget* parent) : + QWidget(parent), + m_hintText(new SimpleTextFloat) +{ +} +VectorGraphViewBase::~VectorGraphViewBase() +{ + delete m_hintText; +} + +void VectorGraphViewBase::showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDisplay, int msecDisplayTime) +{ + m_hintText->setText(hintText); + m_hintText->moveGlobal(thisWidget, QPoint(width() + 2, 0)); + m_hintText->showWithDelay(msecBeforeDisplay, msecDisplayTime); +} +void VectorGraphViewBase::hideHintText() +{ + m_hintText->hide(); +} + +void VectorGraphViewBase::connectToAutomationTrack(QMouseEvent* me, FloatModel* automationModel, QWidget* thisWidget) +{ + if (automationModel != nullptr) + { + qDebug("mousePress automation sent"); + new gui::StringPairDrag("automatable_model", QString::number(automationModel->id()), QPixmap(), thisWidget); + me->accept(); + } +} + +void VectorGraphViewBase::showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName) +{ + CaptionMenu contextMenu(displayName + QString(" - ") + controlName); + addDefaultActions(&contextMenu, automationModel, controlName); + contextMenu.exec(point); +} +void VectorGraphViewBase::addDefaultActions(QMenu* menu, FloatModel* automationModel, QString controlDisplayText) +{ + // context menu settings + menu->addAction(embed::getIconPixmap("reload"), + tr("name: ") + controlDisplayText, + this, SLOT(contextMenuRemoveAutomation())); + menu->addAction(embed::getIconPixmap("reload"), + tr("remove automation"), + this, SLOT(contextMenuRemoveAutomation())); + menu->addSeparator(); + + QString controllerTxt; + + menu->addAction(embed::getIconPixmap("controller"), + tr("Connect to controller..."), + this, SLOT(execConnectionDialog(automationModel))); + if(automationModel != nullptr && automationModel->controllerConnection() != nullptr) + { + + Controller* cont = automationModel->controllerConnection()->getController(); + if(cont) + { + controllerTxt = AutomatableModel::tr( "Connected to %1" ).arg( cont->name() ); + } + else + { + controllerTxt = AutomatableModel::tr( "Connected to controller" ); + } + + + QMenu* contMenu = menu->addMenu(embed::getIconPixmap("controller"), controllerTxt); + + contMenu->addAction(embed::getIconPixmap("cancel"), + tr("Remove connection"), + this, SLOT(contextMenuRemoveAutomation())); + } +} + +void VectorGraphViewBase::contextMenuExecConnectionDialog(FloatModel* automationModel) +{ + if (automationModel != nullptr) + { + gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), automationModel); + + if (dialog.exec() == 1) + { + // Actually chose something + if (dialog.chosenController() != nullptr) + { + // Update + if (automationModel->controllerConnection() != nullptr) + { + automationModel->controllerConnection()->setController(dialog.chosenController()); + } + else + { + // New + auto cc = new ControllerConnection(dialog.chosenController()); + automationModel->setControllerConnection(cc); + } + } + else + { + // no controller, so delete existing connection + contextMenuRemoveAutomation(); + } + } + else + { + // did not return 1 -> delete the created floatModel + contextMenuRemoveAutomation(); + } + } +} + +std::pair VectorGraphViewBase::showCoordInputDialog(std::pair pointPosition) +{ + // show position input dialog + bool ok; + double changedX = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between 0 and 100"), + static_cast(pointPosition.first * 100.0f), + 0.0, 100.0, 2, &ok); + if (ok == true) + { + pointPosition.first = static_cast(changedX) / 100.0f; + } + + double changedY = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between -100 and 100"), + static_cast(pointPosition.second * 100.0f), + -100.0, 100.0, 2, &ok); + if (ok == true) + { + pointPosition.second = static_cast(changedY) / 100.0f; + } + return pointPosition; +} +float VectorGraphViewBase::showInputDialog(float curInputValue) +{ + float output = 0.0f; + + bool ok; + double changedPos = QInputDialog::getDouble(this, tr("Set value"), + tr("Please enter a new value between -100 and 100"), + static_cast(curInputValue * 100.0f), + -100.0, 100.0, 2, &ok); + if (ok == true) + { + output = static_cast(changedPos) / 100.0f; + } + + return output; +} + + +} // namespace gui +} // namespace lmms From 1ec9331b444bdc69780ca84d958b52b19642b55c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 16:28:52 +0200 Subject: [PATCH 113/184] VectorGraph_hint_text_added --- include/VectorGraph.h | 6 +++- src/gui/widgets/VectorGraph.cpp | 48 +++++++++++++++++++------ src/gui/widgets/VectorGraphViewBase.cpp | 2 +- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 70622979053..30af2c8d2b0 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -115,6 +115,8 @@ class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView void mouseMoveEvent(QMouseEvent* me) override; void mouseReleaseEvent(QMouseEvent* me) override; void mouseDoubleClickEvent(QMouseEvent* me) override; + + void leaveEvent(QEvent *event) override; protected slots: void updateGraph(); void updateGraph(bool shouldUseGetLastSamples); @@ -164,6 +166,8 @@ protected slots: QColor getFillColorFromBaseColor(QColor baseColor); // cuts the string to displayedLength(in px) size (estimated) QString getTextFromDisplayLength(QString text, unsigned int displayLength); + // outputs m_controlText for the line type or the switch autmated location or effected location control + QString getTextForAutomatableEffectableOrType(unsigned int controlLocation); // selection // searches VectorGraphDataArray-s to select @@ -217,7 +221,7 @@ protected slots: tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; - std::array m_controlLineEffectText = { + std::array m_controlLineTypeText = { tr("none"), tr("sine"), tr("phase changable sine"), diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d57fb34e6dd..8df701f135e 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -88,7 +88,7 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe m_isEditingActive = false; // set in .h //m_controlText - //m_controlLineEffectText + //m_controlLineTypeText //m_controlIsFloat m_lastTrackPoint.first = -1; @@ -531,6 +531,10 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) } } } +void VectorGraphView::leaveEvent(QEvent *event) +{ + hideHintText(); +} void VectorGraphView::paintEvent(QPaintEvent* pe) { @@ -1015,6 +1019,7 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i m_controlDisplayPage = 0; } qDebug("mouseRelease controlPage: %d", m_controlDisplayPage); + hideHintText(); } else if (pressLocation >= 0 && location < m_controlText.size()) { @@ -1026,15 +1031,7 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i // if the right mouse button was pressed // get context menu input text QString controlDisplayText = m_controlText[location]; - if (location == 5) - { - bool isTrue = false; - int typeVal = static_cast(getInputAttribValue(location, &isTrue)); - if (typeVal < m_controlLineEffectText.size()) - { - controlDisplayText = controlDisplayText + QString(" (") + m_controlLineEffectText[typeVal] + QString(")"); - } - } + controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); // getting the currently selected point's FloatModel model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); @@ -1056,6 +1053,12 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i curBoolValue = !curBoolValue; } setInputAttribValue(location, 0.0f, curBoolValue); + + + // hint text + QString hintText = m_controlText[location]; + hintText = hintText + getTextForAutomatableEffectableOrType(location); + showHintText(widget(), hintText, 5, 3500); } else if (isDragging == true && m_controlIsFloat[location] == true) { @@ -1077,6 +1080,10 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2), convertedCoords.second); setInputAttribValue(location, convertedCoords.second, false); + + + // hint text + showHintText(widget(), m_controlText[location], 5, 3500); } } } @@ -1349,6 +1356,27 @@ QString VectorGraphView::getTextFromDisplayLength(QString text, unsigned int dis } return output; } +QString VectorGraphView::getTextForAutomatableEffectableOrType(unsigned int controlLocation) +{ + QString output; + if (controlLocation >= 0 && controlLocation <= 7) + { + bool isTrue = false; + int typeVal = static_cast(getInputAttribValue(controlLocation, &isTrue)); + if (controlLocation == 5) + { + if (typeVal < m_controlLineTypeText.size()) + { + output = QString(" (") + m_controlLineTypeText[typeVal] + QString(")"); + } + } + else + { + output = QString(tr(" (controls: ")) + m_controlText[1 + typeVal] + QString(")"); + } + } + return output; +} void VectorGraphView::selectData(int mouseX, int mouseY) { diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 9fe2682059a..6146e207a01 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -59,7 +59,7 @@ VectorGraphViewBase::~VectorGraphViewBase() void VectorGraphViewBase::showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDisplay, int msecDisplayTime) { m_hintText->setText(hintText); - m_hintText->moveGlobal(thisWidget, QPoint(width() + 2, 0)); + m_hintText->moveGlobal(thisWidget, QPoint(0, 0)); m_hintText->showWithDelay(msecBeforeDisplay, msecDisplayTime); } void VectorGraphViewBase::hideHintText() From 1a66be996372827119ed21c9622783ee1f04dcb5 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 17:06:57 +0200 Subject: [PATCH 114/184] VectorGraph_improved_automation_selection --- include/VectorGraphViewBase.h | 6 ++--- src/gui/widgets/VectorGraph.cpp | 29 +++++++++++++++---------- src/gui/widgets/VectorGraphViewBase.cpp | 23 ++++++++++---------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 2532d2c2fb9..73a47947f71 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -51,6 +51,7 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget protected slots: virtual void contextMenuRemoveAutomation() = 0; + virtual void contextMenuExecConnectionDialog(); protected: void showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDesplay, int msecDisplayTime); void hideHintText(); @@ -63,12 +64,11 @@ protected slots: std::pair showCoordInputDialog(std::pair pointPosition); float showInputDialog(float curInputValue); -private slots: - void contextMenuExecConnectionDialog(FloatModel* automationModel); private: - void addDefaultActions(QMenu* menu, FloatModel* automationModel, QString controlDisplayText); + void addDefaultActions(QMenu* menu, QString controlDisplayText); SimpleTextFloat* m_hintText; + FloatModel* m_curAutomationModel; }; } // namespace gui } // namespace lmms diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 8df701f135e..bfd16b5d4af 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -486,6 +486,9 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) } } //qDebug("mouseRelease select new array final:", m_selectedArray); + + // hint text + hideHintText(); } m_mousePress = false; m_addition = false; @@ -1028,17 +1031,21 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i if (m_addition == false) { - // if the right mouse button was pressed - // get context menu input text - QString controlDisplayText = m_controlText[location]; - controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); - - // getting the currently selected point's FloatModel - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - - // show context menu - showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); + if (location >= 1 && location <= 4) + { + // if the right mouse button was pressed on a automatabel attribute + // get context menu input text + QString controlDisplayText = m_controlText[location]; + controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); + setInputAttribValue(6, location - 1, false); + + // getting the currently selected point's FloatModel + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + + // show context menu + showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); + } } else if (isDragging == false && m_controlIsFloat[location] == false) { diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 6146e207a01..3c77df76407 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -79,11 +79,12 @@ void VectorGraphViewBase::connectToAutomationTrack(QMouseEvent* me, FloatModel* void VectorGraphViewBase::showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName) { + m_curAutomationModel = automationModel; CaptionMenu contextMenu(displayName + QString(" - ") + controlName); - addDefaultActions(&contextMenu, automationModel, controlName); + addDefaultActions(&contextMenu, controlName); contextMenu.exec(point); } -void VectorGraphViewBase::addDefaultActions(QMenu* menu, FloatModel* automationModel, QString controlDisplayText) +void VectorGraphViewBase::addDefaultActions(QMenu* menu, QString controlDisplayText) { // context menu settings menu->addAction(embed::getIconPixmap("reload"), @@ -98,11 +99,11 @@ void VectorGraphViewBase::addDefaultActions(QMenu* menu, FloatModel* automationM menu->addAction(embed::getIconPixmap("controller"), tr("Connect to controller..."), - this, SLOT(execConnectionDialog(automationModel))); - if(automationModel != nullptr && automationModel->controllerConnection() != nullptr) + this, SLOT(contextMenuExecConnectionDialog())); + if(m_curAutomationModel != nullptr && m_curAutomationModel->controllerConnection() != nullptr) { - Controller* cont = automationModel->controllerConnection()->getController(); + Controller* cont = m_curAutomationModel->controllerConnection()->getController(); if(cont) { controllerTxt = AutomatableModel::tr( "Connected to %1" ).arg( cont->name() ); @@ -121,11 +122,11 @@ void VectorGraphViewBase::addDefaultActions(QMenu* menu, FloatModel* automationM } } -void VectorGraphViewBase::contextMenuExecConnectionDialog(FloatModel* automationModel) +void VectorGraphViewBase::contextMenuExecConnectionDialog() { - if (automationModel != nullptr) + if (m_curAutomationModel != nullptr) { - gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), automationModel); + gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), m_curAutomationModel); if (dialog.exec() == 1) { @@ -133,15 +134,15 @@ void VectorGraphViewBase::contextMenuExecConnectionDialog(FloatModel* automation if (dialog.chosenController() != nullptr) { // Update - if (automationModel->controllerConnection() != nullptr) + if (m_curAutomationModel->controllerConnection() != nullptr) { - automationModel->controllerConnection()->setController(dialog.chosenController()); + m_curAutomationModel->controllerConnection()->setController(dialog.chosenController()); } else { // New auto cc = new ControllerConnection(dialog.chosenController()); - automationModel->setControllerConnection(cc); + m_curAutomationModel->setControllerConnection(cc); } } else From 8dadd46f631eeffc72ed2908854b787ab4f373c7 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 4 May 2024 17:45:39 +0200 Subject: [PATCH 115/184] VectorGraph_optimized_line_types --- include/VectorGraph.h | 12 +++--- src/gui/widgets/VectorGraph.cpp | 66 ++++++++++++--------------------- 2 files changed, 29 insertions(+), 49 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 30af2c8d2b0..078ab7c3536 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -613,22 +613,22 @@ class LMMS_EXPORT VectorGraphDataArray float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); // line types, m_type is used for this - // fadeInStartLoc: from what relative x value should the line type fade out + // fadeInStartVal: from what relative x value should the line type fade out // linking: valA: sineAmp, valB: sineFreq void processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float fadeInStartLoc); + float sineAmp, float sineFreq, float fadeInStartVal); // linking: valA: sineAmp, valB: sineFreq, curve: sinePhase void processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc); + float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal); // linking: valA: amp, valB: x coord, curve: width void processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float peakAmp, float peakX, float peakWidth, float fadeInStartLoc); + float peakAmp, float peakX, float peakWidth, float fadeInStartVal); // linking: y: yArray, valA: stepCount, valB: stepCurve void processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc); + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal); // linking: valA: randomAmp, valB: randomCount, curve: randomSeed void processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc); + float randomAmp, float randomCount, float randomSeed, float fadeInStartVal); // updating // adds the m_dataArray points that are diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index bfd16b5d4af..72a6d7fadf1 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3109,13 +3109,13 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float } void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float fadeInStartLoc) + float sineAmp, float sineFreq, float fadeInStartVal) { processLineTypeArraySineB(samplesOut, xArray, startLoc, endLoc, - sineAmp, sineFreq, 0.0f, fadeInStartLoc); + sineAmp, sineFreq, 0.0f, fadeInStartVal); } void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float sinePhase, float fadeInStartLoc) + float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal) { float startLocVal = (*samplesOut)[startLoc]; float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; @@ -3137,7 +3137,8 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples { end = end > count ? count : end + 1; } - std::vector oneWave(end); + // allocate 1 part of a sine wave on the stack + float oneWave[end]; // calculate 1 wave of sine for (unsigned int i = 0; i < end; i++) @@ -3162,28 +3163,21 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples //qDebug("sineB_3"); // fade in - for (unsigned int i = startLoc; i < endLoc; i++) + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) { - float x = (*xArray)[i] / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (*xArray)[i] / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out - for (unsigned int i = endLoc - 1; i > startLoc; i--) + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) { - float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float peakAmp, float peakX, float peakWidth, float fadeInStartLoc) + float peakAmp, float peakX, float peakWidth, float fadeInStartVal) { float startLocVal = (*samplesOut)[startLoc]; float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; @@ -3199,28 +3193,21 @@ void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesO } // fade in - for (unsigned int i = startLoc; i < endLoc; i++) + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) { - float x = (*xArray)[i] / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (*xArray)[i] / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out - for (unsigned int i = endLoc - 1; i > startLoc; i--) + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) { - float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float stepCount, float stepCurve, float fadeInStartLoc) + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal) { float startLocVal = (*samplesOut)[startLoc]; float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; @@ -3241,28 +3228,21 @@ void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samples } // fade in - for (unsigned int i = startLoc; i < endLoc; i++) + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) { - float x = (*xArray)[i] / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (*xArray)[i] / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); } // fade out - for (unsigned int i = endLoc - 1; i > startLoc; i--) + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) { - float x = (1.0f - (*xArray)[i]) / fadeInStartLoc; - if (x > 1.0f) - { - break; - } + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); } } void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float randomAmp, float randomCount, float randomSeed, float fadeInStartLoc) + float randomAmp, float randomCount, float randomSeed, float fadeInStartVal) { int count = static_cast(endLoc) - static_cast(startLoc); if (count < 0) From 83b079588bc7d42dd3f6265d74f5e911b6528ae0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 08:49:11 +0200 Subject: [PATCH 116/184] VectorGraph_updated_comments_in_base --- include/VectorGraphViewBase.h | 6 ++++-- src/gui/widgets/VectorGraphViewBase.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 73a47947f71..c5996f0fb65 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -1,5 +1,5 @@ /* - * VecorGraph.h - Vector graph widget and model implementation + * VectorGraphViewBase.h - contains implementations of lmms widget classes for VectorGraph * * Copyright (c) 2024 szeli1 TODO * @@ -48,13 +48,14 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget VectorGraphViewBase(QWidget* parent); ~VectorGraphViewBase(); - protected slots: virtual void contextMenuRemoveAutomation() = 0; virtual void contextMenuExecConnectionDialog(); protected: + // hints, SimpleTextFloat void showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDesplay, int msecDisplayTime); void hideHintText(); + // AutomationTrack void connectToAutomationTrack(QMouseEvent* me, FloatModel* automationModel, QWidget* thisWidget); // context menu @@ -65,6 +66,7 @@ protected slots: float showInputDialog(float curInputValue); private: + // context menu void addDefaultActions(QMenu* menu, QString controlDisplayText); SimpleTextFloat* m_hintText; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 3c77df76407..760b9b0cb62 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -1,5 +1,5 @@ /* - * VectorGraph.cpp - Vector graph widget, model, helper class implementation + * VectorGraphViewBase.cpp - contains implementations of lmms widget classes for VectorGraph * * Copyright (c) 2024 szeli1 TODO * From f802ed11ec23632702fdf035346ea24ed61e2516 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 09:30:50 +0200 Subject: [PATCH 117/184] VectorGraph_optimized_drawing_order --- include/VectorGraph.h | 10 +++-- src/gui/widgets/VectorGraph.cpp | 71 ++++++++++++++------------------- 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 078ab7c3536..7614c4a2288 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -284,11 +284,11 @@ Q_OBJECT } } // returns added VectorGraphDataArray location - unsigned int addArray(); + unsigned int addDataArray(); // deletes VectorGraphDataArray at arrayLocation // preservs the order - void delArray(unsigned int arrayLocation); - inline void clearArray() + void deleteDataArray(unsigned int arrayLocation); + inline void clearDataArray() { m_dataArrays.clear(); emit dataChanged(); @@ -368,6 +368,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns true if successful // if callDataChanged then it will call dataChanged() --> paintEvent() bool setEffectorArrayLocation(int arrayLocation, bool callDataChanged); + void setIsAnEffector(bool bValue); bool getIsFixedSize(); bool getIsFixedX(); @@ -385,6 +386,7 @@ class LMMS_EXPORT VectorGraphDataArray // returns -1 if it has no effector int getEffectorArrayLocation(); + bool getIsAnEffector(); int getId(); @@ -690,6 +692,8 @@ class LMMS_EXPORT VectorGraphDataArray // which VectorGraphDataArray can effect this one, -1 if not effected int m_effectorLocation; + // is this VectorGraphDataArray effects others? + bool m_isAnEffector; // ordered array of VectorGraphPoints std::vector m_dataArray; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 72a6d7fadf1..94e3df81963 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -560,50 +560,16 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) p.drawLine(0, height() - 1, width() - 1, height() - 1); p.drawLine(0, 0, 0, height() - 1); - std::vector effectArrays; std::vector sampleBuffer; // updating the VectorGraphDataArray samples before draw if (m_useGetLastSamples == false) { - // getting arrays that effect other arrays - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { - // getting the current array's effector array - int curArrayEffector = model()->getDataArray(i)->getEffectorArrayLocation(); - - if (curArrayEffector != -1) - { - bool found = false; - // checking if it is already in the list - for (unsigned int k = 0; k < effectArrays.size(); k++) - { - if (curArrayEffector == effectArrays[k]) - { - found = true; - break; - } - } - if (found == false) - { - effectArrays.push_back(curArrayEffector); - } - } - } - // updating arrays that do not effect other arrays first + // (this step will run getSamples() on effector arrays (-> every array will be updated about once)) for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - bool found = false; - for (unsigned int j = 0; j < effectArrays.size(); j++) - { - if (i == effectArrays[j]) - { - found = true; - break; - } - } - if (found == false) + if (model()->getDataArray(i)->getIsAnEffector() == false) { // this updates the array and its effector arrays // with width() sample count @@ -647,6 +613,7 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v posA = startPos; pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); + // get the currently drawed VectorGraphDataArray samples dataArray->getLastSamples(sampleBuffer); qDebug("paint sampleBuffer size: %ld", sampleBuffer->size()); @@ -1600,7 +1567,7 @@ VectorGraphModel::~VectorGraphModel() qDebug("VectorGraphModel dstc end"); } -unsigned int VectorGraphModel::addArray() +unsigned int VectorGraphModel::addDataArray() { VectorGraphDataArray tempArray( false, false, false, false, false, false, false, @@ -1610,9 +1577,9 @@ unsigned int VectorGraphModel::addArray() return m_dataArrays.size() - 1; } -void VectorGraphModel::delArray(unsigned int arrayLocation) +void VectorGraphModel::deleteDataArray(unsigned int arrayLocation) { - qDebug("delArray"); + qDebug("deleteDataArray"); std::vector effectorArrayLocations(m_dataArrays.size()); for (unsigned int i = arrayLocation; i < m_dataArrays.size() - 1; i++) { @@ -1639,7 +1606,7 @@ void VectorGraphModel::delArray(unsigned int arrayLocation) // setting updated locations for (unsigned int i = 0; i < m_dataArrays.size(); i++) { - //qDebug("delArray end: set effector location: [%d], %d", i, effectorArrayLocations[i]); + //qDebug("deleteDataArray end: set effector location: [%d], %d", i, effectorArrayLocations[i]); m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); } emit dataChanged(); @@ -1896,6 +1863,7 @@ VectorGraphDataArray::VectorGraphDataArray( m_fillColor = QColor(0, 0, 0, 0); m_effectorLocation = -1; + m_isAnEffector = false; // m_dataArray; m_isDataChanged = false; @@ -2050,6 +2018,7 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool call if (found == false) { m_effectorLocation = arrayLocation; + m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(true); getUpdatingFromPoint(-1); if (callDataChanged == true) { @@ -2061,7 +2030,20 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool call { if (m_effectorLocation != -1) { + // checking if this VectorGraphDataArray's effector is an effector for an other VectorGraphDataArray + bool found = false; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + if (m_parent->getDataArray(i)->getId() != m_id && m_parent->getDataArray(i)->getEffectorArrayLocation() == m_effectorLocation) + { + found = true; + break; + } + } + // setting the correct state for the effector array's m_isAnEffector + m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(found); m_effectorLocation = -1; + getUpdatingFromPoint(-1); if (callDataChanged == true) { @@ -2071,6 +2053,11 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool call } return !found; } +void VectorGraphDataArray::setIsAnEffector(bool bValue) +{ + m_isAnEffector = bValue; + // do not need to update anything after +} bool VectorGraphDataArray::getIsFixedSize() { @@ -2128,6 +2115,10 @@ int VectorGraphDataArray::getEffectorArrayLocation() { return m_effectorLocation; } +bool VectorGraphDataArray::getIsAnEffector() +{ + return m_isAnEffector; +} int VectorGraphDataArray::getId() { return m_id; From b6991a070f8af7f923747b1c21eae14862bc0c31 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 09:31:50 +0200 Subject: [PATCH 118/184] WaveShaper_updated_VectorGraph_functions --- plugins/WaveShaper/WaveShaperControls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 0a559bc03bf..4d4e59403c7 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -49,7 +49,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_clipModel( false, this ), m_vectorGraphSampleBuffer(200) { - unsigned int arrayLocation = m_vectorGraphModel.addArray(); + unsigned int arrayLocation = m_vectorGraphModel.addDataArray(); // see other settings avalible for VectorGraphDataArray in VectorGraph.h m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); @@ -57,7 +57,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); - unsigned int arrayLocationB = m_vectorGraphModel.addArray(); + unsigned int arrayLocationB = m_vectorGraphModel.addDataArray(); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); From 18bfed3b30c5b2c05d85e31c1f7dd1687c6103c7 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 09:54:15 +0200 Subject: [PATCH 119/184] VectorGraph_removed_vector_from_random_line_type --- src/gui/widgets/VectorGraph.cpp | 44 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 94e3df81963..982ac46fce2 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -563,7 +563,7 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) std::vector sampleBuffer; // updating the VectorGraphDataArray samples before draw - if (m_useGetLastSamples == false) + if (m_useGetLastSamples == false || m_isSimplified == true) { // updating arrays that do not effect other arrays first // (this step will run getSamples() on effector arrays (-> every array will be updated about once)) @@ -3240,30 +3240,34 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample { count = 0; } - std::vector randomValues(static_cast(50.0f * (randomCount + 1.0f)) * 2); - float blend = 10.0f + randomSeed * 10.0f; - int randomSeedB = static_cast(blend); - blend = blend - randomSeedB; - std::srand(randomSeedB); + unsigned int randomValuesSize = static_cast(50.0f * (randomCount + 1.0f)) * 2; - // getting the random values - // generating 2 seeds and blending in between them - for (unsigned int i = 0; i < randomValues.size() / 2; i++) + if (randomValuesSize > 0) { - randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } - std::srand(randomSeedB + 1); - for (unsigned int i = randomValues.size() / 2; i < randomValues.size(); i++) - { - randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } + float randomValues[randomValuesSize]; - // blending - if (randomValues.size() > 0) - { + float blend = 10.0f + randomSeed * 10.0f; + int randomSeedB = static_cast(blend); + blend = blend - randomSeedB; + + std::srand(randomSeedB); + + // getting the random values + // generating 2 seeds and blending in between them + for (unsigned int i = 0; i < randomValuesSize / 2; i++) + { + randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + std::srand(randomSeedB + 1); + for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) + { + randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + + // blending // real size - float size = static_cast(randomValues.size() / 2); + float size = static_cast(randomValuesSize / 2); for (unsigned int i = 0; i < count; i++) { float randomValueX = (*xArray)[startLoc + i] * size; From 241b122f71a79b6b58ba2af345f4da0374dcc5e5 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 12:33:16 +0200 Subject: [PATCH 120/184] VectorGraph_added_new_setting_for_effected_points --- include/VectorGraph.h | 38 +++++---- src/gui/widgets/VectorGraph.cpp | 138 +++++++++++++++++++++----------- 2 files changed, 116 insertions(+), 60 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 7614c4a2288..029410f7361 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -213,13 +213,13 @@ protected slots: unsigned int m_controlDisplayCount; unsigned int m_controlDisplayPage; bool m_isEditingActive; - std::array m_controlText = + std::array m_controlText = { tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), - tr("switch graph effected value"), tr("can only effect graph points"), tr("\"add\" effect"), tr("\"subtract\" effect"), - tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), - tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") + tr("switch graph effected value"), tr("can this point be effected"), tr("can this line be effected"), tr("\"add\" effect"), + tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), + tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; std::array m_controlLineTypeText = { tr("none"), @@ -229,12 +229,12 @@ protected slots: tr("steps"), tr("random") }; - std::array m_controlIsFloat = { + std::array m_controlIsFloat = { true, true, true, true, true, false, false, false, false, false, false, false, false, false, false, - false, false, false + false, false, false, false }; std::pair m_lastTrackPoint; @@ -446,10 +446,12 @@ class LMMS_EXPORT VectorGraphDataArray // returns attribLocation: 0 = m_y, 1 = m_c, 2 = m_valA, 3 = m_valB (int VectorGraphPoint) unsigned int getAutomatedAttribLocation(unsigned int pointLocation); unsigned int getEffectedAttribLocation(unsigned int pointLocation); - // returns true when m_effectOnlyPoints is true or - // when getEffectedAttribLocation > 0 (y is uneffected) - // -> when the current point CAN effect lines before it - bool getEffectOnlyPoints(unsigned int pointLocation); + // returns true when m_effectPoints is true or + // when getEffectedAttribLocation() > 0 (y is uneffected) + bool getEffectPoints(unsigned int pointLocation); + // returns true when m_effectLines is true and + // when getEffectedAttribLocation() == 0 (y is effected) + bool getEffectLines(unsigned int pointLocation); // returns if the effectId-th effect is active bool getEffect(unsigned int pointLocation, unsigned int effectId); // true when the automationModel's value changed since last check @@ -485,6 +487,7 @@ class LMMS_EXPORT VectorGraphDataArray // sort -> sort input positions // callDataChanged -> call dataChanged() after -> paintEvent() // PointF = std::pair + // ()the std::vector* inputDataArray modifies the array) void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); void setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); @@ -517,8 +520,11 @@ class LMMS_EXPORT VectorGraphDataArray // sets what attribute gets effected (by effector array) void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); // checks m_isAutomatableEffectable and m_isEditableAttrib - // if bValue is true then the effector array will not effect the line's individual samples - void setEffectOnlyPoints(unsigned int pointLocation, bool bValue); + // if bValue is true then the effector array will effect the point's attributes + void setEffectPoints(unsigned int pointLocation, bool bValue); + // checks m_isAutomatableEffectable and m_isEditableAttribs + // if bValue is true then the effector array will effect the line's individual samples (only when y is effected) + void setEffectLines(unsigned int pointLocation, bool bValue); // checks m_isAutomatableEffectable and m_isEditableAttrib // sets the point's effect type void setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue); @@ -580,10 +586,12 @@ class LMMS_EXPORT VectorGraphDataArray // use getAutomatedAttrib or getEffectedAttrib to get it unsigned int m_automatedEffectedAttribLocations = 0; - // if the point's line should effect only pointss - // getEffectOnlyPoints() will return true when + // if the point attributes should be effected, + // getEffectPoints() will return true when // effected attrib location > 0 - bool m_effectOnlyPoints = false; + bool m_effectPoints = false; + // if the line (each sample) should be effected (only works when y is effected) + bool m_effectLines = true; bool m_effectAdd = false; bool m_effectSubtract = false; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 982ac46fce2..39bfe73c0a4 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1119,33 +1119,36 @@ float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bo output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); break; case 8: - *valueOut = model()->getDataArray(m_selectedArray)->getEffectOnlyPoints(m_selectedLocation); + *valueOut = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation); break; case 9: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); + *valueOut = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation); break; case 10: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); break; case 11: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); break; case 12: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); break; case 13: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); break; case 14: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); break; case 15: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); break; case 16: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); break; case 17: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); + break; + case 18: *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 8); break; } @@ -1228,33 +1231,36 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, flo model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); break; case 8: - model()->getDataArray(m_selectedArray)->setEffectOnlyPoints(m_selectedLocation, boolValue); + model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, boolValue); break; case 9: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); + model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, boolValue); break; case 10: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); break; case 11: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); break; case 12: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); break; case 13: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); break; case 14: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); break; case 15: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); break; case 16: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); break; case 17: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); + break; + case 18: model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValue); break; } @@ -1333,7 +1339,7 @@ QString VectorGraphView::getTextFromDisplayLength(QString text, unsigned int dis QString VectorGraphView::getTextForAutomatableEffectableOrType(unsigned int controlLocation) { QString output; - if (controlLocation >= 0 && controlLocation <= 7) + if (controlLocation >= 5 && controlLocation <= 7) { bool isTrue = false; int typeVal = static_cast(getInputAttribValue(controlLocation, &isTrue)); @@ -2653,9 +2659,9 @@ void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigne m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation); getUpdatingFromPoint(pointLocation); - // if the current point can effect line before it + // if the current point can effect the line before it // update the point before it - if (getEffectOnlyPoints(pointLocation) == false && pointLocation > 0) + if (getEffectPoints(pointLocation) == false && pointLocation > 0) { getUpdatingFromPoint(pointLocation - 1); } @@ -2670,28 +2676,35 @@ unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int pointL { return m_dataArray[pointLocation].m_automatedEffectedAttribLocations % 4; } -bool VectorGraphDataArray::getEffectOnlyPoints(unsigned int pointLocation) +bool VectorGraphDataArray::getEffectPoints(unsigned int pointLocation) +{ + // be careful with changing this + return (m_dataArray[pointLocation].m_effectPoints == true || getEffectedAttribLocation(pointLocation) > 0); +} +bool VectorGraphDataArray::getEffectLines(unsigned int pointLocation) { - return (m_dataArray[pointLocation].m_effectOnlyPoints == true || getEffectedAttribLocation(pointLocation) > 0); + // be careful with changing this + // m_effectLines ought to be false if lines (each sample) can not be changed + return (m_dataArray[pointLocation].m_effectLines == true && getEffectedAttribLocation(pointLocation) == 0); } -void VectorGraphDataArray::setEffectOnlyPoints(unsigned int pointLocation, bool bValue) +void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bValue) { if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) { - if (m_dataArray[pointLocation].m_effectOnlyPoints != bValue) + if (m_dataArray[pointLocation].m_effectPoints != bValue) { - // getEffectOnlyPoints does not return m_effecteOnlyPoints - bool dataChangedValue = getEffectOnlyPoints(pointLocation); - m_dataArray[pointLocation].m_effectOnlyPoints = bValue; + // getEffectPoints does not return m_effectePoints + bool dataChangedValue = getEffectPoints(pointLocation); + m_dataArray[pointLocation].m_effectPoints = bValue; // this change does effect the main output if this // data array is an effector of an other so dataChanged() // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectOnlyPoints(pointLocation)) + if (dataChangedValue != getEffectPoints(pointLocation)) { getUpdatingFromPoint(pointLocation); - // if the current point can effect line before it + // if the current point can effect the line before it // update the point before it - if (getEffectedAttribLocation(pointLocation) <= 0&& pointLocation > 0) + if (getEffectedAttribLocation(pointLocation) <= 0 && pointLocation > 0) { getUpdatingFromPoint(pointLocation - 1); } @@ -2700,6 +2713,26 @@ void VectorGraphDataArray::setEffectOnlyPoints(unsigned int pointLocation, bool } } } +void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValue) +{ + if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) + { + if (m_dataArray[pointLocation].m_effectLines != bValue) + { + // getEffectLines does not return m_effectLines + bool dataChangedValue = getEffectLines(pointLocation); + m_dataArray[pointLocation].m_effectLines = bValue; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectLines(pointLocation)) + { + getUpdatingFromPoint(pointLocation); + } + dataChanged(); + } + } +} bool VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectId) { switch (effectId) @@ -2769,9 +2802,9 @@ void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int ef break; } getUpdatingFromPoint(pointLocation); - // if the current point can effect line before it + // if the current point can effect the line before it // update the point before it - if (getEffectOnlyPoints(pointLocation) == false && pointLocation > 0) + if (getEffectPoints(pointLocation) == true && pointLocation > 0) { getUpdatingFromPoint(pointLocation - 1); } @@ -3315,21 +3348,24 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // translating the effector data array locations to m_dataArray locations bool found = false; bool isBefore = false; + // this can return -1 int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); - if (isBefore == false && locationBefore >= 0 && getEffectOnlyPoints(locationBefore) == true) + if (isBefore == true && locationBefore > 0 && getEffectPoints(locationBefore) == true) { qDebug("getUpdatingFromEffector locationBefore = %d - 1", locationBefore); - // lines before could be effected eaven if the current nearest point - // can only be effected (its line can not be effected) + // the line (or point) before might be effected if the current nearest point + // is effected in some way // so subtract 1 // remember points control the line after (connected to) them // but in this case changes in the points position can effect the line before it locationBefore--; + // now (here) locationBefore is Always before (*updatingPointLocations)[i] } // clamp locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; + isBefore = false; int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); @@ -3357,13 +3393,26 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; qDebug("getUpdatingFromEffector start: %d, end: %d", locationBefore, locationAfter); + + // if the last point was updated (ture in case of j = 0) + bool lastUpdated = true; // adding the values between locationBefore, locationAfter for (unsigned int j = locationBefore; j <= locationAfter; j++) { - if (isEffectedPoint(j) == true) + // update only if effected + if (isEffectedPoint(j) == true && (getEffectPoints(j) == true || getEffectLines(j) == true)) { qDebug("getUpdatingFromEffector: [%d] -> %d", i, j); m_needsUpdating.push_back(j); + if (lastUpdated == false && getEffectPoints(j) == true) + { + m_needsUpdating.push_back(j - 1); + } + lastUpdated = true; + } + else + { + lastUpdated = false; } } if (i < updatingEnd) @@ -3626,7 +3675,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation]) == true) + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation]) == true && getEffectLines(m_needsUpdating[pointLocation]) == false) { curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); @@ -3647,12 +3696,11 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, end = effectYLocation; nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); - // if the current point can only be effected (and not its line) - // and the next point can only be effected - // this is done to avoid adding effectorSamples to the line and to the next point (line's end point) at the same time - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation] + 1) == true && - ((getEffectOnlyPoints(m_needsUpdating[pointLocation]) == true && isEffectedPoint(m_needsUpdating[pointLocation]) == true) || - isEffectedPoint(m_needsUpdating[pointLocation]) == false)) + bool isCurEffected = isEffectedPoint(m_needsUpdating[pointLocation]); + // if the next point (y location) can be effected + // and the current point's line is uneffected + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation] + 1) == true && + (getEffectLines(m_needsUpdating[pointLocation]) == false || isCurEffected == false)) { nextEffectY = (*effectorSamples)[effectYLocation]; nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); @@ -3740,7 +3788,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // line type processLineTypeArrayRandom(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); } - if (effector != nullptr && getEffectOnlyPoints(m_needsUpdating[pointLocation]) == false) + if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) { int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; From 017373615a85fc8c7a37f2410d44f56bd0892328 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 14:29:14 +0200 Subject: [PATCH 121/184] VectorGraph_optimized_getUpdatingOriginals_method --- src/gui/widgets/VectorGraph.cpp | 56 +++++++++++++-------------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 39bfe73c0a4..059b49601f3 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -3458,13 +3458,7 @@ void VectorGraphDataArray::getUpdatingFromAutomation() } void VectorGraphDataArray::getUpdatingOriginals() { - // selecting only original values - // TODO this might be faster if the sort happens before - std::vector originalValues; - if (m_needsUpdating.size() > 0) - { - originalValues.push_back(m_needsUpdating[0]); - } + // selecting only original values and sorting // Debug testing for (unsigned int i = 0; i < m_needsUpdating.size(); i++) @@ -3472,51 +3466,45 @@ void VectorGraphDataArray::getUpdatingOriginals() qDebug("getUpatingOriginals: [%d] -> %d", i, m_needsUpdating[i]); } - for (unsigned int i = 1; i < m_needsUpdating.size(); i++) + // sorting the array + // this is done becaues functions that use m_needsUpdating + // are optimized for a sorted array + std::sort(m_needsUpdating.begin(), m_needsUpdating.end(), + [](unsigned int a, unsigned int b) + { + return a < b; + }); + + // removing duplicates + int sizeDiff = 0; + for (int i = 1; i < m_needsUpdating.size(); i++) { - bool found = false; - for (unsigned int j = 0; j < originalValues.size(); j++) + if (m_needsUpdating[i - 1 + sizeDiff] == m_needsUpdating[i + sizeDiff]) { - if (m_needsUpdating[i] == originalValues[j]) + for (unsigned int j = i + sizeDiff; j < m_needsUpdating.size() - 1 + sizeDiff; j++) { - found = true; - break; + m_needsUpdating[j] = m_needsUpdating[j + 1]; } - } - if (found == false) - { - originalValues.push_back(m_needsUpdating[i]); + sizeDiff--; } } - - // sorting the array - // this is done to optimize the functions that use - // m_needsUpdating in getSamples() - std::sort(originalValues.begin(), originalValues.end(), - [](unsigned int a, unsigned int b) - { - return a < b; - }); + m_needsUpdating.resize(m_needsUpdating.size() + sizeDiff); // removing invalid locations - // because sometimes deleted locations can be in originalValues - for (unsigned int i = 0; i < originalValues.size(); i++) + // because sometimes deleted locations can be in m_needsUpdating + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - if (originalValues[i] >= m_dataArray.size()) + if (m_needsUpdating[i] >= m_dataArray.size()) { - originalValues.resize(i); + m_needsUpdating.resize(i); break; } } - - m_needsUpdating = originalValues; - /* for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); } - */ } void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) { From dd17f97ca6c20aa8b79b758c08d2547605b04813 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 15:08:56 +0200 Subject: [PATCH 122/184] VectorGraph_optimized_getSamples --- include/VectorGraph.h | 5 +- src/gui/widgets/VectorGraph.cpp | 117 ++++++++++++++++++-------------- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 029410f7361..75be27b04c2 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -658,10 +658,11 @@ class LMMS_EXPORT VectorGraphDataArray void getUpdatingOriginals(); // real getSamples processing - void getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); + void getSamplesInner(unsigned int targetSizeIn, std::vector* sampleXLocationsIn, bool* isChangedOut, + std::vector* updatingValuesOut, std::vector* sampleBufferOut); // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* outputXLocations, unsigned int pointLocation, float stepSize); + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize); bool isEffectedPoint(unsigned int pointLocation); // checks m_isFixedEndPoints, does not call dataChanged() diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 059b49601f3..deec864db7b 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2398,9 +2398,50 @@ int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bo void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut) { qDebug("getSamplesA1"); - m_parent->lockGetSamplesAccess(); - getSamples(targetSizeIn, nullptr, nullptr, sampleBufferOut); - m_parent->unlockGetSamplesAccess(); + + float stepSize = 1.0f / static_cast(targetSizeIn); + + + // calculating the relative X locations (in lines) of the output samples + // sampleXLocations[sample_location] is equal to 0.0f if it is at the start of a line + // and it is equal to 1.0f if it is at the end of a line + std::vector sampleXLocations(targetSizeIn); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + unsigned int start = static_cast + (std::ceil(m_dataArray[i].m_x / stepSize)); + if (i + 1 < m_dataArray.size()) + { + unsigned int end = static_cast + (std::ceil(m_dataArray[i + 1].m_x / stepSize)); + for (unsigned int j = start; j < end; j++) + { + sampleXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); + } + } + } + + if (sampleBufferOut != nullptr) + { + if (sampleBufferOut->size() != targetSizeIn) + { + sampleBufferOut->resize(targetSizeIn); + } + + m_parent->lockGetSamplesAccess(); + getSamplesInner(targetSizeIn, &sampleXLocations, nullptr, nullptr, sampleBufferOut); + m_parent->unlockGetSamplesAccess(); + } + else + { + // this needs to be allocated for getSamplesInner to work + // because every effector VectorGraphDataArray uses this to return its m_bakedValues directly + std::vector updatingSampleArray(targetSizeIn); + + m_parent->lockGetSamplesAccess(); + getSamplesInner(targetSizeIn, &sampleXLocations, nullptr, nullptr, &updatingSampleArray); + m_parent->unlockGetSamplesAccess(); + } qDebug("getSamplesA3 finished"); } void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) @@ -3506,19 +3547,19 @@ void VectorGraphDataArray::getUpdatingOriginals() qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); } } -void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) +void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, std::vector* sampleXLocationsIn, bool* isChangedOut, + std::vector* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); std::vector effectorUpdatingValues; - std::vector effectorOutput; - std::vector outputXLocations(targetSizeIn); + // sampleBufferOut will serve as the effector's sampleBufferOut until the new m_bakedSamples gets made bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { - m_parent->getDataArray(m_effectorLocation)->getSamples(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, &effectorOutput); + m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, sampleXLocationsIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); } - qDebug("getSamplesB1, size: %ld - id: %d", outputXLocations.size(), m_id); + qDebug("getSamplesB1, size: %ld - id: %d", sampleXLocationsIn->size(), m_id); m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); @@ -3578,30 +3619,6 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged // calculating point data and lines if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) { - if (effectorOutput.size() != targetSizeIn) - { - effectorOutput.resize(targetSizeIn); - } - - // calculating relative X locations (in lines) of the output values - // for later use in the line calculations - // outputXLocations[sample_location] is equal to 0.0f if it is at the start of a line, - // it is equal to 1.0f if it is at the end of a line - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - unsigned int start = static_cast - (std::ceil(m_dataArray[i].m_x / stepSize)); - if (i + 1 < m_dataArray.size()) - { - unsigned int end = static_cast - (std::ceil(m_dataArray[i + 1].m_x / stepSize)); - for (unsigned int j = start; j < end; j++) - { - outputXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - //qDebug("getSamplesB outputXLocations: [%d] [%d] %f", i, j, outputXLocations[j]); - } - } - } // getting effectorDataArray pointer VectorGraphDataArray* effector = nullptr; if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) @@ -3614,7 +3631,8 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - getSamplesUpdateLines(effector, &effectorOutput, &outputXLocations, i, stepSize); + // sampleBufferOut contains the effector m_bakedValues here + getSamplesUpdateLines(effector, sampleBufferOut, sampleXLocationsIn, i, stepSize); } m_parent->lockBakedSamplesAccess(); @@ -3637,18 +3655,15 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, bool* isChanged // clearing the updated values m_needsUpdating.clear(); } - if (sampleBufferOut != nullptr) - { - m_parent->lockBakedSamplesAccess(); - *sampleBufferOut = m_bakedSamples; - m_parent->unlockBakedSamplesAccess(); - } + m_parent->lockBakedSamplesAccess(); + *sampleBufferOut = m_bakedSamples; + m_parent->unlockBakedSamplesAccess(); m_isDataChanged = false; qDebug("getSamplesB9"); } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* outputXLocations, unsigned int pointLocation, float stepSize) + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) { qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", pointLocation, m_needsUpdating[pointLocation]); unsigned int effectYLocation = static_cast @@ -3722,7 +3737,7 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // calculate curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); } // no line type } @@ -3731,50 +3746,50 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); } // line type - processLineTypeArraySine(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, fadeInStart); + processLineTypeArraySine(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, fadeInStart); } else if (type == 2) { // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); } // line type - processLineTypeArraySineB(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + processLineTypeArraySineB(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } else if (type == 3) { // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); } // line type - processLineTypeArrayPeak(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + processLineTypeArrayPeak(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } else if (type == 4) { // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); } // line type - processLineTypeArraySteps(&m_updatingBakedSamples, outputXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); + processLineTypeArraySteps(&m_updatingBakedSamples, sampleXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); } else if (type == 5) { // curve for (int j = start; j < end; j++) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*outputXLocations)[j]); + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); } // line type - processLineTypeArrayRandom(&m_updatingBakedSamples, outputXLocations, start, end, curValA, curValB, curC, fadeInStart); + processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) { From 1ce7dda7d7fa61908f725320addb51cca24efadb Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 6 May 2024 15:45:48 +0200 Subject: [PATCH 123/184] VectorGraph_getSamples_x_sample_mapping_fixed --- include/VectorGraph.h | 2 +- src/gui/widgets/VectorGraph.cpp | 57 +++++++++++++++++---------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 75be27b04c2..ed6bdd55d16 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -658,7 +658,7 @@ class LMMS_EXPORT VectorGraphDataArray void getUpdatingOriginals(); // real getSamples processing - void getSamplesInner(unsigned int targetSizeIn, std::vector* sampleXLocationsIn, bool* isChangedOut, + void getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut); // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index deec864db7b..1049c3a5220 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2399,37 +2399,19 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector(targetSizeIn); - - - // calculating the relative X locations (in lines) of the output samples - // sampleXLocations[sample_location] is equal to 0.0f if it is at the start of a line - // and it is equal to 1.0f if it is at the end of a line - std::vector sampleXLocations(targetSizeIn); - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - unsigned int start = static_cast - (std::ceil(m_dataArray[i].m_x / stepSize)); - if (i + 1 < m_dataArray.size()) - { - unsigned int end = static_cast - (std::ceil(m_dataArray[i + 1].m_x / stepSize)); - for (unsigned int j = start; j < end; j++) - { - sampleXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - } - } - } - if (sampleBufferOut != nullptr) { if (sampleBufferOut->size() != targetSizeIn) { sampleBufferOut->resize(targetSizeIn); } + for (unsigned int i = 0; i < targetSizeIn; i++) + { + (*sampleBufferOut)[i] = 0; + } m_parent->lockGetSamplesAccess(); - getSamplesInner(targetSizeIn, &sampleXLocations, nullptr, nullptr, sampleBufferOut); + getSamplesInner(targetSizeIn, nullptr, nullptr, sampleBufferOut); m_parent->unlockGetSamplesAccess(); } else @@ -2439,7 +2421,7 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector updatingSampleArray(targetSizeIn); m_parent->lockGetSamplesAccess(); - getSamplesInner(targetSizeIn, &sampleXLocations, nullptr, nullptr, &updatingSampleArray); + getSamplesInner(targetSizeIn, nullptr, nullptr, &updatingSampleArray); m_parent->unlockGetSamplesAccess(); } qDebug("getSamplesA3 finished"); @@ -3547,7 +3529,7 @@ void VectorGraphDataArray::getUpdatingOriginals() qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); } } -void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, std::vector* sampleXLocationsIn, bool* isChangedOut, +void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; @@ -3557,9 +3539,9 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, std::vecto bool isEffected = m_effectorLocation >= 0; if (isEffected == true) { - m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, sampleXLocationsIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); + m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); } - qDebug("getSamplesB1, size: %ld - id: %d", sampleXLocationsIn->size(), m_id); + qDebug("getSamplesB1, size: %d - id: %d", targetSizeIn, m_id); m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); @@ -3619,6 +3601,25 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, std::vecto // calculating point data and lines if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) { + // calculating the relative X locations (in lines) of the output samples + // sampleXLocations[sample_location] is equal to 0.0f if it is at the start of a line + // and it is equal to 1.0f if it is at the end of a line + std::vector sampleXLocations(targetSizeIn); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + unsigned int start = static_cast + (std::ceil(m_dataArray[i].m_x / stepSize)); + if (i + 1 < m_dataArray.size()) + { + unsigned int end = static_cast + (std::ceil(m_dataArray[i + 1].m_x / stepSize)); + for (unsigned int j = start; j < end; j++) + { + sampleXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); + } + } + } + // getting effectorDataArray pointer VectorGraphDataArray* effector = nullptr; if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) @@ -3632,7 +3633,7 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, std::vecto for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { // sampleBufferOut contains the effector m_bakedValues here - getSamplesUpdateLines(effector, sampleBufferOut, sampleXLocationsIn, i, stepSize); + getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, i, stepSize); } m_parent->lockBakedSamplesAccess(); From 4317a7a729b699d22d9e8b4b6d94e1ffab1b80ce Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 7 May 2024 11:59:48 +0200 Subject: [PATCH 124/184] VectorGraph_replaced_c_style_arrays_with_vector --- include/VectorGraph.h | 4 ++++ src/gui/widgets/VectorGraph.cpp | 40 +++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index ed6bdd55d16..cc6f642cbc6 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -737,6 +737,10 @@ class LMMS_EXPORT VectorGraphDataArray // used for automation std::vector m_automationModelArray; + // used in lineType calculations to store + // large amount of floats without reallocation + std::vector m_universalSampleBuffer; + // used for saving friend class lmms::VectorGraphModel; }; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1049c3a5220..44af057c990 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1877,6 +1877,7 @@ VectorGraphDataArray::VectorGraphDataArray( // m_updatingBakedSamples // m_needsUpdating; // m_automationModelArray; + // m_universalSampleBuffer m_id = arrayId; updateConnections(parent); @@ -3184,15 +3185,20 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples { end = end > count ? count : end + 1; } - // allocate 1 part of a sine wave on the stack - float oneWave[end]; + // "allocate" "end" amount of floats + // for 1 whole sine wave + // in the universal buffer + if (m_universalSampleBuffer.size() < end) + { + m_universalSampleBuffer.resize(end); + } // calculate 1 wave of sine for (unsigned int i = 0; i < end; i++) { // 628.318531f = 100.0f * 2.0f * pi // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) - oneWave[i] = sineAmp * std::sin( + m_universalSampleBuffer[i] = sineAmp * std::sin( (*xArray)[startLoc + i] * 628.318531f * tValB + sinePhase * 100.0f); } //qDebug("sineB_2"); @@ -3204,7 +3210,7 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples for (unsigned int j = 0; j < endB; j++) { //qDebug("sineB_2.5: i: %d, %d, %d", endB, j, i + j); - (*samplesOut)[startLoc + j + i] += oneWave[j]; + (*samplesOut)[startLoc + j + i] += m_universalSampleBuffer[j]; } } @@ -3301,7 +3307,13 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample if (randomValuesSize > 0) { - float randomValues[randomValuesSize]; + // "allocate" "randomValuesSize" amount of floats + // for generating random values + // in the universal buffer + if (m_universalSampleBuffer.size() < randomValuesSize) + { + m_universalSampleBuffer.resize(randomValuesSize); + } float blend = 10.0f + randomSeed * 10.0f; int randomSeedB = static_cast(blend); @@ -3313,12 +3325,12 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample // generating 2 seeds and blending in between them for (unsigned int i = 0; i < randomValuesSize / 2; i++) { - randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; } std::srand(randomSeedB + 1); for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) { - randomValues[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; } // blending @@ -3329,7 +3341,7 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample float randomValueX = (*xArray)[startLoc + i] * size; float randomValueLocation = std::floor(randomValueX); (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (randomValues[static_cast(randomValueLocation)] * (1.0f - blend) + randomValues[static_cast(randomValueLocation + size)] * blend) * randomAmp; + (m_universalSampleBuffer[static_cast(randomValueLocation)] * (1.0f - blend) + m_universalSampleBuffer[static_cast(randomValueLocation + size)] * blend) * randomAmp; } } } @@ -3541,7 +3553,7 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); } - qDebug("getSamplesB1, size: %d - id: %d", targetSizeIn, m_id); + qDebug("getSamplesInnerB1, size: %d - id: %d", targetSizeIn, m_id); m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); @@ -3570,12 +3582,12 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh // before use (in this case it is already sorted) getUpdatingFromEffector(&effectorUpdatingValues); } - qDebug("getSamplesB2"); + qDebug("getSamplesInnerB2"); getUpdatingFromAutomation(); // sort and select only original // values getUpdatingOriginals(); - qDebug("getSamplesB3"); + qDebug("getSamplesInnerB3"); } else { @@ -3594,7 +3606,7 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_needsUpdating[i] = i; } - qDebug("getSamplesB4, needsUpdating size: %ld", m_needsUpdating.size()); + qDebug("getSamplesInnerB4, needsUpdating size: %ld", m_needsUpdating.size()); } float stepSize = 1.0f / static_cast(targetSizeIn); @@ -3627,7 +3639,7 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh effector = m_parent->getDataArray(m_effectorLocation); } - qDebug("getSamplesB6, updatingsize: %ld", m_needsUpdating.size()); + qDebug("getSamplesInnerB6, updatingsize: %ld", m_needsUpdating.size()); // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) @@ -3661,7 +3673,7 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh m_parent->unlockBakedSamplesAccess(); m_isDataChanged = false; - qDebug("getSamplesB9"); + qDebug("getSamplesInnerB9"); } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) From b4e0d474aed86c6f7ea902bde8e5bdb567a82c9d Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Tue, 7 May 2024 15:57:58 +0200 Subject: [PATCH 125/184] WaveShaper_added_simplify_button --- .../WaveShaper/WaveShaperControlDialog.cpp | 39 +++++++++++++----- plugins/WaveShaper/WaveShaperControlDialog.h | 5 ++- plugins/WaveShaper/WaveShaperControls.cpp | 2 + plugins/WaveShaper/WaveShaperControls.h | 3 -- plugins/WaveShaper/simplify_active.png | Bin 0 -> 9675 bytes plugins/WaveShaper/simplify_inactive.png | Bin 0 -> 9948 bytes 6 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 plugins/WaveShaper/simplify_active.png create mode 100644 plugins/WaveShaper/simplify_inactive.png diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 8a98ca81ee5..2f2376e96a9 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -40,7 +40,8 @@ namespace lmms::gui WaveShaperControlDialog::WaveShaperControlDialog( WaveShaperControls * _controls ) : - EffectControlDialog( _controls ) + EffectControlDialog(_controls), + m_vectorGraphWidget(nullptr) { setAutoFillBackground( true ); QPalette pal; @@ -49,17 +50,14 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); - auto curGraph = new VectorGraphView(this, 204, 205, 8, 30, 3, false); - curGraph->setModel(&_controls->m_vectorGraphModel); - curGraph->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); + m_vectorGraphWidget = new VectorGraphView(this, 204, 205, 8, 30, 3, false); + m_vectorGraphWidget->setModel(&_controls->m_vectorGraphModel); + m_vectorGraphWidget->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); // this can cause problems with custom colors - curGraph->applyDefaultColors(); + m_vectorGraphWidget->applyDefaultColors(); // custom colors can be set this way (but this garph uses applyDefaultColros()): - //curGraph->setLineColor(QColor(210, 50, 50, 255), arrayLocation); - //curGraph->setActiveColor(QColor(210, 50, 50, 255), arrayLocation); - //curGraph->setFillColor(QColor(210, 50, 50, 255), arrayLocation); - //curGraph->setAutomatedColor(QColor(210, 50, 50, 255), arrayLocation); - curGraph->move(10, 6); + // example: m_vectorGraphWidget->setLineColor(QColor(210, 50, 50, 255), arrayLocation); + m_vectorGraphWidget->move(10, 6); auto inputKnob = new Knob(KnobType::Bright26, this); inputKnob -> setVolumeKnob( true ); @@ -78,12 +76,19 @@ WaveShaperControlDialog::WaveShaperControlDialog( outputKnob->setHintText( tr( "Output gain:" ), "" ); auto resetButton = new PixmapButton(this, tr("Reset wavegraph")); - resetButton -> move(142, 225); + resetButton -> move(162, 225); resetButton -> resize( 13, 46 ); resetButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_active" ) ); resetButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_inactive" ) ); resetButton->setToolTip(tr("Reset wavegraph")); + auto simplifyButton = new PixmapButton(this, tr("Simplify graph displayed")); + simplifyButton->move(112, 225); + simplifyButton->resize(13, 46); + simplifyButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("simplify_active")); + simplifyButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("simplify_inactive")); + simplifyButton->setToolTip(tr("Simplify the graph display for performance")); + auto clipInputToggle = new LedCheckBox("Clip input", this, tr("Clip input"), LedCheckBox::LedColor::Green); clipInputToggle -> move( 131, 252 ); clipInputToggle -> setModel( &_controls -> m_clipModel ); @@ -91,7 +96,19 @@ WaveShaperControlDialog::WaveShaperControlDialog( connect( resetButton, SIGNAL (clicked () ), _controls, SLOT ( resetClicked() ) ); + connect(simplifyButton, SIGNAL(clicked()), + this, SLOT(simplifyClicked())); } +void WaveShaperControlDialog::simplifyClicked() +{ + qDebug("simplifyClicked run"); + if (m_vectorGraphWidget != nullptr) + { + qDebug("simplifyClicked turn on"); + m_vectorGraphWidget->setIsSimplified(!m_vectorGraphWidget->getIsSimplified()); + m_vectorGraphWidget->model()->updateGraphModel(true); + } +} } // namespace lmms::gui diff --git a/plugins/WaveShaper/WaveShaperControlDialog.h b/plugins/WaveShaper/WaveShaperControlDialog.h index 51f05bb7e0a..155df83cc4f 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.h +++ b/plugins/WaveShaper/WaveShaperControlDialog.h @@ -46,8 +46,11 @@ class WaveShaperControlDialog : public EffectControlDialog ~WaveShaperControlDialog() override = default; +private slots: + void simplifyClicked(); private: - + + VectorGraphView* m_vectorGraphWidget; } ; diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 4d4e59403c7..be0848ecae7 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -162,6 +162,8 @@ void WaveShaperControls::setDefaultShape() } } + + void WaveShaperControls::resetClicked() { setDefaultShape(); diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 664cfc8d6bc..6452bbc9bdf 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -67,8 +67,6 @@ class WaveShaperControls : public EffectControls std::vector* getGraphSamples(); - - private slots: void resetClicked(); @@ -82,7 +80,6 @@ private slots: WaveShaperEffect * m_effect; FloatModel m_inputModel; FloatModel m_outputModel; - //graphModel m_wavegraphModel; VectorGraphModel m_vectorGraphModel; BoolModel m_clipModel; diff --git a/plugins/WaveShaper/simplify_active.png b/plugins/WaveShaper/simplify_active.png new file mode 100644 index 0000000000000000000000000000000000000000..19aee18e8ef9a4ae336bbdbc2ff8ff0bbc709a4b GIT binary patch literal 9675 zcmeHLXH=70vkpa?^xiuHLLi|82wghT1!+b1DFrHt2-Kraze0s`ne+55xyuS0N^`Um|^VBEtRHnSsiPM zU1vgCFuP-&_HpBFmR54FOKk>+KyU5?=}szR_P(9ViyYgZUB=~=8Ba9_fp-1IPSvMF z4;^w|-VcT{?G695-TIT82R*=l=}Q2Dgb|TxWUP#K5*f!Z{u-w5>r%Z#W$|U(#IR@@|W?E zn-!g1OBbX<9TSIb#MeY14i(GzAehXS8jLau?mY`{W^ST(A~O*>BCUQ4R63lMG#X5sCJ6E{6Rw@H$V zO6=7>%E(ZQZEZYTYj$cPeVP7Aiw zc&LqVp7I@o-onRbW?SMDCU*wwC(O*h3^oGni_*+d_4QNI9^R_EG7HUlC(CN|Zrq~# zeEIQ^vw}cmCTiUjndN-^$=GD6yRWRgWp4X}vnHxL%X<+qz2GhXc#d$rGet-4)5N&W z<-pvtsrJ{Gic|B?#Dhf(nfmRfn#}sT$#q`iWNmBKD9p zh#@X&4NSslvwCLb5jo)~CzaI}FqqO;-VwB)3&Euk&|z`OKtd& z{ONlc9$qO0WK)v&&23lO>pi5(H-;JeE!RF~Ccpi5^LtHkTY~&>ZJ*7w)rWD*pZDsH zo1JzWPMn4t0?c`JXS!2Y`7Jkm0@Hlo`O*6|tUrM_zT`TqDK1Kwm_|H&tKP_Owyax69I(#N&VPyyK=yl7Gny|N zQoU!raiuUR1B1=m`pJT6YBOep%qWte%Lm%&vcCNp8v= zvqnr`5|+c;4|ykXl|( zGt6p5u6J-S!^c!K^^Lh*g3-*9PR!g~T8sUAXxMw^t?z{&7mic&Kwl>xvEHzH$J56@ zoAS(pw=#WP{qsa7ENUk&-l&#CN#K@Ko{>#Ko31nr=%*O#%*s8CrAvPn6V=4hs2`1EzQ4wWHE)}aH`V+~ zC))3r8c07WQ@(&)=zNy|nVzw}p9AAcFn!=C@K}3~xxFJATb|mV#1BXJrJMf{PD98h zY;$FKz*Murk>;2SVnk$u#hq@zbJ~;eNA&2v7n zKZ&=KKj_b~TS5i6TF-jM4bHicv=EDtQU zcc`wVcIzXWXswO_#RDqd)yS>o3)z5T(=(pK8^8KRjY*#zR^Rx@60;Dd1RP)p7rO=C zb0!rC_&1jlwOVx?+FkqZmL)9iNIdz#j3IcFKG*&X!I>fK3r2I#=`mv2puro zaLaE32X6W0G?7sD`9)0MM5SsW&x*_ZKlP@`;U}*b)V$s5kLS!(y-}g_p{m?)C9mSd z;X}cAY5v%(8%MEDKyy9K`ZZAjkXoL$b^KlSG44ksBiB2O01+#^nY5pV*P9j1x0dDJ zY2)`ws@kV$7St#h>WvmkcX6&t)X2hMBTwq4GRe97s4Q+cW{~6P6~J z6@4*H$T@Vg21Yz7RrUZR7}ziglqzruU@=3>uH_bKKiFId+iuC?c`)Jdts{P$D#(a= z3EMZ`+{aqtj?9+TBX4JeTTF#1?{GYKlSeC~Pc~V|nJ6b#L|+RGjcl>Sl4#t%p+KsX zv&%^C<7^_&|1C~e6)!={FXSwAowbhkX#Dozazh%y)5x=4uP}-&VGvW|UieSzk5A

s3p7YIm&d zZ9fA$3d3DWDmN(SEm316EekGS#t-$KES+D}5Xuz@HG`4)e2`vbAYWAn&QcVYvlH-n zPKnRVv2W^l9^Vp<#4M96AzO9i4mx!0As}i!FQS$HzHy+&jrrMQf+R30XP6Y@P^dDU z@Ci=zdR$v;aDKh1LLssJ9AD=g8U9MBCF#WJ@DCEc+nv(#o$5Qg{Fbmjq^NO(l?m#S(CPDpyW8$mm6Woa;ag-JkYAk1h6ei z>vPP_;(S5Bb&d#^*~C3Cp4X0p4mUoKlvsj;CyN5@;Fw7u?JW=<>e?nUTkY8a*AtFZ zWzj!XK<^fx`mvLBvL#h0T9PHHfOA_>iPheWwAa9ibhyuIuCd1YQ*^|XbI3)oe1__A zEqb&clGpHc%x(bkY@grU{3tdoj#}jCq9wvdFSTBu;Az7%G<#&hd=1Zdevbdpg~jFh z{0;JGRrtcDRianE@;1ylmm5##uC$UpUelxgw_PH8xZvw-xho7jRtcWi)(`3VUh{N| zG^*@!#6#e6eDZy{2F!SF)XQ3%WbUzk;?WOScO17uS`@goKDr&tHW{jaI_@F7Nw<3K zW-f!C$k)=|dS8vCDt4t!{LgFwI?XCsg@T>KJ%yqC3VL=o6lk67_Y3jQLk43_aQx1# zq-70!38VrEyhFt5mnfQDiF^}ObC2AGW!%%YD#h4@y~gszu9x{#aZdr}8{u=4a&)Fp zzNQaTq?8@j&l`Ey?%X(6Ji*VPzzshSYMpM)*Lx)c@XMc8#c#je9o6?)u2f@NH&eBe zX@#8Igq#~bb?hr?+v!+7m1Y@=y)ptzL|Wh9=*AHsar5(|9ZHU4VUEL5)G(@m1P4yAj?P)UqQp7Rq`G5CZ(SC z+!Ulsv8!mQIi`E4RQOoWt+^aoT1L4KxH0l1BC=%MbQ5VnMg`;9O-{)u>SHNhw062Kq6DPGimFe^V@&@$3s$mwi7B zi?Kj3D>B)o+*Tg znDxzZ*ka_UJ3g7c4}U+$)YOgYN$7DedxV{cHIad^#EfDKTE-=3rGM*nsVPWllH(IY zY0Q}4PKJJSeh!kF%1tAEw+Sbv`GKH>(U)wO4?ar=a@+^uBiPJEUc=DxDg8ySkX~O- z`nthl)1xeVmJ9J?jM z(HUiJqWw`K>?$m=h6Aib7Tw@3z{#BQbP1%-00bGsuEi>j!0ome)=tesgRRG#qZ&df z1=EDYxuwGJ%W~-X>~Ntq0zMPqSjv)k%6zaLL9SJ}0_70&v2D)^ZY9{DVMf<8NTmZG$r zXpqJ=h@~|mvx<+E@L^%(su5Tt5jf-kLDO!Mg(yO3THAOiib-Ep@DL6Q8o#n0B&3kT zGbP{@n@M&dgg-rOuF)cbCQF~daegX%S00#3!_BOv3eIw3uje<_HKAI<*@RZGY*1IV zj+F>8u8oZ>n`)2eu~UMmi(5|FA(OWkqyV?=s8mL{fo`j}?w@rCDjt955uND~qG#x2 zZ#)gC@2r<)EC|k(x&p+nkZN=z14CNc~_P7 z^GrgItt+hYAhDoA+Yq=ic z-JBL5M(Tgt6(2n2qBSh%>0grJn+1T}XbrsSS%~t#)Rkzypsm82_&WG0(Up(dtZ6>}hCVD( z+t_FxJG?t%tEEgY4oq4Yg-7uGqvR~9j#*f@xAnWz-<)_H&u7oTW{&8dcb*exrwjzw zB&p5k*EkVjm%JP{Ej05OOlub}9Xj_V&x;C&n|{hZ?YS#9B0KElRa(smak49TrV{zi zV$|>Duxp1>6#-${eMi6iOK&k+1~^CU+-NJSnA%ZFT&We`j;t2+ zbm_P8g&$_RC*JGD{Z#Z?pZ94XT3VwVRgAlZ2hPdT=vvNHr$wB0E zRvQ%1manNlI@~Q>Kh4T?NRpQv`lCHY!Hki5<2erT0lGZTvMxj>a18*!3P&j^>1ik_ z{c%5rxfRO{N|IH7r@-80b?0`WA@dIVN@8A%y`o{KewkhbQQlqq$&R%#VS5{OgL}-^ zro+P79vb1(*;%mMyQcURr*pPLV^l@++{(b7Vzt9fesLjSz6~crH5GMtnm%`{Azg!~ z>)w48;&#pm5GOztj%27!ejK&;y+tkLr4M2Dr{LY;(R^A#JY3}!2IN!7H|V#CB4^h{ z-uUX8a>^X4gbYu`6}3tM)^<0cX2GumPtyknD7vG&4Dbb52KtIrWi*(L#k2M!GrMnY z0Ef)#-9&3$gZ7dg1b1p`D|a|Baqzm$lvkH>LFH-f$gEHvUWCFclR(@)086S>XH$Kxvn(P)`HriorPd^2BHl#49qUTZriI|?q#X)LY{(sors*rU|_-4S>EbqsC&9c`uHobqx+ zGQLm@fHT4q#_sFv#-}L-4X0!LSjN7po%Zb zTZB`Nh+W1Vj)WR0tNspwd6VU|_w;my3Jd%A_z3xk3ZdQYguzl$QkXqPSVRPf(Exh* zxp=~Sfi50gR}jBpC?h;<-BGTdD6|Xv6(-CE?d2)U$%&D({}G?FtG4!^@Gc&|vw-14 z*caw13>E?jJ39;i)xyJ5#Tx_idqDry!ov`A>nm)4@IZUH+agrF5iXuwe}#bC{%P;( z;ZnufOCpB7gX*rA+Ve_3J3{+p&J3i%(h{ubMn z4FqHUC+^?0|H%E9GDb^V8>)=9^|}gALs^#d%0Cp2wnf3AzYReUQ4tY@1Q0BOgaE}P zAP^u-+y(@ckg%}QUnMB*}z4_Y+)b~o4-Qnx}z{%33K{uR98@N43v#H+y;!0vH{wPB49uvbQAr^Mkrx<`=u$Ww+O6~}lC)(W*jdqgdyb6i^%JNrxv&;Ne6m^sbM#Jx_ zUAQ31C#3}rH!opXp`j3odg#Q;O zGQSl5vJGJDew)K=FPPm*_|NU?ch0V8{D1uXUW@-n4;biwo%|zy|E23+y8aOZ|48}Y z?)sOmf5gB)QvSEQ{?F(l`pKK8w85@k(w zo1KO9o1~MnC3>E$*|sfKX6kh*0BKJywLt~}b9mOTHlSyL|4XhSyzp%=`0_@I#!Mc$_C{#I)zbAAxL|E>M9O3dPu{?X%c*KN|92Rnw~5b}yJU+>i2 z)@%iS7p58~$F!sLQwz1+LInmax=}Svv#eQ^1Xh0=f|W)7#t4;;q{@R_pN5eS&o;@- zUEQ!~acQqzoEmN7)8iiQLWl#ivfU~b_MAEl6iy(cXtkfg^su1+ctgl zbJ@;!+LCfEFN)gRTdxJ7hQ@Llq(<-XMI;+kS!-!DJ?(Xhq?yIvu?|b zv}wN`nyJ+fxi7mPclb(ddHtmxQ;W2FPG{WRv9Yp{ud37N?_aZx-PajNr@J@lgehDW zePpJO!Pm9TbF*|Fmiv0lizV(lw;c4We*KBNz@oU7`|eRdwMJpTm3s!lXW9D5`|!g| z*PHD$q2<*dn-W}ahj0f*%oHC{;#8!5oua=ujFmRE{Hpcoe5ivjBCFc&@QYi@R;S9v zIimY)k=xM;6~LXzQgHt?_JhTbE`bDJK%M65n>=Nb3dg66%PAk{w;ae?zhUps?pg3_ zXd47bz5Dz_AFqP2nE!NwY!la#nKYNf|cpeYBf1$|=ySbF82t)^r%r98I|K*vcZ3 zSCsykfUQ$CiCAzJim2;}6?ufERcp=JR}@M`=rwbCgfUScFdXlAE_O&x>wS>z{--Xg#BF_xhYeu~)5=-PeWn*LF1y&gE#= duiYJ=E&&bDWsnls()VfsYpCcbSKhJ?`yYX!r49f9 literal 0 HcmV?d00001 diff --git a/plugins/WaveShaper/simplify_inactive.png b/plugins/WaveShaper/simplify_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8aca74b80a5e94e7698a73a9be02ebbc218a0a GIT binary patch literal 9948 zcmeHrXH=70(>9>=CW7>ifFgkq2ql2hdv8*OBqStsLg>9$5fEw8i&6wcK&1*&MS7Kv zfE4Kh0)qGk&v~Bbob|nbp0&RB-^p6Jv+q4K*Pgj%_FmZ&qo<=vNybcuhlfY0uBK#w z`xUwzlMvya6CsvWczCqIzDA~41E?3LE5-$hc0_PueOwWo2yZkJ56^qLIMWVur_nRw z7o3ir0K-THdt$fv`OE^9tU5AW;X9eC5n@E!T-{EV*LRWo>+b5i6SWBhtzl{X7su0R zfcU~`@$_2Z!tOxV+0Vd}pFf_ST{Km19uW^3hU9+sF+JG)aeS~-(|S;NVDaOXUUt>J z_}w7XeqG?t>Y+^)c^aQUA41r)L;hm!y|Nl=%;bgO zw*xmpTNmCOiuv6|f($aQCIXTlv3%G-^<%%!3SL3FT;Jvhk7L8b&r_cds`3;R>Md6> z1eEu#z2O*-J+i99Juf`ePm)&7Pfs@wx{4RdF^0c>4(yEcE#$fk+@tx~)6z0vb~Gzn z6UQ!EI#8wE{Kh+IxuMOV!2=wg>h$?ewNicV!$FPvx@E7oYQqLM-im&K2sM0Zkak|k z9o1Hd4`k7;XgVH^I>tegp&Zb#tcij~Xe6xx{3tGH;~L*Md1m^(>CH}CHrO@o z+fNSqiN4q-9~izR`P{OFOwMxt&Qy4Q?}l`mK8@D{b!~~Z-N9UrGKaiSb+d_RvFp+~ zyegQWM9x_SVj-<_|E|s_N9Mu7Z#}pf`8XkET}E%W9QRu!Rk`mFehnYMJC!H2)Ci<0 zdcyrbs;wPech3|d=ecd{9$hrU~*@Zh&OF2{}g84Q1dFAaBUIrsaqhmK}7puvTW-+DG6{{ML+%0GSiaKfYDF~#SPT}| zA9xc(TU3YN-&5{(&Rw6*4>El_dOKV^cPQD%vvI($%Hy;w#TOwI^wE+#&$VP*r}}Je z0Ha)&lS9~F_REx1er+K_t@4CrTC(9QTV_4_;8b(^f!V<|n-h=6s&QC>uU&q;_q9+* zR>K_RKVN*@JiVUru;aDb`UBm0gCiuvJ5AdxA_*^ziQ{5WsnqA01FupqUKZ)Bv7Y#g z;`G|Uui=`+DPF|E(y=FLU&`*~L^GPda#8#BTsv~yzQOz4JUBgQ7pz;Ap&LySE~XoJ zOe_&JzPJYTFKtg_$*_n%7YaW!9MRZm67s7%r+hzs9Qg~aq>+_DPfl0Z^21ry5d16O zcOfb^`l7v5z$SW^f2Phe0g5-UU;A}{eWT-nRzJe;1r6;`6-ax&l*k{?b7fPL{E+4UA`Otx|5qb~78>m*{k z>D{m3k#*aqh`vu0vqbTVoP>u}GI9rmZwcfcW2f2%(7Js)wZ@s>mdKhL+cRuE3G<}) zn!s+`?{h!IkI;__4p-T4oYjncO86e)ZLqM{J@#lC^6q^eJrSc! zo49m_T}D@c?aA|(4t@IGN}6WxR>jfsy;u%mId;24e0$nyC?^|1T$0zb1U7QYt4P(Oj3apHGS<7y zW^5&W@8~wZ%qhrNXK_6pxW5&p5*B!SAfF9&S`1x?3()6GA~IgJh52vwA>sB{(g4^gFl>Whn;1p?A2;kgk9Oi;G0P4c=n|urD^3Yyd}oQ5 z!(4YGamYi%SNccG115;`e771*97JtE0d8vA6l$n!-OrecmN}y8;>=B6~SL-frOPNY0*l$gs zw0x&;Xr$BuZk(iV)R6hxk%8p)LJA3FL+nist{7jT*jo2uw#g3=iO zEBwkv>V>Ks2LdFiD&Mq~nAb*|J@( z&j%j{qL!!2NeomfHS=XZ(Yi%-cA9-1Z*G+~e{qwG=SSYhl+Iut0FC_m2CH40S6Bye zkiAO8Csy$;zu69x{3YzkdDE84i3!Y{GUbrTM;pE)6}7?|_TU?k-iWk)xsqB?@9NM^ zY#&|e#{$F^WSk6{XE!qXWpR~|bk0xGcNrlF6?YW#NfHfy8rFAe<32&yoRJFR!O@lJr$rW4bj0w1;x$0O__nLaFvDi+WRYiyP2 zdOVNR>5iwp>uP`V`)cPSE^vR|Cuxz4SK@l*1mzmHPdeEd--JlLt4Lz5NJuZ5l7oxt z8_G9{U+Hxqk6mpbUok=#V$80X$1qx_(j+bB#F(A8#K4Uvh2#s0&D22A&82c%t zjCX;uf}J$cbLq6=HCj}))XQ^9-&`7nvZ^gHtK@AYobUb+F^*C{^zrlNsPv*FeE74~ zqP6H`i)dYbQZ2{S5==o9CIczk!q5jOAAbb&Qcn?>4%kWU$-R6+ToPJ(RYrn+d$X|p_wsq_jpigYk^`vnz~QkYp;@QrIBWfa8vbeoR|KLpTR(_}%) zy@rm6sANmFQks%1NfE(~u&;?ueahyCp;XQleatz17;8Sb%b++jU%I}kU$UMOdA0-; zA}A{?N?J8u$ZNmK-u%)_;k!}NQI79BWcfk$!Xc?RRb?I%!X$~1GLw5v>suERoIiIo z!ZF#a*S02eZ+I33S6d^a`vllP0b))o4xcb@M#EmmY-tJi2v9YB#b#N@BsFXg^FqWf z3i#M|;w*%f^4Z(iZ6XI+Mh7YLYKuQ7mwd_BIkvIYpK$E0u%seGfyVKAEwNg?>(Od& z)N~XW#cob}0VWep23bS$JK--fGSl>>h-n4s5dk-K$h{(2%qNWzV* zqw8^*+%YF-pL-&)7A6AtpzwwgDRuFjj{BdW`i-jj8g3UHkBc!YOA$v z4&@~`(>Z4H%u5+o1?j%GeA53~ox>0m0I;YL+F_u+edP;T6%GCn37+Eoq-221KlE!YJpgs2i}MgeJl2HaDP$_Gzm!`{79uC#G5x^y z6py^x#mPA5DixhDj|(g%v*%F9C!yr759p@7zy~_C!Rmd=*@r~56pO|xKK81CYBaLF z_s*p->q%|Q(fZkok;Y=7vzz84(iZuJ3^fUE1DVH&YJF2rP6^KUDLdgSn5P~KJSM34 zr-fnSRM9YEsZEvLC$plWsM33|qR^W?$r)p5YOmDH+V}Mc7ZK|sL+E)4-j@vp)jj_8 zh_ok==m)A|*mdTZ)#n+D*0w|P(SVa8cd5W~re}jZx)^*4yLNnwg^BoA1)y*>v!?Lc zz)+IzMe&gdtL|Kj#YiZuy`K5LqF^-I(<*9QKUQZJ0>)E~#!u5oVnVDOD_m8f<4=#z z;c{#7R8!h*>tP+$+rJ5N&P{>Qqo}`$Kk6?qKYzGsPCI9-fqs@@-CEuNRxO%mLZbCe(aPWd#gyU)w+wk&EWBT z{DIba;@#P<-ighguv+f5qDnP}$vAqEF05I76oRXc-}M$qB&~Y&y{5-WQDWcGgYOzO zEXhr2{=P!y!k@o0nP@w<(33rhI*o-qx5J2E7wnjkCURG*_K3Q@2N}%WjRDv!$(&G6 zCaG3-cYNK^+zn7>L(12pH@2IzwFS;=nWZ%kSDL?)L<5wRKq_kJ8y)NEWTTwh{uy7B zm`Alw0TR+Rk-9D3Jw{R8GfP@FFT#w4)QH#|%6VoU^IWBQ5t(&JVA(_a$-$3lGE!CQ z<$=BoWp%KX#IPxT5@U@@=IV$%)p__F8j>VMEix-X`GH+ekK&b%0OP)x+>uWwka^$S z!fmC`7?y#3eNt3sJk31%=}l~mq{8bcG%F>!`KDzu=CNd4B>|0%{Hpr~`42Z{?ILI0 z&=ikt>8u!AC*sfDdyF@vui~Mjp`eMEy|?^$w>aH$E00}*Uxr+i`;G=9gqJ@lnoQ@_ z?B`od+kP(&g6+Llif3-(bMk&3~sr9y}L&M-zR{^;(9UZon5RNu5(VT$)d z@9vKI#PTu!iaww7-BsAt|CB7p$p+f^`ILVBiTq*Tiq3nUlyF-%aiXby?ZfX=A$6>+ z5en_BxyJro&Ne0X39mF-Z^Aqa(lLDxelZ1G5kIDnZ@qq~VGAeY?}jiOGgCD5B_61e zKI9&2O@wxXeQ&ERU)}A^0`*^oV(WxV?=(l}K-%!yUqmm zse`o-hd+4*i-O3eb4ldg*tM+oE)HrOhbsD;kM*xRpD(;Qv?D)iUP^01sphUzgf697 z1$`VBPV#-Ocj)6ynr_rL$UE)+)N8(XVPmpUbKy-n@v3e~w9`s`m$O|x{{0O#K?zEv z2MGaDCrOj&w%cYrZ5t)VNr_1Ysdt;EZ6M)(%O)XP$!EX?!?fy*`rR@@eLOt;Ftnng zp1Pvqzj|@F4qR41lB`<09BZewp=PlW>lWuyVtxZk-l#*rTrZp~-vl+@wlX4&f~gr; zvJy^)hH=Ch6EoOZu~`zz?_KGbYEvIp);PB|K+!C>x!s$e^P6qH60Y(DZ8FK2xA8hd zoww66P?_Q#cQ}w6PsJ9=RFj+%xqH%}8eHW?n)4-SXK=WXUXbXj(h?IgU3?$1KlaSY zb)G+=`qhi;xwMZmvGPl*m3P?Rxe3(^?)9Z-^!L$pM|TfuJqw-o`SA>(A@;bQt5- z9+5|ss6?xKCmiQH69PK%e(J+Fulc%VJ>ueQA{X0CI0)F1?5E{Cp|IR=`lWIu{o-cx z{KS%~+^)E*+uTHo>>`GEJqToL=vmCEoo{+|esKNiH@OACHM1jMhwbG<{2qh*8!U^9 z*BFKLzh@3MHcI=Q9cz`pfL2X@N2qAALS6u59 z4^QTvw<{FxfWUIX5O!#1S?=A&cifz4TUqY=U~Qnbt0Dr0R`bOm41INs;JyxUDO>J) zcgbYDAvgdh1QyEa?d0g}4)K=d{*4R4jW4H#xjBEUU>#(+O||tn6J4yq=edOV149Yn4#%Kfv1k`(&Pz-v%*6vM%gv3GbNy_^%f3SY=Nf$e#}VuNLk`xDK~?bVNy^rsFakXh~!_O)Scb2P-i&e5()<{gvQ|j!Qx0!sE7nWL{b6{ z5R-yI0g`Y@AV30y1Vf=f2^dW5uMoNzG_ES4j(_#)63P|_C5c4Bf#L`-4n;}=AO;4B z1E3;OA^;IM%oYh1!8I|!BEP+{g+o+aFiuchI?+y0JA|;Sv)ymOCE*ZxJ#|@bkPz@c zGkT6tED~oR%dLfW_VE6XzzFSxFvLPH*%Xlw0RyFgKrl#3LJBDI7i$v)#vNCQmzW|z zA<;i1muZ3Eg253By{uClz;9SwED%Ku0*ZCP7`eDO%5q=2#Cd7?ySzDN{z!@%+8w9i zb6N3!*1RFY?T@!Vwtyr0w}_MTciBRq@IMxDhk7Dxe=mfy`$GgrL7nXoxc&WSLH%nU z{l6qj94-#TB?bsUO2QEUF$oD60E){$00f64ZAHZ3;!sJczoWamAhBLh3_{)x7bz|p zTmk)#hV#~MDsTT?+Y5!b!JSsZ|30q%2<|FG1k+Si`h6+FJ5_89 z!i`8>)y&-S@W^Q|zxa5WS&XPqrPYTby`1!opz zx~?EQx|^EHDz)6dkI`QHZT3FyV}%PYtb7<9ICa=n!sn&|R$?4~@V zc`L`wV62&F9EO^Gs#x=UjlQ!av51p1Lo1Xr1aByH{V^bgA_S{~Y+1=YIcDQ*D zpF%Xx&7PK6FyH2gUtTVJO9%Ao(7m_ir`XvC@;0BTz|-A@)`aD(5zLBRF!BZ#rQ3o^*RbGZ<%HFlYlVE-!;80 z6St8#pwZ?JvVk;o!yrYsWFn5w1A$%AX~{_jF?f&IbzH$aFo-RrVbIY(_tZAn{XGoQ z(OCQF`2A;pr4oUrW4d|2t8lTC2$n{P7=4lWDeu)q0iu2Vy08e?kFG!K(zto=X0Ah5nD^R1Ba{bY;4)7C7qGJNxC% zq#;n5#JJ9=m~n^^C`u;E)1_u+GW%nTiu?Uj2baD6N$dUXxm}V_saA`sxzp9m2zQOY>(mlETeyVX` zRHl~UW)yMF*01^E;~1`%aEsI%#v~n#B3E|B>~4*1R`UsE>vT^Dwu1|zd| zJW^BIF^1{^KfcgueOo`^db*1jaZDF6NGm~DW)kVkCni}v?vGU8Y(9__M%6M)d^@%d z;+}J!G%*<*G7I2+IOi*F?_epNWcipR-Mmb@FjYN@Htjjm{-j8)aso(%>Rp~U47a Date: Tue, 7 May 2024 15:58:41 +0200 Subject: [PATCH 126/184] VectorGraph_added_getIsSimplifyed_function --- include/VectorGraph.h | 1 + src/gui/widgets/VectorGraph.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index cc6f642cbc6..67db38fef4a 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -90,6 +90,7 @@ class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView // draws estimated line, does not call getSamples() // does not fill graphs with VectorGraphDataArray FillColor void setIsSimplified(bool isSimplified); + bool getIsSimplified(); // returns -1.0f at .first when nothing is selected PointF getSelectedData(); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 44af057c990..e7ae05384ed 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -186,6 +186,10 @@ void VectorGraphView::setIsSimplified(bool isSimplified) { m_isSimplified = isSimplified; } +bool VectorGraphView::getIsSimplified() +{ + return m_isSimplified; +} PointF VectorGraphView::getSelectedData() { From 9a95b2ed8d7b7700dcb729ad12102a829d0d6853 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 9 May 2024 18:59:00 +0200 Subject: [PATCH 127/184] VectorGraph_variable_renamed --- src/gui/widgets/VectorGraph.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index e7ae05384ed..85a62ff2a14 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -1908,6 +1908,7 @@ VectorGraphDataArray::~VectorGraphDataArray() void VectorGraphDataArray::updateConnections(VectorGraphModel* parent) { + qDebug("VectorGrahDataArray updateConnections"); // call VectorGraphModel signals without qt m_parent = parent; m_id = m_parent->getDataArrayNewId(); @@ -1998,7 +1999,7 @@ void VectorGraphDataArray::setAutomatedColor(QColor color) } bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool callDataChanged) { - qDebug("setEffectorArrayLocation start"); + qDebug("setEffectorArrayLocation start %d", arrayLocation); bool found = true; if (arrayLocation >= 0) { @@ -2042,17 +2043,17 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool call if (m_effectorLocation != -1) { // checking if this VectorGraphDataArray's effector is an effector for an other VectorGraphDataArray - bool found = false; + bool foundB = false; for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) { if (m_parent->getDataArray(i)->getId() != m_id && m_parent->getDataArray(i)->getEffectorArrayLocation() == m_effectorLocation) { - found = true; + foundB = true; break; } } // setting the correct state for the effector array's m_isAnEffector - m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(found); + m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(foundB); m_effectorLocation = -1; getUpdatingFromPoint(-1); From 46e7111bfac8dbadd0c30559cfa4bb55d2a8bc50 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 23 Jun 2024 20:52:43 +0200 Subject: [PATCH 128/184] VectorGraph_implemented_projectJournal_and_rewrwrote_qdebug --- include/VectorGraph.h | 14 +- src/gui/widgets/VectorGraph.cpp | 331 +++++++++++++++++++------------- 2 files changed, 208 insertions(+), 137 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 67db38fef4a..35a3fc755bd 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -44,6 +44,7 @@ namespace lmms { //class VectorGraphViewBase; +class VectorGraphView; class VectorGraphModel; class VectorGraphDataArray; class FloatModel; @@ -328,6 +329,9 @@ public slots: void dataArrayClearedEvent(int arrayId); void dataArrayStyleChanged(); private: + // addJournalCheckpoint + void modelAddJournalCheckPoint(); + std::vector m_dataArrays; unsigned int m_maxLength; @@ -335,6 +339,7 @@ public slots: // a dataArray's getSamples() at the same time QMutex m_getSamplesAccess; QMutex m_bakedSamplesAccess; + friend class lmms::gui::VectorGraphView; }; class LMMS_EXPORT VectorGraphDataArray @@ -366,6 +371,7 @@ class LMMS_EXPORT VectorGraphDataArray void setFillColor(QColor color); void setAutomatedColor(QColor color); + // sets a dataArray as an effector to this dataArray // returns true if successful // if callDataChanged then it will call dataChanged() --> paintEvent() bool setEffectorArrayLocation(int arrayLocation, bool callDataChanged); @@ -541,7 +547,7 @@ class LMMS_EXPORT VectorGraphDataArray void clearedEvent(); // color void styleChanged(); -protected: +private: // returns m_automationModelArray std::vector* getAutomationModelArray(); // delete automationModels in m_automationModelArray @@ -550,8 +556,8 @@ class LMMS_EXPORT VectorGraphDataArray // encodes m_dataArray to QString QString getSavedDataArray(); // decodes and sets m_dataArray from QString - void loadDataArray(QString data, unsigned int arraySize); -private: + void loadDataArray(QString data, unsigned int arraySize, bool callDataChanged); + class VectorGraphPoint { public: @@ -734,7 +740,7 @@ class LMMS_EXPORT VectorGraphDataArray // sorted in getUpdatingOriginals() because some functions need this to be sorted std::vector m_needsUpdating; - // this stores all the FloatModels + // this stores all the FloatModels, unsorted, should only contain currently used FloatModels // used for automation std::vector m_automationModelArray; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 85a62ff2a14..3e53f743a37 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -32,7 +32,6 @@ #include #include #include -#include // showInputDialog() #include // context menu #include // locking when getSamples @@ -50,6 +49,8 @@ #include "JournallingObject.h" #include "base64.h" +//#define VECTORGRAPH_DEBUG_USER_INTERACTION +//#define VECTORGRAPH_DEBUG_PAINT_EVENT namespace lmms { @@ -111,8 +112,6 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe } VectorGraphView::~VectorGraphView() { - qDebug("VectorGraphView dstc"); - qDebug("VectorGraphView dstc end"); } void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) @@ -185,6 +184,9 @@ void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCount) void VectorGraphView::setIsSimplified(bool isSimplified) { m_isSimplified = isSimplified; +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setIsSimplified %d", m_isSimplified); +#endif } bool VectorGraphView::getIsSimplified() { @@ -213,11 +215,11 @@ void VectorGraphView::setSelectedData(PointF data) { if (m_isSelected == true) { - qDebug("setSelectedData"); model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, data.second); - qDebug("set value done"); m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, data.first); - qDebug("set position done (%f)", data.first); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setSelectedData (x, y): %f, %f", data.first, data.second); +#endif } } void VectorGraphView::setBackground(const QPixmap background) @@ -231,7 +233,9 @@ void VectorGraphView::useGetLastSamples() void VectorGraphView::mousePressEvent(QMouseEvent* me) { - qDebug("\n\nmousePressStart ---------"); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("\n\nmousePressEvent start ---------"); +#endif // get position int x = me->x(); int y = me->y(); @@ -240,7 +244,9 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) { - qDebug("mousePress automation started"); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mousePressEvent automation connecting"); +#endif // connect to AutomationTrack model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); @@ -311,6 +317,8 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { m_mousePress = false; startMoving = true; + + model()->modelAddJournalCheckPoint(); } } @@ -323,6 +331,9 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) { if (m_isCurveSelected == false) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseMoveEvent point drag"); +#endif // dragging point PointF convertedCoords = mapMousePos(x, m_graphHeight - y); convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); @@ -331,6 +342,9 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseMoveEvent curve drag"); +#endif // dragging curve PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; @@ -407,19 +421,24 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent start"); +#endif // get position int x = me->x(); int y = me->y(); // if did not drag and graph is pressed if (m_mousePress == true && isGraphPressed(x, m_graphHeight - y) == true) { - qDebug("mouseMove graphPressed: %d", m_lastTrackPoint.first); + model()->modelAddJournalCheckPoint(); // add/delete point if (m_isSelected == false && m_addition == true) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent add point, dataArray count: %d", static_cast(model()->getDataArraySize())); +#endif // if selection failed and addition // get the first editable daraArray and add value - qDebug("release size: %ld", model()->getDataArraySize()); bool success = false; if (m_isLastSelectedArray == true) { @@ -443,6 +462,9 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } else if (m_isSelected == true && m_addition == false) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent delete point"); +#endif // if selection was successful -> deletion model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); m_isSelected = false; @@ -451,12 +473,11 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) } else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) { - qDebug("Mouse Release event try running processControlWindowPressed"); + model()->modelAddJournalCheckPoint(); processControlWindowPressed(x, m_graphHeight - y, false, false, 0, 0); } else if (isGraphPressed(x, m_graphHeight - y) == false) { -qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray); // if the "switch graph" button was pressed in editing mode unsigned int oldSelectedArray = m_selectedArray; m_selectedLocation = 0; @@ -470,7 +491,9 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) // selected data array for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - //qDebug("mouseRelease select new array: [%d], m_selectedArray: %d, old: %d", i, m_selectedArray, oldSelectedArray); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray: i: [%d], m_selectedArray: %d, oldSelectedArray: %d", i, m_selectedArray, oldSelectedArray); +#endif if (model()->getDataArray(i)->getIsSelectable() == true) { // if this data array is the first one that is selectable @@ -489,7 +512,9 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) } } } - //qDebug("mouseRelease select new array final:", m_selectedArray); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray final: %d", m_selectedArray); +#endif // hint text hideHintText(); @@ -499,17 +524,21 @@ qDebug("mouseRelease 8, select new array, m_selectedArray: %d", m_selectedArray) // reset trackpoint m_lastTrackPoint.first = -1; updateGraph(false); - qDebug("mouseReleaseEnd"); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent end"); +#endif } void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseDoubleClickEvent start"); +#endif // get position int x = me->x(); int y = me->y(); // if a data/sample is selected then show input dialog to change the data - qDebug("mouseDoubleClickEvent"); if (isGraphPressed(x, m_graphHeight - y) == true) { if (m_isSelected == true && me->button() == Qt::LeftButton) @@ -545,10 +574,12 @@ void VectorGraphView::leaveEvent(QEvent *event) void VectorGraphView::paintEvent(QPaintEvent* pe) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintEvent start"); +#endif QPainter p(this); p.setRenderHint(QPainter::Antialiasing, true); - qDebug("paintEvent"); m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); // paint background @@ -594,12 +625,17 @@ void VectorGraphView::paintEvent(QPaintEvent* pe) paintEditing(&p); m_useGetLastSamples = false; - qDebug("paint event end"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintEvent end"); +#endif emit drawn(); } void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintGraph start: data arrayLocation: %d", arrayLocation); +#endif VectorGraphDataArray* dataArray = model()->getDataArray(arrayLocation); unsigned int length = dataArray->size(); if (length > 0) @@ -620,7 +656,6 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v // get the currently drawed VectorGraphDataArray samples dataArray->getLastSamples(sampleBuffer); - qDebug("paint sampleBuffer size: %ld", sampleBuffer->size()); for (unsigned int j = 0; j < sampleBuffer->size(); j++) { // if nonNegative then only the dataArray output (getDataValues) @@ -850,6 +885,9 @@ void VectorGraphView::updateDefaultColors() } void VectorGraphView::contextMenuRemoveAutomation() { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("contextMenuRemoveAutomation: m_isSelected: %d, m_selectedArray: %d, m_selectedLocation: %d", m_isSelected, m_selectedArray, m_selectedLocation); +#endif if (m_isSelected == true) { // deleting the floatmodel will delete the connecitons @@ -908,6 +946,9 @@ float VectorGraphView::getDistanceF(float xA, float yA, float xB, float yB) bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouseY) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("addPoint: arrayLocation: %d, position (x, y): %d, %d", arrayLocation, mouseX, mouseY); +#endif // mouseY is calculated like this: // m_graphHeight - y bool output = false; @@ -919,10 +960,12 @@ bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouse if (location >= 0) { output = true; - qDebug("addPoint point added: array: %d location: %d %f,%d", arrayLocation, location, curMouseCoords.second, m_graphHeight); model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("addPoint: point location: %d, positionF (x, y): %f, %f, new dataArray size: %d", + location, curMouseCoords.first, curMouseCoords.second, static_cast(model()->getDataArray(arrayLocation)->size())); +#endif } - qDebug("addPoint Location: %d", location); return output; } @@ -934,7 +977,6 @@ bool VectorGraphView::isGraphPressed(int mouseX, int mouseY) if (m_isEditingActive == true && m_graphHeight - mouseY < m_controlHeight && mouseX < m_controlHeight) { // if switch selected data array was pressed - //qDebug("isGraphPressed switch selected dataArray"); output = false; } else if (isControlWindowPressed(mouseY) == true) @@ -951,7 +993,6 @@ bool VectorGraphView::isControlWindowPressed(int mouseY) // m_graphHeight - y if (m_isEditingActive == true && mouseY <= 0) { - //qDebug("isGraphPressed control window was pressed"); output = true; } return output; @@ -962,11 +1003,16 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i // m_graphHeight - y setCursor(Qt::ArrowCursor); - qDebug("mouseMove 7: %d", m_lastTrackPoint.first); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d, tracked position (x, y): %d, %d", mouseX, mouseY, isDragging, startMoving, curX, curY); +#endif if (m_isEditingActive == true) { int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount + 1); int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("processControlWindowPressed: pressLocation: %d, control window location: %d, controlDiyplayPage: %d", pressLocation, location, m_controlDisplayPage); +#endif if (isDragging == false && pressLocation == m_controlDisplayCount) { // if the last button was pressed @@ -992,7 +1038,6 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i { m_controlDisplayPage = 0; } - qDebug("mouseRelease controlPage: %d", m_controlDisplayPage); hideHintText(); } else if (pressLocation >= 0 && location < m_controlText.size()) @@ -1052,13 +1097,16 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i m_lastTrackPoint.first = curX; m_lastTrackPoint.second = curY; - qDebug("get last value: %d, lasttrack: %d, x: %d, y: %d, x2: %d, y2: %d, location: %d", m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, curX, (curY), m_lastTrackPoint.first, m_lastTrackPoint.second, pressLocation); } PointF convertedCoords = mapMousePos(0, m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); - qDebug("dragging ... %d, %f", (m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2), convertedCoords.second); setInputAttribValue(location, convertedCoords.second, false); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("processControlWindowPressed dragging float: m_lastTrackPoint (x, y): %d, %d, m_lastScndTrackPoint (x, y): %d, %d,\n final coords (x, y): %f, %f", + m_lastTrackPoint.first, m_lastTrackPoint.second, m_lastScndTrackPoint.first, + m_lastScndTrackPoint.second, convertedCoords.first, convertedCoords.second); +#endif // hint text showHintText(widget(), m_controlText[location], 5, 3500); @@ -1076,7 +1124,6 @@ int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int if (output > controlCount) { output = controlCount; -qDebug("getPressedControlInput x location ERRROR: %d", mouseX); } return output; } @@ -1161,7 +1208,9 @@ float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bo } void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue, bool boolValue) { - qDebug("setInputAttribValue started"); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setInputAttribute start: control input: %d, set floatValue: %f, set boolValue: %d", controlArrayLocation, floatValue, boolValue); +#endif if (m_isSelected == true) { float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); @@ -1269,7 +1318,6 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, flo break; } } - qDebug("setInputAttribValue finished"); } QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColor) { @@ -1300,7 +1348,6 @@ QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColor) if (colorSum > 382) { // (red * 0.6f + avg * 0.4f / 3.0f) * 0.7 - //qDebug("getFillColorFromBaseColor bigger, %d", brighten); output = QColor(static_cast(static_cast(baseColor.red()) * 0.42f + colorSum * 0.09f) - brighten, static_cast(static_cast(baseColor.green()) * 0.42f + colorSum * 0.09f) - brighten, static_cast(static_cast(baseColor.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); @@ -1364,7 +1411,9 @@ QString VectorGraphView::getTextForAutomatableEffectableOrType(unsigned int cont void VectorGraphView::selectData(int mouseX, int mouseY) { - qDebug("selectData"); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("selectData start: mouse (x, y): %d, %d", mouseX, mouseY); +#endif m_isSelected = false; @@ -1402,10 +1451,8 @@ void VectorGraphView::selectData(int mouseX, int mouseY) int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); if (location > -1) { - //qDebug("selected data!"); m_selectedLocation = location; m_selectedArray = i; - //qDebug("selected data location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = false; m_isLastSelectedArray = true; @@ -1424,10 +1471,8 @@ void VectorGraphView::selectData(int mouseX, int mouseY) int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, true); if (location > -1) { - //qDebug("selected data curve!"); m_selectedLocation = location; m_selectedArray = i; - //qDebug("selected data curve location: %d, %d", location, i); m_isSelected = true; m_isCurveSelected = true; m_isLastSelectedArray = true; @@ -1438,14 +1483,15 @@ void VectorGraphView::selectData(int mouseX, int mouseY) } } } - qDebug("selectDataEnd, Arr: %d, location: %d", m_selectedArray, m_selectedLocation); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("selectData end: m_selectedArray: %d, m_selectedLocation %d", m_selectedArray, m_selectedLocation); +#endif } int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved) { int output = -1; maxDistance = maxDistance * 2.0f; - qDebug("searchData"); PointF transformedMouse = mapMousePos(mouseX, mouseY); @@ -1454,7 +1500,6 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve bool isBefore = false; // get the nearest data to the mouse pos (x) in an optimalized way int location = dataArray->getNearestLocation(transformedMouse.first, &found, &isBefore); - //qDebug("selected location: %d", location); // if getNearestLocation was successful if (location >= 0) @@ -1482,17 +1527,14 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } } // check distance against x coord - //qDebug("selected x distance: %f", std::abs(dataX - transformedMouse.first)); if (std::abs(dataX - transformedMouse.first) <= maxDistance) { // calculate real distance (x and y) float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - //qDebug("selected full distance: %f (%d, %d)", curDistance, location, (location - curvedBefore)); if (curDistance <= maxDistance) { - //qDebug("search successful"); output = location - curvedBefore; } else @@ -1513,7 +1555,6 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve break; } } - //qDebug("search V2AAA temp, start: %d, end: %d", searchStart, searchEnd); // getting where the search needs to end for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) { @@ -1523,7 +1564,6 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve break; } } - //qDebug("search V2, start: %d, end: %d", searchStart, searchEnd); // calculating real distances from the point coords for (int i = searchStart; i <= searchEnd; i++) { @@ -1544,10 +1584,8 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, dataX * 2.0f, dataY); - //qDebug("search v2 full distance %d: %f / %f y: %f, my: %f y:%f size:%ld", i, curDistance, maxDistance, dataY, transformedMouse.second, dataArray->getY(i), dataArray->size()); if (curDistance <= maxDistance) { - //qDebug("search successful V2"); output = i; break; } @@ -1556,7 +1594,6 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } } } - qDebug("searchDataEnd"); return output; } @@ -1571,10 +1608,7 @@ VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parent, b VectorGraphModel::~VectorGraphModel() { - qDebug("VectorGraphModel dstc"); m_dataArrays.clear(); - - qDebug("VectorGraphModel dstc end"); } unsigned int VectorGraphModel::addDataArray() @@ -1589,11 +1623,9 @@ unsigned int VectorGraphModel::addDataArray() void VectorGraphModel::deleteDataArray(unsigned int arrayLocation) { - qDebug("deleteDataArray"); std::vector effectorArrayLocations(m_dataArrays.size()); for (unsigned int i = arrayLocation; i < m_dataArrays.size() - 1; i++) { - //qDebug("copyed [%d] to [%d]", i + 1, i); m_dataArrays[i] = m_dataArrays[i + 1]; } m_dataArrays.pop_back(); @@ -1616,7 +1648,6 @@ void VectorGraphModel::deleteDataArray(unsigned int arrayLocation) // setting updated locations for (unsigned int i = 0; i < m_dataArrays.size(); i++) { - //qDebug("deleteDataArray end: set effector location: [%d], %d", i, effectorArrayLocations[i]); m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); } emit dataChanged(); @@ -1677,7 +1708,9 @@ int VectorGraphModel::getDataArrayNewId() } void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) { - qDebug("saveSettings"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("saveSettings start"); +#endif // getting the models saving name QString saveName("VectorGraphModel"); @@ -1719,7 +1752,9 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con // saving the FloatModels for (unsigned int j = 0; j < automationModels->size(); j++) { - qDebug("saveSettings saved automatinModel %d, %d", i, j); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("saveSettings saved automatinModel dataArray (i): %d, model (j): %d", i, j); +#endif QString readLocationB = QString::number(j) + "-"; (*automationModels)[j]->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); } @@ -1729,6 +1764,9 @@ void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, con } void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadSettings start"); +#endif QString loadName("VectorGraphModel"); if (name.size() > 0) { @@ -1753,14 +1791,11 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n } QDomElement curElement = node.toElement(); - qDebug("loadSettings"); if (curElement.hasAttribute("DataArrayCount") == true) { - qDebug("loadSettings 2"); unsigned int loadSize = curElement.attribute("DataArrayCount").toInt(); for (unsigned int i = 0; i < loadSize; i++) { - qDebug("loadSettings 3"); // getting the start of the attribute name QString readLocation = "a" + QString::number(i) + "-"; if (i < m_dataArrays.size() && curElement.hasAttribute(readLocation + "DataArraySize") == true) @@ -1770,20 +1805,20 @@ void VectorGraphModel::loadSettings(const QDomElement& element, const QString& n // load m_dataArray if (dataArraySize > 0) { - qDebug("loadSettings 4"); - m_dataArrays[i].loadDataArray(curElement.attribute(readLocation + "DataArray"), dataArraySize); + m_dataArrays[i].loadDataArray(curElement.attribute(readLocation + "DataArray"), dataArraySize, true); } // load automationModelDataArray std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); for (unsigned int j = 0; j < automationSize; j++) { - qDebug("loadSettings 5"); QString readLocationB = QString::number(j) + "-"; FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, this, QString(), false); curModel->loadSettings(curElement, readLocation + readLocationB + "AutomationModel"); automationModels->push_back(curModel); - qDebug("loaded automatinModel %d, %d, size: %ld", i, j, automationModels->size()); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadSettings loaded automatinModel: arrayLocation (i): %d, model (j): %d", i, j); +#endif } } else @@ -1817,6 +1852,10 @@ void VectorGraphModel::loadSettings(const QDomElement& element) { loadSettings(element, QString("")); } +void VectorGraphModel::modelAddJournalCheckPoint() +{ + addJournalCheckPoint(); +} // VectorGraphDataArray ------ @@ -1889,7 +1928,6 @@ VectorGraphDataArray::VectorGraphDataArray( VectorGraphDataArray::~VectorGraphDataArray() { - qDebug("VectorGraphDataArray dstc"); //m_dataArray.clear(); //m_bakedSamples.clear(); //m_needsUpdating.clear(); @@ -1902,13 +1940,10 @@ VectorGraphDataArray::~VectorGraphDataArray() } } m_automationModelArray.clear(); - - qDebug("VectorGraphDataArray dstc end"); } void VectorGraphDataArray::updateConnections(VectorGraphModel* parent) { - qDebug("VectorGrahDataArray updateConnections"); // call VectorGraphModel signals without qt m_parent = parent; m_id = m_parent->getDataArrayNewId(); @@ -1999,7 +2034,6 @@ void VectorGraphDataArray::setAutomatedColor(QColor color) } bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool callDataChanged) { - qDebug("setEffectorArrayLocation start %d", arrayLocation); bool found = true; if (arrayLocation >= 0) { @@ -2008,7 +2042,6 @@ bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool call { m_id = m_parent->getDataArrayNewId(); } - qDebug("setEffectorArrayLocation cur_id %d", m_id); int searchArrayLocation = arrayLocation; found = false; // checking if the effector chain has this dataArray in it @@ -2144,19 +2177,16 @@ int VectorGraphDataArray::add(float newX) int location = -1; if (m_isFixedSize == false && m_dataArray.size() < m_parent->getMaxLength()) { - qDebug("add 1. success"); bool found = false; bool isBefore = false; location = getNearestLocation(newX, &found, &isBefore); if (found == false) { - qDebug("add 2. success, nearest: %d", location); int targetLocation = -1; bool dataChangedVal = false; // if getNearestLocation returned a value if (location >= 0) { - qDebug("add 3. success, nearest: %d", location); targetLocation = location; // shift the new data if the closest data x is bigger // (done for swaping) @@ -2169,18 +2199,15 @@ int VectorGraphDataArray::add(float newX) } } m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); - qDebug("add 4. success, target: %d", targetLocation); swap(m_dataArray.size() - 1, targetLocation, true); dataChangedVal = true; } else if (m_dataArray.size() <= 0) { - qDebug("add 5. success"); m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); targetLocation = 0; dataChangedVal = true; } - qDebug("add size: %ld", m_dataArray.size()); location = targetLocation; if (m_dataArray.size() <= 2) @@ -2254,12 +2281,10 @@ void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool s maxY = (*dataArrayOut)[i].second; } } - //qDebug("formatArray 1: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); maxX = (maxX - minX); minX = -minX; maxY = (maxY - minY) * 0.5f; minY = -minY; - //qDebug("formatArray 2: minx: %f maxx: %f miny: %f maxy: %f", minX, maxX, minY, maxY); if (minX != 0.0f || maxX != 1.0f) { for (unsigned int i = 0; i < dataArrayOut->size(); i++) @@ -2360,8 +2385,6 @@ int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bo while (start < end) { mid = start + (end - start) / 2; - //qDebug("getNearestLocation, mid: %d, start: %d, end: %d", mid, start, end); - //qDebug("getNearestLocation, val: %f, pos: %f", m_dataArray[mid].m_x, searchXIn); if (m_dataArray[mid].m_x == searchXIn) { *foundOut = true; @@ -2388,14 +2411,11 @@ int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bo std::abs(m_dataArray[mid + 1].m_x - searchXIn)) { outputDif = 1; - //*isBeforeOut = false; } - //qDebug("getNearestLocation, outputDif: %d", outputDif); *foundOut = searchXIn == m_dataArray[mid + outputDif].m_x; *isBeforeOut = searchXIn >= m_dataArray[mid + outputDif].m_x; return mid + outputDif; } - //qDebug("getNearestLocation, searchXIn: %f", searchXIn); *foundOut = false; *isBeforeOut = false; return -1; @@ -2403,7 +2423,9 @@ int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bo void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut) { - qDebug("getSamplesA1"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamples start: targetSizeIn: %d", targetSizeIn); +#endif if (sampleBufferOut != nullptr) { @@ -2430,7 +2452,9 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vectorunlockGetSamplesAccess(); } - qDebug("getSamplesA3 finished"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamples end"); +#endif } void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) { @@ -2461,7 +2485,9 @@ std::vector VectorGraphDataArray::getEffectorArrayLocations() void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) { - qDebug("setDataArray size: %ld", inputDataArray->size()); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("setDataArray start"); +#endif if (shouldClear == true) { m_dataArray.clear(); @@ -2479,7 +2505,6 @@ void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, bool isNegativeBefore = false; for (unsigned int i = 0; i < m_dataArray.size(); i++) { - //qDebug("setDataArray 1, x: %f, y: %f", (*inputDataArray)[i].first, (*inputDataArray)[i].second); m_dataArray[i].m_x = (*inputDataArray)[i].first; m_dataArray[i].m_y = (*inputDataArray)[i].second; // calculating curves @@ -2505,7 +2530,6 @@ void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, noneBefore = diff < 0.1f && diff > -0.1f; isNegativeBefore = isNegative; - //qDebug("setDataArray curve: %f", m_dataArray[i].m_c); } } // the whole m_dataArray needs to be updated @@ -2559,7 +2583,6 @@ unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) // if getNearestLocation returned a value if (location >= 0) { - qDebug("set 3. success, location: %d", targetLocation); if (location < pointLocation && isBefore == true) { if (targetLocation + 1 < m_dataArray.size()) @@ -2574,7 +2597,6 @@ unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) targetLocation--; } } - qDebug("set 4. success, target: %d", targetLocation); m_dataArray[pointLocation].m_x = newX; swap(pointLocation, targetLocation, true); location = targetLocation; @@ -2852,15 +2874,19 @@ bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int pointLocatio } void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("setAutomated start"); +#endif if (m_isAutomatableEffectable == true) { if (bValue == true) { - qDebug("setAutomated make"); // if it is not already automated if (m_dataArray[pointLocation].m_automationModel == -1) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setAutomated: make new floatModel"); +#endif m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; getUpdatingFromPoint(pointLocation); @@ -2869,14 +2895,14 @@ void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) } else { - qDebug("setAutomated delete"); - +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setAutomated: delete floatModel"); +#endif // dataChanged() is called in this function // this function check if the current point has an automationModel deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); } } - qDebug("setAutomated end"); } FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) { @@ -2887,7 +2913,7 @@ FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) return nullptr; } -// protected: +// private: std::vector* VectorGraphDataArray::getAutomationModelArray() { return &m_automationModelArray; @@ -2934,9 +2960,11 @@ QString VectorGraphDataArray::getSavedDataArray() m_dataArray.size() * sizeof(VectorGraphPoint), output); return output; } -void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize) +void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, bool callDataChanged) { - qDebug("loadDatatArray start"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadDatatArray start: arraySize: %d", arraySize); +#endif int size = 0; char* dst = 0; base64::decode(data, &dst, &size); @@ -2953,13 +2981,16 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize) } delete[] dst; - qDebug("loadDatatArray end"); + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } } -// private: void VectorGraphDataArray::deleteAutomationModel(unsigned int modelLocation, bool callDataChanged) { - if (modelLocation != -1) + if (modelLocation > -1) { FloatModel* curModel = m_automationModelArray[modelLocation]; @@ -3008,15 +3039,14 @@ void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointL { if (shouldShiftBetween == true) { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("swap: -------"); - qDebug("first.: %d, second.: %d", pointLocationA, pointLocationB); - - /* + qDebug("first point location: %d, second point locaiton: %d", pointLocationA, pointLocationB); for (unsigned int i = 0; i < m_dataArray.size(); i++) { qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } - */ +#endif if (pointLocationA < pointLocationB) { @@ -3037,13 +3067,13 @@ void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointL m_dataArray[pointLocationB] = swap; } - /* +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug(" --------- "); for (unsigned int i = 0; i < m_dataArray.size(); i++) { qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); } - */ +#endif } else { @@ -3181,7 +3211,6 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples // calculating how many samples are needed to 1 complete wave // we have "count" amount of samples and "tValB * 100.0f" amount of waves int end = static_cast(std::floor(count / (tValB * 100.0f))); - qDebug("sineB_1, %f, %d", (count / (tValB * 100.0f)), end); if (count <= 0) { end = 0; @@ -3206,20 +3235,16 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples m_universalSampleBuffer[i] = sineAmp * std::sin( (*xArray)[startLoc + i] * 628.318531f * tValB + sinePhase * 100.0f); } - //qDebug("sineB_2"); // copy the first wave until the end for (int i = 0; i < count; i += end) { - //qDebug("sineB_2.4: i: %d, end: %d count - i: %d, count: %d", i, end, count - i, count); int endB = i + end >= count ? count - i : end; for (unsigned int j = 0; j < endB; j++) { - //qDebug("sineB_2.5: i: %d, %d, %d", endB, j, i + j); (*samplesOut)[startLoc + j + i] += m_universalSampleBuffer[j]; } } - //qDebug("sineB_3"); // fade in unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) @@ -3276,7 +3301,6 @@ void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samples } float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; - //qDebug("stepsA - stepCount = %f", stepCount); for (unsigned int i = 0; i < count; i++) { float y = (*yArray)[startLoc + i] + 1.0f; @@ -3369,11 +3393,16 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up (*updatingPointLocations)[j]) { updatingEnd = j; - qDebug("getUpdatingFromEffector new updatingEnd: %d, i: %d", updatingEnd, i); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", updatingEnd, i); +#endif } else { - qDebug("getUpdatingFromEffector updatingEnd %d brake: %d < %d [j = %d]", updatingEnd, ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, + ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); +#endif break; } } @@ -3381,7 +3410,9 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up int updatingEndSlide = 0; if (updatingEnd + 1 < effector->size()) { - qDebug("getUpdatingFromEffector updatingEndSlide = 1"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: updatingEndSlide = 1"); +#endif updatingEndSlide = 1; } @@ -3390,10 +3421,14 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up bool isBefore = false; // this can return -1 int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); - qDebug("getUpdatingFromEffector getNearestLocation before: %d, i: %d", locationBefore, i); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); +#endif if (isBefore == true && locationBefore > 0 && getEffectPoints(locationBefore) == true) { - qDebug("getUpdatingFromEffector locationBefore = %d - 1", locationBefore); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: locationBefore = %d - 1", locationBefore); +#endif // the line (or point) before might be effected if the current nearest point // is effected in some way // so subtract 1 @@ -3408,31 +3443,42 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up isBefore = false; int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); - qDebug("getUpdatingFromEffector getNearestLocation after: %d, updatingEnd: %d (+ %d), ex: %f, dx: %f", locationAfter, updatingEnd, updatingEndSlide, effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, + effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); +#endif if (isBefore == false) { - qDebug("getUpdatingFromEffector locationAfter = %d - 1", locationAfter); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: locationAfter = %d - 1", locationAfter); +#endif // if the nearest point is after ([updatingEnd] + upadtingEndSlide) (where updating ends) locationAfter--; } // updating everything before if i -> 0 if ((*updatingPointLocations)[i] == 0) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything before"); +#endif locationBefore = 0; } // if updatingEnd is the last point in effecor, then // update everithing after if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything after"); +#endif locationAfter = m_dataArray.size() - 1; } // clamp locationAfter = locationAfter < 0 ? 0 : m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; - qDebug("getUpdatingFromEffector start: %d, end: %d", locationBefore, locationAfter); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: final start: %d, final end: %d, i: %d", locationBefore, locationAfter, i); +#endif // if the last point was updated (ture in case of j = 0) bool lastUpdated = true; @@ -3442,7 +3488,9 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // update only if effected if (isEffectedPoint(j) == true && (getEffectPoints(j) == true || getEffectLines(j) == true)) { - qDebug("getUpdatingFromEffector: [%d] -> %d", i, j); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: i: %d, updating: %d", i, j); +#endif m_needsUpdating.push_back(j); if (lastUpdated == false && getEffectPoints(j) == true) { @@ -3485,7 +3533,9 @@ void VectorGraphDataArray::getUpdatingFromAutomation() { if (getIsAutomationValueChanged(i) == true) { - qDebug("getUpdatingFromAutomation: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromAutomation: point location: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); +#endif m_needsUpdating.push_back(i); // if the automatable value effects the y (so the position) // the point before this is updated too @@ -3500,11 +3550,12 @@ void VectorGraphDataArray::getUpdatingOriginals() { // selecting only original values and sorting - // Debug testing +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - qDebug("getUpatingOriginals: [%d] -> %d", i, m_needsUpdating[i]); + qDebug("getUpatingOriginals before: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); } +#endif // sorting the array // this is done becaues functions that use m_needsUpdating @@ -3541,10 +3592,12 @@ void VectorGraphDataArray::getUpdatingOriginals() } } +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - qDebug("getUpatingOriginals final: [%d] -> %d", i, m_needsUpdating[i]); + qDebug("getUpatingOriginals final: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); } +#endif } void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, std::vector* updatingValuesOut, std::vector* sampleBufferOut) @@ -3558,7 +3611,9 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); } - qDebug("getSamplesInnerB1, size: %d - id: %d", targetSizeIn, m_id); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: id: %d", m_id); +#endif m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); @@ -3580,6 +3635,9 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh // updating m_needsUpdating if (m_isDataChanged == false && targetSizeIn == m_updatingBakedSamples.size()) { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: get updating"); +#endif if (isEffected == true && effectorUpdatingValues.size() > 0 && (effectorIsChanged == false || effectedCount > 0)) { @@ -3587,15 +3645,16 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh // before use (in this case it is already sorted) getUpdatingFromEffector(&effectorUpdatingValues); } - qDebug("getSamplesInnerB2"); getUpdatingFromAutomation(); // sort and select only original // values getUpdatingOriginals(); - qDebug("getSamplesInnerB3"); } else { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: update all points"); +#endif m_parent->lockBakedSamplesAccess(); if (targetSizeIn != m_bakedSamples.size()) { @@ -3611,7 +3670,6 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_needsUpdating[i] = i; } - qDebug("getSamplesInnerB4, needsUpdating size: %ld", m_needsUpdating.size()); } float stepSize = 1.0f / static_cast(targetSizeIn); @@ -3644,7 +3702,9 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh effector = m_parent->getDataArray(m_effectorLocation); } - qDebug("getSamplesInnerB6, updatingsize: %ld", m_needsUpdating.size()); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: updatingsize: %d", static_cast(m_needsUpdating.size())); +#endif // calculate final lines for (unsigned int i = 0; i < m_needsUpdating.size(); i++) @@ -3678,15 +3738,18 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh m_parent->unlockBakedSamplesAccess(); m_isDataChanged = false; - qDebug("getSamplesInnerB9"); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner end"); +#endif } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) { - qDebug("getSamplesD6.1 m_needsUpdating[%d]: %d", pointLocation, m_needsUpdating[pointLocation]); unsigned int effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); - qDebug("getSamplesD6.2 effectYlocation: %d, %ld", effectYLocation, effectorSamples->size()); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, m_needsUpdating[pointLocation], effectYLocation); +#endif // current effector output Y near m_needsUpdating[pointLocation] point float curEffectY = (*effectorSamples)[effectYLocation]; float nextEffectY = (*effectorSamples)[effectYLocation]; @@ -3747,7 +3810,10 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, float fadeInStart = 0.05f; unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; -qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, %f, AB: %f, %f", pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesUpdatinLines: point: [%d] start: %d, end: %d, line type: %d, --- attribs: y: %f, next y: %f, curve %f, valA %f, valB %f", + pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); +#endif // calculate final updated line if (type == 0) @@ -3815,7 +3881,6 @@ qDebug("getSamplesD8 [%d] start: %d, end: %d, type: %d, --- %f, %f, % int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; // process line effect // if it is enabled - qDebug("getSamples run prucessEffect run prucessEffect run prucessEffect run prucessEffect"); for (int j = startB; j < endB; j++) { m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); From e2ca5e2ce1f549f6ca942b7744c43d9b5164ab50 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 23 Jun 2024 22:11:56 +0200 Subject: [PATCH 129/184] VectorGraph_inversed_ifs --- src/gui/widgets/VectorGraph.cpp | 1653 +++++++++++++++---------------- 1 file changed, 816 insertions(+), 837 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 3e53f743a37..dee1d563dd3 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -322,100 +322,99 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } } - // if the mouse was moved a lot - if (m_mousePress == false) + // if the mouse was not moved a lot + if (m_mousePress == true) { return; } + + if (isGraphPressed(x, m_lastScndTrackPoint.second) == true) { - if (isGraphPressed(x, m_lastScndTrackPoint.second) == true) + if (m_isSelected == true && m_addition == true) { - if (m_isSelected == true && m_addition == true) + if (m_isCurveSelected == false) { - if (m_isCurveSelected == false) - { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseMoveEvent point drag"); + qDebug("mouseMoveEvent point drag"); #endif - // dragging point - PointF convertedCoords = mapMousePos(x, m_graphHeight - y); - convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); - convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); - setSelectedData(convertedCoords); - } - else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) - { + // dragging point + PointF convertedCoords = mapMousePos(x, m_graphHeight - y); + convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); + convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); + setSelectedData(convertedCoords); + } + else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) + { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseMoveEvent curve drag"); + qDebug("mouseMoveEvent curve drag"); #endif - // dragging curve - PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); - float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; - curveValue = std::clamp(curveValue, -1.0f, 1.0f); - model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); - } + // dragging curve + PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); + float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; + curveValue = std::clamp(curveValue, -1.0f, 1.0f); + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); } - else if (m_addition == false) + } + else if (m_addition == false) + { + // deleting points + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) { - // deleting points - float curDistance = getDistance(x, m_graphHeight - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize) + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + m_isSelected = false; + selectData(x, m_graphHeight - y); + if (m_isSelected == true) { - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = m_graphHeight - y; + model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); m_isSelected = false; - selectData(x, m_graphHeight - y); - if (m_isSelected == true) - { - model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); - m_isSelected = false; - m_isEditingActive = false; - } + m_isEditingActive = false; } } - else + } + else + { + // adding points + if (startMoving == true && m_isLastSelectedArray == true) { - // adding points - if (startMoving == true && m_isLastSelectedArray == true) - { - // trying to add to the last selected array - addPoint(m_selectedArray, x, m_graphHeight - y); - } - float curDistance = getDistance(x, m_graphHeight - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize) + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); + } + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) + { + // calculating angle + // getting the angle between (lastScndTrackPoint and lastTrackPoint) + // and (lastTrackPoint and x and y) + float curAngle = static_cast( + (m_lastTrackPoint.second - m_lastScndTrackPoint.second) * + (m_graphHeight - y - m_lastTrackPoint.second) + + (m_lastTrackPoint.first - m_lastScndTrackPoint.first) * + (x - m_lastTrackPoint.first)); + curAngle = std::acos(curAngle / curDistance / + getDistance(m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, + m_lastTrackPoint.first, m_lastTrackPoint.second)); + // if the angle difference is bigger than 0.3 rad + if (std::abs(curAngle) * curDistance * curDistance / static_cast(m_pointSize * m_pointSize) > 0.3f) { - // calculating angle - // getting the angle between (lastScndTrackPoint and lastTrackPoint) - // and (lastTrackPoint and x and y) - float curAngle = static_cast( - (m_lastTrackPoint.second - m_lastScndTrackPoint.second) * - (m_graphHeight - y - m_lastTrackPoint.second) + - (m_lastTrackPoint.first - m_lastScndTrackPoint.first) * - (x - m_lastTrackPoint.first)); - curAngle = std::acos(curAngle / curDistance / - getDistance(m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, - m_lastTrackPoint.first, m_lastTrackPoint.second)); - // if the angle difference is bigger than 0.3 rad - if (std::abs(curAngle) * curDistance * curDistance / static_cast(m_pointSize * m_pointSize) > 0.3f) + m_lastScndTrackPoint.first = m_lastTrackPoint.first; + m_lastScndTrackPoint.second = m_lastTrackPoint.second; + + if (m_isLastSelectedArray == true) { - m_lastScndTrackPoint.first = m_lastTrackPoint.first; - m_lastScndTrackPoint.second = m_lastTrackPoint.second; - - if (m_isLastSelectedArray == true) - { - // trying to add to the last selected array - addPoint(m_selectedArray, x, m_graphHeight - y); - } + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); } - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = m_graphHeight - y; } - // else m_mousePress does not change + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; } + // else m_mousePress does not change } - else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) - { - processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); - } + } + else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) + { + processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); } } @@ -638,126 +637,125 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v #endif VectorGraphDataArray* dataArray = model()->getDataArray(arrayLocation); unsigned int length = dataArray->size(); - if (length > 0) - { - p->setPen(QPen(*dataArray->getLineColor(), 2)); - p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); + if (length <= 0) { return; } - std::pair posA(0, 0); - std::pair posB(0, 0); - std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), false)); - // draw line - if (m_isSimplified == false) - { - QPainterPath pt; - posA = startPos; - pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); - // get the currently drawed VectorGraphDataArray samples - dataArray->getLastSamples(sampleBuffer); + std::pair posA(0, 0); + std::pair posB(0, 0); + std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), false)); + // draw line + if (m_isSimplified == false) + { + QPainterPath pt; + posA = startPos; + pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - for (unsigned int j = 0; j < sampleBuffer->size(); j++) - { - // if nonNegative then only the dataArray output (getDataValues) - // is bigger than 0 so it matters only here - posB = mapDataPos(0, (*sampleBuffer)[j], dataArray->getIsNonNegative()); - posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); - - if (posA.first != posB.first) - { - pt.lineTo(posB.first, m_graphHeight - posB.second); - // pt replaces drawing with path - //p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - posA = posB; - } + // get the currently drawed VectorGraphDataArray samples + dataArray->getLastSamples(sampleBuffer); - // final draw line, fill - if (dataArray->getFillColor()->alpha() > 0) - { - // getting the line for - // drawing later - QPainterPath ptline(pt); - pt.lineTo(width() - 1, posB.second); - pt.lineTo(width() - 1, m_graphHeight - 1); - pt.lineTo(startPos.first + 1, m_graphHeight - 1); - pt.lineTo(startPos.first + 1, startPos.second); - // draw fill - p->fillPath(pt, QBrush(*dataArray->getFillColor())); - // draw line - p->drawPath(ptline); - } - else + for (unsigned int j = 0; j < sampleBuffer->size(); j++) + { + // if nonNegative then only the dataArray output (getDataValues) + // is bigger than 0 so it matters only here + posB = mapDataPos(0, (*sampleBuffer)[j], dataArray->getIsNonNegative()); + posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); + + if (posA.first != posB.first) { - p->drawPath(pt); + pt.lineTo(posB.first, m_graphHeight - posB.second); + // pt replaces drawing with path + //p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } + posA = posB; } - // draw points - if (dataArray->getIsSelectable() == true || m_isSimplified == true) + // final draw line, fill + if (dataArray->getFillColor()->alpha() > 0) + { + // getting the line for + // drawing later + QPainterPath ptline(pt); + pt.lineTo(width() - 1, posB.second); + pt.lineTo(width() - 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, startPos.second); + // draw fill + p->fillPath(pt, QBrush(*dataArray->getFillColor())); + // draw line + p->drawPath(ptline); + } + else { - posA = startPos; + p->drawPath(pt); + } + } + + // draw points + if (dataArray->getIsSelectable() == true || m_isSimplified == true) + { + posA = startPos; - int squareSize = m_pointSize; + int squareSize = m_pointSize; - QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); - bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; - bool resetColor = false; - for (unsigned int j = 0; j < length; j++) + QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); + bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; + bool resetColor = false; + for (unsigned int j = 0; j < length; j++) + { + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), false); + // draw point + if (drawPoints == true) { - posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), false); - // draw point - if (drawPoints == true) + // set point color + if (dataArray->getAutomationModel(j) != nullptr) { - // set point color - if (dataArray->getAutomationModel(j) != nullptr) - { - // if automated - p->setPen(QPen(*dataArray->getAutomatedColor(), 2)); - p->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); - resetColor = true; - } - else if (m_isSelected == true && m_selectedArray == arrayLocation && m_selectedLocation == j) - { - // if selected - p->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); - resetColor = true; - } + // if automated + p->setPen(QPen(*dataArray->getAutomatedColor(), 2)); + p->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); + resetColor = true; + } + else if (m_isSelected == true && m_selectedArray == arrayLocation && m_selectedLocation == j) + { + // if selected + p->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); + resetColor = true; + } - p->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + p->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); - // reset point color - if (resetColor == true) - { - p->setPen(QPen(*dataArray->getLineColor(), 2)); - p->setBrush(Qt::NoBrush); - resetColor = false; - } + // reset point color + if (resetColor == true) + { + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(Qt::NoBrush); + resetColor = false; + } - if (j > 0) + if (j > 0) + { + if (dataArray->getIsEditableAttrib() == true) { - if (dataArray->getIsEditableAttrib() == true) - { - std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - p->drawRect(posC.first - squareSize / 2, - m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); - } + std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + p->drawRect(posC.first - squareSize / 2, + m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); } } + } - // draw simplified line - if (m_isSimplified == true) - { - p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - posA = posB; + // draw simplified line + if (m_isSimplified == true) + { + p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); } + posA = posB; } - // draw last simplified line - if (m_isSimplified == true) - { - p->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); - } + } + // draw last simplified line + if (m_isSimplified == true) + { + p->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); } } void VectorGraphView::paintEditing(QPainter* p) @@ -956,16 +954,16 @@ bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouse curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); int location = model()->getDataArray(arrayLocation)->add(curMouseCoords.first); - // if adding was successful - if (location >= 0) - { - output = true; - model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); + + // if adding was not successful + if (location < 0) { return output; } + + output = true; + model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("addPoint: point location: %d, positionF (x, y): %f, %f, new dataArray size: %d", - location, curMouseCoords.first, curMouseCoords.second, static_cast(model()->getDataArray(arrayLocation)->size())); + qDebug("addPoint: point location: %d, positionF (x, y): %f, %f, new dataArray size: %d", + location, curMouseCoords.first, curMouseCoords.second, static_cast(model()->getDataArray(arrayLocation)->size())); #endif - } return output; } @@ -1006,111 +1004,111 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d, tracked position (x, y): %d, %d", mouseX, mouseY, isDragging, startMoving, curX, curY); #endif - if (m_isEditingActive == true) - { - int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount + 1); - int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; + + if (m_isEditingActive == false) { return; } + + int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount + 1); + int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed: pressLocation: %d, control window location: %d, controlDiyplayPage: %d", pressLocation, location, m_controlDisplayPage); + qDebug("processControlWindowPressed: pressLocation: %d, control window location: %d, controlDiyplayPage: %d", pressLocation, location, m_controlDisplayPage); #endif - if (isDragging == false && pressLocation == m_controlDisplayCount) - { - // if the last button was pressed + if (isDragging == false && pressLocation == m_controlDisplayCount) + { + // if the last button was pressed - // how many inputs are there - int controlTextCount = m_controlText.size(); - if (m_isSelected == true) + // how many inputs are there + int controlTextCount = m_controlText.size(); + if (m_isSelected == true) + { + if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) { - if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) - { - // x, y - controlTextCount = 2; - } - else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) - { - // x, y, curve, valA, valB, switch type - controlTextCount = 6; - } + // x, y + controlTextCount = 2; } - - m_controlDisplayPage++; - if (m_controlDisplayCount * m_controlDisplayPage >= controlTextCount) + else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) { - m_controlDisplayPage = 0; + // x, y, curve, valA, valB, switch type + controlTextCount = 6; } - hideHintText(); } - else if (pressLocation >= 0 && location < m_controlText.size()) + + m_controlDisplayPage++; + if (m_controlDisplayCount * m_controlDisplayPage >= controlTextCount) { - // pressLocation should always be bigger than -1 - // if the control window was pressed + m_controlDisplayPage = 0; + } + hideHintText(); + } + else if (pressLocation >= 0 && location < m_controlText.size()) + { + // pressLocation should always be bigger than -1 + // if the control window was pressed - if (m_addition == false) + if (m_addition == false) + { + if (location >= 1 && location <= 4) { - if (location >= 1 && location <= 4) - { - // if the right mouse button was pressed on a automatabel attribute - // get context menu input text - QString controlDisplayText = m_controlText[location]; - controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); - setInputAttribValue(6, location - 1, false); - - // getting the currently selected point's FloatModel - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - - // show context menu - showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); - } + // if the right mouse button was pressed on a automatabel attribute + // get context menu input text + QString controlDisplayText = m_controlText[location]; + controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); + setInputAttribValue(6, location - 1, false); + + // getting the currently selected point's FloatModel + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + + // show context menu + showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); } - else if (isDragging == false && m_controlIsFloat[location] == false) + } + else if (isDragging == false && m_controlIsFloat[location] == false) + { + // if the input type is a bool + + bool curBoolValue = true; + // if location is not at "set type" or "set automation location" or "set effect location" + // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) + if (location < 5 || location > 7) { - // if the input type is a bool + getInputAttribValue(location, &curBoolValue); + curBoolValue = !curBoolValue; + } + setInputAttribValue(location, 0.0f, curBoolValue); - bool curBoolValue = true; - // if location is not at "set type" or "set automation location" or "set effect location" - // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) - if (location < 5 || location > 7) - { - getInputAttribValue(location, &curBoolValue); - curBoolValue = !curBoolValue; - } - setInputAttribValue(location, 0.0f, curBoolValue); + // hint text + QString hintText = m_controlText[location]; + hintText = hintText + getTextForAutomatableEffectableOrType(location); + showHintText(widget(), hintText, 5, 3500); + } + else if (isDragging == true && m_controlIsFloat[location] == true) + { + // if the input type is a float - // hint text - QString hintText = m_controlText[location]; - hintText = hintText + getTextForAutomatableEffectableOrType(location); - showHintText(widget(), hintText, 5, 3500); - } - else if (isDragging == true && m_controlIsFloat[location] == true) + // if the user just started to move the mouse it is pressed + if (startMoving == true) { - // if the input type is a float - - // if the user just started to move the mouse it is pressed - if (startMoving == true) - { - // unused bool - bool isTrue = false; - // set m_lastScndTrackPoint.first to the current input value - m_lastScndTrackPoint.first = mapControlInputX(getInputAttribValue(location, &isTrue), m_graphHeight); + // unused bool + bool isTrue = false; + // set m_lastScndTrackPoint.first to the current input value + m_lastScndTrackPoint.first = mapControlInputX(getInputAttribValue(location, &isTrue), m_graphHeight); - m_lastTrackPoint.first = curX; - m_lastTrackPoint.second = curY; - } - PointF convertedCoords = mapMousePos(0, - m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); - setInputAttribValue(location, convertedCoords.second, false); + m_lastTrackPoint.first = curX; + m_lastTrackPoint.second = curY; + } + PointF convertedCoords = mapMousePos(0, + m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); + setInputAttribValue(location, convertedCoords.second, false); #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed dragging float: m_lastTrackPoint (x, y): %d, %d, m_lastScndTrackPoint (x, y): %d, %d,\n final coords (x, y): %f, %f", - m_lastTrackPoint.first, m_lastTrackPoint.second, m_lastScndTrackPoint.first, - m_lastScndTrackPoint.second, convertedCoords.first, convertedCoords.second); + qDebug("processControlWindowPressed dragging float: m_lastTrackPoint (x, y): %d, %d, m_lastScndTrackPoint (x, y): %d, %d,\n final coords (x, y): %f, %f", + m_lastTrackPoint.first, m_lastTrackPoint.second, m_lastScndTrackPoint.first, + m_lastScndTrackPoint.second, convertedCoords.first, convertedCoords.second); #endif - // hint text - showHintText(widget(), m_controlText[location], 5, 3500); - } + // hint text + showHintText(widget(), m_controlText[location], 5, 3500); } } } @@ -1130,79 +1128,78 @@ int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bool* valueOut) { float output = 0.0f; - if (m_isSelected == true) + if (m_isSelected == false) { return output; } + + switch (controlArrayLocation) { - switch (controlArrayLocation) - { - case 0: - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); - break; - case 1: - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); - break; - case 2: - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); - break; - case 3: - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); - break; - case 4: - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); - break; - case 5: - // type - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); - break; - case 6: - // automation location - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); - break; - case 7: - // effect location - *valueOut = false; - output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); - break; - case 8: - *valueOut = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation); - break; - case 9: - *valueOut = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation); - break; - case 10: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); - break; - case 11: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); - break; - case 12: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); - break; - case 13: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); - break; - case 14: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); - break; - case 15: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); - break; - case 16: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); - break; - case 17: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); - break; - case 18: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 8); - break; - } + case 0: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + break; + case 1: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); + break; + case 2: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); + break; + case 3: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); + break; + case 4: + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); + break; + case 5: + // type + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); + break; + case 6: + // automation location + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); + break; + case 7: + // effect location + *valueOut = false; + output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); + break; + case 8: + *valueOut = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation); + break; + case 9: + *valueOut = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation); + break; + case 10: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); + break; + case 11: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); + break; + case 12: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); + break; + case 13: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); + break; + case 14: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); + break; + case 15: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); + break; + case 16: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); + break; + case 17: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); + break; + case 18: + *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 8); + break; } return output; } @@ -1211,112 +1208,111 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, flo #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("setInputAttribute start: control input: %d, set floatValue: %f, set boolValue: %d", controlArrayLocation, floatValue, boolValue); #endif - if (m_isSelected == true) + if (m_isSelected == false) { return; } + + float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); + unsigned int clampedValueB = 0; + switch (controlArrayLocation) { - float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); - unsigned int clampedValueB = 0; - switch (controlArrayLocation) - { - case 0: - m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); - break; - case 1: - model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); - break; - case 2: - model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, clampedValue); - break; - case 3: - model()->getDataArray(m_selectedArray)->setValA(m_selectedLocation, clampedValue); - break; - case 4: - model()->getDataArray(m_selectedArray)->setValB(m_selectedLocation, clampedValue); - break; - case 5: - // type - clampedValueB = 0; - if (boolValue == true) - { - clampedValueB = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation) + 1; - if (clampedValueB > 5) - { - clampedValueB = 0; - } - } - else - { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); - } - model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); - break; - case 6: - // automation location - clampedValueB = 0; - if (boolValue == true) - { - clampedValueB = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation) + 1; - if (clampedValueB > 4) - { - clampedValueB = 0; - } - } - else + case 0: + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); + break; + case 1: + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); + break; + case 2: + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, clampedValue); + break; + case 3: + model()->getDataArray(m_selectedArray)->setValA(m_selectedLocation, clampedValue); + break; + case 4: + model()->getDataArray(m_selectedArray)->setValB(m_selectedLocation, clampedValue); + break; + case 5: + // type + clampedValueB = 0; + if (boolValue == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation) + 1; + if (clampedValueB > 5) { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + clampedValueB = 0; } - model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); - break; - case 7: - // effect location - clampedValueB = 0; - if (boolValue == true) + } + else + { + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); + } + model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); + break; + case 6: + // automation location + clampedValueB = 0; + if (boolValue == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation) + 1; + if (clampedValueB > 4) { - clampedValueB = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation) + 1; - if (clampedValueB > 4) - { - clampedValueB = 0; - } + clampedValueB = 0; } - else + } + else + { + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + } + model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); + break; + case 7: + // effect location + clampedValueB = 0; + if (boolValue == true) + { + clampedValueB = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation) + 1; + if (clampedValueB > 4) { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + clampedValueB = 0; } - model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); - break; - case 8: - model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, boolValue); - break; - case 9: - model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, boolValue); - break; - case 10: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); - break; - case 11: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); - break; - case 12: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); - break; - case 13: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); - break; - case 14: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); - break; - case 15: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); - break; - case 16: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); - break; - case 17: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); - break; - case 18: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValue); - break; - } + } + else + { + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + } + model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); + break; + case 8: + model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, boolValue); + break; + case 9: + model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, boolValue); + break; + case 10: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); + break; + case 11: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); + break; + case 12: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); + break; + case 13: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); + break; + case 14: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); + break; + case 15: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); + break; + case 16: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); + break; + case 17: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); + break; + case 18: + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValue); + break; } } QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColor) @@ -1501,95 +1497,94 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve // get the nearest data to the mouse pos (x) in an optimalized way int location = dataArray->getNearestLocation(transformedMouse.first, &found, &isBefore); - // if getNearestLocation was successful - if (location >= 0) + // if getNearestLocation was not successful + if (location < 0) { return output; } + + float dataX = dataArray->getX(location); + float dataY = dataArray->getY(location); + // this is set to one when isCurved == true + // and isBefore == false + int curvedBefore = 0; + // if isCurved then get the closest curved coord + if (isCurved == true && dataArray->size() > 1) { - float dataX = dataArray->getX(location); - float dataY = dataArray->getY(location); - // this is set to one when isCurved == true - // and isBefore == false - int curvedBefore = 0; - // if isCurved then get the closest curved coord - if (isCurved == true && dataArray->size() > 1) + if (isBefore == false && 1 < location) { - if (isBefore == false && 1 < location) - { - curvedBefore = 1; - } - if (location - curvedBefore < dataArray->size() - 1) - { - PointF curvedDataCoords = mapDataCurvePosF( - dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), - dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), - dataArray->getC(location - curvedBefore)); - dataX = curvedDataCoords.first; - dataY = curvedDataCoords.second; - } + curvedBefore = 1; } - // check distance against x coord - if (std::abs(dataX - transformedMouse.first) <= maxDistance) + if (location - curvedBefore < dataArray->size() - 1) { - // calculate real distance (x and y) - float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, - dataX * 2.0f, dataY); + PointF curvedDataCoords = mapDataCurvePosF( + dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), + dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), + dataArray->getC(location - curvedBefore)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; + } + } + // check distance against x coord + if (std::abs(dataX - transformedMouse.first) <= maxDistance) + { + // calculate real distance (x and y) + float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); - if (curDistance <= maxDistance) - { - output = location - curvedBefore; - } - else + if (curDistance <= maxDistance) + { + output = location - curvedBefore; + } + else + { + // sometimes the mouse x and the nearest point x + // coordinates are close but the y coords are not + // calculating and testing all near by point distances + int searchStart = 0; + int searchEnd = dataArray->size() - 1; + // from where we need to search the data + for (int i = location - curvedBefore - 1; i > 0; i--) { - // sometimes the mouse x and the nearest point x - // coordinates are close but the y coords are not - // calculating and testing all near by point distances - int searchStart = 0; - int searchEnd = dataArray->size() - 1; - // from where we need to search the data - for (int i = location - curvedBefore - 1; i > 0; i--) + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) { - if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) - { - // if it is isCurved, then subtract 1 - // add 1 to i because [i] > maxDistance - searchStart = i + 1 - (i > 0 && isCurved == true ? 1 : 0); - break; - } + // if it is isCurved, then subtract 1 + // add 1 to i because [i] > maxDistance + searchStart = i + 1 - (i > 0 && isCurved == true ? 1 : 0); + break; } - // getting where the search needs to end - for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) + } + // getting where the search needs to end + for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) + { + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) { - if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) - { - searchEnd = i - 1 - (i > 0 && isCurved == true ? 1 : 0); - break; - } + searchEnd = i - 1 - (i > 0 && isCurved == true ? 1 : 0); + break; } - // calculating real distances from the point coords - for (int i = searchStart; i <= searchEnd; i++) + } + // calculating real distances from the point coords + for (int i = searchStart; i <= searchEnd; i++) + { + if (i != location) { - if (i != location) + dataX = dataArray->getX(i); + dataY = dataArray->getY(i); + if (isCurved == true && dataArray->size() > 1) { - dataX = dataArray->getX(i); - dataY = dataArray->getY(i); - if (isCurved == true && dataArray->size() > 1) - { - if (dataArray->size() - 1 > i) - { - PointF curvedDataCoords = mapDataCurvePosF( - dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), - dataArray->getC(i)); - dataX = curvedDataCoords.first; - dataY = curvedDataCoords.second; - } - } - curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, - dataX * 2.0f, dataY); - if (curDistance <= maxDistance) + if (dataArray->size() - 1 > i) { - output = i; - break; + PointF curvedDataCoords = mapDataCurvePosF( + dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), + dataArray->getC(i)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; } } + curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); + if (curDistance <= maxDistance) + { + output = i; + break; + } } } } @@ -1680,15 +1675,15 @@ void VectorGraphModel::dataArrayStyleChanged() int VectorGraphModel::getDataArrayLocationFromId(int arrayId) { int output = -1; - if (arrayId >= 0) + + if (arrayId < 0) { return output; } + + for (unsigned int i = 0; i < m_dataArrays.size(); i++) { - for (unsigned int i = 0; i < m_dataArrays.size(); i++) + if (m_dataArrays[i].getId() == arrayId) { - if (m_dataArrays[i].getId() == arrayId) - { - output = i; - break; - } + output = i; + break; } } return output; @@ -2175,53 +2170,52 @@ int VectorGraphDataArray::getId() int VectorGraphDataArray::add(float newX) { int location = -1; - if (m_isFixedSize == false && m_dataArray.size() < m_parent->getMaxLength()) + if (m_isFixedSize == true || m_dataArray.size() >= m_parent->getMaxLength()) { return location; } + + bool found = false; + bool isBefore = false; + location = getNearestLocation(newX, &found, &isBefore); + if (found == false) { - bool found = false; - bool isBefore = false; - location = getNearestLocation(newX, &found, &isBefore); - if (found == false) + int targetLocation = -1; + bool dataChangedVal = false; + // if getNearestLocation returned a value + if (location >= 0) { - int targetLocation = -1; - bool dataChangedVal = false; - // if getNearestLocation returned a value - if (location >= 0) + targetLocation = location; + // shift the new data if the closest data x is bigger + // (done for swaping) + if (isBefore == true) { - targetLocation = location; - // shift the new data if the closest data x is bigger - // (done for swaping) - if (isBefore == true) + // we are adding one value, so dataArray.size() will be a valid location + if (targetLocation < m_dataArray.size()) { - // we are adding one value, so dataArray.size() will be a valid location - if (targetLocation < m_dataArray.size()) - { - targetLocation++; - } + targetLocation++; } - m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); - swap(m_dataArray.size() - 1, targetLocation, true); - dataChangedVal = true; - } - else if (m_dataArray.size() <= 0) - { - m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); - targetLocation = 0; - dataChangedVal = true; } - location = targetLocation; + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); + swap(m_dataArray.size() - 1, targetLocation, true); + dataChangedVal = true; + } + else if (m_dataArray.size() <= 0) + { + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); + targetLocation = 0; + dataChangedVal = true; + } + location = targetLocation; - if (m_dataArray.size() <= 2) - { - formatDataArrayEndPoints(); - dataChangedVal = true; - } - if (dataChangedVal == true) - { - // addtition breaks the order of the locations - // in m_needsUpdating, so we update the whole m_dataArray - getUpdatingFromPoint(-1); - dataChanged(); - } + if (m_dataArray.size() <= 2) + { + formatDataArrayEndPoints(); + dataChangedVal = true; + } + if (dataChangedVal == true) + { + // addtition breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); } } return location; @@ -2229,28 +2223,27 @@ int VectorGraphDataArray::add(float newX) void VectorGraphDataArray::deletePoint(unsigned int pointLocation) { - if (m_isFixedSize == false && pointLocation < m_dataArray.size()) + if (m_isFixedSize == true || pointLocation >= m_dataArray.size()) { return; } + + // deleting the points automationModel + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); + // swaping the point to the last location + // in m_dataArray + swap(pointLocation, m_dataArray.size() - 1, true); + m_dataArray.pop_back(); + if (pointLocation == 0 || pointLocation == m_dataArray.size()) { - // deleting the points automationModel - deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); - // swaping the point to the last location - // in m_dataArray - swap(pointLocation, m_dataArray.size() - 1, true); - m_dataArray.pop_back(); - if (pointLocation == 0 || pointLocation == m_dataArray.size()) - { - formatDataArrayEndPoints(); - } - // calling clearedEvent - if (m_dataArray.size() == 0) - { - clearedEvent(); - } - // deletion breaks the order of the locations - // in m_needsUpdating, so we update the whole m_dataArray - getUpdatingFromPoint(-1); - dataChanged(); + formatDataArrayEndPoints(); + } + // calling clearedEvent + if (m_dataArray.size() == 0) + { + clearedEvent(); } + // deletion breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); } void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) @@ -2625,99 +2618,92 @@ unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) void VectorGraphDataArray::setY(unsigned int pointLocation, float newY) { - if (m_isFixedY == false) + if (m_isFixedY == true) { return; } + + m_dataArray[pointLocation].m_y = newY; + getUpdatingFromPoint(pointLocation); + // changes in the position can change lines before + // so the point before this is updated + if (pointLocation > 0) { - m_dataArray[pointLocation].m_y = newY; - getUpdatingFromPoint(pointLocation); - // changes in the position can change lines before - // so the point before this is updated - if (pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - if (m_isFixedEndPoints == true && - (pointLocation <= 0 || pointLocation >= m_dataArray.size() - 1)) - { - formatDataArrayEndPoints(); - getUpdatingFromPoint(0); - getUpdatingFromPoint(m_dataArray.size() - 1); - } - dataChanged(); + getUpdatingFromPoint(pointLocation - 1); + } + if (m_isFixedEndPoints == true && + (pointLocation <= 0 || pointLocation >= m_dataArray.size() - 1)) + { + formatDataArrayEndPoints(); + getUpdatingFromPoint(0); + getUpdatingFromPoint(m_dataArray.size() - 1); } + dataChanged(); } void VectorGraphDataArray::setC(unsigned int pointLocation, float newC) { - if (m_isEditableAttrib == true) - { - m_dataArray[pointLocation].m_c = newC; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_c = newC; + getUpdatingFromPoint(pointLocation); + dataChanged(); } void VectorGraphDataArray::setValA(unsigned int pointLocation, float fValue) { - if (m_isEditableAttrib == true) - { - m_dataArray[pointLocation].m_valA = fValue; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_valA = fValue; + getUpdatingFromPoint(pointLocation); + dataChanged(); } void VectorGraphDataArray::setValB(unsigned int pointLocation, float fValue) { - if (m_isEditableAttrib == true) - { - m_dataArray[pointLocation].m_valB = fValue; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_valB = fValue; + getUpdatingFromPoint(pointLocation); + dataChanged(); } void VectorGraphDataArray::setType(unsigned int pointLocation, unsigned int newType) { - if (m_isEditableAttrib == true) - { - // set the type without changing the automated attribute location - m_dataArray[pointLocation].m_type = newType; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } + if (m_isEditableAttrib == false) { return; } + + // set the type without changing the automated attribute location + m_dataArray[pointLocation].m_type = newType; + getUpdatingFromPoint(pointLocation); + dataChanged(); } void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation) { - if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) - { - // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocation = attribLocation > 3 ? 0 : attribLocation; - // set automated location correctly (effected_location = automatedEffectedLocation % 4) - m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation * 4 + getEffectedAttribLocation(pointLocation); + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - getUpdatingFromPoint(pointLocation); - // the line before this can get added later - // in getUpdatingFromAutomation - // so the point before this is not updated here + // clamp only 4 attributes can be automated (y, c, valA, valB) + attribLocation = attribLocation > 3 ? 0 : attribLocation; + // set automated location correctly (effected_location = automatedEffectedLocation % 4) + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation * 4 + getEffectedAttribLocation(pointLocation); - dataChanged(); - } + getUpdatingFromPoint(pointLocation); + // the line before this can get added later + // in getUpdatingFromAutomation + // so the point before this is not updated here + + dataChanged(); } void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation) { - if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) - { - // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocation = attribLocation > 3 ? 0 : attribLocation; - // set effected location correctly - m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation); + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectPoints(pointLocation) == false && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - dataChanged(); + // clamp only 4 attributes can be automated (y, c, valA, valB) + attribLocation = attribLocation > 3 ? 0 : attribLocation; + // set effected location correctly + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation); + + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectPoints(pointLocation) == false && pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); } + dataChanged(); } unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int pointLocation) { @@ -2740,48 +2726,46 @@ bool VectorGraphDataArray::getEffectLines(unsigned int pointLocation) } void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bValue) { - if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + if (m_dataArray[pointLocation].m_effectPoints != bValue) { - if (m_dataArray[pointLocation].m_effectPoints != bValue) + // getEffectPoints does not return m_effectePoints + bool dataChangedValue = getEffectPoints(pointLocation); + m_dataArray[pointLocation].m_effectPoints = bValue; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectPoints(pointLocation)) { - // getEffectPoints does not return m_effectePoints - bool dataChangedValue = getEffectPoints(pointLocation); - m_dataArray[pointLocation].m_effectPoints = bValue; - // this change does effect the main output if this - // data array is an effector of an other so dataChanged() - // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectPoints(pointLocation)) + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectedAttribLocation(pointLocation) <= 0 && pointLocation > 0) { - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectedAttribLocation(pointLocation) <= 0 && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } + getUpdatingFromPoint(pointLocation - 1); } - dataChanged(); } + dataChanged(); } } void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValue) { - if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + if (m_dataArray[pointLocation].m_effectLines != bValue) { - if (m_dataArray[pointLocation].m_effectLines != bValue) + // getEffectLines does not return m_effectLines + bool dataChangedValue = getEffectLines(pointLocation); + m_dataArray[pointLocation].m_effectLines = bValue; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectLines(pointLocation)) { - // getEffectLines does not return m_effectLines - bool dataChangedValue = getEffectLines(pointLocation); - m_dataArray[pointLocation].m_effectLines = bValue; - // this change does effect the main output if this - // data array is an effector of an other so dataChanged() - // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectLines(pointLocation)) - { - getUpdatingFromPoint(pointLocation); - } - dataChanged(); + getUpdatingFromPoint(pointLocation); } + dataChanged(); } } bool VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectId) @@ -2820,47 +2804,46 @@ bool VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int ef } void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue) { - if (m_isAutomatableEffectable == true && m_isEditableAttrib == true) + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + switch (effectId) { - switch (effectId) - { - case 0: - m_dataArray[pointLocation].m_effectAdd = bValue; - break; - case 1: - m_dataArray[pointLocation].m_effectSubtract = bValue; - break; - case 2: - m_dataArray[pointLocation].m_effectMultiply = bValue; - break; - case 3: - m_dataArray[pointLocation].m_effectDivide = bValue; - break; - case 4: - m_dataArray[pointLocation].m_effectPower = bValue; - break; - case 5: - m_dataArray[pointLocation].m_effectLog = bValue; - break; - case 6: - m_dataArray[pointLocation].m_effectSine = bValue; - break; - case 7: - m_dataArray[pointLocation].m_effectClampLower = bValue; - break; - case 8: - m_dataArray[pointLocation].m_effectClampUpper = bValue; - break; - } - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectPoints(pointLocation) == true && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - dataChanged(); + case 0: + m_dataArray[pointLocation].m_effectAdd = bValue; + break; + case 1: + m_dataArray[pointLocation].m_effectSubtract = bValue; + break; + case 2: + m_dataArray[pointLocation].m_effectMultiply = bValue; + break; + case 3: + m_dataArray[pointLocation].m_effectDivide = bValue; + break; + case 4: + m_dataArray[pointLocation].m_effectPower = bValue; + break; + case 5: + m_dataArray[pointLocation].m_effectLog = bValue; + break; + case 6: + m_dataArray[pointLocation].m_effectSine = bValue; + break; + case 7: + m_dataArray[pointLocation].m_effectClampLower = bValue; + break; + case 8: + m_dataArray[pointLocation].m_effectClampUpper = bValue; + break; + } + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectPoints(pointLocation) == true && pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); } + dataChanged(); } bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int pointLocation) { @@ -2877,31 +2860,30 @@ void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("setAutomated start"); #endif - if (m_isAutomatableEffectable == true) + if (m_isAutomatableEffectable == false) { return; } + + if (bValue == true) { - if (bValue == true) + // if it is not already automated + if (m_dataArray[pointLocation].m_automationModel == -1) { - // if it is not already automated - if (m_dataArray[pointLocation].m_automationModel == -1) - { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setAutomated: make new floatModel"); + qDebug("setAutomated: make new floatModel, location: %d", pointLocation); #endif - m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); - m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } + m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); + m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; + getUpdatingFromPoint(pointLocation); + dataChanged(); } - else - { + } + else + { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setAutomated: delete floatModel"); + qDebug("setAutomated: delete floatModel, location: %d, size: %d", pointLocation, static_cast(m_automationModelArray.size())); #endif - // dataChanged() is called in this function - // this function check if the current point has an automationModel - deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); - } + // dataChanged() is called in this function + // this function check if the current point has an automationModel + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); } } FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) @@ -2922,11 +2904,11 @@ void VectorGraphDataArray::deleteUnusedAutomation() { bool dataChangedVal = false; std::vector usedAutomation; - for (unsigned int i = 0; i < m_dataArray.size(); i++) + for (auto i : m_dataArray) { - if (m_dataArray[i].m_automationModel != -1) + if (i.m_automationModel != -1) { - usedAutomation.push_back(m_dataArray[i].m_automationModel); + usedAutomation.push_back(i.m_automationModel); } } for (unsigned int i = 0; i < m_automationModelArray.size(); i++) @@ -2990,104 +2972,102 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, b void VectorGraphDataArray::deleteAutomationModel(unsigned int modelLocation, bool callDataChanged) { - if (modelLocation > -1) - { - FloatModel* curModel = m_automationModelArray[modelLocation]; + if (modelLocation >= m_automationModelArray.size()) { return; } - // copy the last FloatModel* to the current location - m_automationModelArray[modelLocation] = - m_automationModelArray[m_automationModelArray.size() - 1]; + FloatModel* curModel = m_automationModelArray[modelLocation]; - m_automationModelArray.pop_back(); + // copy the last FloatModel* to the current location + m_automationModelArray[modelLocation] = + m_automationModelArray[m_automationModelArray.size() - 1]; - // replace all m_auttomationModel-s in the current copyed location with -1 - // replace all last m_automationModel-s to the currently copyed location - // there should be only 2 points changed but because of safety - // all of them are checked - for (unsigned int i = 0; i < m_dataArray.size(); i++) + m_automationModelArray.pop_back(); + + // replace all m_auttomationModel-s in the current copyed location with -1 + // replace all last m_automationModel-s to the currently copyed location + // there should be only 2 points changed but because of safety + // all of them are checked + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].m_automationModel == modelLocation) { - if (m_dataArray[i].m_automationModel == modelLocation) + m_dataArray[i].m_automationModel = -1; + getUpdatingFromPoint(i); + if (i > 0) { - m_dataArray[i].m_automationModel = -1; - getUpdatingFromPoint(i); - if (i > 0) - { - getUpdatingFromPoint(i - 1); - } - } - if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) - { - m_dataArray[i].m_automationModel = modelLocation; + getUpdatingFromPoint(i - 1); } } - if (curModel != nullptr) + if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) { - delete curModel; - curModel = nullptr; + m_dataArray[i].m_automationModel = modelLocation; } + } + if (curModel != nullptr) + { + delete curModel; + curModel = nullptr; + } - if (callDataChanged == true) - { - dataChanged(); - } + if (callDataChanged == true) + { + dataChanged(); } } void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween) { - if (pointLocationA != pointLocationB) + if (pointLocationA == pointLocationB) { return; } + + if (shouldShiftBetween == true) { - if (shouldShiftBetween == true) - { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("swap: -------"); - qDebug("first point location: %d, second point locaiton: %d", pointLocationA, pointLocationB); - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); - } + qDebug("swap: -------"); + qDebug("first point location: %d, second point locaiton: %d", pointLocationA, pointLocationB); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); + } #endif - - if (pointLocationA < pointLocationB) - { - VectorGraphPoint swap = m_dataArray[pointLocationA]; - for (unsigned int i = pointLocationA; i < pointLocationB; i++) - { - m_dataArray[i] = m_dataArray[i + 1]; - } - m_dataArray[pointLocationB] = swap; - } - else - { - VectorGraphPoint swap = m_dataArray[pointLocationA]; - for (unsigned int i = pointLocationA; i > pointLocationB; i--) - { - m_dataArray[i] = m_dataArray[i - 1]; - } - m_dataArray[pointLocationB] = swap; - } - -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug(" --------- "); - for (unsigned int i = 0; i < m_dataArray.size(); i++) + + if (pointLocationA < pointLocationB) + { + VectorGraphPoint swap = m_dataArray[pointLocationA]; + for (unsigned int i = pointLocationA; i < pointLocationB; i++) { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); + m_dataArray[i] = m_dataArray[i + 1]; } -#endif + m_dataArray[pointLocationB] = swap; } else { - // normal swap VectorGraphPoint swap = m_dataArray[pointLocationA]; - m_dataArray[pointLocationA] = m_dataArray[pointLocationB]; + for (unsigned int i = pointLocationA; i > pointLocationB; i--) + { + m_dataArray[i] = m_dataArray[i - 1]; + } m_dataArray[pointLocationB] = swap; } - getUpdatingFromPoint(pointLocationB - 1 > 0 ? pointLocationB - 1 : 0); - getUpdatingFromPoint(pointLocationA - 1 > 0 ? pointLocationA - 1 : 0); - getUpdatingFromPoint(pointLocationA); - getUpdatingFromPoint(pointLocationB); - dataChanged(); + +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug(" --------- "); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); + } +#endif + } + else + { + // normal swap + VectorGraphPoint swap = m_dataArray[pointLocationA]; + m_dataArray[pointLocationA] = m_dataArray[pointLocationB]; + m_dataArray[pointLocationB] = swap; } + getUpdatingFromPoint(pointLocationB - 1 > 0 ? pointLocationB - 1 : 0); + getUpdatingFromPoint(pointLocationA - 1 > 0 ? pointLocationA - 1 : 0); + getUpdatingFromPoint(pointLocationA); + getUpdatingFromPoint(pointLocationB); + dataChanged(); } float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float x) { @@ -3334,44 +3314,43 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample unsigned int randomValuesSize = static_cast(50.0f * (randomCount + 1.0f)) * 2; - if (randomValuesSize > 0) + if (randomValuesSize <= 0) { return; } + + // "allocate" "randomValuesSize" amount of floats + // for generating random values + // in the universal buffer + if (m_universalSampleBuffer.size() < randomValuesSize) { - // "allocate" "randomValuesSize" amount of floats - // for generating random values - // in the universal buffer - if (m_universalSampleBuffer.size() < randomValuesSize) - { - m_universalSampleBuffer.resize(randomValuesSize); - } + m_universalSampleBuffer.resize(randomValuesSize); + } - float blend = 10.0f + randomSeed * 10.0f; - int randomSeedB = static_cast(blend); - blend = blend - randomSeedB; + float blend = 10.0f + randomSeed * 10.0f; + int randomSeedB = static_cast(blend); + blend = blend - randomSeedB; - std::srand(randomSeedB); + std::srand(randomSeedB); - // getting the random values - // generating 2 seeds and blending in between them - for (unsigned int i = 0; i < randomValuesSize / 2; i++) - { - m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } - std::srand(randomSeedB + 1); - for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) - { - m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } + // getting the random values + // generating 2 seeds and blending in between them + for (unsigned int i = 0; i < randomValuesSize / 2; i++) + { + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + std::srand(randomSeedB + 1); + for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) + { + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } - // blending - // real size - float size = static_cast(randomValuesSize / 2); - for (unsigned int i = 0; i < count; i++) - { - float randomValueX = (*xArray)[startLoc + i] * size; - float randomValueLocation = std::floor(randomValueX); - (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (m_universalSampleBuffer[static_cast(randomValueLocation)] * (1.0f - blend) + m_universalSampleBuffer[static_cast(randomValueLocation + size)] * blend) * randomAmp; - } + // blending + // real size + float size = static_cast(randomValuesSize / 2); + for (unsigned int i = 0; i < count; i++) + { + float randomValueX = (*xArray)[startLoc + i] * size; + float randomValueLocation = std::floor(randomValueX); + (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + (m_universalSampleBuffer[static_cast(randomValueLocation)] * (1.0f - blend) + m_universalSampleBuffer[static_cast(randomValueLocation + size)] * blend) * randomAmp; } } From 7154ae0572d03aa4ff4e367cf8d27ac3ef13d816 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:25:01 +0200 Subject: [PATCH 130/184] VectorGraph_automatableModel_id_casting_bug_fixed --- src/gui/widgets/VectorGraph.cpp | 4 ++-- src/gui/widgets/VectorGraphViewBase.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index dee1d563dd3..5c8f0d28400 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -2970,9 +2970,9 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, b } } -void VectorGraphDataArray::deleteAutomationModel(unsigned int modelLocation, bool callDataChanged) +void VectorGraphDataArray::deleteAutomationModel(int modelLocation, bool callDataChanged) { - if (modelLocation >= m_automationModelArray.size()) { return; } + if (modelLocation < 0 || modelLocation >= m_automationModelArray.size()) { return; } FloatModel* curModel = m_automationModelArray[modelLocation]; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 760b9b0cb62..b644c7ec99f 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -102,7 +102,6 @@ void VectorGraphViewBase::addDefaultActions(QMenu* menu, QString controlDisplayT this, SLOT(contextMenuExecConnectionDialog())); if(m_curAutomationModel != nullptr && m_curAutomationModel->controllerConnection() != nullptr) { - Controller* cont = m_curAutomationModel->controllerConnection()->getController(); if(cont) { From 1c3b8d0fef81a43130de8975614292bbdf10f40d Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:18:53 +0200 Subject: [PATCH 131/184] VectorGraphViewBase_VectorGraphControlDialog_window_implementation_started --- include/VectorGraphViewBase.h | 27 +++- src/gui/widgets/VectorGraphViewBase.cpp | 169 ++++++++++++++++++++++++ 2 files changed, 195 insertions(+), 1 deletion(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index c5996f0fb65..f04bffb99f1 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "ModelView.h" #include "SimpleTextFloat.h" @@ -67,11 +68,35 @@ protected slots: private: // context menu - void addDefaultActions(QMenu* menu, QString controlDisplayText); + void addDefaultActions(QMenu* menu, QString controlDisplayText); SimpleTextFloat* m_hintText; FloatModel* m_curAutomationModel; }; + +class VectorGraphView; + +class LMMS_EXPORT VectorGraphCotnrolDialog : public QMdiSubWindow +{ + Q_OBJECT +public: + VectorGraphCotnrolDialog(QWidget* parent, VectorGraphView* targetVectorGraphView); + ~VectorGraphCotnrolDialog(); + + void hideControls(); + void switchPoint(unsigned int selectedArray, unsigned int selectedLocation); + +signals: + void controlValueChanged(); + +private: + VectorGraphView* m_vectorGraphView; + + FloatModel* m_curAutomationModel; + + std::vector m_controlModelArray; +}; + } // namespace gui } // namespace lmms diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index b644c7ec99f..59f0535ac4d 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -199,5 +199,174 @@ float VectorGraphViewBase::showInputDialog(float curInputValue) } +VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraphView* targetVectorGraphModel) : + QMdiSubWindow(_parent) +{ + /* + setWindowIcon(embed::getIconPixmap("setup_audio")); + setWindowTitle(tr("Connection Settings")); + //setModal(true); +*/ + + setWindowTitle(tr("vector graph settings")); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + qDebug("VectorGraphControllerDialog Running"); + + /* + // Midi stuff + m_midiGroupBox = new GroupBox( tr( "MIDI CONTROLLER" ), this ); + m_midiGroupBox->setGeometry( 8, 10, 240, 80 ); + connect( m_midiGroupBox->model(), SIGNAL(dataChanged()), + this, SLOT(midiToggled())); + + m_midiChannelSpinBox = new LcdSpinBox( 2, m_midiGroupBox, + tr( "Input channel" ) ); + m_midiChannelSpinBox->addTextForValue( 0, "--" ); + m_midiChannelSpinBox->setLabel( tr( "CHANNEL" ) ); + m_midiChannelSpinBox->move( 8, 24 ); + + m_midiControllerSpinBox = new LcdSpinBox( 3, m_midiGroupBox, + tr( "Input controller" ) ); + m_midiControllerSpinBox->addTextForValue(MidiController::NONE, "---" ); + m_midiControllerSpinBox->setLabel( tr( "CONTROLLER" ) ); + m_midiControllerSpinBox->move( 68, 24 ); + + + m_midiAutoDetectCheckBox = + new LedCheckBox( tr("Auto Detect"), + m_midiGroupBox, tr("Auto Detect") ); + m_midiAutoDetectCheckBox->setModel( &m_midiAutoDetect ); + m_midiAutoDetectCheckBox->move( 8, 60 ); + connect( &m_midiAutoDetect, SIGNAL(dataChanged()), + this, SLOT(autoDetectToggled())); + + // when using with non-raw-clients we can provide buttons showing + // our port-menus when being clicked + if( !Engine::audioEngine()->midiClient()->isRaw() ) + { + m_readablePorts = new MidiPortMenu( MidiPort::Mode::Input ); + connect( m_readablePorts, SIGNAL(triggered(QAction*)), + this, SLOT(enableAutoDetect(QAction*))); + auto rp_btn = new ToolButton(m_midiGroupBox); + rp_btn->setText( tr( "MIDI-devices to receive " + "MIDI-events from" ) ); + rp_btn->setIcon( embed::getIconPixmap( "piano" ) ); + rp_btn->setGeometry( 160, 24, 32, 32 ); + rp_btn->setMenu( m_readablePorts ); + rp_btn->setPopupMode( QToolButton::InstantPopup ); + } + + + // User stuff + m_userGroupBox = new GroupBox( tr( "USER CONTROLLER" ), this ); + m_userGroupBox->setGeometry( 8, 100, 240, 60 ); + connect( m_userGroupBox->model(), SIGNAL(dataChanged()), + this, SLOT(userToggled())); + + m_userController = new ComboBox( m_userGroupBox, "Controller" ); + m_userController->setGeometry( 10, 24, 200, ComboBox::DEFAULT_HEIGHT ); + for (Controller * c : Engine::getSong()->controllers()) + { + m_userController->model()->addItem( c->name() ); + } + connect( m_userController->model(), SIGNAL(dataUnchanged()), + this, SLOT(userSelected())); + connect( m_userController->model(), SIGNAL(dataChanged()), + this, SLOT(userSelected())); + + + // Mapping functions + m_mappingBox = new TabWidget( tr( "MAPPING FUNCTION" ), this ); + m_mappingBox->setGeometry( 8, 170, 240, 64 ); + m_mappingFunction = new QLineEdit( m_mappingBox ); + m_mappingFunction->setGeometry( 10, 20, 170, 16 ); + m_mappingFunction->setText( "input" ); + m_mappingFunction->setReadOnly( true ); + + + // Buttons + auto buttons = new QWidget(this); + buttons->setGeometry( 8, 240, 240, 32 ); + + auto btn_layout = new QHBoxLayout(buttons); + btn_layout->setSpacing( 0 ); + btn_layout->setContentsMargins(0, 0, 0, 0); + + auto select_btn = new QPushButton(embed::getIconPixmap("add"), tr("OK"), buttons); + connect( select_btn, SIGNAL(clicked()), + this, SLOT(selectController())); + + auto cancel_btn = new QPushButton(embed::getIconPixmap("cancel"), tr("Cancel"), buttons); + connect( cancel_btn, SIGNAL(clicked()), + this, SLOT(reject())); + + btn_layout->addStretch(); + btn_layout->addSpacing( 10 ); + btn_layout->addWidget( select_btn ); + btn_layout->addSpacing( 10 ); + btn_layout->addWidget( cancel_btn ); + btn_layout->addSpacing( 10 ); + + setFixedSize( 256, 280 ); + + // Crazy MIDI View stuff + + // TODO, handle by making this a model for the Dialog "view" + ControllerConnection * cc = nullptr; + if( m_targetModel ) + { + cc = m_targetModel->controllerConnection(); + + if( cc && cc->getController()->type() != Controller::ControllerType::Dummy && Engine::getSong() ) + { + if ( cc->getController()->type() == Controller::ControllerType::Midi ) + { + m_midiGroupBox->model()->setValue( true ); + // ensure controller is created + midiToggled(); + + auto cont = (MidiController*)(cc->getController()); + m_midiChannelSpinBox->model()->setValue( cont->m_midiPort.inputChannel() ); + m_midiControllerSpinBox->model()->setValue( cont->m_midiPort.inputController() ); + + m_midiController->subscribeReadablePorts( static_cast( cc->getController() )->m_midiPort.readablePorts() ); + } + else + { + auto& controllers = Engine::getSong()->controllers(); + auto it = std::find(controllers.begin(), controllers.end(), cc->getController()); + + if (it != controllers.end()) + { + int idx = std::distance(controllers.begin(), it); + m_userGroupBox->model()->setValue( true ); + m_userController->model()->setValue( idx ); + } + } + } + } + + if( !cc ) + { + m_midiGroupBox->model()->setValue( true ); + } +*/ + show(); +} +VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() +{ + +} +void VectorGraphCotnrolDialog::hideControls() +{ + +} +void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned int selectedLocation) +{ + +} + + } // namespace gui } // namespace lmms From 77ddb2663d3f40b0d6ba1ea949407806dde66f8c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:20:05 +0200 Subject: [PATCH 132/184] VectorGraph_VectorGraphControlDialog_basic_implementation --- include/VectorGraph.h | 5 +++-- src/gui/widgets/VectorGraph.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 35a3fc755bd..1e0ad5d1896 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -242,7 +242,8 @@ protected slots: std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; - + VectorGraphCotnrolDialog* m_controlDialog; + // default VectorGraphDataArray colors // applyed in constructor QColor m_vectorGraphDefaultAutomatedColor; @@ -617,7 +618,7 @@ class LMMS_EXPORT VectorGraphDataArray }; // deletes the point's automation model // if modelLocation == point location - void deleteAutomationModel(unsigned int modelLocation, bool callDataChanged); + void deleteAutomationModel(int modelLocation, bool callDataChanged); // swapping values, "shouldShiftBetween" moves the values (between) once left or right to keep the order // handle m_isFixedEndPoints when using this void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween); diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 5c8f0d28400..e07517f5502 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -109,9 +109,15 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe { applyDefaultColors(); } + + m_controlDialog = nullptr; } VectorGraphView::~VectorGraphView() { + if (m_controlDialog == nullptr) + { + delete m_controlDialog; + } } void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) @@ -997,6 +1003,17 @@ bool VectorGraphView::isControlWindowPressed(int mouseY) } void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving, int curX, int curY) { + if (m_controlDialog == nullptr) + { + m_controlDialog = new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this); + } + /*/ + if (dialogB.exec() == 1) + { + + } + */ + // mouseY is calculated like this: // m_graphHeight - y setCursor(Qt::ArrowCursor); From efd5f6e0f8da096627790b35eda8210978524a98 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 26 Jun 2024 18:45:49 +0200 Subject: [PATCH 133/184] VectorGraphViewBase_dialog_gui_implemented --- include/VectorGraphViewBase.h | 46 +++++- src/gui/widgets/VectorGraphViewBase.cpp | 207 +++++++++++++++++++++++- 2 files changed, 249 insertions(+), 4 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index f04bffb99f1..68db530dc84 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -29,10 +29,14 @@ #include #include #include +#include #include "ModelView.h" #include "SimpleTextFloat.h" #include "AutomatableModel.h" +#include "Knob.h" +#include "ComboBoxModel.h" +#include "ComboBox.h" namespace lmms { @@ -83,16 +87,56 @@ class LMMS_EXPORT VectorGraphCotnrolDialog : public QMdiSubWindow VectorGraphCotnrolDialog(QWidget* parent, VectorGraphView* targetVectorGraphView); ~VectorGraphCotnrolDialog(); - void hideControls(); + void hideAutomation(); void switchPoint(unsigned int selectedArray, unsigned int selectedLocation); signals: void controlValueChanged(); + void pointEffectedButton(); + void lineEffectedButton(); private: + void updateControls(); + VectorGraphView* m_vectorGraphView; FloatModel* m_curAutomationModel; + Knob* m_curAutomationModelKnob; + QVBoxLayout* m_automationLayout; + + ComboBoxModel m_lineTypeModel; + ComboBoxModel m_automatedAttribModel; + ComboBoxModel m_effectedAttribModel; + ComboBoxModel m_effectModelA; + ComboBoxModel m_effectModelB; + ComboBoxModel m_effectModelC; + + const std::array m_controlFloatText = + { + tr("x coordinate"), "x", tr("y coordinate"), "y", tr("curve"), tr("curve"), tr("1. attribute value"), tr("1. attribute"), + tr("2. attribute value"), tr("2. attribute") + }; + const std::array m_controlFloatTextB = + { + tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), + tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), + tr("switch graph effected value"), tr("can this point be effected"), tr("can this line be effected"), tr("\"add\" effect"), + tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), + tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") + }; + const std::array m_controlLineTypeText = { + tr("none"), + tr("sine"), + tr("phase changable sine"), + tr("peak"), + tr("steps"), + tr("random") + }; + const std::array m_controlLineEffectText = { + tr("none"), tr("\"add\" effect"), tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), + tr("\"power\" effect"), tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") + }; + std::vector m_controlModelArray; }; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 59f0535ac4d..edf271493c4 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -24,10 +24,14 @@ #include "VectorGraphViewBase.h" +#include "VectorGraph.h" #include #include // showInputDialog() #include // context menu +#include +#include +#include #include "StringPairDrag.h" @@ -39,6 +43,8 @@ #include "AutomatableModel.h" #include "ControllerConnectionDialog.h" #include "ControllerConnection.h" +#include "Knob.h" +#include "ComboBox.h" namespace lmms @@ -200,19 +206,172 @@ float VectorGraphViewBase::showInputDialog(float curInputValue) VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraphView* targetVectorGraphModel) : - QMdiSubWindow(_parent) + QMdiSubWindow(_parent), + m_vectorGraphView(targetVectorGraphModel), + m_curAutomationModel(nullptr), + m_curAutomationModelKnob(nullptr), + m_automationLayout(nullptr), + m_lineTypeModel(nullptr, "", false), + m_automatedAttribModel(nullptr, "", false), + m_effectedAttribModel(nullptr, "", false), + m_effectModelA(nullptr, "", false), + m_effectModelB(nullptr, "", false), + m_effectModelC(nullptr, "", false) { + + auto makeKnob = [this](const QString& label, const QString& hintText, const QString& unit, FloatModel* model) + { + Knob* newKnob = new Knob(KnobType::Bright26, this); + newKnob->setModel(model); + newKnob->setLabel(label); + newKnob->setHintText(hintText, unit); + newKnob->setVolumeKnob(false); + return newKnob; + }; + /* setWindowIcon(embed::getIconPixmap("setup_audio")); setWindowTitle(tr("Connection Settings")); //setModal(true); */ - setWindowTitle(tr("vector graph settings")); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); qDebug("VectorGraphControllerDialog Running"); + setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + resize(300, 500); + + if (layout() != nullptr) + { + delete layout(); + //m_subWindow->layout()->setSizeConstraint(QLayout::SetFixedSize); + } + + QHBoxLayout* mainLayout = new QHBoxLayout(this); + mainLayout->setContentsMargins(5, 5, 5, 5); + setLayout(mainLayout); + + QVBoxLayout* knobLayout = new QVBoxLayout(nullptr); + mainLayout->addLayout(knobLayout); + + for (size_t i = 0; i < m_controlFloatText.size(); i += 2) + { + FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, nullptr, QString(), false); + m_controlModelArray.push_back(curModel); + Knob* newKnob = makeKnob(m_controlFloatText[i + 1], m_controlFloatText[i], "%", curModel); + knobLayout->addWidget(newKnob); + knobLayout->setAlignment(newKnob, Qt::AlignHCenter); + } + + QVBoxLayout* settingLayout = new QVBoxLayout(nullptr); + mainLayout->addLayout(settingLayout); + + for (size_t i = 0; i < m_controlLineTypeText.size(); i++) + { + m_lineTypeModel.addItem(m_controlLineTypeText[i], nullptr); + } + m_automatedAttribModel.addItem(m_controlFloatText[2], nullptr); + m_automatedAttribModel.addItem(m_controlFloatText[4], nullptr); + m_automatedAttribModel.addItem(m_controlFloatText[6], nullptr); + m_automatedAttribModel.addItem(m_controlFloatText[8], nullptr); + m_effectedAttribModel.addItem(m_controlFloatText[2], nullptr); + m_effectedAttribModel.addItem(m_controlFloatText[4], nullptr); + m_effectedAttribModel.addItem(m_controlFloatText[6], nullptr); + m_effectedAttribModel.addItem(m_controlFloatText[8], nullptr); + for (size_t i = 0; i < m_controlLineEffectText.size(); i++) + { + m_effectModelA.addItem(m_controlLineEffectText[i], nullptr); + m_effectModelB.addItem(m_controlLineEffectText[i], nullptr); + m_effectModelC.addItem(m_controlLineEffectText[i], nullptr); + } + + + + QLabel* lineTypeLabel = new QLabel(tr("line type:")); + lineTypeLabel->setFixedSize(100, 20); + settingLayout->addWidget(lineTypeLabel); + settingLayout->setAlignment(lineTypeLabel, Qt::AlignHCenter); + ComboBox* lineTypeComboBox = new ComboBox(this); + lineTypeComboBox->setModel(&m_lineTypeModel); + lineTypeComboBox->setFixedSize(100, 20); + lineTypeComboBox->show(); + settingLayout->addWidget(lineTypeComboBox); + settingLayout->setAlignment(lineTypeComboBox, Qt::AlignHCenter); + + QLabel* automatedAttribLabel = new QLabel(tr("automated attribute:")); + automatedAttribLabel->setFixedSize(130, 20); + settingLayout->addWidget(automatedAttribLabel); + settingLayout->setAlignment(automatedAttribLabel, Qt::AlignHCenter); + ComboBox* automatedAttribComboBox = new ComboBox(this); + automatedAttribComboBox->setModel(&m_automatedAttribModel); + automatedAttribComboBox->setFixedSize(100, 20); + automatedAttribComboBox->show(); + settingLayout->addWidget(automatedAttribComboBox); + settingLayout->setAlignment(automatedAttribComboBox, Qt::AlignHCenter); + + QLabel* effectedAttribLabel = new QLabel(tr("effected attribute:")); + effectedAttribLabel->setFixedSize(130, 20); + settingLayout->addWidget(effectedAttribLabel); + settingLayout->setAlignment(effectedAttribLabel, Qt::AlignHCenter); + ComboBox* effectedAttribComboBox = new ComboBox(this); + effectedAttribComboBox->setModel(&m_effectedAttribModel); + effectedAttribComboBox->setFixedSize(100, 20); + effectedAttribComboBox->show(); + settingLayout->addWidget(effectedAttribComboBox); + settingLayout->setAlignment(effectedAttribComboBox, Qt::AlignHCenter); + + QLabel* effectedLabelA = new QLabel(tr("1. effect:")); + effectedLabelA->setFixedSize(100, 20); + settingLayout->addWidget(effectedLabelA); + settingLayout->setAlignment(effectedLabelA, Qt::AlignHCenter); + ComboBox* effectedComboBoxA = new ComboBox(this); + effectedComboBoxA->setModel(&m_effectModelA); + effectedComboBoxA->setFixedSize(100, 20); + effectedComboBoxA->show(); + settingLayout->addWidget(effectedComboBoxA); + settingLayout->setAlignment(effectedComboBoxA, Qt::AlignHCenter); + + QLabel* effectedLabelB = new QLabel(tr("2. effect:")); + effectedLabelB->setFixedSize(100, 20); + settingLayout->addWidget(effectedLabelB); + settingLayout->setAlignment(effectedLabelB, Qt::AlignHCenter); + ComboBox* effectedComboBoxB = new ComboBox(this); + effectedComboBoxB->setModel(&m_effectModelB); + effectedComboBoxB->setFixedSize(100, 20); + effectedComboBoxB->show(); + settingLayout->addWidget(effectedComboBoxB); + settingLayout->setAlignment(effectedComboBoxB, Qt::AlignHCenter); + + QLabel* effectedLabelC = new QLabel(tr("3. effect:")); + effectedLabelC->setFixedSize(100, 20); + settingLayout->addWidget(effectedLabelC); + settingLayout->setAlignment(effectedLabelC, Qt::AlignHCenter); + ComboBox* effectedComboBoxC = new ComboBox(this); + effectedComboBoxC->setModel(&m_effectModelC); + effectedComboBoxC->setFixedSize(100, 20); + effectedComboBoxC->show(); + settingLayout->addWidget(effectedComboBoxC); + settingLayout->setAlignment(effectedComboBoxC, Qt::AlignHCenter); + + + m_automationLayout = new QVBoxLayout(nullptr); + mainLayout->addLayout(m_automationLayout); + + QPushButton* effectPointButton = new QPushButton(tr("effect point"), this); + m_automationLayout->addWidget(effectPointButton); + m_automationLayout->setAlignment(effectPointButton, Qt::AlignHCenter); + + QPushButton* effectLineButton = new QPushButton(tr("effect line"), this); + m_automationLayout->addWidget(effectLineButton); + m_automationLayout->setAlignment(effectLineButton, Qt::AlignHCenter); + + QLabel* automationModelLabel = new QLabel(tr("only this\nkonb can be\nautomated:")); + automationModelLabel->setFixedSize(100, 60); + m_automationLayout->addWidget(automationModelLabel); + m_automationLayout->setAlignment(automationModelLabel, Qt::AlignHCenter); + + /* // Midi stuff m_midiGroupBox = new GroupBox( tr( "MIDI CONTROLLER" ), this ); @@ -356,15 +515,57 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph } VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() { + for (auto i : m_controlModelArray) + { + if (i != nullptr) + { + delete i; + } + } } -void VectorGraphCotnrolDialog::hideControls() +void VectorGraphCotnrolDialog::hideAutomation() { + if (m_curAutomationModelKnob != nullptr) + { + m_automationLayout->removeWidget(m_curAutomationModelKnob); + delete m_curAutomationModelKnob; + m_curAutomationModelKnob = nullptr; + } } void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned int selectedLocation) { + qDebug("switch point 0: %d, %d", selectedArray, selectedLocation); + m_vectorGraphView->model()->getDataArray(selectedArray)->setAutomated(selectedLocation, true); + qDebug("switch point 0.5"); + m_curAutomationModel = m_vectorGraphView->model()->getDataArray(selectedArray)->getAutomationModel(selectedLocation); + qDebug("switch point 1"); + + if (m_curAutomationModel == nullptr) { hideAutomation(); return; } + qDebug("switch point 2"); + if (m_curAutomationModelKnob != nullptr) + { + if (m_curAutomationModel != m_curAutomationModelKnob->model()) + { + qDebug("switch point 3"); + m_curAutomationModelKnob->setModel(m_curAutomationModel); + } + } + else + { + qDebug("switch point 4"); + m_curAutomationModelKnob = new Knob(KnobType::Bright26, this); + m_curAutomationModelKnob->setModel(m_curAutomationModel); + m_curAutomationModelKnob->setLabel(tr("automation knob")); + m_curAutomationModelKnob->setHintText(tr("automate this to automate a value of the vector graph"), "%"); + m_curAutomationModelKnob->setVolumeKnob(false); + + m_automationLayout->addWidget(m_curAutomationModelKnob); + m_automationLayout->setAlignment(m_curAutomationModelKnob, Qt::AlignHCenter); + //m_curAutomationModelKnob->show(); + } } From 2052f91d9418b23d07684029695bf4a103ede37c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:34:16 +0200 Subject: [PATCH 134/184] VectorGraphViewBase_dialog_FloatModel-graph_connection_implemented --- include/VectorGraphViewBase.h | 21 +- src/gui/widgets/VectorGraphViewBase.cpp | 253 ++++++++++-------------- 2 files changed, 114 insertions(+), 160 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 68db530dc84..33c5675d3d5 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -90,19 +90,26 @@ class LMMS_EXPORT VectorGraphCotnrolDialog : public QMdiSubWindow void hideAutomation(); void switchPoint(unsigned int selectedArray, unsigned int selectedLocation); -signals: +public slots: void controlValueChanged(); - void pointEffectedButton(); - void lineEffectedButton(); + void effectedPointClicked(bool isChecked); + void effectedLineClicked(bool isChecked); private: void updateControls(); + void updateVectorGraphAttribs(); VectorGraphView* m_vectorGraphView; FloatModel* m_curAutomationModel; Knob* m_curAutomationModelKnob; QVBoxLayout* m_automationLayout; + // VectorGraphView should run hideAutomation() + // to notify that these are invalid + // selected VectorGraphDataArray + unsigned int m_curSelectedArray; + // selected VectorGraphPoint + unsigned int m_curSelectedLocation; ComboBoxModel m_lineTypeModel; ComboBoxModel m_automatedAttribModel; @@ -116,14 +123,6 @@ class LMMS_EXPORT VectorGraphCotnrolDialog : public QMdiSubWindow tr("x coordinate"), "x", tr("y coordinate"), "y", tr("curve"), tr("curve"), tr("1. attribute value"), tr("1. attribute"), tr("2. attribute value"), tr("2. attribute") }; - const std::array m_controlFloatTextB = - { - tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), - tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), - tr("switch graph effected value"), tr("can this point be effected"), tr("can this line be effected"), tr("\"add\" effect"), - tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), - tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") - }; const std::array m_controlLineTypeText = { tr("none"), tr("sine"), diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index edf271493c4..01281077526 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -257,11 +257,18 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph for (size_t i = 0; i < m_controlFloatText.size(); i += 2) { - FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, nullptr, QString(), false); + FloatModel* curModel = new FloatModel(0.0f, (i == 0 ? 0.0f : -1.0f), 1.0f, 0.01f, nullptr, QString(), false); m_controlModelArray.push_back(curModel); Knob* newKnob = makeKnob(m_controlFloatText[i + 1], m_controlFloatText[i], "%", curModel); knobLayout->addWidget(newKnob); knobLayout->setAlignment(newKnob, Qt::AlignHCenter); + + connect(curModel, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + /* + connect(curModel, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + */ } QVBoxLayout* settingLayout = new QVBoxLayout(nullptr); @@ -371,148 +378,53 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph m_automationLayout->addWidget(automationModelLabel); m_automationLayout->setAlignment(automationModelLabel, Qt::AlignHCenter); + show(); - /* - // Midi stuff - m_midiGroupBox = new GroupBox( tr( "MIDI CONTROLLER" ), this ); - m_midiGroupBox->setGeometry( 8, 10, 240, 80 ); - connect( m_midiGroupBox->model(), SIGNAL(dataChanged()), - this, SLOT(midiToggled())); - - m_midiChannelSpinBox = new LcdSpinBox( 2, m_midiGroupBox, - tr( "Input channel" ) ); - m_midiChannelSpinBox->addTextForValue( 0, "--" ); - m_midiChannelSpinBox->setLabel( tr( "CHANNEL" ) ); - m_midiChannelSpinBox->move( 8, 24 ); - - m_midiControllerSpinBox = new LcdSpinBox( 3, m_midiGroupBox, - tr( "Input controller" ) ); - m_midiControllerSpinBox->addTextForValue(MidiController::NONE, "---" ); - m_midiControllerSpinBox->setLabel( tr( "CONTROLLER" ) ); - m_midiControllerSpinBox->move( 68, 24 ); - - - m_midiAutoDetectCheckBox = - new LedCheckBox( tr("Auto Detect"), - m_midiGroupBox, tr("Auto Detect") ); - m_midiAutoDetectCheckBox->setModel( &m_midiAutoDetect ); - m_midiAutoDetectCheckBox->move( 8, 60 ); - connect( &m_midiAutoDetect, SIGNAL(dataChanged()), - this, SLOT(autoDetectToggled())); - - // when using with non-raw-clients we can provide buttons showing - // our port-menus when being clicked - if( !Engine::audioEngine()->midiClient()->isRaw() ) - { - m_readablePorts = new MidiPortMenu( MidiPort::Mode::Input ); - connect( m_readablePorts, SIGNAL(triggered(QAction*)), - this, SLOT(enableAutoDetect(QAction*))); - auto rp_btn = new ToolButton(m_midiGroupBox); - rp_btn->setText( tr( "MIDI-devices to receive " - "MIDI-events from" ) ); - rp_btn->setIcon( embed::getIconPixmap( "piano" ) ); - rp_btn->setGeometry( 160, 24, 32, 32 ); - rp_btn->setMenu( m_readablePorts ); - rp_btn->setPopupMode( QToolButton::InstantPopup ); - } - - - // User stuff - m_userGroupBox = new GroupBox( tr( "USER CONTROLLER" ), this ); - m_userGroupBox->setGeometry( 8, 100, 240, 60 ); - connect( m_userGroupBox->model(), SIGNAL(dataChanged()), - this, SLOT(userToggled())); - - m_userController = new ComboBox( m_userGroupBox, "Controller" ); - m_userController->setGeometry( 10, 24, 200, ComboBox::DEFAULT_HEIGHT ); - for (Controller * c : Engine::getSong()->controllers()) - { - m_userController->model()->addItem( c->name() ); - } - connect( m_userController->model(), SIGNAL(dataUnchanged()), - this, SLOT(userSelected())); - connect( m_userController->model(), SIGNAL(dataChanged()), - this, SLOT(userSelected())); - - - // Mapping functions - m_mappingBox = new TabWidget( tr( "MAPPING FUNCTION" ), this ); - m_mappingBox->setGeometry( 8, 170, 240, 64 ); - m_mappingFunction = new QLineEdit( m_mappingBox ); - m_mappingFunction->setGeometry( 10, 20, 170, 16 ); - m_mappingFunction->setText( "input" ); - m_mappingFunction->setReadOnly( true ); - - - // Buttons - auto buttons = new QWidget(this); - buttons->setGeometry( 8, 240, 240, 32 ); - - auto btn_layout = new QHBoxLayout(buttons); - btn_layout->setSpacing( 0 ); - btn_layout->setContentsMargins(0, 0, 0, 0); - - auto select_btn = new QPushButton(embed::getIconPixmap("add"), tr("OK"), buttons); - connect( select_btn, SIGNAL(clicked()), - this, SLOT(selectController())); - - auto cancel_btn = new QPushButton(embed::getIconPixmap("cancel"), tr("Cancel"), buttons); - connect( cancel_btn, SIGNAL(clicked()), - this, SLOT(reject())); - - btn_layout->addStretch(); - btn_layout->addSpacing( 10 ); - btn_layout->addWidget( select_btn ); - btn_layout->addSpacing( 10 ); - btn_layout->addWidget( cancel_btn ); - btn_layout->addSpacing( 10 ); - - setFixedSize( 256, 280 ); - - // Crazy MIDI View stuff - - // TODO, handle by making this a model for the Dialog "view" - ControllerConnection * cc = nullptr; - if( m_targetModel ) - { - cc = m_targetModel->controllerConnection(); - - if( cc && cc->getController()->type() != Controller::ControllerType::Dummy && Engine::getSong() ) - { - if ( cc->getController()->type() == Controller::ControllerType::Midi ) - { - m_midiGroupBox->model()->setValue( true ); - // ensure controller is created - midiToggled(); - - auto cont = (MidiController*)(cc->getController()); - m_midiChannelSpinBox->model()->setValue( cont->m_midiPort.inputChannel() ); - m_midiControllerSpinBox->model()->setValue( cont->m_midiPort.inputController() ); - - m_midiController->subscribeReadablePorts( static_cast( cc->getController() )->m_midiPort.readablePorts() ); - } - else - { - auto& controllers = Engine::getSong()->controllers(); - auto it = std::find(controllers.begin(), controllers.end(), cc->getController()); - - if (it != controllers.end()) - { - int idx = std::distance(controllers.begin(), it); - m_userGroupBox->model()->setValue( true ); - m_userController->model()->setValue( idx ); - } - } - } - } + connect(&m_lineTypeModel, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + connect(&m_automatedAttribModel, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + connect(&m_effectedAttribModel, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + connect(&m_effectModelA, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + connect(&m_effectModelB, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); + connect(&m_effectModelC, &AutomatableModel::setValueEvent, + this, &VectorGraphCotnrolDialog::controlValueChanged); - if( !cc ) - { - m_midiGroupBox->model()->setValue( true ); - } -*/ - show(); + /* + connect(m_lineTypeModel, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + connect(m_automatedAttribModel, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + connect(m_effectedAttribModel, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + connect(m_effectModelA, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + connect(m_effectModelB, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + connect(m_effectModelC, SIGNAL(setValueEvent()), + this, SLOT(controlValueChanged())); + */ + + /* + connect(effectPointButton, SIGNAL(clicked()), + this, &VectorGraphCotnrolDialog::controlValueChanged); + */ + QObject::connect(effectPointButton, SIGNAL(clicked(bool)), + //this, &VectorGraphCotnrolDialog::effectedPointClicked); + this, SLOT(effectedPointClicked(bool))); + QObject::connect(effectLineButton, SIGNAL(clicked(bool)), + this, SLOT(effectedLineClicked(bool))); + /* + QObject::connect(effectPointButton, SIGNAL(clicked()), + this, SLOT(pointEffectedButton)); + QObject::connect(effectLineButton, SIGNAL(clicked()), + this, SLOT(lineEffectedButton)); //&VectorGraphCotnrolDialog::lineEffectedButton); + */ } + VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() { for (auto i : m_controlModelArray) @@ -522,13 +434,13 @@ VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() delete i; } } - } + void VectorGraphCotnrolDialog::hideAutomation() { - if (m_curAutomationModelKnob != nullptr) { + // taking control of m_curAutomationModelKnob m_automationLayout->removeWidget(m_curAutomationModelKnob); delete m_curAutomationModelKnob; m_curAutomationModelKnob = nullptr; @@ -536,26 +448,22 @@ void VectorGraphCotnrolDialog::hideAutomation() } void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned int selectedLocation) { - qDebug("switch point 0: %d, %d", selectedArray, selectedLocation); + m_curSelectedArray = selectedArray; + m_curSelectedLocation = selectedLocation; m_vectorGraphView->model()->getDataArray(selectedArray)->setAutomated(selectedLocation, true); - qDebug("switch point 0.5"); m_curAutomationModel = m_vectorGraphView->model()->getDataArray(selectedArray)->getAutomationModel(selectedLocation); - qDebug("switch point 1"); if (m_curAutomationModel == nullptr) { hideAutomation(); return; } - qDebug("switch point 2"); if (m_curAutomationModelKnob != nullptr) { if (m_curAutomationModel != m_curAutomationModelKnob->model()) { - qDebug("switch point 3"); m_curAutomationModelKnob->setModel(m_curAutomationModel); } } else { - qDebug("switch point 4"); m_curAutomationModelKnob = new Knob(KnobType::Bright26, this); m_curAutomationModelKnob->setModel(m_curAutomationModel); m_curAutomationModelKnob->setLabel(tr("automation knob")); @@ -564,8 +472,55 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned m_automationLayout->addWidget(m_curAutomationModelKnob); m_automationLayout->setAlignment(m_curAutomationModelKnob, Qt::AlignHCenter); - //m_curAutomationModelKnob->show(); } + updateControls(); +} + +void VectorGraphCotnrolDialog::controlValueChanged() +{ + qDebug("val changed B"); + updateVectorGraphAttribs(); +} + +void VectorGraphCotnrolDialog::effectedPointClicked(bool isChecked) +{ + qDebug("clikced A"); +} + +void VectorGraphCotnrolDialog::effectedLineClicked(bool isChecked) +{ + qDebug("clikced B"); +} + +void VectorGraphCotnrolDialog::updateControls() +{ + if (m_curAutomationModel == nullptr) { return; } + + bool unusedBool = false; + for (size_t i = 0; i < m_controlModelArray.size(); i++) + { + m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i, &unusedBool)); + } + + m_lineTypeModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(5, &unusedBool)); + m_automatedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(6, &unusedBool)); + m_effectedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(7, &unusedBool)); + //m_effectModelA; + //m_effectModelB; + //m_effectModelC; +} + +void VectorGraphCotnrolDialog::updateVectorGraphAttribs() +{ + if (m_curAutomationModel == nullptr) { return; } + + qDebug("set input attrib value"); + for (size_t i = 0; i < m_controlModelArray.size(); i++) + { + m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value(), false); + //m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i, &unusedBool)); + } + } From 3f897f3550ff4cc15114aa3a9d17307de577f4bd Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:35:17 +0200 Subject: [PATCH 135/184] AutomatableModel_new_setValue_signal_added --- include/AutomatableModel.h | 4 +++- src/core/AutomatableModel.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 15285e17ab3..f1c3a5872ee 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -322,7 +322,9 @@ public slots: void unlinkControllerConnection(); void setUseControllerValue(bool b = true); - +signals: + // runs when setValue was successful + void setValueEvent(); protected: AutomatableModel( const float val = 0, diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index e006be651a4..da554e0af1a 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -316,6 +316,7 @@ void AutomatableModel::setValue( const float value ) } m_valueChanged = true; emit dataChanged(); + emit setValueEvent(); } else { @@ -816,4 +817,4 @@ QString BoolModel::displayValue( const float val ) const } -} // namespace lmms \ No newline at end of file +} // namespace lmms From 5736bb6c2676dc3ae8eb00c75c9aa5aacb6e993c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:36:43 +0200 Subject: [PATCH 136/184] WaveShaperControlDialog_qDebug_removed --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 2f2376e96a9..ba262ef531a 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -102,10 +102,8 @@ WaveShaperControlDialog::WaveShaperControlDialog( void WaveShaperControlDialog::simplifyClicked() { - qDebug("simplifyClicked run"); if (m_vectorGraphWidget != nullptr) { - qDebug("simplifyClicked turn on"); m_vectorGraphWidget->setIsSimplified(!m_vectorGraphWidget->getIsSimplified()); m_vectorGraphWidget->model()->updateGraphModel(true); } From 85119dc4813dc62b89323ffa915863d726382f57 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:43:33 +0200 Subject: [PATCH 137/184] VectorGraphViewBase_finished_dialog_implementation --- include/VectorGraphViewBase.h | 10 +- src/gui/widgets/VectorGraphViewBase.cpp | 187 +++++------------------- 2 files changed, 41 insertions(+), 156 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 33c5675d3d5..945a9d4cb7e 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -53,9 +53,6 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget VectorGraphViewBase(QWidget* parent); ~VectorGraphViewBase(); -protected slots: - virtual void contextMenuRemoveAutomation() = 0; - virtual void contextMenuExecConnectionDialog(); protected: // hints, SimpleTextFloat void showHintText(QWidget* thisWidget, QString hintText, int msecBeforeDesplay, int msecDisplayTime); @@ -64,18 +61,16 @@ protected slots: void connectToAutomationTrack(QMouseEvent* me, FloatModel* automationModel, QWidget* thisWidget); // context menu - void showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName); + //void showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName); // inputDialog std::pair showCoordInputDialog(std::pair pointPosition); - float showInputDialog(float curInputValue); private: // context menu - void addDefaultActions(QMenu* menu, QString controlDisplayText); + //void addDefaultActions(QMenu* menu, QString controlDisplayText); SimpleTextFloat* m_hintText; - FloatModel* m_curAutomationModel; }; class VectorGraphView; @@ -94,6 +89,7 @@ public slots: void controlValueChanged(); void effectedPointClicked(bool isChecked); void effectedLineClicked(bool isChecked); + void deleteAutomationClicked(bool isChecked); private: void updateControls(); diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 01281077526..cf35f53c892 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -28,16 +28,13 @@ #include #include // showInputDialog() -#include // context menu #include #include #include #include "StringPairDrag.h" -#include "CaptionMenu.h" // context menu #include "embed.h" // context menu -#include "MainWindow.h" // getting main window for context menu #include "GuiApplication.h" // getGUI #include "SimpleTextFloat.h" #include "AutomatableModel.h" @@ -77,93 +74,11 @@ void VectorGraphViewBase::connectToAutomationTrack(QMouseEvent* me, FloatModel* { if (automationModel != nullptr) { - qDebug("mousePress automation sent"); new gui::StringPairDrag("automatable_model", QString::number(automationModel->id()), QPixmap(), thisWidget); me->accept(); } } -void VectorGraphViewBase::showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName) -{ - m_curAutomationModel = automationModel; - CaptionMenu contextMenu(displayName + QString(" - ") + controlName); - addDefaultActions(&contextMenu, controlName); - contextMenu.exec(point); -} -void VectorGraphViewBase::addDefaultActions(QMenu* menu, QString controlDisplayText) -{ - // context menu settings - menu->addAction(embed::getIconPixmap("reload"), - tr("name: ") + controlDisplayText, - this, SLOT(contextMenuRemoveAutomation())); - menu->addAction(embed::getIconPixmap("reload"), - tr("remove automation"), - this, SLOT(contextMenuRemoveAutomation())); - menu->addSeparator(); - - QString controllerTxt; - - menu->addAction(embed::getIconPixmap("controller"), - tr("Connect to controller..."), - this, SLOT(contextMenuExecConnectionDialog())); - if(m_curAutomationModel != nullptr && m_curAutomationModel->controllerConnection() != nullptr) - { - Controller* cont = m_curAutomationModel->controllerConnection()->getController(); - if(cont) - { - controllerTxt = AutomatableModel::tr( "Connected to %1" ).arg( cont->name() ); - } - else - { - controllerTxt = AutomatableModel::tr( "Connected to controller" ); - } - - - QMenu* contMenu = menu->addMenu(embed::getIconPixmap("controller"), controllerTxt); - - contMenu->addAction(embed::getIconPixmap("cancel"), - tr("Remove connection"), - this, SLOT(contextMenuRemoveAutomation())); - } -} - -void VectorGraphViewBase::contextMenuExecConnectionDialog() -{ - if (m_curAutomationModel != nullptr) - { - gui::ControllerConnectionDialog dialog(getGUI()->mainWindow(), m_curAutomationModel); - - if (dialog.exec() == 1) - { - // Actually chose something - if (dialog.chosenController() != nullptr) - { - // Update - if (m_curAutomationModel->controllerConnection() != nullptr) - { - m_curAutomationModel->controllerConnection()->setController(dialog.chosenController()); - } - else - { - // New - auto cc = new ControllerConnection(dialog.chosenController()); - m_curAutomationModel->setControllerConnection(cc); - } - } - else - { - // no controller, so delete existing connection - contextMenuRemoveAutomation(); - } - } - else - { - // did not return 1 -> delete the created floatModel - contextMenuRemoveAutomation(); - } - } -} - std::pair VectorGraphViewBase::showCoordInputDialog(std::pair pointPosition) { // show position input dialog @@ -187,23 +102,6 @@ std::pair VectorGraphViewBase::showCoordInputDialog(std::pair(curInputValue * 100.0f), - -100.0, 100.0, 2, &ok); - if (ok == true) - { - output = static_cast(changedPos) / 100.0f; - } - - return output; -} - VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraphView* targetVectorGraphModel) : QMdiSubWindow(_parent), @@ -235,12 +133,13 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph //setModal(true); */ setWindowTitle(tr("vector graph settings")); - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - - qDebug("VectorGraphControllerDialog Running"); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - resize(300, 500); + setFixedSize(300, 500); + + Qt::WindowFlags flags = windowFlags(); + flags &= ~Qt::WindowMaximizeButtonHint; + setWindowFlags(flags); if (layout() != nullptr) { @@ -265,10 +164,6 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph connect(curModel, &AutomatableModel::setValueEvent, this, &VectorGraphCotnrolDialog::controlValueChanged); - /* - connect(curModel, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - */ } QVBoxLayout* settingLayout = new QVBoxLayout(nullptr); @@ -373,6 +268,10 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph m_automationLayout->addWidget(effectLineButton); m_automationLayout->setAlignment(effectLineButton, Qt::AlignHCenter); + QPushButton* deleteAutomationButton = new QPushButton(tr("delete\nautomation"), this); + m_automationLayout->addWidget(deleteAutomationButton); + m_automationLayout->setAlignment(deleteAutomationButton, Qt::AlignHCenter); + QLabel* automationModelLabel = new QLabel(tr("only this\nkonb can be\nautomated:")); automationModelLabel->setFixedSize(100, 60); m_automationLayout->addWidget(automationModelLabel); @@ -393,40 +292,17 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* _parent, VectorGraph connect(&m_effectModelC, &AutomatableModel::setValueEvent, this, &VectorGraphCotnrolDialog::controlValueChanged); - /* - connect(m_lineTypeModel, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - connect(m_automatedAttribModel, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - connect(m_effectedAttribModel, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - connect(m_effectModelA, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - connect(m_effectModelB, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - connect(m_effectModelC, SIGNAL(setValueEvent()), - this, SLOT(controlValueChanged())); - */ - - /* - connect(effectPointButton, SIGNAL(clicked()), - this, &VectorGraphCotnrolDialog::controlValueChanged); - */ QObject::connect(effectPointButton, SIGNAL(clicked(bool)), - //this, &VectorGraphCotnrolDialog::effectedPointClicked); this, SLOT(effectedPointClicked(bool))); QObject::connect(effectLineButton, SIGNAL(clicked(bool)), this, SLOT(effectedLineClicked(bool))); - /* - QObject::connect(effectPointButton, SIGNAL(clicked()), - this, SLOT(pointEffectedButton)); - QObject::connect(effectLineButton, SIGNAL(clicked()), - this, SLOT(lineEffectedButton)); //&VectorGraphCotnrolDialog::lineEffectedButton); - */ + QObject::connect(deleteAutomationButton, SIGNAL(clicked(bool)), + this, SLOT(deleteAutomationClicked(bool))); } VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() { + hideAutomation(); for (auto i : m_controlModelArray) { if (i != nullptr) @@ -438,6 +314,7 @@ VectorGraphCotnrolDialog::~VectorGraphCotnrolDialog() void VectorGraphCotnrolDialog::hideAutomation() { + m_curAutomationModel = nullptr; if (m_curAutomationModelKnob != nullptr) { // taking control of m_curAutomationModelKnob @@ -478,49 +355,61 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned void VectorGraphCotnrolDialog::controlValueChanged() { - qDebug("val changed B"); updateVectorGraphAttribs(); } void VectorGraphCotnrolDialog::effectedPointClicked(bool isChecked) { - qDebug("clikced A"); + float currentValue = m_vectorGraphView->getInputAttribValue(11); + m_vectorGraphView->setInputAttribValue(11, currentValue >= 0.5f ? 0.0f : 1.0f); } void VectorGraphCotnrolDialog::effectedLineClicked(bool isChecked) { - qDebug("clikced B"); + float currentValue = m_vectorGraphView->getInputAttribValue(12); + m_vectorGraphView->setInputAttribValue(12, currentValue >= 0.5f ? 0.0f : 1.0f); +} +void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) +{ + if (m_curAutomationModel == nullptr) { return; } + + hideAutomation(); + m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->setAutomated(m_curSelectedLocation, false); } void VectorGraphCotnrolDialog::updateControls() { if (m_curAutomationModel == nullptr) { return; } - bool unusedBool = false; for (size_t i = 0; i < m_controlModelArray.size(); i++) { - m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i, &unusedBool)); + m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i)); } - m_lineTypeModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(5, &unusedBool)); - m_automatedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(6, &unusedBool)); - m_effectedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(7, &unusedBool)); - //m_effectModelA; - //m_effectModelB; - //m_effectModelC; + m_lineTypeModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(5)); + m_automatedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(6)); + m_effectedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(7)); + m_effectModelA.setAutomatedValue(m_vectorGraphView->getInputAttribValue(8)); + m_effectModelB.setAutomatedValue(m_vectorGraphView->getInputAttribValue(9)); + m_effectModelC.setAutomatedValue(m_vectorGraphView->getInputAttribValue(10)); } void VectorGraphCotnrolDialog::updateVectorGraphAttribs() { if (m_curAutomationModel == nullptr) { return; } - qDebug("set input attrib value"); for (size_t i = 0; i < m_controlModelArray.size(); i++) { - m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value(), false); + m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value()); //m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i, &unusedBool)); } + m_vectorGraphView->setInputAttribValue(5, m_lineTypeModel.value()); + m_vectorGraphView->setInputAttribValue(6, m_automatedAttribModel.value()); + m_vectorGraphView->setInputAttribValue(7, m_effectedAttribModel.value()); + m_vectorGraphView->setInputAttribValue(8, m_effectModelA.value()); + m_vectorGraphView->setInputAttribValue(9, m_effectModelB.value()); + m_vectorGraphView->setInputAttribValue(10, m_effectModelC.value()); } From ce053fe98447f20443363387ba440799cb19b644 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:44:42 +0200 Subject: [PATCH 138/184] VectorGraph_reworked_effect_implementation --- include/VectorGraph.h | 70 ++-- src/gui/widgets/VectorGraph.cpp | 633 +++++++++----------------------- 2 files changed, 228 insertions(+), 475 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 1e0ad5d1896..1c5bc9031de 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -69,7 +69,7 @@ class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView public: VectorGraphView(QWidget* parent, int widgetWidth, int widgetHeight, unsigned int pointSize, - unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors); + unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors); ~VectorGraphView(); void setLineColor(QColor color, unsigned int dataArrayLocation); @@ -123,14 +123,14 @@ protected slots: void updateGraph(); void updateGraph(bool shouldUseGetLastSamples); void updateDefaultColors(); - - void contextMenuRemoveAutomation(); private: void paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer); void paintEditing(QPainter* p); void modelChanged() override; + VectorGraphCotnrolDialog m_controlDialog; + // utility // calculate graph coords from screen space coords PointF mapMousePos(int x, int y); @@ -151,25 +151,21 @@ protected slots: // editing menu / controls // returns true if the graph was clicked - bool isGraphPressed(int mouseX, int mouseY); + bool isGraphPressed(int mouseY); // returns true if the control window was clicked while in editing mode bool isControlWindowPressed(int mouseY); - void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving, int curX, int curY); + void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving); // returns -1 if no control / input was clicked // returns displayed absolute control / input location based on inputCount int getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount); - // returns a float attrib value, valueOut = attrib value if it is a bool - float getInputAttribValue(unsigned int controlArrayLocation, bool* valueOut); - // sets the selected point's attrib to floatValue it it is float, else it sets the attrib to boolValue - void setInputAttribValue(unsigned int controlArrayLocation, float floatValue, bool boolValue); + // returns a float attrib value + float getInputAttribValue(unsigned int controlArrayLocation); + // sets the selected point's attrib (controlArrayLocation) to floatValue + void setInputAttribValue(unsigned int controlArrayLocation, float floatValue); // calculates the ideal text color QColor getTextColorFromBaseColor(QColor baseColor); // calculates a replacement background fill color QColor getFillColorFromBaseColor(QColor baseColor); - // cuts the string to displayedLength(in px) size (estimated) - QString getTextFromDisplayLength(QString text, unsigned int displayLength); - // outputs m_controlText for the line type or the switch autmated location or effected location control - QString getTextForAutomatableEffectableOrType(unsigned int controlLocation); // selection // searches VectorGraphDataArray-s to select @@ -213,9 +209,8 @@ protected slots: unsigned int m_controlHeight; // displayed control count (+1 because of the ">>" button in editing mode) unsigned int m_controlDisplayCount; - unsigned int m_controlDisplayPage; bool m_isEditingActive; - std::array m_controlText = + const std::array m_controlTextB = { tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), @@ -223,7 +218,11 @@ protected slots: tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; - std::array m_controlLineTypeText = { + const std::array m_controlText = + { + tr("edit point"), tr("switch graph") + }; + const std::array m_controlLineTypeText = { tr("none"), tr("sine"), tr("phase changable sine"), @@ -231,7 +230,7 @@ protected slots: tr("steps"), tr("random") }; - std::array m_controlIsFloat = { + const std::array m_controlIsFloat = { true, true, true, true, true, false, false, false, false, false, false, @@ -242,8 +241,6 @@ protected slots: std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; - VectorGraphCotnrolDialog* m_controlDialog; - // default VectorGraphDataArray colors // applyed in constructor QColor m_vectorGraphDefaultAutomatedColor; @@ -254,6 +251,8 @@ protected slots: QColor m_vectorGraphSecondaryLineColor; QColor m_vectorGraphSecondaryActiveColor; QColor m_vectorGraphSecondaryFillColor; + + friend class lmms::gui::VectorGraphCotnrolDialog; }; } // namespace gui @@ -460,12 +459,13 @@ class LMMS_EXPORT VectorGraphDataArray // returns true when m_effectLines is true and // when getEffectedAttribLocation() == 0 (y is effected) bool getEffectLines(unsigned int pointLocation); - // returns if the effectId-th effect is active - bool getEffect(unsigned int pointLocation, unsigned int effectId); + // returns the effect type of the selected id or slot + // effectSlot: which effect slot (m_effectTypeA / B / C) + unsigned int getEffect(unsigned int pointLocation, unsigned int effectSlot); // true when the automationModel's value changed since last check bool getIsAutomationValueChanged(unsigned int pointLocation); // can return nullptr - inline FloatModel* getAutomationModel(unsigned int pointLocation); + FloatModel* getAutomationModel(unsigned int pointLocation); // get: ------------------- @@ -535,7 +535,8 @@ class LMMS_EXPORT VectorGraphDataArray void setEffectLines(unsigned int pointLocation, bool bValue); // checks m_isAutomatableEffectable and m_isEditableAttrib // sets the point's effect type - void setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue); + // effectSlot: which effect slot (m_effectTypeA / B / C), effectType: what kind of effect (add, exct) + void setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType); // checks m_isAutomatableEffectable // if bValue is true then make a new FloatModel and connect it, else delete // the currently used FloatModel @@ -594,6 +595,22 @@ class LMMS_EXPORT VectorGraphDataArray // use getAutomatedAttrib or getEffectedAttrib to get it unsigned int m_automatedEffectedAttribLocations = 0; + // what effect will be applyed if effected + // effects: + // 0 - none + // 1 - add + // 2 - subtract + // 3 - multiply + // 4 - divide + // 5 - power + // 6 - log + // 7 - sine + // 8 - lower clamp + // 9 - upper clamp + unsigned int m_effectTypeA = 0; + unsigned int m_effectTypeB = 0; + unsigned int m_effectTypeC = 0; + // if the point attributes should be effected, // getEffectPoints() will return true when // effected attrib location > 0 @@ -601,6 +618,7 @@ class LMMS_EXPORT VectorGraphDataArray // if the line (each sample) should be effected (only works when y is effected) bool m_effectLines = true; + /* bool m_effectAdd = false; bool m_effectSubtract = false; bool m_effectMultiply = false; @@ -610,6 +628,7 @@ class LMMS_EXPORT VectorGraphDataArray bool m_effectSine = false; bool m_effectClampLower = false; bool m_effectClampUpper = false; + */ // stores m_automationModel->value(), used in getSamples() when updating float m_bufferedAutomationValue = 0.0f; @@ -625,8 +644,9 @@ class LMMS_EXPORT VectorGraphDataArray // returns the curve value at a given x coord, does clamp float processCurve(float yBefore, float yAfter, float curve, float xIn); // returns effected attribute value from base attribValue (input attribute value), does clamp - // this function applies the point Effects (like m_effectAdd) based on attribValue and effectValue + // this function applies the point Effects (like add effect) based on attribValue and effectValue float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); + float processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, float attribValue, float effectValue); // returns automated attribute value from base attribValue (input attribute value), does clamp float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); @@ -727,7 +747,7 @@ class LMMS_EXPORT VectorGraphDataArray // updating a line means recalculating m_bakedSamples in getSamples() // based on the changed points (stored in m_needsUpdating) // changes in a point will causes its line to update (line started by the point) - // changes in position needs to cause multiple lines to update + // changes in position needs to cause the line before to update too // addition or deletion needs to cause all the lines to update // if we want to update all (the full line in getSamples()) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index e07517f5502..d44722ea3f2 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -32,15 +32,12 @@ #include #include #include -#include // context menu #include // locking when getSamples #include "VectorGraphViewBase.h" #include "StringPairDrag.h" -#include "CaptionMenu.h" // context menu -#include "embed.h" // context menu -#include "MainWindow.h" // getting main window for context menu +#include "MainWindow.h" // getting main window for control dialog #include "GuiApplication.h" // getGUI #include "AutomatableModel.h" #include "ControllerConnectionDialog.h" @@ -58,12 +55,14 @@ namespace lmms namespace gui { VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, - unsigned int controlHeight, unsigned int controlDisplayCount, bool shouldApplyDefaultVectorGraphColors) : + unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : VectorGraphViewBase(parent), //QWidget(parent), - ModelView(new VectorGraphModel(2048, nullptr, false), this) + ModelView(new VectorGraphModel(2048, nullptr, false), this), + m_controlDialog(getGUI()->mainWindow(), this) { resize(widgetWidth, widgetHeight); + m_controlDialog.hide(); m_mousePress = false; m_addition = false; @@ -84,8 +83,7 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe m_graphHeight = height(); m_controlHeight = controlHeight; - m_controlDisplayCount = controlDisplayCount; - m_controlDisplayPage = 0; + m_controlDisplayCount = 2; m_isEditingActive = false; // set in .h //m_controlText @@ -109,15 +107,9 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe { applyDefaultColors(); } - - m_controlDialog = nullptr; } VectorGraphView::~VectorGraphView() { - if (m_controlDialog == nullptr) - { - delete m_controlDialog; - } } void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) @@ -183,6 +175,7 @@ void VectorGraphView::setControlHeight(unsigned int controlHeight) } void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCount) { + // TODO remove m_controlDisplayCount = controlDisplayCount; updateGraph(); } @@ -248,6 +241,19 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) m_addition = false; m_mousePress = false; + // a point's FloatModel might be deleted after this + // cleaning up connected Knob in the dialog + m_controlDialog.hideAutomation(); + m_controlDialog.hide(); + if (m_isSelected == true) + { + FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + if (curFloatModel != nullptr && curFloatModel->isAutomatedOrControlled() == false) + { + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); + } + } + if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION @@ -273,7 +279,7 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) m_addition = false; m_mousePress = true; } - if (isGraphPressed(x, m_graphHeight - y) == true) + if (isGraphPressed(m_graphHeight - y) == true) { // try selecting the clicked point (if it is near) selectData(x, m_graphHeight - y); @@ -331,7 +337,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) // if the mouse was not moved a lot if (m_mousePress == true) { return; } - if (isGraphPressed(x, m_lastScndTrackPoint.second) == true) + if (isGraphPressed(m_lastScndTrackPoint.second) == true) { if (m_isSelected == true && m_addition == true) { @@ -420,7 +426,7 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) } else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) { - processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving, x, m_graphHeight - y); + processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving); } } @@ -433,7 +439,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) int x = me->x(); int y = me->y(); // if did not drag and graph is pressed - if (m_mousePress == true && isGraphPressed(x, m_graphHeight - y) == true) + if (m_mousePress == true && isGraphPressed(m_graphHeight - y) == true) { model()->modelAddJournalCheckPoint(); // add/delete point @@ -479,50 +485,7 @@ void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) { model()->modelAddJournalCheckPoint(); - processControlWindowPressed(x, m_graphHeight - y, false, false, 0, 0); - } - else if (isGraphPressed(x, m_graphHeight - y) == false) - { - // if the "switch graph" button was pressed in editing mode - unsigned int oldSelectedArray = m_selectedArray; - m_selectedLocation = 0; - m_selectedArray = 0; - m_isLastSelectedArray = false; - m_isSelected = false; - m_isEditingActive = false; - m_isCurveSelected = false; - - // looping throught the data arrays to get a new - // selected data array - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent select dataArray: i: [%d], m_selectedArray: %d, oldSelectedArray: %d", i, m_selectedArray, oldSelectedArray); -#endif - if (model()->getDataArray(i)->getIsSelectable() == true) - { - // if this data array is the first one that is selectable - if (m_isLastSelectedArray == false) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - } - // if this data array's location is bigger than the old location - // if this is false then m_selectedArray will equal to the first selectable array - if (i > oldSelectedArray) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - break; - } - } - } -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent select dataArray final: %d", m_selectedArray); -#endif - - // hint text - hideHintText(); + processControlWindowPressed(x, m_graphHeight - y, false, false); } m_mousePress = false; m_addition = false; @@ -540,11 +503,11 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) qDebug("mouseDoubleClickEvent start"); #endif // get position - int x = me->x(); + //int x = me->x(); int y = me->y(); // if a data/sample is selected then show input dialog to change the data - if (isGraphPressed(x, m_graphHeight - y) == true) + if (isGraphPressed(m_graphHeight - y) == true) { if (m_isSelected == true && me->button() == Qt::LeftButton) { @@ -554,23 +517,6 @@ void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) setSelectedData(curData); } } - else if (isControlWindowPressed(m_graphHeight - y) == true) - { - m_mousePress = true; - int pressLocation = getPressedControlInput(x, m_graphHeight - y, m_controlDisplayCount + 1); - if (pressLocation >= 0 && pressLocation != m_controlDisplayCount) - { - unsigned int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; - if (location < m_controlText.size() && m_controlIsFloat[location] == true) - { - // unused bool - bool isTrue = false; - // set m_lastScndTrackPoint.first to the current input value - float curValue = getInputAttribValue(location, &isTrue); - setInputAttribValue(location, showInputDialog(curValue), isTrue); - } - } - } } void VectorGraphView::leaveEvent(QEvent *event) { @@ -772,7 +718,6 @@ void VectorGraphView::paintEditing(QPainter* p) VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); // background of float values - QColor backColor(getFillColorFromBaseColor(*dataArray->getFillColor())); QColor foreColor = *dataArray->getLineColor(); if (dataArray->getFillColor()->alpha() > 0) { @@ -791,64 +736,22 @@ void VectorGraphView::paintEditing(QPainter* p) controlTextCount = 6; } - int segmentLength = width() / (m_controlDisplayCount + 1); + int segmentLength = width() / (m_controlDisplayCount); // draw inputs p->setPen(QPen(textColor, 1)); for (unsigned int i = 0; i < m_controlDisplayCount; i++) { - int controlLocation = m_controlDisplayCount * m_controlDisplayPage + i; - if (controlLocation < controlTextCount) - { - if (m_controlIsFloat[controlLocation] == true) - { - QColor curBackColor = backColor; - QColor curForeColor = foreColor; - // unused bool - bool isTrue = false; - float inputValue = getInputAttribValue(controlLocation, &isTrue); - if (dataArray->getAutomationModel(m_selectedLocation) != nullptr && static_cast(getInputAttribValue(6, &isTrue)) == controlLocation - 1) - { - curForeColor = *dataArray->getAutomatedColor(); - curBackColor = getFillColorFromBaseColor(curForeColor); - } - else if (dataArray->getIsAutomatableEffectable() == true && static_cast(getInputAttribValue(7, &isTrue)) == controlLocation - 1) - { - curForeColor = *dataArray->getActiveColor(); - curBackColor = getFillColorFromBaseColor(curForeColor); - } - p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curBackColor); - p->fillRect(i * segmentLength, m_graphHeight, mapControlInputX(inputValue, segmentLength), m_controlHeight, curForeColor); - p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, - getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); - } - else - { - QColor curForeColor = *dataArray->getFillColor(); - bool isTrue = false; - getInputAttribValue(controlLocation, &isTrue); - if (isTrue == true) - { - curForeColor = *dataArray->getActiveColor(); - } - p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); - p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, - getTextFromDisplayLength(m_controlText[controlLocation], segmentLength)); - } - } + QColor curForeColor = *dataArray->getFillColor(); + p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); + p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, m_controlText[i]); } - // draw "next page" button - p->fillRect(m_controlDisplayCount * segmentLength, m_graphHeight, segmentLength, m_controlHeight, *dataArray->getFillColor()); - p->setPen(textColor); - p->drawText(m_controlDisplayCount * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, ">>"); - // draw selected array display outline - p->setPen(*dataArray->getLineColor()); - p->drawRect(0, 0, m_controlHeight, m_controlHeight); // draw outline + p->setPen(QPen(*dataArray->getLineColor(), 1)); p->drawLine(0, m_graphHeight, width(), m_graphHeight); - for (unsigned int i = 1; i < m_controlDisplayCount + 1; i++) + for (unsigned int i = 1; i < m_controlDisplayCount; i++) { - if (m_controlDisplayCount * m_controlDisplayPage + i < controlTextCount || i >= m_controlDisplayCount) + if (i < controlTextCount || i >= m_controlDisplayCount) { p->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); } @@ -887,17 +790,6 @@ void VectorGraphView::updateDefaultColors() applyDefaultColors(); } } -void VectorGraphView::contextMenuRemoveAutomation() -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("contextMenuRemoveAutomation: m_isSelected: %d, m_selectedArray: %d, m_selectedLocation: %d", m_isSelected, m_selectedArray, m_selectedLocation); -#endif - if (m_isSelected == true) - { - // deleting the floatmodel will delete the connecitons - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); - } -} PointF VectorGraphView::mapMousePos(int x, int y) { @@ -973,22 +865,9 @@ bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouse return output; } -bool VectorGraphView::isGraphPressed(int mouseX, int mouseY) +bool VectorGraphView::isGraphPressed(int mouseY) { - bool output = true; - // mouseY is calculated like this: - // m_graphHeight - y - if (m_isEditingActive == true && m_graphHeight - mouseY < m_controlHeight && mouseX < m_controlHeight) - { - // if switch selected data array was pressed - output = false; - } - else if (isControlWindowPressed(mouseY) == true) - { - // if the control window was pressed - output = false; - } - return output; + return !isControlWindowPressed(mouseY); } bool VectorGraphView::isControlWindowPressed(int mouseY) { @@ -1001,131 +880,82 @@ bool VectorGraphView::isControlWindowPressed(int mouseY) } return output; } -void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving, int curX, int curY) +void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving) { - if (m_controlDialog == nullptr) - { - m_controlDialog = new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this); - } - /*/ - if (dialogB.exec() == 1) - { - - } - */ - // mouseY is calculated like this: // m_graphHeight - y setCursor(Qt::ArrowCursor); #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d, tracked position (x, y): %d, %d", mouseX, mouseY, isDragging, startMoving, curX, curY); + qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d", mouseX, mouseY, isDragging, startMoving); #endif if (m_isEditingActive == false) { return; } - int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount + 1); - int location = m_controlDisplayCount * m_controlDisplayPage + pressLocation; + int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount); #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed: pressLocation: %d, control window location: %d, controlDiyplayPage: %d", pressLocation, location, m_controlDisplayPage); + qDebug("processControlWindowPressed: pressLocation: %d", pressLocation); #endif - if (isDragging == false && pressLocation == m_controlDisplayCount) + if (isDragging == false || (isDragging == true && startMoving == false)) { - // if the last button was pressed - - // how many inputs are there - int controlTextCount = m_controlText.size(); - if (m_isSelected == true) + if (pressLocation == 0) { - if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == false) - { - // x, y - controlTextCount = 2; - } - else if (model()->getDataArray(m_selectedArray)->getIsAutomatableEffectable() == false) + m_controlDialog.show(); + if (m_isSelected == true) { - // x, y, curve, valA, valB, switch type - controlTextCount = 6; + m_controlDialog.switchPoint(m_selectedArray, m_selectedLocation); } + hideHintText(); } - - m_controlDisplayPage++; - if (m_controlDisplayCount * m_controlDisplayPage >= controlTextCount) + else if (pressLocation == 1) { - m_controlDisplayPage = 0; - } - hideHintText(); - } - else if (pressLocation >= 0 && location < m_controlText.size()) - { - // pressLocation should always be bigger than -1 - // if the control window was pressed + // if the "switch graph" button was pressed in editing mode + unsigned int oldSelectedArray = m_selectedArray; + m_selectedLocation = 0; + m_selectedArray = 0; + m_isLastSelectedArray = false; + m_isSelected = false; + m_isEditingActive = false; + m_isCurveSelected = false; - if (m_addition == false) - { - if (location >= 1 && location <= 4) + // looping throught the data arrays to get a new + // selected data array + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) { - // if the right mouse button was pressed on a automatabel attribute - // get context menu input text - QString controlDisplayText = m_controlText[location]; - controlDisplayText = controlDisplayText + getTextForAutomatableEffectableOrType(location); - setInputAttribValue(6, location - 1, false); - - // getting the currently selected point's FloatModel - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curAutomationModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - - // show context menu - showContextMenu(QCursor::pos(), curAutomationModel, model()->displayName(), controlDisplayText); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray: i: [%d], m_selectedArray: %d, oldSelectedArray: %d", i, m_selectedArray, oldSelectedArray); +#endif + if (model()->getDataArray(i)->getIsSelectable() == true) + { + // if this data array is the first one that is selectable + if (m_isLastSelectedArray == false) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + } + // if this data array's location is bigger than the old location + // if this is false then m_selectedArray will equal to the first selectable array + if (i > oldSelectedArray) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + break; + } + } } - } - else if (isDragging == false && m_controlIsFloat[location] == false) - { - // if the input type is a bool +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray final: %d", m_selectedArray); +#endif - bool curBoolValue = true; - // if location is not at "set type" or "set automation location" or "set effect location" - // (else curBoolValue = true -> setInputAttribValue will add 1 to the attribute) - if (location < 5 || location > 7) + // hint text + if (m_selectedArray != oldSelectedArray) { - getInputAttribValue(location, &curBoolValue); - curBoolValue = !curBoolValue; + showHintText(widget(), tr("selected graph changed"), 5, 3500); } - setInputAttribValue(location, 0.0f, curBoolValue); - - - // hint text - QString hintText = m_controlText[location]; - hintText = hintText + getTextForAutomatableEffectableOrType(location); - showHintText(widget(), hintText, 5, 3500); - } - else if (isDragging == true && m_controlIsFloat[location] == true) - { - // if the input type is a float - - // if the user just started to move the mouse it is pressed - if (startMoving == true) + else { - // unused bool - bool isTrue = false; - // set m_lastScndTrackPoint.first to the current input value - m_lastScndTrackPoint.first = mapControlInputX(getInputAttribValue(location, &isTrue), m_graphHeight); - - m_lastTrackPoint.first = curX; - m_lastTrackPoint.second = curY; + showHintText(widget(), tr("unable to select other graph"), 5, 3500); } - PointF convertedCoords = mapMousePos(0, - m_lastScndTrackPoint.first + static_cast(curY - m_lastTrackPoint.second) / 2); - setInputAttribValue(location, convertedCoords.second, false); - -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed dragging float: m_lastTrackPoint (x, y): %d, %d, m_lastScndTrackPoint (x, y): %d, %d,\n final coords (x, y): %f, %f", - m_lastTrackPoint.first, m_lastTrackPoint.second, m_lastScndTrackPoint.first, - m_lastScndTrackPoint.second, convertedCoords.first, convertedCoords.second); -#endif - - // hint text - showHintText(widget(), m_controlText[location], 5, 3500); } } } @@ -1142,7 +972,7 @@ int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int } return output; } -float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bool* valueOut) +float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation) { float output = 0.0f; if (m_isSelected == false) { return output; } @@ -1150,80 +980,54 @@ float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation, bo switch (controlArrayLocation) { case 0: - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); break; case 1: - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); break; case 2: - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); break; case 3: - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); break; case 4: - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); break; case 5: // type - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); break; case 6: // automation location - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); break; case 7: // effect location - *valueOut = false; output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); break; case 8: - *valueOut = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation); + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); break; case 9: - *valueOut = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation); + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); break; case 10: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); break; case 11: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); + output = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation) ? 1.0f : 0.0f; break; case 12: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); - break; - case 13: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 3); - break; - case 14: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 4); - break; - case 15: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 5); - break; - case 16: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 6); - break; - case 17: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 7); - break; - case 18: - *valueOut = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 8); + output = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation) ? 1.0f : 0.0f; break; } return output; } -void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue, bool boolValue) +void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue) { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setInputAttribute start: control input: %d, set floatValue: %f, set boolValue: %d", controlArrayLocation, floatValue, boolValue); + qDebug("setInputAttribute start: control input: %d, set floatValue: %f", controlArrayLocation, floatValue); #endif if (m_isSelected == false) { return; } @@ -1248,87 +1052,36 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, flo break; case 5: // type - clampedValueB = 0; - if (boolValue == true) - { - clampedValueB = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation) + 1; - if (clampedValueB > 5) - { - clampedValueB = 0; - } - } - else - { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); - } + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); break; case 6: // automation location - clampedValueB = 0; - if (boolValue == true) - { - clampedValueB = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation) + 1; - if (clampedValueB > 4) - { - clampedValueB = 0; - } - } - else - { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); - } + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); break; case 7: // effect location - clampedValueB = 0; - if (boolValue == true) - { - clampedValueB = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation) + 1; - if (clampedValueB > 4) - { - clampedValueB = 0; - } - } - else - { - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); - } + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); break; case 8: - model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, boolValue); + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, clampedValueB); break; case 9: - model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, boolValue); + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, clampedValueB); break; case 10: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, boolValue); + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, clampedValueB); break; case 11: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, boolValue); + model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, floatValue >= 0.5f); break; case 12: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, boolValue); - break; - case 13: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 3, boolValue); - break; - case 14: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 4, boolValue); - break; - case 15: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 5, boolValue); - break; - case 16: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 6, boolValue); - break; - case 17: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 7, boolValue); - break; - case 18: - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 8, boolValue); + model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, floatValue >= 0.5f); break; } } @@ -1374,53 +1127,6 @@ QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColor) } return output; } -QString VectorGraphView::getTextFromDisplayLength(QString text, unsigned int displayLength) -{ - // estimating text length - int charLength = static_cast(m_fontSize * 0.65f); - QString output = ""; - int targetSize = displayLength / charLength < text.size() ? displayLength / charLength : text.size(); - if (targetSize != text.size()) - { - for (unsigned int i = 0; i < targetSize; i++) - { - if (i + 2 < targetSize) - { - output = output + text[i]; - } - else - { - output = output + QString("."); - } - } - } - else - { - output = text; - } - return output; -} -QString VectorGraphView::getTextForAutomatableEffectableOrType(unsigned int controlLocation) -{ - QString output; - if (controlLocation >= 5 && controlLocation <= 7) - { - bool isTrue = false; - int typeVal = static_cast(getInputAttribValue(controlLocation, &isTrue)); - if (controlLocation == 5) - { - if (typeVal < m_controlLineTypeText.size()) - { - output = QString(" (") + m_controlLineTypeText[typeVal] + QString(")"); - } - } - else - { - output = QString(tr(" (controls: ")) + m_controlText[1 + typeVal] + QString(")"); - } - } - return output; -} void VectorGraphView::selectData(int mouseX, int mouseY) { @@ -2711,7 +2417,7 @@ void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigne // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocation = attribLocation > 3 ? 0 : attribLocation; // set effected location correctly - m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation); + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation) * 4; getUpdatingFromPoint(pointLocation); // if the current point can effect the line before it @@ -2785,72 +2491,33 @@ void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValu dataChanged(); } } -bool VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectId) +unsigned int VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectSlot) { - switch (effectId) + switch (effectSlot) { case 0: - return m_dataArray[pointLocation].m_effectAdd; - break; + return m_dataArray[pointLocation].m_effectTypeA; case 1: - return m_dataArray[pointLocation].m_effectSubtract; - break; + return m_dataArray[pointLocation].m_effectTypeB; case 2: - return m_dataArray[pointLocation].m_effectMultiply; - break; - case 3: - return m_dataArray[pointLocation].m_effectDivide; - break; - case 4: - return m_dataArray[pointLocation].m_effectPower; - break; - case 5: - return m_dataArray[pointLocation].m_effectLog; - break; - case 6: - return m_dataArray[pointLocation].m_effectSine; - break; - case 7: - return m_dataArray[pointLocation].m_effectClampLower; - break; - case 8: - return m_dataArray[pointLocation].m_effectClampUpper; - break; + return m_dataArray[pointLocation].m_effectTypeC; } - return false; + return 0; } -void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectId, bool bValue) +void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType) { if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - switch (effectId) + switch (effectSlot) { case 0: - m_dataArray[pointLocation].m_effectAdd = bValue; + m_dataArray[pointLocation].m_effectTypeA = effectType; break; case 1: - m_dataArray[pointLocation].m_effectSubtract = bValue; + m_dataArray[pointLocation].m_effectTypeB = effectType; break; case 2: - m_dataArray[pointLocation].m_effectMultiply = bValue; - break; - case 3: - m_dataArray[pointLocation].m_effectDivide = bValue; - break; - case 4: - m_dataArray[pointLocation].m_effectPower = bValue; - break; - case 5: - m_dataArray[pointLocation].m_effectLog = bValue; - break; - case 6: - m_dataArray[pointLocation].m_effectSine = bValue; - break; - case 7: - m_dataArray[pointLocation].m_effectClampLower = bValue; - break; - case 8: - m_dataArray[pointLocation].m_effectClampUpper = bValue; + m_dataArray[pointLocation].m_effectTypeC = effectType; break; } getUpdatingFromPoint(pointLocation); @@ -3115,6 +2782,10 @@ float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attr // effects if (getEffectedAttribLocation(pointLocation) == attribLocation) { + output = processSingleEffect(pointLocation, 0, output, effectValue); + output = processSingleEffect(pointLocation, 1, output, effectValue); + output = processSingleEffect(pointLocation, 2, output, effectValue); + /* if (getEffect(pointLocation, 6) == true) { // sine @@ -3163,12 +2834,74 @@ float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attr // clamp upper output = std::min(effectValue, output); } + */ // clamp output = std::clamp(output, -1.0f, 1.0f); } return output; } + +float VectorGraphDataArray::processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, + float attribValue, float effectValue) +{ + // calculating an effect on attribValue + float output = attribValue; + + // none + if (getEffect(pointLocation, effectSlot) == 0) { return output; } + + // effects + if (getEffect(pointLocation, effectSlot) == 1) + { + // add + output += effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 2) + { + // subtract + output -= effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 3) + { + // multiply + output = output * 5.0f * effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 4 && effectValue != 0.0f) + { + // divide + output = output / 5.0f / effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 5 && output > 0.0f) + { + // power + output = std::pow(output, effectValue * 5.0f); + output = std::clamp(output, -1.0f, 1.0f); + } + else if (getEffect(pointLocation, effectSlot) == 6 && output > 0.0f && effectValue > 0.0f) + { + // log + output = std::log(output) / std::log(effectValue); + output = std::clamp(output, -1.0f, 1.0f); + } + else if (getEffect(pointLocation, effectSlot) == 7) + { + // sine + output = output + std::sin(effectValue * 100.0f); + } + else if (getEffect(pointLocation, effectSlot) == 8) + { + // clamp lower + output = std::max(effectValue, output); + } + else if (getEffect(pointLocation, effectSlot) == 9) + { + // clamp upper + output = std::min(effectValue, output); + } + return output; +} + float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation) { // adding the automation value to attribValue From ade342ba75418b3f8b1e6495c0d8c46b3ea1156a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 27 Jun 2024 18:45:35 +0200 Subject: [PATCH 139/184] WaveShaperControlDialog_updated_constructor --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index ba262ef531a..3b851272949 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -50,7 +50,7 @@ WaveShaperControlDialog::WaveShaperControlDialog( setPalette( pal ); setFixedSize( 224, 274 ); - m_vectorGraphWidget = new VectorGraphView(this, 204, 205, 8, 30, 3, false); + m_vectorGraphWidget = new VectorGraphView(this, 204, 205, 8, 30, false); m_vectorGraphWidget->setModel(&_controls->m_vectorGraphModel); m_vectorGraphWidget->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); // this can cause problems with custom colors From cc1e069316ca699c9db919d692bde60441153009 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:31:14 +0200 Subject: [PATCH 140/184] VectorGraphViewBase_dialog_converted_to_widget --- include/VectorGraphViewBase.h | 7 +++--- src/gui/widgets/VectorGraphViewBase.cpp | 31 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 945a9d4cb7e..10622c7aacd 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "ModelView.h" @@ -75,7 +74,7 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget class VectorGraphView; -class LMMS_EXPORT VectorGraphCotnrolDialog : public QMdiSubWindow +class LMMS_EXPORT VectorGraphCotnrolDialog : public QWidget, public ModelView { Q_OBJECT public: @@ -90,7 +89,8 @@ public slots: void effectedPointClicked(bool isChecked); void effectedLineClicked(bool isChecked); void deleteAutomationClicked(bool isChecked); - +protected slots: + void closeEvent(QCloseEvent * ce); private: void updateControls(); void updateVectorGraphAttribs(); @@ -106,6 +106,7 @@ public slots: unsigned int m_curSelectedArray; // selected VectorGraphPoint unsigned int m_curSelectedLocation; + bool m_isValidSelection; ComboBoxModel m_lineTypeModel; ComboBoxModel m_automatedAttribModel; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index cf35f53c892..9a080a9b8f2 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -103,12 +103,14 @@ std::pair VectorGraphViewBase::showCoordInputDialog(std::pairmodel()->getDataArray(selectedArray)->setAutomated(selectedLocation, true); m_curAutomationModel = m_vectorGraphView->model()->getDataArray(selectedArray)->getAutomationModel(selectedLocation); @@ -371,15 +371,27 @@ void VectorGraphCotnrolDialog::effectedLineClicked(bool isChecked) } void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) { - if (m_curAutomationModel == nullptr) { return; } + if (m_isValidSelection == false) { hideAutomation(); return; } + bool swapIsValidSelection = m_isValidSelection; hideAutomation(); m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->setAutomated(m_curSelectedLocation, false); + m_isValidSelection = swapIsValidSelection; +} + +void VectorGraphCotnrolDialog::closeEvent(QCloseEvent * ce) +{ + // we need to ignore this event + // because Qt::WA_DeleteOnClose was activated by MainWindow::addWindowedWidget + // or else this widget will be deleted + ce->ignore(); + + parentWidget()->hide(); } void VectorGraphCotnrolDialog::updateControls() { - if (m_curAutomationModel == nullptr) { return; } + if (m_isValidSelection == false) { hideAutomation(); return; } for (size_t i = 0; i < m_controlModelArray.size(); i++) { @@ -396,12 +408,11 @@ void VectorGraphCotnrolDialog::updateControls() void VectorGraphCotnrolDialog::updateVectorGraphAttribs() { - if (m_curAutomationModel == nullptr) { return; } + if (m_isValidSelection == false) { hideAutomation(); return; } for (size_t i = 0; i < m_controlModelArray.size(); i++) { m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value()); - //m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i, &unusedBool)); } m_vectorGraphView->setInputAttribValue(5, m_lineTypeModel.value()); From 5b6e1c2334f3e8d9018cbdefa8f3f624e5db3b7f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:33:06 +0200 Subject: [PATCH 141/184] VectorGraph_changed_control_dialog_class_to_QMdiSubWindow --- include/VectorGraph.h | 28 +++------------------------- src/gui/widgets/VectorGraph.cpp | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 32 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 1c5bc9031de..0f13eaca35a 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -39,6 +39,7 @@ #include "lmms_basics.h" #include "AutomatableModel.h" #include "JournallingObject.h" +#include "SubWindow.h" namespace lmms { @@ -129,8 +130,6 @@ protected slots: void modelChanged() override; - VectorGraphCotnrolDialog m_controlDialog; - // utility // calculate graph coords from screen space coords PointF mapMousePos(int x, int y); @@ -167,6 +166,8 @@ protected slots: // calculates a replacement background fill color QColor getFillColorFromBaseColor(QColor baseColor); + SubWindow* m_controlDialog; + // selection // searches VectorGraphDataArray-s to select // near clicked location @@ -210,33 +211,10 @@ protected slots: // displayed control count (+1 because of the ">>" button in editing mode) unsigned int m_controlDisplayCount; bool m_isEditingActive; - const std::array m_controlTextB = - { - tr("x coordinate"), tr("y coordinate"), tr("curve"), tr("1. attribute value"), - tr("2. attribute value"), tr("switch graph line type"), tr("switch graph automated value"), - tr("switch graph effected value"), tr("can this point be effected"), tr("can this line be effected"), tr("\"add\" effect"), - tr("\"subtract\" effect"), tr("\"multiply\" effect"), tr("\"divide\" effect"), tr("\"power\" effect"), - tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") - }; const std::array m_controlText = { tr("edit point"), tr("switch graph") }; - const std::array m_controlLineTypeText = { - tr("none"), - tr("sine"), - tr("phase changable sine"), - tr("peak"), - tr("steps"), - tr("random") - }; - const std::array m_controlIsFloat = { - true, true, true, true, - true, false, false, - false, false, false, false, - false, false, false, false, - false, false, false, false - }; std::pair m_lastTrackPoint; std::pair m_lastScndTrackPoint; diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index d44722ea3f2..44282f56d5d 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -57,12 +57,15 @@ namespace gui VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : VectorGraphViewBase(parent), - //QWidget(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this), - m_controlDialog(getGUI()->mainWindow(), this) + m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this))) { resize(widgetWidth, widgetHeight); - m_controlDialog.hide(); + + m_controlDialog->hide(); + Qt::WindowFlags flags = m_controlDialog->windowFlags(); + flags &= ~Qt::WindowMaximizeButtonHint; + m_controlDialog->setWindowFlags(flags); m_mousePress = false; m_addition = false; @@ -110,6 +113,10 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe } VectorGraphView::~VectorGraphView() { + if (m_controlDialog != nullptr) + { + delete m_controlDialog; + } } void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) @@ -243,8 +250,8 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) // a point's FloatModel might be deleted after this // cleaning up connected Knob in the dialog - m_controlDialog.hideAutomation(); - m_controlDialog.hide(); + reinterpret_cast(m_controlDialog->widget())->hideAutomation(); + m_controlDialog->hide(); if (m_isSelected == true) { FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); @@ -900,10 +907,10 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i { if (pressLocation == 0) { - m_controlDialog.show(); + m_controlDialog->show(); if (m_isSelected == true) { - m_controlDialog.switchPoint(m_selectedArray, m_selectedLocation); + reinterpret_cast(m_controlDialog->widget())->switchPoint(m_selectedArray, m_selectedLocation); } hideHintText(); } From 48dff77389d35e4817a883c26512d1735c706884 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:41:19 +0200 Subject: [PATCH 142/184] VectorGraph_chagned_std_pair_to_PointInt --- include/VectorGraph.h | 9 +++++---- src/gui/widgets/VectorGraph.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 0f13eaca35a..639ef2d7a82 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -51,6 +51,7 @@ class VectorGraphDataArray; class FloatModel; using PointF = std::pair; +using PointInt = std::pair; namespace gui { @@ -135,10 +136,10 @@ protected slots: PointF mapMousePos(int x, int y); // calculate gui curve point's position PointF mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); - std::pair mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); + PointInt mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); // calculate screen space coords from graph coords // isNonNegative can only be true when graph line / getSamples() is mapped - std::pair mapDataPos(float x, float y, bool isNonNegative); + PointInt mapDataPos(float x, float y, bool isNonNegative); // map where each Control is displayed when m_isEdtitingActive is true int mapControlInputX(float inputValue, unsigned int displayLength); @@ -216,8 +217,8 @@ protected slots: tr("edit point"), tr("switch graph") }; - std::pair m_lastTrackPoint; - std::pair m_lastScndTrackPoint; + PointInt m_lastTrackPoint; + PointInt m_lastScndTrackPoint; // default VectorGraphDataArray colors // applyed in constructor diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 44282f56d5d..db0c08d7d92 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -601,9 +601,9 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v p->setPen(QPen(*dataArray->getLineColor(), 2)); p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); - std::pair posA(0, 0); - std::pair posB(0, 0); - std::pair startPos(mapDataPos(0.0f, dataArray->getY(0), false)); + PointInt posA(0, 0); + PointInt posB(0, 0); + PointInt startPos(mapDataPos(0.0f, dataArray->getY(0), false)); // draw line if (m_isSimplified == false) { @@ -696,7 +696,7 @@ void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::v { if (dataArray->getIsEditableAttrib() == true) { - std::pair posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + PointInt posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); p->drawRect(posC.first - squareSize / 2, m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); } @@ -805,18 +805,18 @@ PointF VectorGraphView::mapMousePos(int x, int y) static_cast(x / static_cast(width())), static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); } -std::pair VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) +PointInt VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) { // mapping the point/sample positon to mouse/view position if (isNonNegative == true) { - return std::pair( + return PointInt( static_cast(x * width()), static_cast(y * m_graphHeight)); } else { - return std::pair( + return PointInt( static_cast(x * width()), static_cast((y + 1.0f) * static_cast(m_graphHeight) / 2.0f)); } @@ -827,9 +827,9 @@ PointF VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, (xA + xB) / 2.0f, yA + (curve / 2.0f + 0.5f) * (yB - yA)); } -std::pair VectorGraphView::mapDataCurvePos(int xA, int yA, int xB, int yB, float curve) +PointInt VectorGraphView::mapDataCurvePos(int xA, int yA, int xB, int yB, float curve) { - return std::pair( + return PointInt( (xA + xB) / 2, yA + static_cast((curve / 2.0f + 0.5f) * (yB - yA))); } From 8d5e9bc3eebc7a5955e109a754fb5b98fb21142a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:52:02 +0200 Subject: [PATCH 143/184] VectorGraph_style_changes --- src/gui/widgets/VectorGraph.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index db0c08d7d92..9c6bd9f3150 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -23,28 +23,26 @@ */ #include "VectorGraph.h" +#include "VectorGraphViewBase.h" -#include +#include // sort #include #include // sine -#include // sort #include // rand -#include -#include +#include #include #include // locking when getSamples +#include +#include - -#include "VectorGraphViewBase.h" -#include "StringPairDrag.h" -#include "MainWindow.h" // getting main window for control dialog -#include "GuiApplication.h" // getGUI #include "AutomatableModel.h" -#include "ControllerConnectionDialog.h" +#include "base64.h" #include "ControllerConnection.h" -#include "ProjectJournal.h" +#include "ControllerConnectionDialog.h" +#include "GuiApplication.h" // getGUI #include "JournallingObject.h" -#include "base64.h" +#include "MainWindow.h" // getting main window for control dialog +#include "ProjectJournal.h" //#define VECTORGRAPH_DEBUG_USER_INTERACTION //#define VECTORGRAPH_DEBUG_PAINT_EVENT From 798b05ab792115e336f60d53b8f059a7809eb576 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:33:58 +0200 Subject: [PATCH 144/184] VectorGraph_needsUpdating_converted_to_set_started --- include/VectorGraph.h | 9 +-- src/gui/widgets/VectorGraph.cpp | 124 ++++++++++++++++---------------- 2 files changed, 68 insertions(+), 65 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index 639ef2d7a82..b65051317e0 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -26,6 +26,7 @@ #define LMMS_GUI_VECTORGRAPH_H #include +#include #include #include #include @@ -651,7 +652,7 @@ class LMMS_EXPORT VectorGraphDataArray // adds the m_dataArray points that are // effected by the changed effector array points. // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::vector* updatingPointLocations); + void getUpdatingFromEffector(std::set* updatingPointLocations); // if pointLocation >= 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedSamples // changes in the size of m_dataArray (addtition, deletion, ect.) @@ -666,10 +667,10 @@ class LMMS_EXPORT VectorGraphDataArray // real getSamples processing void getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::vector* updatingValuesOut, std::vector* sampleBufferOut); + std::set* updatingValuesOut, std::vector* sampleBufferOut); // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int pointLocation, float stepSize); + std::vector* sampleXLocations, unsigned int curPoint, float stepSize); bool isEffectedPoint(unsigned int pointLocation); // checks m_isFixedEndPoints, does not call dataChanged() @@ -738,7 +739,7 @@ class LMMS_EXPORT VectorGraphDataArray // unsorted array of locations in m_dataArray // that need to be updated // sorted in getUpdatingOriginals() because some functions need this to be sorted - std::vector m_needsUpdating; + std::set m_needsUpdating; // this stores all the FloatModels, unsorted, should only contain currently used FloatModels // used for automation diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 9c6bd9f3150..077747d7f5a 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -29,6 +29,8 @@ #include #include // sine #include // rand +#include // m_needsUpdating +#include // std::set #include #include #include // locking when getSamples @@ -1651,10 +1653,6 @@ VectorGraphDataArray::VectorGraphDataArray( VectorGraphDataArray::~VectorGraphDataArray() { - //m_dataArray.clear(); - //m_bakedSamples.clear(); - //m_needsUpdating.clear(); - for (unsigned int i = 0; i < m_automationModelArray.size(); i++) { if (m_automationModelArray[i] != nullptr) @@ -3109,40 +3107,42 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample } } -void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) +void VectorGraphDataArray::getUpdatingFromEffector(std::set* updatingPointLocations) { VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); - for (unsigned int i = 0; i < updatingPointLocations->size(); i++) + for (std::set::iterator i = updatingPointLocations->begin(); i != updatingPointLocations->end(); ++i) { // since updatingPointLocations is a sorted list, we can get the end // location and update everithing between them // starting effector location is i, end effector location is updatingEnd - unsigned int updatingEnd = i; - for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) + std::set::iterator updatingEnd = i; + bool updatingEndChanged = false; + for (std::set::iterator j = (++i); j != updatingPointLocations->end(); ++j) { // we can not skip gaps because // every updatingPointLocations point effects their line only // (the line that starts with the point) - if ((*updatingPointLocations)[updatingEnd] + 1 >= - (*updatingPointLocations)[j]) + if ((*updatingEnd) + 1 >= *j) { updatingEnd = j; + updatingEndChanged = true; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", updatingEnd, i); + qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", *updatingEnd, *i); #endif } else { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, - ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); + qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < [j = %d]", updatingEnd, + (*updatingEnd) + 1, *j); #endif break; } } + --i; // getting the point that comes after updatingEnd int updatingEndSlide = 0; - if (updatingEnd + 1 < effector->size()) + if (updatingEnd != --(updatingPointLocations->end())) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: updatingEndSlide = 1"); @@ -3154,7 +3154,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up bool found = false; bool isBefore = false; // this can return -1 - int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); + int locationBefore = getNearestLocation(effector->getX((*i), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); #endif @@ -3169,17 +3169,17 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // remember points control the line after (connected to) them // but in this case changes in the points position can effect the line before it locationBefore--; - // now (here) locationBefore is Always before (*updatingPointLocations)[i] + // now (here) locationBefore is Always before *i } // clamp locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); + int locationAfter = getNearestLocation(effector->getX((*updatingEnd) + updatingEndSlide), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, - effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); + effector->getX(((*updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); #endif if (isBefore == false) { @@ -3190,7 +3190,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationAfter--; } // updating everything before if i -> 0 - if ((*updatingPointLocations)[i] == 0) + if (*i == 0) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything before"); @@ -3199,7 +3199,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up } // if updatingEnd is the last point in effecor, then // update everithing after - if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) + if (*updatingEnd + updatingEndSlide + 1 >= effector->size()) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything after"); @@ -3225,10 +3225,10 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: i: %d, updating: %d", i, j); #endif - m_needsUpdating.push_back(j); + m_needsUpdating.insert(j); if (lastUpdated == false && getEffectPoints(j) == true) { - m_needsUpdating.push_back(j - 1); + m_needsUpdating.insert(j - 1); } lastUpdated = true; } @@ -3237,7 +3237,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up lastUpdated = false; } } - if (i < updatingEnd) + if (updatingEndChanged == true) { i = updatingEnd; } @@ -3249,7 +3249,7 @@ void VectorGraphDataArray::getUpdatingFromPoint(int pointLocation) // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) if (m_isDataChanged == false && pointLocation >= 0) { - m_needsUpdating.push_back(pointLocation); + m_needsUpdating.insert(pointLocation); if (m_needsUpdating.size() > m_dataArray.size() * 3) { m_isDataChanged = true; @@ -3270,18 +3270,19 @@ void VectorGraphDataArray::getUpdatingFromAutomation() #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromAutomation: point location: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); #endif - m_needsUpdating.push_back(i); + m_needsUpdating.insert(i); // if the automatable value effects the y (so the position) // the point before this is updated too if (i > 0 && getAutomatedAttribLocation(i) == 0) { - m_needsUpdating.push_back(i - 1); + m_needsUpdating.insert(i - 1); } } } } void VectorGraphDataArray::getUpdatingOriginals() { + /* // selecting only original values and sorting #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT @@ -3332,13 +3333,14 @@ void VectorGraphDataArray::getUpdatingOriginals() qDebug("getUpatingOriginals final: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); } #endif +*/ } void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::vector* updatingValuesOut, std::vector* sampleBufferOut) + std::set* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); - std::vector effectorUpdatingValues; + std::set effectorUpdatingValues; // sampleBufferOut will serve as the effector's sampleBufferOut until the new m_bakedSamples gets made bool isEffected = m_effectorLocation >= 0; if (isEffected == true) @@ -3399,10 +3401,10 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_updatingBakedSamples.resize(targetSizeIn); } - m_needsUpdating.resize(m_dataArray.size()); + m_needsUpdating.clear(); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - m_needsUpdating[i] = i; + m_needsUpdating.insert(i); } } @@ -3441,10 +3443,10 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh #endif // calculate final lines - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + for (std::set::iterator i = m_needsUpdating.begin(); i != m_needsUpdating.end(); ++i) { // sampleBufferOut contains the effector m_bakedValues here - getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, i, stepSize); + getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, *i, stepSize); } m_parent->lockBakedSamplesAccess(); @@ -3477,28 +3479,28 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh #endif } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) + std::vector* sampleXLocations, unsigned int curPoint, float stepSize) { unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); + (std::ceil(m_dataArray[curPoint].m_x / stepSize)); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, m_needsUpdating[pointLocation], effectYLocation); + qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, curPoint, effectYLocation); #endif - // current effector output Y near m_needsUpdating[pointLocation] point + // current effector output Y near curPoint point float curEffectY = (*effectorSamples)[effectYLocation]; float nextEffectY = (*effectorSamples)[effectYLocation]; // getting the final automatable / effectable point values - float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); - float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); - float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); - float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); - if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation]) == true && getEffectLines(m_needsUpdating[pointLocation]) == false) + float curY = processAutomation(curPoint, m_dataArray[curPoint].m_y, 0); + float curC = processAutomation(curPoint, m_dataArray[curPoint].m_c, 1); + float curValA = processAutomation(curPoint, m_dataArray[curPoint].m_valA, 2); + float curValB = processAutomation(curPoint, m_dataArray[curPoint].m_valB, 3); + if (effector != nullptr && getEffectPoints(curPoint) == true && getEffectLines(curPoint) == false) { - curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); - curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); - curValA = processEffect(m_needsUpdating[pointLocation], curValA, 2, curEffectY); - curValB = processEffect(m_needsUpdating[pointLocation], curValB, 3, curEffectY); + curY = processEffect(curPoint, curY, 0, curEffectY); + curC = processEffect(curPoint, curC, 1, curEffectY); + curValA = processEffect(curPoint, curValA, 2, curEffectY); + curValB = processEffect(curPoint, curValB, 3, curEffectY); } // from where to update line int start = effectYLocation; @@ -3506,26 +3508,26 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, float nextY = curY; - if (m_needsUpdating[pointLocation] + 1 < m_dataArray.size()) + if (curPoint + 1 < m_dataArray.size()) { effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); + (std::ceil(m_dataArray[curPoint + 1].m_x / stepSize)); // where updating line ends (+1) end = effectYLocation; - nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); + nextY = processAutomation(curPoint + 1, m_dataArray[curPoint + 1].m_y, 0); - bool isCurEffected = isEffectedPoint(m_needsUpdating[pointLocation]); + bool isCurEffected = isEffectedPoint(curPoint); // if the next point (y location) can be effected // and the current point's line is uneffected - if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation] + 1) == true && - (getEffectLines(m_needsUpdating[pointLocation]) == false || isCurEffected == false)) + if (effector != nullptr && getEffectPoints(curPoint + 1) == true && + (getEffectLines(curPoint) == false || isCurEffected == false)) { nextEffectY = (*effectorSamples)[effectYLocation]; - nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); + nextY = processEffect(curPoint + 1, nextY, 0, nextEffectY); } } // calculating line ends - if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) + if (curPoint + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray for (int j = end; j < m_updatingBakedSamples.size(); j++) @@ -3533,7 +3535,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, m_updatingBakedSamples[j] = curY; } } - if (m_needsUpdating[pointLocation] == 0) + if (curPoint == 0) { // if this point is at the 0 location in m_dataArray for (int j = 0; j < start; j++) @@ -3543,7 +3545,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, } float fadeInStart = 0.05f; - unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; + unsigned int type = m_dataArray[curPoint].m_type; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getSamplesUpdatinLines: point: [%d] start: %d, end: %d, line type: %d, --- attribs: y: %f, next y: %f, curve %f, valA %f, valB %f", pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); @@ -3609,15 +3611,15 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, // line type processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } - if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) + if (effector != nullptr && getEffectLines(curPoint) == true) { - int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; - int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = curPoint == 0 ? 0 : start; + int endB = curPoint >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; // process line effect // if it is enabled for (int j = startB; j < endB; j++) { - m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); + m_updatingBakedSamples[j] = processEffect(curPoint, m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); } } // clamp @@ -3634,8 +3636,8 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, } if (m_isNonNegative == true) { - int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; - int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = curPoint == 0 ? 0 : start; + int endB = curPoint >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; for (int j = startB; j < endB; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; From b473f951f062ad8d69de6630b41f539d48b3f683 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:14:21 +0200 Subject: [PATCH 145/184] VectorGraph_needsUpdating_set_changes_reverted --- include/VectorGraph.h | 9 +- src/gui/widgets/VectorGraph.cpp | 170 +++++++++++--------------------- 2 files changed, 61 insertions(+), 118 deletions(-) diff --git a/include/VectorGraph.h b/include/VectorGraph.h index b65051317e0..639ef2d7a82 100644 --- a/include/VectorGraph.h +++ b/include/VectorGraph.h @@ -26,7 +26,6 @@ #define LMMS_GUI_VECTORGRAPH_H #include -#include #include #include #include @@ -652,7 +651,7 @@ class LMMS_EXPORT VectorGraphDataArray // adds the m_dataArray points that are // effected by the changed effector array points. // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::set* updatingPointLocations); + void getUpdatingFromEffector(std::vector* updatingPointLocations); // if pointLocation >= 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedSamples // changes in the size of m_dataArray (addtition, deletion, ect.) @@ -667,10 +666,10 @@ class LMMS_EXPORT VectorGraphDataArray // real getSamples processing void getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::set* updatingValuesOut, std::vector* sampleBufferOut); + std::vector* updatingValuesOut, std::vector* sampleBufferOut); // redraw lines void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int curPoint, float stepSize); + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize); bool isEffectedPoint(unsigned int pointLocation); // checks m_isFixedEndPoints, does not call dataChanged() @@ -739,7 +738,7 @@ class LMMS_EXPORT VectorGraphDataArray // unsorted array of locations in m_dataArray // that need to be updated // sorted in getUpdatingOriginals() because some functions need this to be sorted - std::set m_needsUpdating; + std::vector m_needsUpdating; // this stores all the FloatModels, unsorted, should only contain currently used FloatModels // used for automation diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 077747d7f5a..1c22ee3e609 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -29,8 +29,6 @@ #include #include // sine #include // rand -#include // m_needsUpdating -#include // std::set #include #include #include // locking when getSamples @@ -2788,56 +2786,6 @@ float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attr output = processSingleEffect(pointLocation, 0, output, effectValue); output = processSingleEffect(pointLocation, 1, output, effectValue); output = processSingleEffect(pointLocation, 2, output, effectValue); - /* - if (getEffect(pointLocation, 6) == true) - { - // sine - output = output + std::sin(effectValue * 100.0f); - } - if (getEffect(pointLocation, 4) == true && output > 0.0f) - { - // power - output = std::pow(output, effectValue); - } - else if (getEffect(pointLocation, 5) == true && output > 0.0f && effectValue > 0.0f) - { - // log - output = std::log(output) / std::log(effectValue); - } - - if (getEffect(pointLocation, 2) == true) - { - // multiply - output = output * 5.0f * effectValue; - } - else if (getEffect(pointLocation, 3) == true && effectValue != 0.0f) - { - // divide - output = output / 5.0f / effectValue; - } - - if (getEffect(pointLocation, 0) == true) - { - // add - output += effectValue; - } - else if (getEffect(pointLocation, 1) == true) - { - // subtract - output -= effectValue; - } - - if (getEffect(pointLocation, 7) == true) - { - // clamp lower - output = std::max(effectValue, output); - } - else if (getEffect(pointLocation, 8) == true) - { - // clamp upper - output = std::min(effectValue, output); - } - */ // clamp output = std::clamp(output, -1.0f, 1.0f); @@ -3107,42 +3055,40 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample } } -void VectorGraphDataArray::getUpdatingFromEffector(std::set* updatingPointLocations) +void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) { VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); - for (std::set::iterator i = updatingPointLocations->begin(); i != updatingPointLocations->end(); ++i) + for (unsigned int i = 0; i < updatingPointLocations->size(); i++) { // since updatingPointLocations is a sorted list, we can get the end // location and update everithing between them // starting effector location is i, end effector location is updatingEnd - std::set::iterator updatingEnd = i; - bool updatingEndChanged = false; - for (std::set::iterator j = (++i); j != updatingPointLocations->end(); ++j) + unsigned int updatingEnd = i; + for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) { // we can not skip gaps because // every updatingPointLocations point effects their line only // (the line that starts with the point) - if ((*updatingEnd) + 1 >= *j) + if ((*updatingPointLocations)[updatingEnd] + 1 >= + (*updatingPointLocations)[j]) { updatingEnd = j; - updatingEndChanged = true; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", *updatingEnd, *i); + qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", updatingEnd, i); #endif } else { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < [j = %d]", updatingEnd, - (*updatingEnd) + 1, *j); + qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, + ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); #endif break; } } - --i; // getting the point that comes after updatingEnd int updatingEndSlide = 0; - if (updatingEnd != --(updatingPointLocations->end())) + if (updatingEnd + 1 < effector->size()) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: updatingEndSlide = 1"); @@ -3154,7 +3100,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat bool found = false; bool isBefore = false; // this can return -1 - int locationBefore = getNearestLocation(effector->getX((*i), &found, &isBefore); + int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); #endif @@ -3169,17 +3115,17 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat // remember points control the line after (connected to) them // but in this case changes in the points position can effect the line before it locationBefore--; - // now (here) locationBefore is Always before *i + // now (here) locationBefore is Always before (*updatingPointLocations)[i] } // clamp locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - int locationAfter = getNearestLocation(effector->getX((*updatingEnd) + updatingEndSlide), &found, &isBefore); + int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, - effector->getX(((*updatingEnd) + updatingEndSlide), m_dataArray[locationAfter].m_x); + effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); #endif if (isBefore == false) { @@ -3190,7 +3136,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat locationAfter--; } // updating everything before if i -> 0 - if (*i == 0) + if ((*updatingPointLocations)[i] == 0) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything before"); @@ -3199,7 +3145,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat } // if updatingEnd is the last point in effecor, then // update everithing after - if (*updatingEnd + updatingEndSlide + 1 >= effector->size()) + if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything after"); @@ -3225,10 +3171,10 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: i: %d, updating: %d", i, j); #endif - m_needsUpdating.insert(j); + m_needsUpdating.push_back(j); if (lastUpdated == false && getEffectPoints(j) == true) { - m_needsUpdating.insert(j - 1); + m_needsUpdating.push_back(j - 1); } lastUpdated = true; } @@ -3237,7 +3183,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::set* updat lastUpdated = false; } } - if (updatingEndChanged == true) + if (i < updatingEnd) { i = updatingEnd; } @@ -3249,7 +3195,7 @@ void VectorGraphDataArray::getUpdatingFromPoint(int pointLocation) // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) if (m_isDataChanged == false && pointLocation >= 0) { - m_needsUpdating.insert(pointLocation); + m_needsUpdating.push_back(pointLocation); if (m_needsUpdating.size() > m_dataArray.size() * 3) { m_isDataChanged = true; @@ -3270,19 +3216,18 @@ void VectorGraphDataArray::getUpdatingFromAutomation() #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromAutomation: point location: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); #endif - m_needsUpdating.insert(i); + m_needsUpdating.push_back(i); // if the automatable value effects the y (so the position) // the point before this is updated too if (i > 0 && getAutomatedAttribLocation(i) == 0) { - m_needsUpdating.insert(i - 1); + m_needsUpdating.push_back(i - 1); } } } } void VectorGraphDataArray::getUpdatingOriginals() { - /* // selecting only original values and sorting #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT @@ -3333,14 +3278,13 @@ void VectorGraphDataArray::getUpdatingOriginals() qDebug("getUpatingOriginals final: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); } #endif -*/ } void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::set* updatingValuesOut, std::vector* sampleBufferOut) + std::vector* updatingValuesOut, std::vector* sampleBufferOut) { bool effectorIsChanged = false; //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); - std::set effectorUpdatingValues; + std::vector effectorUpdatingValues; // sampleBufferOut will serve as the effector's sampleBufferOut until the new m_bakedSamples gets made bool isEffected = m_effectorLocation >= 0; if (isEffected == true) @@ -3401,10 +3345,10 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { m_updatingBakedSamples.resize(targetSizeIn); } - m_needsUpdating.clear(); + m_needsUpdating.resize(m_dataArray.size()); for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { - m_needsUpdating.insert(i); + m_needsUpdating[i] = i; } } @@ -3443,10 +3387,10 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh #endif // calculate final lines - for (std::set::iterator i = m_needsUpdating.begin(); i != m_needsUpdating.end(); ++i) + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) { // sampleBufferOut contains the effector m_bakedValues here - getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, *i, stepSize); + getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, i, stepSize); } m_parent->lockBakedSamplesAccess(); @@ -3479,28 +3423,28 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh #endif } void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int curPoint, float stepSize) + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) { unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[curPoint].m_x / stepSize)); + (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, curPoint, effectYLocation); + qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, m_needsUpdating[pointLocation], effectYLocation); #endif - // current effector output Y near curPoint point + // current effector output Y near m_needsUpdating[pointLocation] point float curEffectY = (*effectorSamples)[effectYLocation]; float nextEffectY = (*effectorSamples)[effectYLocation]; // getting the final automatable / effectable point values - float curY = processAutomation(curPoint, m_dataArray[curPoint].m_y, 0); - float curC = processAutomation(curPoint, m_dataArray[curPoint].m_c, 1); - float curValA = processAutomation(curPoint, m_dataArray[curPoint].m_valA, 2); - float curValB = processAutomation(curPoint, m_dataArray[curPoint].m_valB, 3); - if (effector != nullptr && getEffectPoints(curPoint) == true && getEffectLines(curPoint) == false) + float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); + float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); + float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); + float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation]) == true && getEffectLines(m_needsUpdating[pointLocation]) == false) { - curY = processEffect(curPoint, curY, 0, curEffectY); - curC = processEffect(curPoint, curC, 1, curEffectY); - curValA = processEffect(curPoint, curValA, 2, curEffectY); - curValB = processEffect(curPoint, curValB, 3, curEffectY); + curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); + curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); + curValA = processEffect(m_needsUpdating[pointLocation], curValA, 2, curEffectY); + curValB = processEffect(m_needsUpdating[pointLocation], curValB, 3, curEffectY); } // from where to update line int start = effectYLocation; @@ -3508,26 +3452,26 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, float nextY = curY; - if (curPoint + 1 < m_dataArray.size()) + if (m_needsUpdating[pointLocation] + 1 < m_dataArray.size()) { effectYLocation = static_cast - (std::ceil(m_dataArray[curPoint + 1].m_x / stepSize)); + (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); // where updating line ends (+1) end = effectYLocation; - nextY = processAutomation(curPoint + 1, m_dataArray[curPoint + 1].m_y, 0); + nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); - bool isCurEffected = isEffectedPoint(curPoint); + bool isCurEffected = isEffectedPoint(m_needsUpdating[pointLocation]); // if the next point (y location) can be effected // and the current point's line is uneffected - if (effector != nullptr && getEffectPoints(curPoint + 1) == true && - (getEffectLines(curPoint) == false || isCurEffected == false)) + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation] + 1) == true && + (getEffectLines(m_needsUpdating[pointLocation]) == false || isCurEffected == false)) { nextEffectY = (*effectorSamples)[effectYLocation]; - nextY = processEffect(curPoint + 1, nextY, 0, nextEffectY); + nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); } } // calculating line ends - if (curPoint + 1 >= m_dataArray.size()) + if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray for (int j = end; j < m_updatingBakedSamples.size(); j++) @@ -3535,7 +3479,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, m_updatingBakedSamples[j] = curY; } } - if (curPoint == 0) + if (m_needsUpdating[pointLocation] == 0) { // if this point is at the 0 location in m_dataArray for (int j = 0; j < start; j++) @@ -3545,7 +3489,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, } float fadeInStart = 0.05f; - unsigned int type = m_dataArray[curPoint].m_type; + unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getSamplesUpdatinLines: point: [%d] start: %d, end: %d, line type: %d, --- attribs: y: %f, next y: %f, curve %f, valA %f, valB %f", pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); @@ -3611,15 +3555,15 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, // line type processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } - if (effector != nullptr && getEffectLines(curPoint) == true) + if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) { - int startB = curPoint == 0 ? 0 : start; - int endB = curPoint >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; // process line effect // if it is enabled for (int j = startB; j < endB; j++) { - m_updatingBakedSamples[j] = processEffect(curPoint, m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); } } // clamp @@ -3636,8 +3580,8 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, } if (m_isNonNegative == true) { - int startB = curPoint == 0 ? 0 : start; - int endB = curPoint >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; for (int j = startB; j < endB; j++) { m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; From c31d11fc43f4825f24a047b7d56d89f909ac9f98 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:12:03 +0200 Subject: [PATCH 146/184] VectorGraph_fixed_updating_bug --- src/gui/widgets/VectorGraph.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1c22ee3e609..753210a04d6 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -45,7 +45,7 @@ #include "ProjectJournal.h" //#define VECTORGRAPH_DEBUG_USER_INTERACTION -//#define VECTORGRAPH_DEBUG_PAINT_EVENT +#define VECTORGRAPH_DEBUG_PAINT_EVENT namespace lmms { @@ -3591,18 +3591,8 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, bool VectorGraphDataArray::isEffectedPoint(unsigned int pointLocation) { - // loops througth all the effects // return true when 1 or more effects are active - bool output = false; - for (unsigned int i = 0; i <= 8; i++) - { - if (getEffect(pointLocation, i) == true) - { - output = true; - break; - } - } - return output; + return (getEffect(pointLocation, 0) + getEffect(pointLocation, 1) + getEffect(pointLocation, 2)) != 0; } void VectorGraphDataArray::formatDataArrayEndPoints() { From ff64842aa826d9b388359d232ffb3862e9593a05 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:16:09 +0200 Subject: [PATCH 147/184] VectorGraph_commented_define --- src/gui/widgets/VectorGraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 753210a04d6..1b97335ab2d 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -45,7 +45,7 @@ #include "ProjectJournal.h" //#define VECTORGRAPH_DEBUG_USER_INTERACTION -#define VECTORGRAPH_DEBUG_PAINT_EVENT +//#define VECTORGRAPH_DEBUG_PAINT_EVENT namespace lmms { From ec1abd2b31dc3904ffbbf7b187a8ba6cac4d5567 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Fri, 28 Jun 2024 20:45:24 +0200 Subject: [PATCH 148/184] VectorGraph_close_editing_window_when_control_dialog_is_opened --- src/gui/widgets/VectorGraph.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp index 1b97335ab2d..e62f1aa82ca 100644 --- a/src/gui/widgets/VectorGraph.cpp +++ b/src/gui/widgets/VectorGraph.cpp @@ -905,6 +905,7 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i { if (pressLocation == 0) { + m_isEditingActive = false; m_controlDialog->show(); if (m_isSelected == true) { @@ -3057,6 +3058,16 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) { + /* + * here m_needsUpdating points are decided + * firstly we get changed points from the effector graph (updatingPointLocations) + * we get a segment consisting of changed effector points that come after each other + * this will be useful because we can update the current graph's points between this segment (segment start = i, segment end = updatingEnd) + * secondly we get a (current graph's) point before the segment start and after the segment end + * so we get locationBefore and locationAfter which will be added to m_needsUpdating + * thirdly we finalyze locationBefore and locationAfter, clamp them and start adding the points between them to m_needsUpdating + * if the (current graph's) point is not effected, we avoid adding it to m_needsUpdating + */ VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); for (unsigned int i = 0; i < updatingPointLocations->size(); i++) { @@ -3087,6 +3098,8 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up } } // getting the point that comes after updatingEnd + // this is done because updatingEnd was changed so the line directly after updatingEnd point was changed + // so every (current graph's) point before updatingEnd + 1 needs to be changed int updatingEndSlide = 0; if (updatingEnd + 1 < effector->size()) { From 3ee7e3515e64773491f42554b979adf87bbc01b3 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:13:45 +0200 Subject: [PATCH 149/184] VectorGraph_file_renamed --- include/VectorGraph.h | 757 ------- src/gui/widgets/VectorGraph.cpp | 3636 ------------------------------- 2 files changed, 4393 deletions(-) delete mode 100644 include/VectorGraph.h delete mode 100644 src/gui/widgets/VectorGraph.cpp diff --git a/include/VectorGraph.h b/include/VectorGraph.h deleted file mode 100644 index 639ef2d7a82..00000000000 --- a/include/VectorGraph.h +++ /dev/null @@ -1,757 +0,0 @@ -/* - * VecorGraph.h - Vector graph widget and model implementation - * - * Copyright (c) 2024 szeli1 TODO - * - * 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 LMMS_GUI_VECTORGRAPH_H -#define LMMS_GUI_VECTORGRAPH_H - -#include -#include -#include -#include -#include -#include -#include - -#include "VectorGraphViewBase.h" -#include "Model.h" -#include "ModelView.h" -#include "lmms_basics.h" -#include "AutomatableModel.h" -#include "JournallingObject.h" -#include "SubWindow.h" - -namespace lmms -{ - -//class VectorGraphViewBase; -class VectorGraphView; -class VectorGraphModel; -class VectorGraphDataArray; -class FloatModel; - -using PointF = std::pair; -using PointInt = std::pair; - -namespace gui -{ -class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView -{ - Q_OBJECT - // set default VectorGraph css colors and styles - Q_PROPERTY(QColor vectorGraphDefaultAutomatedColor MEMBER m_vectorGraphDefaultAutomatedColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphDefaultLineColor MEMBER m_vectorGraphDefaultLineColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphDefaultActiveColor MEMBER m_vectorGraphDefaultActiveColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphDefaultFillColor MEMBER m_vectorGraphDefaultFillColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor NOTIFY changedDefaultColors) - Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor NOTIFY changedDefaultColors) - - Q_PROPERTY(int fontSize MEMBER m_fontSize) -public: - - VectorGraphView(QWidget* parent, int widgetWidth, int widgetHeight, unsigned int pointSize, - unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors); - ~VectorGraphView(); - - void setLineColor(QColor color, unsigned int dataArrayLocation); - void setActiveColor(QColor color, unsigned int dataArrayLocation); - void setFillColor(QColor color, unsigned int dataArrayLocation); - void setAutomatedColor(QColor color, unsigned int dataArrayLocation); - void applyDefaultColors(); - void setPointSize(unsigned int pointSize); - void setControlHeight(unsigned int controlHeight); - void setControlDisplayCount(unsigned int controlDisplayCount); - - - inline VectorGraphModel* model() - { - return castModel(); - } - - - // draws estimated line, does not call getSamples() - // does not fill graphs with VectorGraphDataArray FillColor - void setIsSimplified(bool isSimplified); - bool getIsSimplified(); - - // returns -1.0f at .first when nothing is selected - PointF getSelectedData(); - // returns -1 it can not return an array location - int getLastSelectedArray(); - // sets the position of the currently selected point - void setSelectedData(PointF data); - // sets the background pixmap - void setBackground(const QPixmap backgound); - - // if this function is called - // paintEvent will not call getSamples() (optimization) - // insted calls getLastSamples - // resets after every paint event - void useGetLastSamples(); -signals: - // emited after paintEvent - void drawn(); - void changedDefaultColors(); -protected: - void paintEvent(QPaintEvent* pe) override; - void mousePressEvent(QMouseEvent* me) override; - void mouseMoveEvent(QMouseEvent* me) override; - void mouseReleaseEvent(QMouseEvent* me) override; - void mouseDoubleClickEvent(QMouseEvent* me) override; - - void leaveEvent(QEvent *event) override; -protected slots: - void updateGraph(); - void updateGraph(bool shouldUseGetLastSamples); - void updateDefaultColors(); -private: - void paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer); - void paintEditing(QPainter* p); - - void modelChanged() override; - - // utility - // calculate graph coords from screen space coords - PointF mapMousePos(int x, int y); - // calculate gui curve point's position - PointF mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); - PointInt mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); - // calculate screen space coords from graph coords - // isNonNegative can only be true when graph line / getSamples() is mapped - PointInt mapDataPos(float x, float y, bool isNonNegative); - // map where each Control is displayed when m_isEdtitingActive is true - int mapControlInputX(float inputValue, unsigned int displayLength); - - float getDistance(int xA, int yA, int xB, int yB); - float getDistanceF(float xA, float yA, float xB, float yB); - - // adds point to the selected VectorGraphDataArray - bool addPoint(unsigned int arrayLocation, int mouseX, int mouseY); - - // editing menu / controls - // returns true if the graph was clicked - bool isGraphPressed(int mouseY); - // returns true if the control window was clicked while in editing mode - bool isControlWindowPressed(int mouseY); - void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving); - // returns -1 if no control / input was clicked - // returns displayed absolute control / input location based on inputCount - int getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount); - // returns a float attrib value - float getInputAttribValue(unsigned int controlArrayLocation); - // sets the selected point's attrib (controlArrayLocation) to floatValue - void setInputAttribValue(unsigned int controlArrayLocation, float floatValue); - // calculates the ideal text color - QColor getTextColorFromBaseColor(QColor baseColor); - // calculates a replacement background fill color - QColor getFillColorFromBaseColor(QColor baseColor); - - SubWindow* m_controlDialog; - - // selection - // searches VectorGraphDataArray-s to select - // near clicked location - void selectData(int mouseX, int mouseY); - // searches for point in a given VectorGraphDataArray - // returns found location, when a point - // was found in the given distance - // else it returns -1 - int searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved); - - // if the mouse is not moved - bool m_mousePress; - // decides addition or deletion - bool m_addition; - - // radius, rx = ry - unsigned int m_pointSize; - unsigned int m_fontSize; - // draw simplified lines - bool m_isSimplified; - // true when applyDefaultColors is called, used when defaultColors are loading - bool m_isDefaultColorsApplyed; - QPixmap m_background; - // for 1 draw, it will use the VectorGraphDataArray - // m_bakedSamples without calling getSamples() - bool m_useGetLastSamples; - - // if m_isLastSelectedArray == true then - // m_selectedArray can be used - // else if m_isSelected == false then - // m_selectedLocation and m_selectedArray should not be used - unsigned int m_selectedLocation; - unsigned int m_selectedArray; - bool m_isSelected; - bool m_isCurveSelected; - // if m_selectedArray was the last array selected - bool m_isLastSelectedArray; - - unsigned int m_graphHeight; - unsigned int m_controlHeight; - // displayed control count (+1 because of the ">>" button in editing mode) - unsigned int m_controlDisplayCount; - bool m_isEditingActive; - const std::array m_controlText = - { - tr("edit point"), tr("switch graph") - }; - - PointInt m_lastTrackPoint; - PointInt m_lastScndTrackPoint; - - // default VectorGraphDataArray colors - // applyed in constructor - QColor m_vectorGraphDefaultAutomatedColor; - - QColor m_vectorGraphDefaultLineColor; - QColor m_vectorGraphDefaultActiveColor; - QColor m_vectorGraphDefaultFillColor; - QColor m_vectorGraphSecondaryLineColor; - QColor m_vectorGraphSecondaryActiveColor; - QColor m_vectorGraphSecondaryFillColor; - - friend class lmms::gui::VectorGraphCotnrolDialog; -}; - -} // namespace gui - -class LMMS_EXPORT VectorGraphModel : public Model, public JournallingObject -{ -Q_OBJECT -public: - VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed); - ~VectorGraphModel(); - - inline size_t getDataArraySize() - { - return m_dataArrays.size(); - } - inline VectorGraphDataArray* getDataArray(unsigned int arrayLocation) - { - return &m_dataArrays[arrayLocation]; - } - inline unsigned int getMaxLength() - { - return m_maxLength; - } - inline void setMaxLength(unsigned int arrayMaxLength) - { - if (m_maxLength != arrayMaxLength) - { - m_maxLength = arrayMaxLength; - emit dataChanged(); - emit updateGraphView(false); - } - } - // returns added VectorGraphDataArray location - unsigned int addDataArray(); - // deletes VectorGraphDataArray at arrayLocation - // preservs the order - void deleteDataArray(unsigned int arrayLocation); - inline void clearDataArray() - { - m_dataArrays.clear(); - emit dataChanged(); - emit updateGraphView(false); - } - // if the id is not found then it will return 0 - int getDataArrayLocationFromId(int arrayId); - int getDataArrayNewId(); - - // save, load - QString nodeName() const override - { - return "VectorGraphModel"; - } - virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); - virtual void loadSettings(const QDomElement& element, const QString& name); - virtual void saveSettings(QDomDocument& doc, QDomElement& element); - virtual void loadSettings(const QDomElement& element); - void lockGetSamplesAccess(); - void unlockGetSamplesAccess(); - void lockBakedSamplesAccess(); - void unlockBakedSamplesAccess(); -signals: - // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed - void dataChanged(); - void updateGraphView(bool shouldUseGetLastSamples); - // signals when a dataArray gets to 0 element size - // arrayLocation is the location of the VectorGraphDataArray - // arrayLocation can be -1 - void clearedEvent(int arrayLocation); - // style changed inside m_dataArray - void styleChanged(); -public slots: - void dataArrayChanged(); - void updateGraphModel(bool shouldUseGetLastSamples); - void dataArrayClearedEvent(int arrayId); - void dataArrayStyleChanged(); -private: - // addJournalCheckpoint - void modelAddJournalCheckPoint(); - - std::vector m_dataArrays; - unsigned int m_maxLength; - - // block threads that want to access - // a dataArray's getSamples() at the same time - QMutex m_getSamplesAccess; - QMutex m_bakedSamplesAccess; - friend class lmms::gui::VectorGraphView; -}; - -class LMMS_EXPORT VectorGraphDataArray -{ - -public: - // avoid using this or run updateConnections() after initialization - VectorGraphDataArray(); - VectorGraphDataArray( - bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, - bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parent, int arrayId); - ~VectorGraphDataArray(); - - void updateConnections(VectorGraphModel* parent); - - // see descriptions in privete - void setIsFixedSize(bool bValue); - void setIsFixedX(bool bValue); - void setIsFixedY(bool bValue); - void setIsFixedEndPoints(bool bValue); - void setIsSelectable(bool bValue); - void setIsEditableAttrib(bool bValue); - void setIsAutomatableEffectable(bool bValue); - void setIsSaveable(bool bValue); - void setIsNonNegative(bool bValue); - void setLineColor(QColor color); - void setActiveColor(QColor color); - void setFillColor(QColor color); - void setAutomatedColor(QColor color); - - // sets a dataArray as an effector to this dataArray - // returns true if successful - // if callDataChanged then it will call dataChanged() --> paintEvent() - bool setEffectorArrayLocation(int arrayLocation, bool callDataChanged); - void setIsAnEffector(bool bValue); - - bool getIsFixedSize(); - bool getIsFixedX(); - bool getIsFixedY(); - bool getIsFixedEndPoints(); - bool getIsSelectable(); - bool getIsEditableAttrib(); - bool getIsAutomatableEffectable(); - bool getIsSaveable(); - bool getIsNonNegative(); - QColor* getLineColor(); - QColor* getActiveColor(); - QColor* getFillColor(); - QColor* getAutomatedColor(); - // returns -1 if it has no effector - - int getEffectorArrayLocation(); - bool getIsAnEffector(); - int getId(); - - - // array: ------------------- - // checks m_isFixedSize (== false) and m_maxLength - // returns the location of added point, -1 if not found or can not be added - // returns the location of found point if there is a point already at newX - int add(float newX); - // checks m_isFixedSize (== false) - // deletes the point in pointLocation location - void deletePoint(unsigned int pointLocation); - // clears m_dataArray without any checks - inline void clear() - { - m_dataArray.clear(); - m_needsUpdating.clear(); - // m_automationModelArray should not be cleared without FloatModel destruction - clearedEvent(); - getUpdatingFromPoint(-1); - dataChanged(); - } - inline size_t size() - { - return m_dataArray.size(); - } - // clamps down the values to 0 - 1, -1 - 1 - // sorts array, removes duplicated x positions, calls dataChanged() if callDataChanged - // clamp: should clamp, sort: should sort - void formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); - - - // get attribute: ------------------- - inline float getX(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_x; - } - inline float getY(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_y; - } - inline float getC(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_c; - } - inline float getValA(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_valA; - } - inline float getValB(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_valB; - } - inline unsigned int getType(unsigned int pointLocation) - { - return m_dataArray[pointLocation].m_type; - } - // returns attribLocation: 0 = m_y, 1 = m_c, 2 = m_valA, 3 = m_valB (int VectorGraphPoint) - unsigned int getAutomatedAttribLocation(unsigned int pointLocation); - unsigned int getEffectedAttribLocation(unsigned int pointLocation); - // returns true when m_effectPoints is true or - // when getEffectedAttribLocation() > 0 (y is uneffected) - bool getEffectPoints(unsigned int pointLocation); - // returns true when m_effectLines is true and - // when getEffectedAttribLocation() == 0 (y is effected) - bool getEffectLines(unsigned int pointLocation); - // returns the effect type of the selected id or slot - // effectSlot: which effect slot (m_effectTypeA / B / C) - unsigned int getEffect(unsigned int pointLocation, unsigned int effectSlot); - // true when the automationModel's value changed since last check - bool getIsAutomationValueChanged(unsigned int pointLocation); - // can return nullptr - FloatModel* getAutomationModel(unsigned int pointLocation); - - - // get: ------------------- - // returns -1 when position is not found - int getLocation(float searchX); - // gets the nearest data location to the position, - // foundOut is true when the nearest position = searchXIn, - // reurns -1 when search failed - int getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut); - - - // returns the latest updated graph values - // targetSizeIn is the retuned vector's size - void getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut); - // returns m_bakedSamples without updating - void getLastSamples(std::vector* sampleBufferOut); - std::vector getEffectorArrayLocations(); - - - // set: ------------------- - // sets / adds m_dataArray points - // .first = x, .second = y coords - // isCurved -> should set curve automatically - // clear -> clear m_dataArray before setting - // clamp -> clamp input positions - // rescale -> scale input positions - // sort -> sort input positions - // callDataChanged -> call dataChanged() after -> paintEvent() - // PointF = std::pair - // ()the std::vector* inputDataArray modifies the array) - void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); - void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); - void setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); - - - // set attribute: ------------------- - // checks m_isFixedX (== false) - // sets x position, returns final location - // returns the location of found point if there is a point already at newX - unsigned int setX(unsigned int pointLocation, float newX); - // checks m_isFixedY (== false) - // sets y position - void setY(unsigned int pointLocation, float newY); - // checks m_isEditableAttrib - // sets curve - void setC(unsigned int pointLocation, float newC); - // checks m_isEditableAttrib - // sets 1. attribute value - void setValA(unsigned int pointLocation, float fValue); - // checks m_isEditableAttrib - // sets 2. attribute value - void setValB(unsigned int pointLocation, float fValue); - // checks m_isEditableAttrib - // sets line type - void setType(unsigned int pointLocation, unsigned int newType); - // checks m_isAutomatableEffectable and m_isEditableAttrib - // sets what attribute gets automated (by point's FloatModel) - void setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation); - // checks m_isAutomatableEffectable and m_isEditableAttrib - // sets what attribute gets effected (by effector array) - void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); - // checks m_isAutomatableEffectable and m_isEditableAttrib - // if bValue is true then the effector array will effect the point's attributes - void setEffectPoints(unsigned int pointLocation, bool bValue); - // checks m_isAutomatableEffectable and m_isEditableAttribs - // if bValue is true then the effector array will effect the line's individual samples (only when y is effected) - void setEffectLines(unsigned int pointLocation, bool bValue); - // checks m_isAutomatableEffectable and m_isEditableAttrib - // sets the point's effect type - // effectSlot: which effect slot (m_effectTypeA / B / C), effectType: what kind of effect (add, exct) - void setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType); - // checks m_isAutomatableEffectable - // if bValue is true then make a new FloatModel and connect it, else delete - // the currently used FloatModel - void setAutomated(unsigned int pointLocation, bool bValue); - - -// signals: // not qt - void dataChanged(); - // runs when m_dataArray.size() gets to 0 - void clearedEvent(); - // color - void styleChanged(); -private: - // returns m_automationModelArray - std::vector* getAutomationModelArray(); - // delete automationModels in m_automationModelArray - // that are not used by points (there should be 0 cases like this) - void deleteUnusedAutomation(); - // encodes m_dataArray to QString - QString getSavedDataArray(); - // decodes and sets m_dataArray from QString - void loadDataArray(QString data, unsigned int arraySize, bool callDataChanged); - - class VectorGraphPoint - { - public: - inline VectorGraphPoint() - { - } - inline VectorGraphPoint(float x, float y) - { - m_x = x; - m_y = y; - } - // 0 - 1 - float m_x = 0.0f; - // -1 - 1, getAutomatedAttrib() -> 0 - float m_y = 0.0f; - // curve, -1 - 1, getAutomatedAttrib() -> 1 - float m_c = 0.0f; - // valueA, -1 - 1, getAutomatedAttrib() -> 2 - float m_valA = 0.0f; - // valueB, -1 - 1, getAutomatedAttrib() -> 3 - float m_valB = 0.0f; - // line type: - // 0 - none - // 1 - sine - // 2 - sineB - // 3 - peak - // 4 - steps - // 5 - random - unsigned int m_type = 0; - // the automated attrib location and - // the effected attrib location is - // stored here - // use getAutomatedAttrib or getEffectedAttrib to get it - unsigned int m_automatedEffectedAttribLocations = 0; - - // what effect will be applyed if effected - // effects: - // 0 - none - // 1 - add - // 2 - subtract - // 3 - multiply - // 4 - divide - // 5 - power - // 6 - log - // 7 - sine - // 8 - lower clamp - // 9 - upper clamp - unsigned int m_effectTypeA = 0; - unsigned int m_effectTypeB = 0; - unsigned int m_effectTypeC = 0; - - // if the point attributes should be effected, - // getEffectPoints() will return true when - // effected attrib location > 0 - bool m_effectPoints = false; - // if the line (each sample) should be effected (only works when y is effected) - bool m_effectLines = true; - - /* - bool m_effectAdd = false; - bool m_effectSubtract = false; - bool m_effectMultiply = false; - bool m_effectDivide = false; - bool m_effectPower = false; - bool m_effectLog = false; - bool m_effectSine = false; - bool m_effectClampLower = false; - bool m_effectClampUpper = false; - */ - - // stores m_automationModel->value(), used in getSamples() when updating - float m_bufferedAutomationValue = 0.0f; - // automation: connecting to floatmodels, -1 when it isn't conntected - int m_automationModel = -1; - }; - // deletes the point's automation model - // if modelLocation == point location - void deleteAutomationModel(int modelLocation, bool callDataChanged); - // swapping values, "shouldShiftBetween" moves the values (between) once left or right to keep the order - // handle m_isFixedEndPoints when using this - void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween); - // returns the curve value at a given x coord, does clamp - float processCurve(float yBefore, float yAfter, float curve, float xIn); - // returns effected attribute value from base attribValue (input attribute value), does clamp - // this function applies the point Effects (like add effect) based on attribValue and effectValue - float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); - float processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, float attribValue, float effectValue); - // returns automated attribute value from base attribValue (input attribute value), does clamp - float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); - - // line types, m_type is used for this - // fadeInStartVal: from what relative x value should the line type fade out - // linking: valA: sineAmp, valB: sineFreq - void processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float fadeInStartVal); - // linking: valA: sineAmp, valB: sineFreq, curve: sinePhase - void processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal); - // linking: valA: amp, valB: x coord, curve: width - void processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float peakAmp, float peakX, float peakWidth, float fadeInStartVal); - // linking: y: yArray, valA: stepCount, valB: stepCurve - void processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal); - // linking: valA: randomAmp, valB: randomCount, curve: randomSeed - void processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float randomAmp, float randomCount, float randomSeed, float fadeInStartVal); - - // updating - // adds the m_dataArray points that are - // effected by the changed effector array points. - // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::vector* updatingPointLocations); - // if pointLocation >= 0 -> adds the location to m_needsUpdating - // else it will update the whole m_dataArray and m_bakedSamples - // changes in the size of m_dataArray (addtition, deletion, ect.) - // should to cause a full update - void getUpdatingFromPoint(int pointLocation); - // adds the points that are changed because their - // automation is changed - void getUpdatingFromAutomation(); - // recalculates and sorts m_needsUpdating so - // every point is in there only once - void getUpdatingOriginals(); - - // real getSamples processing - void getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::vector* updatingValuesOut, std::vector* sampleBufferOut); - // redraw lines - void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int pointLocation, float stepSize); - bool isEffectedPoint(unsigned int pointLocation); - - // checks m_isFixedEndPoints, does not call dataChanged() - void formatDataArrayEndPoints(); - - // can new data be added or removed - bool m_isFixedSize; - // can the positions be changed - bool m_isFixedX; - // can the values be changed - bool m_isFixedY; - // if true then it makes the last point coordinate 1, 1, the first point coordinate -1, 0 - bool m_isFixedEndPoints; - // can VectorGraphView select this - bool m_isSelectable; - // can the point attributes be edited - // every attribute outside of x and y - // automation can be changed - bool m_isEditableAttrib; - // can the points be automated or effected - // (can these settings be changed) - bool m_isAutomatableEffectable; - // if VectorGraphDataArray is allowed to save this - bool m_isSaveable; - // can values be less than 0 - bool m_isNonNegative; - - QColor m_lineColor; - QColor m_activeColor; - QColor m_fillColor; - QColor m_automatedColor; - - VectorGraphModel* m_parent; - // simple id system for setEffectorArrayLocation - int m_id; - - // which VectorGraphDataArray can effect this one, -1 if not effected - int m_effectorLocation; - // is this VectorGraphDataArray effects others? - bool m_isAnEffector; - - // ordered array of VectorGraphPoints - std::vector m_dataArray; - - - // baking - - // getSamples() will return m_bakedSamples if lines are unchanged - // else it will recalculate the changed line's values, update m_bakedSamples - // getSamples() needs to know where did lines change so it updates - // m_needsUpdating by running getUpdatingFromEffector() - // if m_isDataChanged is true, then getSamples recalculates all the lines/samples - // getSamples() clears m_needsUpdating after it has run - // updating a line means recalculating m_bakedSamples in getSamples() - // based on the changed points (stored in m_needsUpdating) - // changes in a point will causes its line to update (line started by the point) - // changes in position needs to cause the line before to update too - // addition or deletion needs to cause all the lines to update - - // if we want to update all (the full line in getSamples()) - bool m_isDataChanged; - // array containing output final float values for optimalization - std::vector m_bakedSamples; - // used for updating m_bakedSamples fast - std::vector m_updatingBakedSamples; - // unsorted array of locations in m_dataArray - // that need to be updated - // sorted in getUpdatingOriginals() because some functions need this to be sorted - std::vector m_needsUpdating; - - // this stores all the FloatModels, unsorted, should only contain currently used FloatModels - // used for automation - std::vector m_automationModelArray; - - // used in lineType calculations to store - // large amount of floats without reallocation - std::vector m_universalSampleBuffer; - - // used for saving - friend class lmms::VectorGraphModel; -}; - -} // namespace lmms - -#endif // LMMS_GUI_VECTORGRAPH_H diff --git a/src/gui/widgets/VectorGraph.cpp b/src/gui/widgets/VectorGraph.cpp deleted file mode 100644 index e62f1aa82ca..00000000000 --- a/src/gui/widgets/VectorGraph.cpp +++ /dev/null @@ -1,3636 +0,0 @@ -/* - * VectorGraph.cpp - Vector graph widget, model, helper class implementation - * - * Copyright (c) 2024 szeli1 TODO - * - * 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 "VectorGraph.h" -#include "VectorGraphViewBase.h" - -#include // sort -#include -#include // sine -#include // rand -#include -#include -#include // locking when getSamples -#include -#include - -#include "AutomatableModel.h" -#include "base64.h" -#include "ControllerConnection.h" -#include "ControllerConnectionDialog.h" -#include "GuiApplication.h" // getGUI -#include "JournallingObject.h" -#include "MainWindow.h" // getting main window for control dialog -#include "ProjectJournal.h" - -//#define VECTORGRAPH_DEBUG_USER_INTERACTION -//#define VECTORGRAPH_DEBUG_PAINT_EVENT - -namespace lmms -{ - -namespace gui -{ -VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, - unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : - VectorGraphViewBase(parent), - ModelView(new VectorGraphModel(2048, nullptr, false), this), - m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this))) -{ - resize(widgetWidth, widgetHeight); - - m_controlDialog->hide(); - Qt::WindowFlags flags = m_controlDialog->windowFlags(); - flags &= ~Qt::WindowMaximizeButtonHint; - m_controlDialog->setWindowFlags(flags); - - m_mousePress = false; - m_addition = false; - - m_pointSize = pointSize; - // gets set in style - //m_fontSize = 12; // set in css - m_isSimplified = false; - m_isDefaultColorsApplyed = false; - //m_background; - m_useGetLastSamples = false; - - m_selectedLocation = 0; - m_selectedArray = 0; - m_isSelected = false; - m_isCurveSelected = false; - m_isLastSelectedArray = false; - - m_graphHeight = height(); - m_controlHeight = controlHeight; - m_controlDisplayCount = 2; - m_isEditingActive = false; - // set in .h - //m_controlText - //m_controlLineTypeText - //m_controlIsFloat - - m_lastTrackPoint.first = -1; - m_lastTrackPoint.second = 0; - m_lastScndTrackPoint.first = 0; - m_lastScndTrackPoint.second = 0; - - setCursor(Qt::CrossCursor); - - modelChanged(); - - // connect loading of default colors to applyDefaultColors - QObject::connect(this, &VectorGraphView::changedDefaultColors, - this, &VectorGraphView::updateDefaultColors); - - if (shouldApplyDefaultVectorGraphColors == true) - { - applyDefaultColors(); - } -} -VectorGraphView::~VectorGraphView() -{ - if (m_controlDialog != nullptr) - { - delete m_controlDialog; - } -} - -void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) -{ - if (model()->getDataArraySize() > dataArrayLocation) - { - model()->getDataArray(dataArrayLocation)->setLineColor(color); - updateGraph(); - } -} -void VectorGraphView::setActiveColor(QColor color, unsigned int dataArrayLocation) -{ - if (model()->getDataArraySize() > dataArrayLocation) - { - model()->getDataArray(dataArrayLocation)->setActiveColor(color); - updateGraph(); - } -} -void VectorGraphView::setFillColor(QColor color, unsigned int dataArrayLocation) -{ - if (model()->getDataArraySize() > dataArrayLocation) - { - model()->getDataArray(dataArrayLocation)->setFillColor(color); - updateGraph(); - } -} -void VectorGraphView::setAutomatedColor(QColor color, unsigned int dataArrayLocation) -{ - if (model()->getDataArraySize() > dataArrayLocation) - { - model()->getDataArray(dataArrayLocation)->setAutomatedColor(color); - updateGraph(); - } -} -void VectorGraphView::applyDefaultColors() -{ - m_isDefaultColorsApplyed = true; - unsigned int size = model()->getDataArraySize(); - if (size > 0) - { - setLineColor(m_vectorGraphDefaultLineColor, 0); - setActiveColor(m_vectorGraphDefaultActiveColor, 0); - setFillColor(m_vectorGraphDefaultFillColor, 0); - setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); - if (size > 1) - { - setLineColor(m_vectorGraphSecondaryLineColor, 1); - setActiveColor(m_vectorGraphSecondaryActiveColor, 1); - setFillColor(m_vectorGraphSecondaryFillColor, 1); - setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 1); - } - } -} -void VectorGraphView::setPointSize(unsigned int pointSize) -{ - m_pointSize = pointSize; - updateGraph(); -} -void VectorGraphView::setControlHeight(unsigned int controlHeight) -{ - m_controlHeight = controlHeight; - updateGraph(); -} -void VectorGraphView::setControlDisplayCount(unsigned int controlDisplayCount) -{ - // TODO remove - m_controlDisplayCount = controlDisplayCount; - updateGraph(); -} - -void VectorGraphView::setIsSimplified(bool isSimplified) -{ - m_isSimplified = isSimplified; -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setIsSimplified %d", m_isSimplified); -#endif -} -bool VectorGraphView::getIsSimplified() -{ - return m_isSimplified; -} - -PointF VectorGraphView::getSelectedData() -{ - PointF output(-1.0f, 0.00); - if (m_isSelected == true) - { - output.first = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); - output.second = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); - } - return output; -} -int VectorGraphView::getLastSelectedArray() -{ - if (m_isLastSelectedArray == true) - { - return m_selectedArray; - } - return -1; -} -void VectorGraphView::setSelectedData(PointF data) -{ - if (m_isSelected == true) - { - model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, data.second); - m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, data.first); -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setSelectedData (x, y): %f, %f", data.first, data.second); -#endif - } -} -void VectorGraphView::setBackground(const QPixmap background) -{ - m_background = background; -} -void VectorGraphView::useGetLastSamples() -{ - m_useGetLastSamples = true; -} - -void VectorGraphView::mousePressEvent(QMouseEvent* me) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("\n\nmousePressEvent start ---------"); -#endif - // get position - int x = me->x(); - int y = me->y(); - m_addition = false; - m_mousePress = false; - - // a point's FloatModel might be deleted after this - // cleaning up connected Knob in the dialog - reinterpret_cast(m_controlDialog->widget())->hideAutomation(); - m_controlDialog->hide(); - if (m_isSelected == true) - { - FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - if (curFloatModel != nullptr && curFloatModel->isAutomatedOrControlled() == false) - { - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); - } - } - - if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mousePressEvent automation connecting"); -#endif - // connect to AutomationTrack - model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); - FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); - // (VectorGraphViewBase method:) - connectToAutomationTrack(me, curFloatModel, widget()); - } - else - { - if (me->button() == Qt::LeftButton) - { - // add - m_addition = true; - m_mousePress = true; - } - else if (me->button() == Qt::RightButton) - { - // delete - m_addition = false; - m_mousePress = true; - } - if (isGraphPressed(m_graphHeight - y) == true) - { - // try selecting the clicked point (if it is near) - selectData(x, m_graphHeight - y); - // avoid triggering editing window while deleting - // points are only deleted when - // m_isSelected == true -> m_isEditingActive = true - // so m_isEditingActive is set to false - if (m_isSelected == true && m_addition == false) - { - m_isEditingActive = false; - } - if (m_isSelected == true) - { - setCursor(Qt::ArrowCursor); - } - else - { - setCursor(Qt::CrossCursor); - } - } - } -} - -void VectorGraphView::mouseMoveEvent(QMouseEvent* me) -{ - // get position - // the x coord is clamped because - // m_lastTrackPoint.first < 0 is used - int x = me->x() >= 0 ? me->x() : 0; - int y = me->y(); - - bool startMoving = false; - if (m_lastTrackPoint.first < 0) - { - m_lastTrackPoint.first = m_lastScndTrackPoint.first = x; - m_lastTrackPoint.second = m_lastScndTrackPoint.second = m_graphHeight - y; - m_mousePress = true; - } - - if (m_mousePress == true) - { - // the mouse needs to move a bigger distance - // before it is registered as dragging (-> m_mousePress = false) - float curDistance = getDistance(x, m_graphHeight - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize) - { - m_mousePress = false; - startMoving = true; - - model()->modelAddJournalCheckPoint(); - } - } - - // if the mouse was not moved a lot - if (m_mousePress == true) { return; } - - if (isGraphPressed(m_lastScndTrackPoint.second) == true) - { - if (m_isSelected == true && m_addition == true) - { - if (m_isCurveSelected == false) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseMoveEvent point drag"); -#endif - // dragging point - PointF convertedCoords = mapMousePos(x, m_graphHeight - y); - convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); - convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); - setSelectedData(convertedCoords); - } - else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseMoveEvent curve drag"); -#endif - // dragging curve - PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); - float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; - curveValue = std::clamp(curveValue, -1.0f, 1.0f); - model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); - } - } - else if (m_addition == false) - { - // deleting points - float curDistance = getDistance(x, m_graphHeight - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize) - { - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = m_graphHeight - y; - m_isSelected = false; - selectData(x, m_graphHeight - y); - if (m_isSelected == true) - { - model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); - m_isSelected = false; - m_isEditingActive = false; - } - } - } - else - { - // adding points - if (startMoving == true && m_isLastSelectedArray == true) - { - // trying to add to the last selected array - addPoint(m_selectedArray, x, m_graphHeight - y); - } - float curDistance = getDistance(x, m_graphHeight - y, - m_lastTrackPoint.first, m_lastTrackPoint.second); - if (curDistance > m_pointSize) - { - // calculating angle - // getting the angle between (lastScndTrackPoint and lastTrackPoint) - // and (lastTrackPoint and x and y) - float curAngle = static_cast( - (m_lastTrackPoint.second - m_lastScndTrackPoint.second) * - (m_graphHeight - y - m_lastTrackPoint.second) + - (m_lastTrackPoint.first - m_lastScndTrackPoint.first) * - (x - m_lastTrackPoint.first)); - curAngle = std::acos(curAngle / curDistance / - getDistance(m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, - m_lastTrackPoint.first, m_lastTrackPoint.second)); - // if the angle difference is bigger than 0.3 rad - if (std::abs(curAngle) * curDistance * curDistance / static_cast(m_pointSize * m_pointSize) > 0.3f) - { - m_lastScndTrackPoint.first = m_lastTrackPoint.first; - m_lastScndTrackPoint.second = m_lastTrackPoint.second; - - if (m_isLastSelectedArray == true) - { - // trying to add to the last selected array - addPoint(m_selectedArray, x, m_graphHeight - y); - } - } - m_lastTrackPoint.first = x; - m_lastTrackPoint.second = m_graphHeight - y; - } - // else m_mousePress does not change - } - } - else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) - { - processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving); - } -} - -void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent start"); -#endif - // get position - int x = me->x(); - int y = me->y(); - // if did not drag and graph is pressed - if (m_mousePress == true && isGraphPressed(m_graphHeight - y) == true) - { - model()->modelAddJournalCheckPoint(); - // add/delete point - if (m_isSelected == false && m_addition == true) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent add point, dataArray count: %d", static_cast(model()->getDataArraySize())); -#endif - // if selection failed and addition - // get the first editable daraArray and add value - bool success = false; - if (m_isLastSelectedArray == true) - { - // trying to add to the last selected array - success = addPoint(m_selectedArray, x, m_graphHeight - y); - } - if (success == false) - { - // trying to add to all the selected arrays - for(unsigned int i = 0; i < model()->getDataArraySize(); i++) - { - success = addPoint(i, x, m_graphHeight - y); - if (success == true) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - break; - } - } - } - } - else if (m_isSelected == true && m_addition == false) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent delete point"); -#endif - // if selection was successful -> deletion - model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); - m_isSelected = false; - m_isEditingActive = false; - } - } - else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) - { - model()->modelAddJournalCheckPoint(); - processControlWindowPressed(x, m_graphHeight - y, false, false); - } - m_mousePress = false; - m_addition = false; - // reset trackpoint - m_lastTrackPoint.first = -1; - updateGraph(false); -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent end"); -#endif -} - -void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseDoubleClickEvent start"); -#endif - // get position - //int x = me->x(); - int y = me->y(); - - // if a data/sample is selected then show input dialog to change the data - if (isGraphPressed(m_graphHeight - y) == true) - { - if (m_isSelected == true && me->button() == Qt::LeftButton) - { - // display dialog - PointF curData = showCoordInputDialog(getSelectedData()); - // change data - setSelectedData(curData); - } - } -} -void VectorGraphView::leaveEvent(QEvent *event) -{ - hideHintText(); -} - -void VectorGraphView::paintEvent(QPaintEvent* pe) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("paintEvent start"); -#endif - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing, true); - - m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); - - // paint background - if (m_background.isNull() == false) - { - p.drawPixmap(0, 0, m_background); - } - - // paint outline - p.setPen(QPen(QColor(127, 127, 127, 255), 1)); - p.drawLine(0, 0, width() - 1, 0); - p.drawLine(width() - 1, 0, width() - 1, height() - 1); - p.drawLine(0, height() - 1, width() - 1, height() - 1); - p.drawLine(0, 0, 0, height() - 1); - - std::vector sampleBuffer; - - // updating the VectorGraphDataArray samples before draw - if (m_useGetLastSamples == false || m_isSimplified == true) - { - // updating arrays that do not effect other arrays first - // (this step will run getSamples() on effector arrays (-> every array will be updated about once)) - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { - if (model()->getDataArray(i)->getIsAnEffector() == false) - { - // this updates the array and its effector arrays - // with width() sample count - model()->getDataArray(i)->getSamples(width(), nullptr); - } - } - } - - // draw the updated VectorGraphDataArray samples in order - // sometimes an other getSamples() call elsewhere can - // change the sample count between updating and drawing - // causing badly drawn output (if sample count is low) - for (int i = model()->getDataArraySize() - 1; i >= 0; i--) - { - paintGraph(&p, i, &sampleBuffer); - } - - paintEditing(&p); - - m_useGetLastSamples = false; -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("paintEvent end"); -#endif - emit drawn(); -} - -void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("paintGraph start: data arrayLocation: %d", arrayLocation); -#endif - VectorGraphDataArray* dataArray = model()->getDataArray(arrayLocation); - unsigned int length = dataArray->size(); - if (length <= 0) { return; } - - p->setPen(QPen(*dataArray->getLineColor(), 2)); - p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); - - PointInt posA(0, 0); - PointInt posB(0, 0); - PointInt startPos(mapDataPos(0.0f, dataArray->getY(0), false)); - // draw line - if (m_isSimplified == false) - { - QPainterPath pt; - posA = startPos; - pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); - - // get the currently drawed VectorGraphDataArray samples - dataArray->getLastSamples(sampleBuffer); - - for (unsigned int j = 0; j < sampleBuffer->size(); j++) - { - // if nonNegative then only the dataArray output (getDataValues) - // is bigger than 0 so it matters only here - posB = mapDataPos(0, (*sampleBuffer)[j], dataArray->getIsNonNegative()); - posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); - - if (posA.first != posB.first) - { - pt.lineTo(posB.first, m_graphHeight - posB.second); - // pt replaces drawing with path - //p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - posA = posB; - } - - // final draw line, fill - if (dataArray->getFillColor()->alpha() > 0) - { - // getting the line for - // drawing later - QPainterPath ptline(pt); - pt.lineTo(width() - 1, posB.second); - pt.lineTo(width() - 1, m_graphHeight - 1); - pt.lineTo(startPos.first + 1, m_graphHeight - 1); - pt.lineTo(startPos.first + 1, startPos.second); - // draw fill - p->fillPath(pt, QBrush(*dataArray->getFillColor())); - // draw line - p->drawPath(ptline); - } - else - { - p->drawPath(pt); - } - } - - // draw points - if (dataArray->getIsSelectable() == true || m_isSimplified == true) - { - posA = startPos; - - int squareSize = m_pointSize; - - QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); - bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; - bool resetColor = false; - for (unsigned int j = 0; j < length; j++) - { - posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), false); - // draw point - if (drawPoints == true) - { - // set point color - if (dataArray->getAutomationModel(j) != nullptr) - { - // if automated - p->setPen(QPen(*dataArray->getAutomatedColor(), 2)); - p->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); - resetColor = true; - } - else if (m_isSelected == true && m_selectedArray == arrayLocation && m_selectedLocation == j) - { - // if selected - p->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); - resetColor = true; - } - - p->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); - - // reset point color - if (resetColor == true) - { - p->setPen(QPen(*dataArray->getLineColor(), 2)); - p->setBrush(Qt::NoBrush); - resetColor = false; - } - - if (j > 0) - { - if (dataArray->getIsEditableAttrib() == true) - { - PointInt posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); - p->drawRect(posC.first - squareSize / 2, - m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); - } - } - } - - // draw simplified line - if (m_isSimplified == true) - { - p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); - } - posA = posB; - } - } - // draw last simplified line - if (m_isSimplified == true) - { - p->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); - } -} -void VectorGraphView::paintEditing(QPainter* p) -{ - p->setFont(QFont("Arial", m_fontSize)); - if (m_isEditingActive == true) - { - VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); - QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); - // background of float values - QColor foreColor = *dataArray->getLineColor(); - if (dataArray->getFillColor()->alpha() > 0) - { - foreColor = *dataArray->getFillColor(); - } - - int controlTextCount = m_controlText.size(); - if (dataArray->getIsEditableAttrib() == false) - { - // x, y - controlTextCount = 2; - } - else if (dataArray->getIsAutomatableEffectable() == false) - { - // x, y, curve, valA, valB, switch type - controlTextCount = 6; - } - - int segmentLength = width() / (m_controlDisplayCount); - // draw inputs - p->setPen(QPen(textColor, 1)); - for (unsigned int i = 0; i < m_controlDisplayCount; i++) - { - QColor curForeColor = *dataArray->getFillColor(); - p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); - p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, m_controlText[i]); - } - - // draw outline - p->setPen(QPen(*dataArray->getLineColor(), 1)); - p->drawLine(0, m_graphHeight, width(), m_graphHeight); - for (unsigned int i = 1; i < m_controlDisplayCount; i++) - { - if (i < controlTextCount || i >= m_controlDisplayCount) - { - p->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); - } - } - } - if (m_isLastSelectedArray == true) - { - // draw selected array number - p->setPen(QPen(QColor(127, 127, 127, 255), 2)); - p->drawText(2, (m_controlHeight - m_fontSize) / 2 + m_fontSize, QString::number(m_selectedArray)); - } -} - -void VectorGraphView::modelChanged() -{ - auto gModel = model(); - QObject::connect(gModel, SIGNAL(updateGraphView(bool)), - this, SLOT(updateGraph(bool))); - QObject::connect(gModel, SIGNAL(styleChanged()), - this, SLOT(updateGraph())); -} - -void VectorGraphView::updateGraph() -{ - update(); -} -void VectorGraphView::updateGraph(bool shouldUseGetLastSamples) -{ - m_useGetLastSamples = shouldUseGetLastSamples; - update(); -} -void VectorGraphView::updateDefaultColors() -{ - if (m_isDefaultColorsApplyed == true) - { - applyDefaultColors(); - } -} - -PointF VectorGraphView::mapMousePos(int x, int y) -{ - // mapping the position to 0 - 1, -1 - 1 using qWidget width and height - return PointF( - static_cast(x / static_cast(width())), - static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); -} -PointInt VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) -{ - // mapping the point/sample positon to mouse/view position - if (isNonNegative == true) - { - return PointInt( - static_cast(x * width()), - static_cast(y * m_graphHeight)); - } - else - { - return PointInt( - static_cast(x * width()), - static_cast((y + 1.0f) * static_cast(m_graphHeight) / 2.0f)); - } -} -PointF VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve) -{ - return PointF( - (xA + xB) / 2.0f, - yA + (curve / 2.0f + 0.5f) * (yB - yA)); -} -PointInt VectorGraphView::mapDataCurvePos(int xA, int yA, int xB, int yB, float curve) -{ - return PointInt( - (xA + xB) / 2, - yA + static_cast((curve / 2.0f + 0.5f) * (yB - yA))); -} -int VectorGraphView::mapControlInputX(float inputValue, unsigned int displayLength) -{ - return (inputValue / 2.0f + 0.5f) * displayLength; -} - -float VectorGraphView::getDistance(int xA, int yA, int xB, int yB) -{ - return std::sqrt(static_cast((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB))); -} -float VectorGraphView::getDistanceF(float xA, float yA, float xB, float yB) -{ - return std::sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB)); -} - -bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouseY) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("addPoint: arrayLocation: %d, position (x, y): %d, %d", arrayLocation, mouseX, mouseY); -#endif - // mouseY is calculated like this: - // m_graphHeight - y - bool output = false; - PointF curMouseCoords = mapMousePos(mouseX, mouseY); - curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); - curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); - int location = model()->getDataArray(arrayLocation)->add(curMouseCoords.first); - - // if adding was not successful - if (location < 0) { return output; } - - output = true; - model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("addPoint: point location: %d, positionF (x, y): %f, %f, new dataArray size: %d", - location, curMouseCoords.first, curMouseCoords.second, static_cast(model()->getDataArray(arrayLocation)->size())); -#endif - return output; -} - -bool VectorGraphView::isGraphPressed(int mouseY) -{ - return !isControlWindowPressed(mouseY); -} -bool VectorGraphView::isControlWindowPressed(int mouseY) -{ - bool output = false; - // mouseY is calculated like this: - // m_graphHeight - y - if (m_isEditingActive == true && mouseY <= 0) - { - output = true; - } - return output; -} -void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving) -{ - // mouseY is calculated like this: - // m_graphHeight - y - setCursor(Qt::ArrowCursor); - -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d", mouseX, mouseY, isDragging, startMoving); -#endif - - if (m_isEditingActive == false) { return; } - - int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount); -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("processControlWindowPressed: pressLocation: %d", pressLocation); -#endif - if (isDragging == false || (isDragging == true && startMoving == false)) - { - if (pressLocation == 0) - { - m_isEditingActive = false; - m_controlDialog->show(); - if (m_isSelected == true) - { - reinterpret_cast(m_controlDialog->widget())->switchPoint(m_selectedArray, m_selectedLocation); - } - hideHintText(); - } - else if (pressLocation == 1) - { - // if the "switch graph" button was pressed in editing mode - unsigned int oldSelectedArray = m_selectedArray; - m_selectedLocation = 0; - m_selectedArray = 0; - m_isLastSelectedArray = false; - m_isSelected = false; - m_isEditingActive = false; - m_isCurveSelected = false; - - // looping throught the data arrays to get a new - // selected data array - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent select dataArray: i: [%d], m_selectedArray: %d, oldSelectedArray: %d", i, m_selectedArray, oldSelectedArray); -#endif - if (model()->getDataArray(i)->getIsSelectable() == true) - { - // if this data array is the first one that is selectable - if (m_isLastSelectedArray == false) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - } - // if this data array's location is bigger than the old location - // if this is false then m_selectedArray will equal to the first selectable array - if (i > oldSelectedArray) - { - m_selectedArray = i; - m_isLastSelectedArray = true; - break; - } - } - } -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseReleaseEvent select dataArray final: %d", m_selectedArray); -#endif - - // hint text - if (m_selectedArray != oldSelectedArray) - { - showHintText(widget(), tr("selected graph changed"), 5, 3500); - } - else - { - showHintText(widget(), tr("unable to select other graph"), 5, 3500); - } - } - } -} -int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount) -{ - int output = -1; - if (m_isEditingActive == true && mouseY > m_graphHeight) - { - output = mouseX * controlCount / width(); - } - if (output > controlCount) - { - output = controlCount; - } - return output; -} -float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation) -{ - float output = 0.0f; - if (m_isSelected == false) { return output; } - - switch (controlArrayLocation) - { - case 0: - output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); - break; - case 1: - output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); - break; - case 2: - output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); - break; - case 3: - output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); - break; - case 4: - output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); - break; - case 5: - // type - output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); - break; - case 6: - // automation location - output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); - break; - case 7: - // effect location - output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); - break; - case 8: - output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); - break; - case 9: - output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); - break; - case 10: - output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); - break; - case 11: - output = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation) ? 1.0f : 0.0f; - break; - case 12: - output = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation) ? 1.0f : 0.0f; - break; - } - return output; -} -void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setInputAttribute start: control input: %d, set floatValue: %f", controlArrayLocation, floatValue); -#endif - if (m_isSelected == false) { return; } - - float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); - unsigned int clampedValueB = 0; - switch (controlArrayLocation) - { - case 0: - m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); - break; - case 1: - model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); - break; - case 2: - model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, clampedValue); - break; - case 3: - model()->getDataArray(m_selectedArray)->setValA(m_selectedLocation, clampedValue); - break; - case 4: - model()->getDataArray(m_selectedArray)->setValB(m_selectedLocation, clampedValue); - break; - case 5: - // type - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); - model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); - break; - case 6: - // automation location - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); - model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); - break; - case 7: - // effect location - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); - model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); - break; - case 8: - clampedValueB = static_cast(floatValue); - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, clampedValueB); - break; - case 9: - clampedValueB = static_cast(floatValue); - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, clampedValueB); - break; - case 10: - clampedValueB = static_cast(floatValue); - model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, clampedValueB); - break; - case 11: - model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, floatValue >= 0.5f); - break; - case 12: - model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, floatValue >= 0.5f); - break; - } -} -QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColor) -{ - QColor output(255, 255, 255, 255); - int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); - // > 127 * 3 - if (colorSum > 382) - { - output = QColor(0, 0, 0, 255); - } - return output; -} -QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColor) -{ - QColor output; - int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); - int brighten = 0; - int alpha = baseColor.alpha(); - if (alpha == 0) - { - alpha = 255; - } - if (std::abs(colorSum - 382) > 191) - { - brighten = 45; - } - // > 127 * 3 - if (colorSum > 382) - { - // (red * 0.6f + avg * 0.4f / 3.0f) * 0.7 - output = QColor(static_cast(static_cast(baseColor.red()) * 0.42f + colorSum * 0.09f) - brighten, - static_cast(static_cast(baseColor.green()) * 0.42f + colorSum * 0.09f) - brighten, - static_cast(static_cast(baseColor.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); - } - else - { - // (red * 0.6f + avg * 0.4f / 3.0f) * 1.3 - output = QColor(static_cast(static_cast(baseColor.red()) * 0.78f + colorSum * 0.17f) + brighten, - static_cast(static_cast(baseColor.green()) * 0.78f + colorSum * 0.17f) + brighten, - static_cast(static_cast(baseColor.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); - } - return output; -} - -void VectorGraphView::selectData(int mouseX, int mouseY) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("selectData start: mouse (x, y): %d, %d", mouseX, mouseY); -#endif - - m_isSelected = false; - - // trying to select the last selected array - if (m_isLastSelectedArray == true) - { - VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); - int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); - if (location > -1) - { - m_selectedLocation = location; - // m_selectedArray - do not set - m_isSelected = true; - m_isCurveSelected = false; - m_isEditingActive = true; - } - } - - if (m_isSelected == false) - { - m_selectedLocation = 0; - // m_selectedArray can not be set to 0 in case of - // m_isLastSelectedArray is active - // m_selectedArray = 0; - do not reset - m_isSelected = false; - m_isCurveSelected = false; - m_isEditingActive = false; - //m_isLastSelectedArray = false; - - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { - VectorGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getIsSelectable() == true) - { - int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); - if (location > -1) - { - m_selectedLocation = location; - m_selectedArray = i; - m_isSelected = true; - m_isCurveSelected = false; - m_isLastSelectedArray = true; - m_isEditingActive = true; - break; - } - } - } - if (m_isSelected == false) - { - for (unsigned int i = 0; i < model()->getDataArraySize(); i++) - { - VectorGraphDataArray* dataArray = model()->getDataArray(i); - if (dataArray->getIsSelectable() == true) - { - int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, true); - if (location > -1) - { - m_selectedLocation = location; - m_selectedArray = i; - m_isSelected = true; - m_isCurveSelected = true; - m_isLastSelectedArray = true; - m_isEditingActive = true; - break; - } - } - } - } - } -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("selectData end: m_selectedArray: %d, m_selectedLocation %d", m_selectedArray, m_selectedLocation); -#endif -} - -int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved) -{ - int output = -1; - maxDistance = maxDistance * 2.0f; - - PointF transformedMouse = mapMousePos(mouseX, mouseY); - - // unused bool - bool found = false; - bool isBefore = false; - // get the nearest data to the mouse pos (x) in an optimalized way - int location = dataArray->getNearestLocation(transformedMouse.first, &found, &isBefore); - - // if getNearestLocation was not successful - if (location < 0) { return output; } - - float dataX = dataArray->getX(location); - float dataY = dataArray->getY(location); - // this is set to one when isCurved == true - // and isBefore == false - int curvedBefore = 0; - // if isCurved then get the closest curved coord - if (isCurved == true && dataArray->size() > 1) - { - if (isBefore == false && 1 < location) - { - curvedBefore = 1; - } - if (location - curvedBefore < dataArray->size() - 1) - { - PointF curvedDataCoords = mapDataCurvePosF( - dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), - dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), - dataArray->getC(location - curvedBefore)); - dataX = curvedDataCoords.first; - dataY = curvedDataCoords.second; - } - } - // check distance against x coord - if (std::abs(dataX - transformedMouse.first) <= maxDistance) - { - // calculate real distance (x and y) - float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, - dataX * 2.0f, dataY); - - if (curDistance <= maxDistance) - { - output = location - curvedBefore; - } - else - { - // sometimes the mouse x and the nearest point x - // coordinates are close but the y coords are not - // calculating and testing all near by point distances - int searchStart = 0; - int searchEnd = dataArray->size() - 1; - // from where we need to search the data - for (int i = location - curvedBefore - 1; i > 0; i--) - { - if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) - { - // if it is isCurved, then subtract 1 - // add 1 to i because [i] > maxDistance - searchStart = i + 1 - (i > 0 && isCurved == true ? 1 : 0); - break; - } - } - // getting where the search needs to end - for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) - { - if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) - { - searchEnd = i - 1 - (i > 0 && isCurved == true ? 1 : 0); - break; - } - } - // calculating real distances from the point coords - for (int i = searchStart; i <= searchEnd; i++) - { - if (i != location) - { - dataX = dataArray->getX(i); - dataY = dataArray->getY(i); - if (isCurved == true && dataArray->size() > 1) - { - if (dataArray->size() - 1 > i) - { - PointF curvedDataCoords = mapDataCurvePosF( - dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), - dataArray->getC(i)); - dataX = curvedDataCoords.first; - dataY = curvedDataCoords.second; - } - } - curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, - dataX * 2.0f, dataY); - if (curDistance <= maxDistance) - { - output = i; - break; - } - } - } - } - } - return output; -} - -} // namespace gui - -VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed) : - Model(parent, tr("VectorGraphModel"), defaultConstructed) -{ - m_maxLength = arrayMaxLength; - //m_dataArrays -} - -VectorGraphModel::~VectorGraphModel() -{ - m_dataArrays.clear(); -} - -unsigned int VectorGraphModel::addDataArray() -{ - VectorGraphDataArray tempArray( - false, false, false, false, false, false, false, - false, true, this, getDataArrayNewId()); - m_dataArrays.push_back(tempArray); - emit dataChanged(); - return m_dataArrays.size() - 1; -} - -void VectorGraphModel::deleteDataArray(unsigned int arrayLocation) -{ - std::vector effectorArrayLocations(m_dataArrays.size()); - for (unsigned int i = arrayLocation; i < m_dataArrays.size() - 1; i++) - { - m_dataArrays[i] = m_dataArrays[i + 1]; - } - m_dataArrays.pop_back(); - // reset effector locations to the correct locations - for (unsigned int i = 0; i < m_dataArrays.size(); i++) - { - effectorArrayLocations[i] = m_dataArrays[i].getEffectorArrayLocation(); - if (m_dataArrays[i].getEffectorArrayLocation() == static_cast(arrayLocation)) - { - effectorArrayLocations[i] = -1; - } - else if (effectorArrayLocations[i] >= static_cast(arrayLocation)) - { - effectorArrayLocations[i]--; - } - // effectorLocations are cleared to avoid the - // dataArrays detecting loops and then not setting - m_dataArrays[i].setEffectorArrayLocation(-1, false); - } - // setting updated locations - for (unsigned int i = 0; i < m_dataArrays.size(); i++) - { - m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); - } - emit dataChanged(); - emit updateGraphView(false); -} - -void VectorGraphModel::dataArrayChanged() -{ - emit dataChanged(); - emit updateGraphView(false); -} -void VectorGraphModel::updateGraphModel(bool shouldUseGetLastSamples) -{ - // connects to external update signal - emit updateGraphView(shouldUseGetLastSamples); -} -void VectorGraphModel::dataArrayClearedEvent(int arrayId) -{ - // TODO needs testing - int location = getDataArrayLocationFromId(arrayId); - emit clearedEvent(location); - emit dataChanged(); - emit updateGraphView(false); -} - -void VectorGraphModel::dataArrayStyleChanged() -{ - emit styleChanged(); -} -int VectorGraphModel::getDataArrayLocationFromId(int arrayId) -{ - int output = -1; - - if (arrayId < 0) { return output; } - - for (unsigned int i = 0; i < m_dataArrays.size(); i++) - { - if (m_dataArrays[i].getId() == arrayId) - { - output = i; - break; - } - } - return output; -} -int VectorGraphModel::getDataArrayNewId() -{ - int maxId = 0; - for (unsigned int i = 0; i < m_dataArrays.size(); i++) - { - if (m_dataArrays[i].getId() > maxId) - { - maxId = m_dataArrays[i].getId(); - } - } - maxId++; - return maxId; -} -void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("saveSettings start"); -#endif - - // getting the models saving name - QString saveName("VectorGraphModel"); - if (name.size() > 0) - { - saveName = name; - } - - QDomElement me = doc.createElement(saveName); - me.setAttribute("DataArrayCount", static_cast(m_dataArrays.size())); - for (unsigned int i = 0; i < m_dataArrays.size(); i++) - { - // getting rid of nullptr FloatMdoels - // (there should be 0) - for (unsigned int j = 0; j < m_dataArrays[i].size(); j++) - { - if (m_dataArrays[i].getAutomationModel(j) == nullptr) - { - m_dataArrays[i].setAutomated(j, false); - } - } - // delete automation that is in the automationModelArray - // but not used by a point (there should be 0 cases like this) - m_dataArrays[i].deleteUnusedAutomation(); - - // getting the start of the attribute name - QString readLocation = "a" + QString::number(i) + "-"; - std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); - bool isSaveable = m_dataArrays[i].getIsSaveable(); - // general saving attributes - me.setAttribute(readLocation + "DataArraySize", isSaveable == true ? static_cast(m_dataArrays[i].size()) : 0); - me.setAttribute(readLocation + "AutomationSize", isSaveable == true ? static_cast(automationModels->size()) : 0); - - if (isSaveable == true && m_dataArrays[i].size() > 0) - { - // saving the DataArray - me.setAttribute(readLocation + "DataArray", m_dataArrays[i].getSavedDataArray()); - - // saving the FloatModels - for (unsigned int j = 0; j < automationModels->size(); j++) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("saveSettings saved automatinModel dataArray (i): %d, model (j): %d", i, j); -#endif - QString readLocationB = QString::number(j) + "-"; - (*automationModels)[j]->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); - } - } - } - element.appendChild(me); -} -void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("loadSettings start"); -#endif - QString loadName("VectorGraphModel"); - if (name.size() > 0) - { - loadName = name; - } - - QDomNode node = element.namedItem(loadName); - - if(node.isNull() == true) - { - for(QDomElement othernode = element.firstChildElement(); - !othernode.isNull(); - othernode = othernode.nextSiblingElement()) - { - if((!othernode.hasAttribute("DataArrayCount") && - othernode.nodeName() == loadName)) - { - node = othernode; - break; - } - } - } - - QDomElement curElement = node.toElement(); - if (curElement.hasAttribute("DataArrayCount") == true) - { - unsigned int loadSize = curElement.attribute("DataArrayCount").toInt(); - for (unsigned int i = 0; i < loadSize; i++) - { - // getting the start of the attribute name - QString readLocation = "a" + QString::number(i) + "-"; - if (i < m_dataArrays.size() && curElement.hasAttribute(readLocation + "DataArraySize") == true) - { - unsigned int dataArraySize = curElement.attribute(readLocation + "DataArraySize").toInt(); - unsigned int automationSize = curElement.attribute(readLocation + "AutomationSize").toInt(); - // load m_dataArray - if (dataArraySize > 0) - { - m_dataArrays[i].loadDataArray(curElement.attribute(readLocation + "DataArray"), dataArraySize, true); - } - - // load automationModelDataArray - std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); - for (unsigned int j = 0; j < automationSize; j++) - { - QString readLocationB = QString::number(j) + "-"; - FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, this, QString(), false); - curModel->loadSettings(curElement, readLocation + readLocationB + "AutomationModel"); - automationModels->push_back(curModel); -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("loadSettings loaded automatinModel: arrayLocation (i): %d, model (j): %d", i, j); -#endif - } - } - else - { - break; - } - } - } -} -void VectorGraphModel::lockGetSamplesAccess() -{ - m_getSamplesAccess.lock(); -} -void VectorGraphModel::unlockGetSamplesAccess() -{ - m_getSamplesAccess.unlock(); -} -void VectorGraphModel::lockBakedSamplesAccess() -{ - m_bakedSamplesAccess.lock(); -} -void VectorGraphModel::unlockBakedSamplesAccess() -{ - m_bakedSamplesAccess.unlock(); -} -void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) -{ - saveSettings(doc, element, QString("")); -} -void VectorGraphModel::loadSettings(const QDomElement& element) -{ - loadSettings(element, QString("")); -} -void VectorGraphModel::modelAddJournalCheckPoint() -{ - addJournalCheckPoint(); -} - -// VectorGraphDataArray ------ - -VectorGraphDataArray::VectorGraphDataArray() -{ - m_isFixedSize = false; - m_isFixedY = false; - m_isFixedX = false; - m_isFixedEndPoints = false; - m_isSelectable = false; - m_isEditableAttrib = false; - m_isAutomatableEffectable = false; - m_isSaveable = false; - m_isNonNegative = false; - - m_lineColor = QColor(200, 200, 200, 255); - m_activeColor = QColor(255, 255, 255, 255); - // fill color is not enabled by default - // (if alpha = 0) - m_fillColor = QColor(0, 0, 0, 0); - m_automatedColor = QColor(0, 0, 0, 0); - - m_effectorLocation = -1; - - // m_dataArray - m_isDataChanged = false; - // m_bakedSamples; - // m_updatingBakedSamples - // m_needsUpdating; - // m_automationModelArray; - - m_id = -1; -} - -VectorGraphDataArray::VectorGraphDataArray( - bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, - bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parent, int arrayId) -{ - m_isFixedSize = isFixedSize; - m_isFixedY = isFixedX; - m_isFixedX = isFixedY; - m_isFixedEndPoints = isFixedEndPoints; - m_isSelectable = isSelectable; - m_isEditableAttrib = isEditableAttrib; - m_isAutomatableEffectable = isAutomatableEffectable; - m_isSaveable = isSaveable; - m_isNonNegative = isNonNegative; - - m_lineColor = QColor(200, 200, 200, 255); - m_activeColor = QColor(255, 255, 255, 255); - // fill color is not enabled by default - // (if alpha = 0) - m_fillColor = QColor(0, 0, 0, 0); - - m_effectorLocation = -1; - m_isAnEffector = false; - - // m_dataArray; - m_isDataChanged = false; - // m_bakedSamples; - // m_updatingBakedSamples - // m_needsUpdating; - // m_automationModelArray; - // m_universalSampleBuffer - - m_id = arrayId; - updateConnections(parent); -} - -VectorGraphDataArray::~VectorGraphDataArray() -{ - for (unsigned int i = 0; i < m_automationModelArray.size(); i++) - { - if (m_automationModelArray[i] != nullptr) - { - delete m_automationModelArray[i]; - } - } - m_automationModelArray.clear(); -} - -void VectorGraphDataArray::updateConnections(VectorGraphModel* parent) -{ - // call VectorGraphModel signals without qt - m_parent = parent; - m_id = m_parent->getDataArrayNewId(); - // reseting effectors - setEffectorArrayLocation(-1, true); -} - -void VectorGraphDataArray::setIsFixedSize(bool bValue) -{ - m_isFixedSize = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsFixedX(bool bValue) -{ - m_isFixedX = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsFixedY(bool bValue) -{ - m_isFixedY = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsFixedEndPoints(bool bValue) -{ - m_isFixedEndPoints = bValue; - formatDataArrayEndPoints(); - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsSelectable(bool bValue) -{ - m_isSelectable = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsEditableAttrib(bool bValue) -{ - m_isEditableAttrib = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setIsAutomatableEffectable(bool bValue) -{ - m_isAutomatableEffectable = bValue; - if (bValue == false) - { - // setEffectorArray will call dataChanged() - setEffectorArrayLocation(-1, true); - } - else - { - getUpdatingFromPoint(-1); - dataChanged(); - } -} -void VectorGraphDataArray::setIsSaveable(bool bValue) -{ - m_isSaveable = bValue; -} -void VectorGraphDataArray::setIsNonNegative(bool bValue) -{ - m_isNonNegative = bValue; - getUpdatingFromPoint(-1); - dataChanged(); -} -void VectorGraphDataArray::setLineColor(QColor bValue) -{ - m_lineColor = bValue; - styleChanged(); -} -void VectorGraphDataArray::setActiveColor(QColor color) -{ - m_activeColor = color; - styleChanged(); -} -void VectorGraphDataArray::setFillColor(QColor color) -{ - m_fillColor = color; - styleChanged(); -} -void VectorGraphDataArray::setAutomatedColor(QColor color) -{ - m_automatedColor = color; - styleChanged(); -} -bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool callDataChanged) -{ - bool found = true; - if (arrayLocation >= 0) - { - // if there is no valid id - if (m_id < 0) - { - m_id = m_parent->getDataArrayNewId(); - } - int searchArrayLocation = arrayLocation; - found = false; - // checking if the effector chain has this dataArray in it - for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) - { - int arrayId = m_parent->getDataArray(searchArrayLocation)->getId(); - searchArrayLocation = m_parent->getDataArray(searchArrayLocation)->getEffectorArrayLocation(); - if(arrayId == m_id) - { - found = true; - break; - } - if (searchArrayLocation == -1) - { - break; - } - } - // if the effector chain does not contain this dataArray - if (found == false) - { - m_effectorLocation = arrayLocation; - m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(true); - getUpdatingFromPoint(-1); - if (callDataChanged == true) - { - dataChanged(); - } - } - } - else - { - if (m_effectorLocation != -1) - { - // checking if this VectorGraphDataArray's effector is an effector for an other VectorGraphDataArray - bool foundB = false; - for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) - { - if (m_parent->getDataArray(i)->getId() != m_id && m_parent->getDataArray(i)->getEffectorArrayLocation() == m_effectorLocation) - { - foundB = true; - break; - } - } - // setting the correct state for the effector array's m_isAnEffector - m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(foundB); - m_effectorLocation = -1; - - getUpdatingFromPoint(-1); - if (callDataChanged == true) - { - dataChanged(); - } - } - } - return !found; -} -void VectorGraphDataArray::setIsAnEffector(bool bValue) -{ - m_isAnEffector = bValue; - // do not need to update anything after -} - -bool VectorGraphDataArray::getIsFixedSize() -{ - return m_isFixedSize; -} -bool VectorGraphDataArray::getIsFixedX() -{ - return m_isFixedX; -} -bool VectorGraphDataArray::getIsFixedY() -{ - return m_isFixedY; -} -bool VectorGraphDataArray::getIsFixedEndPoints() -{ - return m_isFixedEndPoints; -} -bool VectorGraphDataArray::getIsSelectable() -{ - return m_isSelectable; -} -bool VectorGraphDataArray::getIsEditableAttrib() -{ - return m_isEditableAttrib; -} -bool VectorGraphDataArray::getIsAutomatableEffectable() -{ - return m_isAutomatableEffectable; -} -bool VectorGraphDataArray::getIsSaveable() -{ - return m_isSaveable; -} -bool VectorGraphDataArray::getIsNonNegative() -{ - return m_isNonNegative; -} -QColor* VectorGraphDataArray::getLineColor() -{ - return &m_lineColor; -} -QColor* VectorGraphDataArray::getActiveColor() -{ - return &m_activeColor; -} -QColor* VectorGraphDataArray::getFillColor() -{ - return &m_fillColor; -} -QColor* VectorGraphDataArray::getAutomatedColor() -{ - return &m_automatedColor; -} -int VectorGraphDataArray::getEffectorArrayLocation() -{ - return m_effectorLocation; -} -bool VectorGraphDataArray::getIsAnEffector() -{ - return m_isAnEffector; -} -int VectorGraphDataArray::getId() -{ - return m_id; -} - - -// array: - -int VectorGraphDataArray::add(float newX) -{ - int location = -1; - if (m_isFixedSize == true || m_dataArray.size() >= m_parent->getMaxLength()) { return location; } - - bool found = false; - bool isBefore = false; - location = getNearestLocation(newX, &found, &isBefore); - if (found == false) - { - int targetLocation = -1; - bool dataChangedVal = false; - // if getNearestLocation returned a value - if (location >= 0) - { - targetLocation = location; - // shift the new data if the closest data x is bigger - // (done for swaping) - if (isBefore == true) - { - // we are adding one value, so dataArray.size() will be a valid location - if (targetLocation < m_dataArray.size()) - { - targetLocation++; - } - } - m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); - swap(m_dataArray.size() - 1, targetLocation, true); - dataChangedVal = true; - } - else if (m_dataArray.size() <= 0) - { - m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); - targetLocation = 0; - dataChangedVal = true; - } - location = targetLocation; - - if (m_dataArray.size() <= 2) - { - formatDataArrayEndPoints(); - dataChangedVal = true; - } - if (dataChangedVal == true) - { - // addtition breaks the order of the locations - // in m_needsUpdating, so we update the whole m_dataArray - getUpdatingFromPoint(-1); - dataChanged(); - } - } - return location; -} - -void VectorGraphDataArray::deletePoint(unsigned int pointLocation) -{ - if (m_isFixedSize == true || pointLocation >= m_dataArray.size()) { return; } - - // deleting the points automationModel - deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); - // swaping the point to the last location - // in m_dataArray - swap(pointLocation, m_dataArray.size() - 1, true); - m_dataArray.pop_back(); - if (pointLocation == 0 || pointLocation == m_dataArray.size()) - { - formatDataArrayEndPoints(); - } - // calling clearedEvent - if (m_dataArray.size() == 0) - { - clearedEvent(); - } - // deletion breaks the order of the locations - // in m_needsUpdating, so we update the whole m_dataArray - getUpdatingFromPoint(-1); - dataChanged(); -} - -void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) -{ - if (shouldRescale == true) - { - // scale - float minX = 0.0f; - float maxX = 1.0f; - float minY = -1.0f; - float maxY = 1.0f; - for (unsigned int i = 0; i < dataArrayOut->size(); i++) - { - if ((*dataArrayOut)[i].first < minX) - { - minX = (*dataArrayOut)[i].first; - } - if ((*dataArrayOut)[i].first > maxX) - { - maxX = (*dataArrayOut)[i].first; - } - if ((*dataArrayOut)[i].second < minY) - { - minY = (*dataArrayOut)[i].second; - } - if ((*dataArrayOut)[i].second > maxY) - { - maxY = (*dataArrayOut)[i].second; - } - } - maxX = (maxX - minX); - minX = -minX; - maxY = (maxY - minY) * 0.5f; - minY = -minY; - if (minX != 0.0f || maxX != 1.0f) - { - for (unsigned int i = 0; i < dataArrayOut->size(); i++) - { - (*dataArrayOut)[i].first = ((*dataArrayOut)[i].first + minX) / maxX; - } - } - if (minY != -1.0f || maxY != 1.0f) - { - for (unsigned int i = 0; i < dataArrayOut->size(); i++) - { - (*dataArrayOut)[i].second = ((*dataArrayOut)[i].second + minY) / maxY - 1.0f; - } - } - } - if (shouldClamp == true || shouldRescale == true) - { - // clamp - for (unsigned int i = 0; i < dataArrayOut->size(); i++) - { - if ((*dataArrayOut)[i].first < 0.0f) - { - (*dataArrayOut)[i].first = 0.0f; - } - if ((*dataArrayOut)[i].first > 1.0f) - { - (*dataArrayOut)[i].first = 1.0f; - } - if ((*dataArrayOut)[i].second < -1.0f) - { - (*dataArrayOut)[i].second = -1.0f; - } - if ((*dataArrayOut)[i].second > 1.0f) - { - (*dataArrayOut)[i].second = 1.0f; - } - } - formatDataArrayEndPoints(); - } - - // sort - if (shouldSort == true) - { - std::sort(dataArrayOut->begin(), dataArrayOut->end(), - [](PointF a, PointF b) - { - return a.first < b.first; - }); - } - - // delete duplicates - float lastPos = -1.0f; - if (dataArrayOut->size() > 0) - { - lastPos = (*dataArrayOut)[0].first; - } - for (unsigned int i = 1; i < dataArrayOut->size(); i++) - { - if ((*dataArrayOut)[i].first == lastPos) - { - deletePoint(i); - } - else - { - lastPos = (*dataArrayOut)[i].first; - } - } - // calling clearedEvent is not needed - // because all of the values can not be cleared here - getUpdatingFromPoint(-1); - if (callDataChanged == true) - { - dataChanged(); - } -} - -int VectorGraphDataArray::getLocation(float searchX) -{ - bool found = false; - bool isBefore = false; - int location = getNearestLocation(searchX, &found, &isBefore); - if (found == false) - { - return -1; - } - return location; -} - -int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut) -{ - // modified binary search - if (m_dataArray.size() > 0) - { - int start = 0; - int end = m_dataArray.size() - 1; - int mid = 0; - // binary search - while (start < end) - { - mid = start + (end - start) / 2; - if (m_dataArray[mid].m_x == searchXIn) - { - *foundOut = true; - *isBeforeOut = false; - return mid; - } - else if (m_dataArray[mid].m_x < searchXIn) - { - start = mid + 1; - } - else - { - end = mid - 1; - } - } - int outputDif = 0; - mid = start + (end - start) / 2; - if (m_dataArray[mid].m_x > searchXIn && mid > 0) - { - mid = mid - 1; - } - if (mid + 1 < m_dataArray.size() && - std::abs(m_dataArray[mid].m_x - searchXIn) > - std::abs(m_dataArray[mid + 1].m_x - searchXIn)) - { - outputDif = 1; - } - *foundOut = searchXIn == m_dataArray[mid + outputDif].m_x; - *isBeforeOut = searchXIn >= m_dataArray[mid + outputDif].m_x; - return mid + outputDif; - } - *foundOut = false; - *isBeforeOut = false; - return -1; -} - -void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamples start: targetSizeIn: %d", targetSizeIn); -#endif - - if (sampleBufferOut != nullptr) - { - if (sampleBufferOut->size() != targetSizeIn) - { - sampleBufferOut->resize(targetSizeIn); - } - for (unsigned int i = 0; i < targetSizeIn; i++) - { - (*sampleBufferOut)[i] = 0; - } - - m_parent->lockGetSamplesAccess(); - getSamplesInner(targetSizeIn, nullptr, nullptr, sampleBufferOut); - m_parent->unlockGetSamplesAccess(); - } - else - { - // this needs to be allocated for getSamplesInner to work - // because every effector VectorGraphDataArray uses this to return its m_bakedValues directly - std::vector updatingSampleArray(targetSizeIn); - - m_parent->lockGetSamplesAccess(); - getSamplesInner(targetSizeIn, nullptr, nullptr, &updatingSampleArray); - m_parent->unlockGetSamplesAccess(); - } -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamples end"); -#endif -} -void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) -{ - m_parent->lockBakedSamplesAccess(); - *sampleBufferOut = m_bakedSamples; - m_parent->unlockBakedSamplesAccess(); -} -std::vector VectorGraphDataArray::getEffectorArrayLocations() -{ - // getting the effector array chain - std::vector output; - int currentLocation = m_effectorLocation; - for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) - { - if (currentLocation == -1) - { - break; - } - else - { - output.push_back(m_effectorLocation); - currentLocation = m_parent->getDataArray(currentLocation)->getEffectorArrayLocation(); - } - } - return output; -} - -void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, - bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("setDataArray start"); -#endif - if (shouldClear == true) - { - m_dataArray.clear(); - } - m_dataArray.resize(inputDataArray->size()); - if (m_dataArray.size() == 0) - { - clearedEvent(); - } - if (shouldClamp == true || shouldRescale == true || shouldSort == true) - { - formatArray(inputDataArray, shouldClamp, shouldRescale, shouldSort, false); - } - bool noneBefore = true; - bool isNegativeBefore = false; - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - m_dataArray[i].m_x = (*inputDataArray)[i].first; - m_dataArray[i].m_y = (*inputDataArray)[i].second; - // calculating curves - if (shouldCurve == true && i > 0) - { - // TODO take in to account x coords - float diff = m_dataArray[i - 1].m_y - m_dataArray[i].m_y; - // if before is bigger than after - bool isNegative = diff >= 0; - float direction = 0; - if (noneBefore == true) - { - direction = isNegative == true ? 1.0f : -1.0f; - } - else - { - direction = isNegative == isNegativeBefore ? 1.0f : isNegative == true ? -1.0f : 1.0f; - } - - diff = diff * diff * 10.0f * direction; - diff = std::clamp(diff, -0.7f, 0.7f); - m_dataArray[i - 1].m_c = diff; - - noneBefore = diff < 0.1f && diff > -0.1f; - isNegativeBefore = isNegative; - } - } - // the whole m_dataArray needs to be updated - getUpdatingFromPoint(-1); - if (callDataChanged == true) - { - dataChanged(); - } -} -void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, - bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) -{ - std::vector convertedDataArray(inputDataArray->size()); - float stepSize = 1.0f / static_cast(convertedDataArray.size()); - for (unsigned int i = 0; i < inputDataArray->size(); i++) - { - convertedDataArray[i].first = i * stepSize; - convertedDataArray[i].second = (*inputDataArray)[i]; - } - setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); -} -void VectorGraphDataArray::setDataArray(float* inputDataArray, unsigned int size, - bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) -{ - std::vector convertedDataArray(size); - float stepSize = 1.0f / static_cast(size); - for (unsigned int i = 0; i < size; i++) - { - convertedDataArray[i].first = i * stepSize; - convertedDataArray[i].second = inputDataArray[i]; - } - setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); -} - -unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) -{ - int location = pointLocation; - if (m_isFixedX == false && newX <= 1.0f) - { - bool found = false; - bool isBefore = false; - location = getNearestLocation(newX, &found, &isBefore); - // if an other point was not found exactly at newX - // and if dataArray end points are changeable - if (found == false && ((m_isFixedEndPoints == true && - pointLocation < m_dataArray.size() - 1 && pointLocation > 0) || - m_isFixedEndPoints == false)) - { - int targetLocation = location; - // bool dataChangedVal = false; - // if getNearestLocation returned a value - if (location >= 0) - { - if (location < pointLocation && isBefore == true) - { - if (targetLocation + 1 < m_dataArray.size()) - { - targetLocation++; - } - } - else if (location > pointLocation && isBefore == false) - { - if (targetLocation > 0) - { - targetLocation--; - } - } - m_dataArray[pointLocation].m_x = newX; - swap(pointLocation, targetLocation, true); - location = targetLocation; - - getUpdatingFromPoint(-1); - // changes in the position can change lines before - // so the point before this is updated - if (location > 0) - { - getUpdatingFromPoint(location - 1); - } - dataChanged(); - } - else - { - location = pointLocation; - } - } - else - { - location = pointLocation; - } - } - return location; -} - -void VectorGraphDataArray::setY(unsigned int pointLocation, float newY) -{ - if (m_isFixedY == true) { return; } - - m_dataArray[pointLocation].m_y = newY; - getUpdatingFromPoint(pointLocation); - // changes in the position can change lines before - // so the point before this is updated - if (pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - if (m_isFixedEndPoints == true && - (pointLocation <= 0 || pointLocation >= m_dataArray.size() - 1)) - { - formatDataArrayEndPoints(); - getUpdatingFromPoint(0); - getUpdatingFromPoint(m_dataArray.size() - 1); - } - dataChanged(); -} - -void VectorGraphDataArray::setC(unsigned int pointLocation, float newC) -{ - if (m_isEditableAttrib == false) { return; } - - m_dataArray[pointLocation].m_c = newC; - getUpdatingFromPoint(pointLocation); - dataChanged(); -} -void VectorGraphDataArray::setValA(unsigned int pointLocation, float fValue) -{ - if (m_isEditableAttrib == false) { return; } - - m_dataArray[pointLocation].m_valA = fValue; - getUpdatingFromPoint(pointLocation); - dataChanged(); -} -void VectorGraphDataArray::setValB(unsigned int pointLocation, float fValue) -{ - if (m_isEditableAttrib == false) { return; } - - m_dataArray[pointLocation].m_valB = fValue; - getUpdatingFromPoint(pointLocation); - dataChanged(); -} -void VectorGraphDataArray::setType(unsigned int pointLocation, unsigned int newType) -{ - if (m_isEditableAttrib == false) { return; } - - // set the type without changing the automated attribute location - m_dataArray[pointLocation].m_type = newType; - getUpdatingFromPoint(pointLocation); - dataChanged(); -} -void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation) -{ - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - - // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocation = attribLocation > 3 ? 0 : attribLocation; - // set automated location correctly (effected_location = automatedEffectedLocation % 4) - m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation * 4 + getEffectedAttribLocation(pointLocation); - - getUpdatingFromPoint(pointLocation); - // the line before this can get added later - // in getUpdatingFromAutomation - // so the point before this is not updated here - - dataChanged(); -} -void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation) -{ - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - - // clamp only 4 attributes can be automated (y, c, valA, valB) - attribLocation = attribLocation > 3 ? 0 : attribLocation; - // set effected location correctly - m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation) * 4; - - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectPoints(pointLocation) == false && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - dataChanged(); -} -unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int pointLocation) -{ - return m_dataArray[pointLocation].m_automatedEffectedAttribLocations / 4; -} -unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int pointLocation) -{ - return m_dataArray[pointLocation].m_automatedEffectedAttribLocations % 4; -} -bool VectorGraphDataArray::getEffectPoints(unsigned int pointLocation) -{ - // be careful with changing this - return (m_dataArray[pointLocation].m_effectPoints == true || getEffectedAttribLocation(pointLocation) > 0); -} -bool VectorGraphDataArray::getEffectLines(unsigned int pointLocation) -{ - // be careful with changing this - // m_effectLines ought to be false if lines (each sample) can not be changed - return (m_dataArray[pointLocation].m_effectLines == true && getEffectedAttribLocation(pointLocation) == 0); -} -void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bValue) -{ - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - - if (m_dataArray[pointLocation].m_effectPoints != bValue) - { - // getEffectPoints does not return m_effectePoints - bool dataChangedValue = getEffectPoints(pointLocation); - m_dataArray[pointLocation].m_effectPoints = bValue; - // this change does effect the main output if this - // data array is an effector of an other so dataChanged() - // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectPoints(pointLocation)) - { - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectedAttribLocation(pointLocation) <= 0 && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - } - dataChanged(); - } -} -void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValue) -{ - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - - if (m_dataArray[pointLocation].m_effectLines != bValue) - { - // getEffectLines does not return m_effectLines - bool dataChangedValue = getEffectLines(pointLocation); - m_dataArray[pointLocation].m_effectLines = bValue; - // this change does effect the main output if this - // data array is an effector of an other so dataChanged() - // and getUpdatingFromPoint is called - if (dataChangedValue != getEffectLines(pointLocation)) - { - getUpdatingFromPoint(pointLocation); - } - dataChanged(); - } -} -unsigned int VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectSlot) -{ - switch (effectSlot) - { - case 0: - return m_dataArray[pointLocation].m_effectTypeA; - case 1: - return m_dataArray[pointLocation].m_effectTypeB; - case 2: - return m_dataArray[pointLocation].m_effectTypeC; - } - return 0; -} -void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType) -{ - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } - - switch (effectSlot) - { - case 0: - m_dataArray[pointLocation].m_effectTypeA = effectType; - break; - case 1: - m_dataArray[pointLocation].m_effectTypeB = effectType; - break; - case 2: - m_dataArray[pointLocation].m_effectTypeC = effectType; - break; - } - getUpdatingFromPoint(pointLocation); - // if the current point can effect the line before it - // update the point before it - if (getEffectPoints(pointLocation) == true && pointLocation > 0) - { - getUpdatingFromPoint(pointLocation - 1); - } - dataChanged(); -} -bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int pointLocation) -{ - if (getAutomationModel(pointLocation) != nullptr && - m_dataArray[pointLocation].m_bufferedAutomationValue != getAutomationModel(pointLocation)->value()) - { - m_dataArray[pointLocation].m_bufferedAutomationValue = getAutomationModel(pointLocation)->value(); - return true; - } - return false; -} -void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) -{ -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setAutomated start"); -#endif - if (m_isAutomatableEffectable == false) { return; } - - if (bValue == true) - { - // if it is not already automated - if (m_dataArray[pointLocation].m_automationModel == -1) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setAutomated: make new floatModel, location: %d", pointLocation); -#endif - m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); - m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; - getUpdatingFromPoint(pointLocation); - dataChanged(); - } - } - else - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("setAutomated: delete floatModel, location: %d, size: %d", pointLocation, static_cast(m_automationModelArray.size())); -#endif - // dataChanged() is called in this function - // this function check if the current point has an automationModel - deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); - } -} -FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) -{ - if (m_dataArray[pointLocation].m_automationModel != -1) - { - return m_automationModelArray[m_dataArray[pointLocation].m_automationModel]; - } - return nullptr; -} - -// private: -std::vector* VectorGraphDataArray::getAutomationModelArray() -{ - return &m_automationModelArray; -} -void VectorGraphDataArray::deleteUnusedAutomation() -{ - bool dataChangedVal = false; - std::vector usedAutomation; - for (auto i : m_dataArray) - { - if (i.m_automationModel != -1) - { - usedAutomation.push_back(i.m_automationModel); - } - } - for (unsigned int i = 0; i < m_automationModelArray.size(); i++) - { - bool found = false; - for (unsigned int j = 0; j < usedAutomation.size(); j++) - { - if (i == usedAutomation[j]) - { - found = true; - break; - } - } - if (found == false) - { - dataChangedVal = true; - deleteAutomationModel(i, false); - } - } - - // getUpdatingFromPoint() is called in deleteAutomationModel() - if (dataChangedVal == true) - { - dataChanged(); - } -} -QString VectorGraphDataArray::getSavedDataArray() -{ - QString output; - base64::encode((const char *)(m_dataArray.data()), - m_dataArray.size() * sizeof(VectorGraphPoint), output); - return output; -} -void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, bool callDataChanged) -{ -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("loadDatatArray start: arraySize: %d", arraySize); -#endif - int size = 0; - char* dst = 0; - base64::decode(data, &dst, &size); - - if (size == arraySize * sizeof(VectorGraphPoint)) - { - m_dataArray.resize(arraySize); - - VectorGraphPoint* points = (VectorGraphPoint*)dst; - for (unsigned int i = 0; i < arraySize; i++) - { - m_dataArray[i] = points[i]; - } - } - - delete[] dst; - getUpdatingFromPoint(-1); - if (callDataChanged == true) - { - dataChanged(); - } -} - -void VectorGraphDataArray::deleteAutomationModel(int modelLocation, bool callDataChanged) -{ - if (modelLocation < 0 || modelLocation >= m_automationModelArray.size()) { return; } - - FloatModel* curModel = m_automationModelArray[modelLocation]; - - // copy the last FloatModel* to the current location - m_automationModelArray[modelLocation] = - m_automationModelArray[m_automationModelArray.size() - 1]; - - m_automationModelArray.pop_back(); - - // replace all m_auttomationModel-s in the current copyed location with -1 - // replace all last m_automationModel-s to the currently copyed location - // there should be only 2 points changed but because of safety - // all of them are checked - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - if (m_dataArray[i].m_automationModel == modelLocation) - { - m_dataArray[i].m_automationModel = -1; - getUpdatingFromPoint(i); - if (i > 0) - { - getUpdatingFromPoint(i - 1); - } - } - if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) - { - m_dataArray[i].m_automationModel = modelLocation; - } - } - if (curModel != nullptr) - { - delete curModel; - curModel = nullptr; - } - - if (callDataChanged == true) - { - dataChanged(); - } -} - -void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween) -{ - if (pointLocationA == pointLocationB) { return; } - - if (shouldShiftBetween == true) - { -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("swap: -------"); - qDebug("first point location: %d, second point locaiton: %d", pointLocationA, pointLocationB); - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); - } -#endif - - if (pointLocationA < pointLocationB) - { - VectorGraphPoint swap = m_dataArray[pointLocationA]; - for (unsigned int i = pointLocationA; i < pointLocationB; i++) - { - m_dataArray[i] = m_dataArray[i + 1]; - } - m_dataArray[pointLocationB] = swap; - } - else - { - VectorGraphPoint swap = m_dataArray[pointLocationA]; - for (unsigned int i = pointLocationA; i > pointLocationB; i--) - { - m_dataArray[i] = m_dataArray[i - 1]; - } - m_dataArray[pointLocationB] = swap; - } - -#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug(" --------- "); - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); - } -#endif - } - else - { - // normal swap - VectorGraphPoint swap = m_dataArray[pointLocationA]; - m_dataArray[pointLocationA] = m_dataArray[pointLocationB]; - m_dataArray[pointLocationB] = swap; - } - getUpdatingFromPoint(pointLocationB - 1 > 0 ? pointLocationB - 1 : 0); - getUpdatingFromPoint(pointLocationA - 1 > 0 ? pointLocationA - 1 : 0); - getUpdatingFromPoint(pointLocationA); - getUpdatingFromPoint(pointLocationB); - dataChanged(); -} -float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float x) -{ - // calculating line curve - float absCurveIn = std::abs(curve); - float pow = curve < 0.0f ? 1.0f - x : x; - pow = std::pow(pow, 1.0f - absCurveIn) - pow; - - float output = yBefore + (yAfter - yBefore) * x; - output = curve > 0.0f ? output + pow * (yAfter - yBefore) : output - pow * (yAfter - yBefore); - // clamp - if (yBefore > yAfter) - { - output = std::clamp(output, yAfter, yBefore); - } - else - { - output = std::clamp(output, yBefore, yAfter); - } - return output; -} - -float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attribValue, - unsigned int attribLocation, float effectValue) -{ - // calculating an effect on attribValue - float output = attribValue; - // effects - if (getEffectedAttribLocation(pointLocation) == attribLocation) - { - output = processSingleEffect(pointLocation, 0, output, effectValue); - output = processSingleEffect(pointLocation, 1, output, effectValue); - output = processSingleEffect(pointLocation, 2, output, effectValue); - - // clamp - output = std::clamp(output, -1.0f, 1.0f); - } - return output; -} - -float VectorGraphDataArray::processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, - float attribValue, float effectValue) -{ - // calculating an effect on attribValue - float output = attribValue; - - // none - if (getEffect(pointLocation, effectSlot) == 0) { return output; } - - // effects - if (getEffect(pointLocation, effectSlot) == 1) - { - // add - output += effectValue; - } - else if (getEffect(pointLocation, effectSlot) == 2) - { - // subtract - output -= effectValue; - } - else if (getEffect(pointLocation, effectSlot) == 3) - { - // multiply - output = output * 5.0f * effectValue; - } - else if (getEffect(pointLocation, effectSlot) == 4 && effectValue != 0.0f) - { - // divide - output = output / 5.0f / effectValue; - } - else if (getEffect(pointLocation, effectSlot) == 5 && output > 0.0f) - { - // power - output = std::pow(output, effectValue * 5.0f); - output = std::clamp(output, -1.0f, 1.0f); - } - else if (getEffect(pointLocation, effectSlot) == 6 && output > 0.0f && effectValue > 0.0f) - { - // log - output = std::log(output) / std::log(effectValue); - output = std::clamp(output, -1.0f, 1.0f); - } - else if (getEffect(pointLocation, effectSlot) == 7) - { - // sine - output = output + std::sin(effectValue * 100.0f); - } - else if (getEffect(pointLocation, effectSlot) == 8) - { - // clamp lower - output = std::max(effectValue, output); - } - else if (getEffect(pointLocation, effectSlot) == 9) - { - // clamp upper - output = std::min(effectValue, output); - } - return output; -} - -float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation) -{ - // adding the automation value to attribValue - float output = 0.0f; - // if automated - FloatModel* automationModel = getAutomationModel(pointLocation); - if (automationModel != nullptr) - { - if (getAutomatedAttribLocation(pointLocation) == attribLocation) - { - output += automationModel->value(); - } - } - output += attribValue; - - output = std::clamp(output, -1.0f, 1.0f); - return output; -} - -void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float fadeInStartVal) -{ - processLineTypeArraySineB(samplesOut, xArray, startLoc, endLoc, - sineAmp, sineFreq, 0.0f, fadeInStartVal); -} -void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal) -{ - float startLocVal = (*samplesOut)[startLoc]; - float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; - int count = static_cast(endLoc) - static_cast(startLoc); - if (count < 0) - { - count = 0; - } - float tValB = 0.001f + ((sineFreq + 1.0f) / 2.0f) * 0.999f; - // calculating how many samples are needed to 1 complete wave - // we have "count" amount of samples and "tValB * 100.0f" amount of waves - int end = static_cast(std::floor(count / (tValB * 100.0f))); - if (count <= 0) - { - end = 0; - } - else - { - end = end > count ? count : end + 1; - } - // "allocate" "end" amount of floats - // for 1 whole sine wave - // in the universal buffer - if (m_universalSampleBuffer.size() < end) - { - m_universalSampleBuffer.resize(end); - } - - // calculate 1 wave of sine - for (unsigned int i = 0; i < end; i++) - { - // 628.318531f = 100.0f * 2.0f * pi - // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) - m_universalSampleBuffer[i] = sineAmp * std::sin( - (*xArray)[startLoc + i] * 628.318531f * tValB + sinePhase * 100.0f); - } - // copy the first wave until the end - for (int i = 0; i < count; i += end) - { - int endB = i + end >= count ? count - i : end; - for (unsigned int j = 0; j < endB; j++) - { - (*samplesOut)[startLoc + j + i] += m_universalSampleBuffer[j]; - } - } - - // fade in - unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); - for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) - { - float x = (*xArray)[i] / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); - } - // fade out - for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) - { - float x = (1.0f - (*xArray)[i]) / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); - } -} -void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float peakAmp, float peakX, float peakWidth, float fadeInStartVal) -{ - float startLocVal = (*samplesOut)[startLoc]; - float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; - int count = static_cast(endLoc) - static_cast(startLoc); - if (count < 0) - { - count = 0; - } - for (unsigned int i = 0; i < count; i++) - { - (*samplesOut)[startLoc + i] += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, - std::abs((*xArray)[startLoc + i] - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; - } - - // fade in - unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); - for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) - { - float x = (*xArray)[i] / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); - } - // fade out - for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) - { - float x = (1.0f - (*xArray)[i]) / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); - } -} -void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal) -{ - float startLocVal = (*samplesOut)[startLoc]; - float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; - int count = static_cast(endLoc) - static_cast(startLoc); - if (count < 0) - { - count = 0; - } - - float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; - for (unsigned int i = 0; i < count; i++) - { - float y = (*yArray)[startLoc + i] + 1.0f; - float diff = std::round(y * stepCountB) - y * stepCountB; - float smooth = 1.0f - std::abs(diff) * (1.0f - (stepCurve + 1.0f) / 2.0f) * 2.0f; - (*samplesOut)[startLoc + i] += diff / stepCountB * smooth; - } - - // fade in - unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); - for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) - { - float x = (*xArray)[i] / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); - } - // fade out - for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) - { - float x = (1.0f - (*xArray)[i]) / fadeInStartVal; - (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); - } -} -void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, - float randomAmp, float randomCount, float randomSeed, float fadeInStartVal) -{ - int count = static_cast(endLoc) - static_cast(startLoc); - if (count < 0) - { - count = 0; - } - - unsigned int randomValuesSize = static_cast(50.0f * (randomCount + 1.0f)) * 2; - - if (randomValuesSize <= 0) { return; } - - // "allocate" "randomValuesSize" amount of floats - // for generating random values - // in the universal buffer - if (m_universalSampleBuffer.size() < randomValuesSize) - { - m_universalSampleBuffer.resize(randomValuesSize); - } - - float blend = 10.0f + randomSeed * 10.0f; - int randomSeedB = static_cast(blend); - blend = blend - randomSeedB; - - std::srand(randomSeedB); - - // getting the random values - // generating 2 seeds and blending in between them - for (unsigned int i = 0; i < randomValuesSize / 2; i++) - { - m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } - std::srand(randomSeedB + 1); - for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) - { - m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; - } - - // blending - // real size - float size = static_cast(randomValuesSize / 2); - for (unsigned int i = 0; i < count; i++) - { - float randomValueX = (*xArray)[startLoc + i] * size; - float randomValueLocation = std::floor(randomValueX); - (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * - (m_universalSampleBuffer[static_cast(randomValueLocation)] * (1.0f - blend) + m_universalSampleBuffer[static_cast(randomValueLocation + size)] * blend) * randomAmp; - } -} - -void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) -{ - /* - * here m_needsUpdating points are decided - * firstly we get changed points from the effector graph (updatingPointLocations) - * we get a segment consisting of changed effector points that come after each other - * this will be useful because we can update the current graph's points between this segment (segment start = i, segment end = updatingEnd) - * secondly we get a (current graph's) point before the segment start and after the segment end - * so we get locationBefore and locationAfter which will be added to m_needsUpdating - * thirdly we finalyze locationBefore and locationAfter, clamp them and start adding the points between them to m_needsUpdating - * if the (current graph's) point is not effected, we avoid adding it to m_needsUpdating - */ - VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); - for (unsigned int i = 0; i < updatingPointLocations->size(); i++) - { - // since updatingPointLocations is a sorted list, we can get the end - // location and update everithing between them - // starting effector location is i, end effector location is updatingEnd - unsigned int updatingEnd = i; - for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) - { - // we can not skip gaps because - // every updatingPointLocations point effects their line only - // (the line that starts with the point) - if ((*updatingPointLocations)[updatingEnd] + 1 >= - (*updatingPointLocations)[j]) - { - updatingEnd = j; -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", updatingEnd, i); -#endif - } - else - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, - ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); -#endif - break; - } - } - // getting the point that comes after updatingEnd - // this is done because updatingEnd was changed so the line directly after updatingEnd point was changed - // so every (current graph's) point before updatingEnd + 1 needs to be changed - int updatingEndSlide = 0; - if (updatingEnd + 1 < effector->size()) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: updatingEndSlide = 1"); -#endif - updatingEndSlide = 1; - } - - // translating the effector data array locations to m_dataArray locations - bool found = false; - bool isBefore = false; - // this can return -1 - int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); -#endif - if (isBefore == true && locationBefore > 0 && getEffectPoints(locationBefore) == true) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: locationBefore = %d - 1", locationBefore); -#endif - // the line (or point) before might be effected if the current nearest point - // is effected in some way - // so subtract 1 - // remember points control the line after (connected to) them - // but in this case changes in the points position can effect the line before it - locationBefore--; - // now (here) locationBefore is Always before (*updatingPointLocations)[i] - } - // clamp - locationBefore = locationBefore < 0 ? 0 : - m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; - - isBefore = false; - int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, - effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); -#endif - if (isBefore == false) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: locationAfter = %d - 1", locationAfter); -#endif - // if the nearest point is after ([updatingEnd] + upadtingEndSlide) (where updating ends) - locationAfter--; - } - // updating everything before if i -> 0 - if ((*updatingPointLocations)[i] == 0) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector updating everything before"); -#endif - locationBefore = 0; - } - // if updatingEnd is the last point in effecor, then - // update everithing after - if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector updating everything after"); -#endif - locationAfter = m_dataArray.size() - 1; - } - // clamp - locationAfter = locationAfter < 0 ? 0 : - m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; - -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: final start: %d, final end: %d, i: %d", locationBefore, locationAfter, i); -#endif - - // if the last point was updated (ture in case of j = 0) - bool lastUpdated = true; - // adding the values between locationBefore, locationAfter - for (unsigned int j = locationBefore; j <= locationAfter; j++) - { - // update only if effected - if (isEffectedPoint(j) == true && (getEffectPoints(j) == true || getEffectLines(j) == true)) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromEffector: i: %d, updating: %d", i, j); -#endif - m_needsUpdating.push_back(j); - if (lastUpdated == false && getEffectPoints(j) == true) - { - m_needsUpdating.push_back(j - 1); - } - lastUpdated = true; - } - else - { - lastUpdated = false; - } - } - if (i < updatingEnd) - { - i = updatingEnd; - } - } -} -void VectorGraphDataArray::getUpdatingFromPoint(int pointLocation) -{ - // changes in position need to cause updates before the changed point - // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) - if (m_isDataChanged == false && pointLocation >= 0) - { - m_needsUpdating.push_back(pointLocation); - if (m_needsUpdating.size() > m_dataArray.size() * 3) - { - m_isDataChanged = true; - } - } - else if (pointLocation < 0) - { - m_isDataChanged = true; - } -} -void VectorGraphDataArray::getUpdatingFromAutomation() -{ - // adding points with changed automation values - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - if (getIsAutomationValueChanged(i) == true) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getUpdatingFromAutomation: point location: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); -#endif - m_needsUpdating.push_back(i); - // if the automatable value effects the y (so the position) - // the point before this is updated too - if (i > 0 && getAutomatedAttribLocation(i) == 0) - { - m_needsUpdating.push_back(i - 1); - } - } - } -} -void VectorGraphDataArray::getUpdatingOriginals() -{ - // selecting only original values and sorting - -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - qDebug("getUpatingOriginals before: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); - } -#endif - - // sorting the array - // this is done becaues functions that use m_needsUpdating - // are optimized for a sorted array - std::sort(m_needsUpdating.begin(), m_needsUpdating.end(), - [](unsigned int a, unsigned int b) - { - return a < b; - }); - - // removing duplicates - int sizeDiff = 0; - for (int i = 1; i < m_needsUpdating.size(); i++) - { - if (m_needsUpdating[i - 1 + sizeDiff] == m_needsUpdating[i + sizeDiff]) - { - for (unsigned int j = i + sizeDiff; j < m_needsUpdating.size() - 1 + sizeDiff; j++) - { - m_needsUpdating[j] = m_needsUpdating[j + 1]; - } - sizeDiff--; - } - } - m_needsUpdating.resize(m_needsUpdating.size() + sizeDiff); - - // removing invalid locations - // because sometimes deleted locations can be in m_needsUpdating - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - if (m_needsUpdating[i] >= m_dataArray.size()) - { - m_needsUpdating.resize(i); - break; - } - } - -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - qDebug("getUpatingOriginals final: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); - } -#endif -} -void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, - std::vector* updatingValuesOut, std::vector* sampleBufferOut) -{ - bool effectorIsChanged = false; - //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); - std::vector effectorUpdatingValues; - // sampleBufferOut will serve as the effector's sampleBufferOut until the new m_bakedSamples gets made - bool isEffected = m_effectorLocation >= 0; - if (isEffected == true) - { - m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); - } -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesInner: id: %d", m_id); -#endif - - m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); - - // deciding if the whole dataArray should be updated - // if the whole effectorDataArray was updated - int effectedCount = 0; - if (effectorIsChanged == true) - { - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - effectedCount += isEffectedPoint(i) == true? 1 : 0; - } - if (effectedCount > m_dataArray.size() / 2) - { - m_isDataChanged = m_isDataChanged || effectorIsChanged; - } - } - - // updating m_needsUpdating - if (m_isDataChanged == false && targetSizeIn == m_updatingBakedSamples.size()) - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesInner: get updating"); -#endif - if (isEffected == true && effectorUpdatingValues.size() > 0 && - (effectorIsChanged == false || effectedCount > 0)) - { - // effectorUpdatingValues needs to be sorted - // before use (in this case it is already sorted) - getUpdatingFromEffector(&effectorUpdatingValues); - } - getUpdatingFromAutomation(); - // sort and select only original - // values - getUpdatingOriginals(); - } - else - { -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesInner: update all points"); -#endif - m_parent->lockBakedSamplesAccess(); - if (targetSizeIn != m_bakedSamples.size()) - { - m_bakedSamples.resize(targetSizeIn); - } - m_parent->unlockBakedSamplesAccess(); - if (targetSizeIn != m_updatingBakedSamples.size()) - { - m_updatingBakedSamples.resize(targetSizeIn); - } - m_needsUpdating.resize(m_dataArray.size()); - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - m_needsUpdating[i] = i; - } - } - - float stepSize = 1.0f / static_cast(targetSizeIn); - // calculating point data and lines - if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) - { - // calculating the relative X locations (in lines) of the output samples - // sampleXLocations[sample_location] is equal to 0.0f if it is at the start of a line - // and it is equal to 1.0f if it is at the end of a line - std::vector sampleXLocations(targetSizeIn); - for (unsigned int i = 0; i < m_dataArray.size(); i++) - { - unsigned int start = static_cast - (std::ceil(m_dataArray[i].m_x / stepSize)); - if (i + 1 < m_dataArray.size()) - { - unsigned int end = static_cast - (std::ceil(m_dataArray[i + 1].m_x / stepSize)); - for (unsigned int j = start; j < end; j++) - { - sampleXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); - } - } - } - - // getting effectorDataArray pointer - VectorGraphDataArray* effector = nullptr; - if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) - { - effector = m_parent->getDataArray(m_effectorLocation); - } - -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesInner: updatingsize: %d", static_cast(m_needsUpdating.size())); -#endif - - // calculate final lines - for (unsigned int i = 0; i < m_needsUpdating.size(); i++) - { - // sampleBufferOut contains the effector m_bakedValues here - getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, i, stepSize); - } - - m_parent->lockBakedSamplesAccess(); - m_bakedSamples = m_updatingBakedSamples; - m_parent->unlockBakedSamplesAccess(); - } - - // setting outputs - if (isChangedOut != nullptr) - { - *isChangedOut = m_isDataChanged; - } - if (m_needsUpdating.size() > 0) - { - if (updatingValuesOut != nullptr) - { - *updatingValuesOut = m_needsUpdating; - } - - // clearing the updated values - m_needsUpdating.clear(); - } - m_parent->lockBakedSamplesAccess(); - *sampleBufferOut = m_bakedSamples; - m_parent->unlockBakedSamplesAccess(); - - m_isDataChanged = false; -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesInner end"); -#endif -} -void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, - std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) -{ - unsigned int effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, m_needsUpdating[pointLocation], effectYLocation); -#endif - // current effector output Y near m_needsUpdating[pointLocation] point - float curEffectY = (*effectorSamples)[effectYLocation]; - float nextEffectY = (*effectorSamples)[effectYLocation]; - - // getting the final automatable / effectable point values - float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); - float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); - float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); - float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); - if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation]) == true && getEffectLines(m_needsUpdating[pointLocation]) == false) - { - curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); - curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); - curValA = processEffect(m_needsUpdating[pointLocation], curValA, 2, curEffectY); - curValB = processEffect(m_needsUpdating[pointLocation], curValB, 3, curEffectY); - } - // from where to update line - int start = effectYLocation; - int end = start; - - float nextY = curY; - - if (m_needsUpdating[pointLocation] + 1 < m_dataArray.size()) - { - effectYLocation = static_cast - (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); - // where updating line ends (+1) - end = effectYLocation; - nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); - - bool isCurEffected = isEffectedPoint(m_needsUpdating[pointLocation]); - // if the next point (y location) can be effected - // and the current point's line is uneffected - if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation] + 1) == true && - (getEffectLines(m_needsUpdating[pointLocation]) == false || isCurEffected == false)) - { - nextEffectY = (*effectorSamples)[effectYLocation]; - nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); - } - } - // calculating line ends - if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) - { - // if this point is at the last location in m_dataArray - for (int j = end; j < m_updatingBakedSamples.size(); j++) - { - m_updatingBakedSamples[j] = curY; - } - } - if (m_needsUpdating[pointLocation] == 0) - { - // if this point is at the 0 location in m_dataArray - for (int j = 0; j < start; j++) - { - m_updatingBakedSamples[j] = curY; - } - } - - float fadeInStart = 0.05f; - unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; -#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT - qDebug("getSamplesUpdatinLines: point: [%d] start: %d, end: %d, line type: %d, --- attribs: y: %f, next y: %f, curve %f, valA %f, valB %f", - pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); -#endif - - // calculate final updated line - if (type == 0) - { - // calculate curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); - } - // no line type - } - else if (type == 1) - { - // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); - } - // line type - processLineTypeArraySine(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, fadeInStart); - } - else if (type == 2) - { - // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } - // line type - processLineTypeArraySineB(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); - } - else if (type == 3) - { - // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } - // line type - processLineTypeArrayPeak(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); - } - else if (type == 4) - { - // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); - } - // line type - processLineTypeArraySteps(&m_updatingBakedSamples, sampleXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); - } - else if (type == 5) - { - // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } - // line type - processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); - } - if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) - { - int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; - int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; - // process line effect - // if it is enabled - for (int j = startB; j < endB; j++) - { - m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); - } - } - // clamp - for (int j = start; j < end; j++) - { - if (m_updatingBakedSamples[j] > 1.0f) - { - m_updatingBakedSamples[j] = 1.0f; - } - else if (m_updatingBakedSamples[j] < -1.0f) - { - m_updatingBakedSamples[j] = -1.0f; - } - } - if (m_isNonNegative == true) - { - int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; - int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; - for (int j = startB; j < endB; j++) - { - m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; - } - } -} - -bool VectorGraphDataArray::isEffectedPoint(unsigned int pointLocation) -{ - // return true when 1 or more effects are active - return (getEffect(pointLocation, 0) + getEffect(pointLocation, 1) + getEffect(pointLocation, 2)) != 0; -} -void VectorGraphDataArray::formatDataArrayEndPoints() -{ - if (m_isFixedEndPoints == true && m_dataArray.size() > 0) - { - m_dataArray[m_dataArray.size() - 1].m_x = 1; - m_dataArray[m_dataArray.size() - 1].m_y = 1.0f; - m_dataArray[0].m_x = 0; - m_dataArray[0].m_y = -1.0f; - // dataChanged is called in functions using this function - // so this function does not call it - } -} - -void VectorGraphDataArray::dataChanged() -{ - m_parent->dataArrayChanged(); -} -void VectorGraphDataArray::clearedEvent() -{ - m_parent->dataArrayClearedEvent(m_id); -} -void VectorGraphDataArray::styleChanged() -{ - m_parent->dataArrayStyleChanged(); -} - -} // namespace lmms From 262935e8b0835c91494255904d55d15b5c20ee17 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:18:44 +0200 Subject: [PATCH 150/184] CMakeLists_updated --- src/core/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1e2c4f3cfdb..02d75870747 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -87,6 +87,7 @@ set(LMMS_SRCS core/UpgradeExtendedNoteRange.cpp core/Clip.cpp core/ValueBuffer.cpp + core/VectorGraphModel.cpp core/VstSyncController.cpp core/StepRecorder.cpp From 6e52a6e76e0cdc25f1e0b0749b8b9f26216fe61c Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:19:34 +0200 Subject: [PATCH 151/184] CMakeLists_updated_2 --- src/gui/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index f9f6911c289..65c601f1895 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -128,7 +128,7 @@ SET(LMMS_SRCS gui/widgets/TextFloat.cpp gui/widgets/TimeDisplayWidget.cpp gui/widgets/ToolButton.cpp - gui/widgets/VectorGraph.cpp + gui/widgets/VectorGraphView.cpp gui/widgets/VectorGraphViewBase.cpp PARENT_SCOPE From a0f1487c05f7de00df2d0f462de26f4230713958 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:20:06 +0200 Subject: [PATCH 152/184] VectorGraphViewBase_updated_includes --- include/VectorGraphViewBase.h | 2 +- src/gui/widgets/VectorGraphViewBase.cpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 10622c7aacd..5866aa14e31 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -40,7 +40,7 @@ namespace lmms { -class VectorGraphModel; +class VectorGraphView; class FloatModel; namespace gui diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 9a080a9b8f2..c61757447bd 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -24,7 +24,7 @@ #include "VectorGraphViewBase.h" -#include "VectorGraph.h" +#include "VectorGraphView.h" #include #include // showInputDialog() @@ -38,8 +38,6 @@ #include "GuiApplication.h" // getGUI #include "SimpleTextFloat.h" #include "AutomatableModel.h" -#include "ControllerConnectionDialog.h" -#include "ControllerConnection.h" #include "Knob.h" #include "ComboBox.h" From bdc9076d0e19c0644a0a058fcebcf031b2399901 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:20:49 +0200 Subject: [PATCH 153/184] VectorGraphModel_separated_model_class --- include/VectorGraphModel.h | 570 ++++++++ src/core/VectorGraphModel.cpp | 2357 +++++++++++++++++++++++++++++++++ 2 files changed, 2927 insertions(+) create mode 100644 include/VectorGraphModel.h create mode 100644 src/core/VectorGraphModel.cpp diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h new file mode 100644 index 00000000000..da0776adb5e --- /dev/null +++ b/include/VectorGraphModel.h @@ -0,0 +1,570 @@ +/* + * VecorGraph.h - Vector graph model implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 LMMS_GUI_VECTORGRAPHMODEL_H +#define LMMS_GUI_VECTORGRAPHMODEL_H + +#include +#include +#include +#include +#include +#include +#include + +#include "VectorGraphView.h" +#include "Model.h" +#include "ModelView.h" +#include "lmms_basics.h" +#include "AutomatableModel.h" +#include "JournallingObject.h" +#include "SubWindow.h" + +namespace lmms +{ + +class VectorGraphDataArray; +class FloatModel; + +using PointF = std::pair; + +class LMMS_EXPORT VectorGraphModel : public Model, public JournallingObject +{ +Q_OBJECT +public: + VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed); + ~VectorGraphModel(); + + inline size_t getDataArraySize() + { + return m_dataArrays.size(); + } + inline VectorGraphDataArray* getDataArray(unsigned int arrayLocation) + { + return &m_dataArrays[arrayLocation]; + } + inline unsigned int getMaxLength() + { + return m_maxLength; + } + inline void setMaxLength(unsigned int arrayMaxLength) + { + if (m_maxLength != arrayMaxLength) + { + m_maxLength = arrayMaxLength; + emit dataChanged(); + emit updateGraphView(false); + } + } + // returns added VectorGraphDataArray location + unsigned int addDataArray(); + // deletes VectorGraphDataArray at arrayLocation + // preservs the order + void deleteDataArray(unsigned int arrayLocation); + inline void clearDataArray() + { + m_dataArrays.clear(); + emit dataChanged(); + emit updateGraphView(false); + } + // if the id is not found then it will return 0 + int getDataArrayLocationFromId(int arrayId); + int getDataArrayNewId(); + + // save, load + QString nodeName() const override + { + return "VectorGraphModel"; + } + virtual void saveSettings(QDomDocument& doc, QDomElement& element, const QString& name); + virtual void loadSettings(const QDomElement& element, const QString& name); + virtual void saveSettings(QDomDocument& doc, QDomElement& element); + virtual void loadSettings(const QDomElement& element); + void lockGetSamplesAccess(); + void unlockGetSamplesAccess(); + void lockBakedSamplesAccess(); + void unlockBakedSamplesAccess(); +signals: + // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed + void dataChanged(); + void updateGraphView(bool shouldUseGetLastSamples); + // signals when a dataArray gets to 0 element size + // arrayLocation is the location of the VectorGraphDataArray + // arrayLocation can be -1 + void clearedEvent(int arrayLocation); + // style changed inside m_dataArray + void styleChanged(); +public slots: + void dataArrayChanged(); + void updateGraphModel(bool shouldUseGetLastSamples); + void dataArrayClearedEvent(int arrayId); + void dataArrayStyleChanged(); +private: + // addJournalCheckpoint + void modelAddJournalCheckPoint(); + + std::vector m_dataArrays; + unsigned int m_maxLength; + + // block threads that want to access + // a dataArray's getSamples() at the same time + QMutex m_getSamplesAccess; + QMutex m_bakedSamplesAccess; + friend class lmms::gui::VectorGraphView; +}; + +class LMMS_EXPORT VectorGraphDataArray +{ + +public: + // avoid using this or run updateConnections() after initialization + VectorGraphDataArray(); + VectorGraphDataArray( + bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, + bool isSaveable, VectorGraphModel* parent, int arrayId); + ~VectorGraphDataArray(); + + void updateConnections(VectorGraphModel* parent); + + // see descriptions in privete + void setIsFixedSize(bool bValue); + void setIsFixedX(bool bValue); + void setIsFixedY(bool bValue); + void setIsFixedEndPoints(bool bValue); + void setIsSelectable(bool bValue); + void setIsEditableAttrib(bool bValue); + void setIsAutomatableEffectable(bool bValue); + void setIsSaveable(bool bValue); + void setIsNonNegative(bool bValue); + void setLineColor(QColor color); + void setActiveColor(QColor color); + void setFillColor(QColor color); + void setAutomatedColor(QColor color); + + // sets a dataArray as an effector to this dataArray + // returns true if successful + // if callDataChanged then it will call dataChanged() --> paintEvent() + bool setEffectorArrayLocation(int arrayLocation, bool callDataChanged); + void setIsAnEffector(bool bValue); + + bool getIsFixedSize(); + bool getIsFixedX(); + bool getIsFixedY(); + bool getIsFixedEndPoints(); + bool getIsSelectable(); + bool getIsEditableAttrib(); + bool getIsAutomatableEffectable(); + bool getIsSaveable(); + bool getIsNonNegative(); + QColor* getLineColor(); + QColor* getActiveColor(); + QColor* getFillColor(); + QColor* getAutomatedColor(); + // returns -1 if it has no effector + + int getEffectorArrayLocation(); + bool getIsAnEffector(); + int getId(); + + + // array: ------------------- + // checks m_isFixedSize (== false) and m_maxLength + // returns the location of added point, -1 if not found or can not be added + // returns the location of found point if there is a point already at newX + int add(float newX); + // checks m_isFixedSize (== false) + // deletes the point in pointLocation location + void deletePoint(unsigned int pointLocation); + // clears m_dataArray without any checks + inline void clear() + { + m_dataArray.clear(); + m_needsUpdating.clear(); + // m_automationModelArray should not be cleared without FloatModel destruction + clearedEvent(); + getUpdatingFromPoint(-1); + dataChanged(); + } + inline size_t size() + { + return m_dataArray.size(); + } + // clamps down the values to 0 - 1, -1 - 1 + // sorts array, removes duplicated x positions, calls dataChanged() if callDataChanged + // clamp: should clamp, sort: should sort + void formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + + + // get attribute: ------------------- + inline float getX(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_x; + } + inline float getY(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_y; + } + inline float getC(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_c; + } + inline float getValA(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_valA; + } + inline float getValB(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_valB; + } + inline unsigned int getType(unsigned int pointLocation) + { + return m_dataArray[pointLocation].m_type; + } + // returns attribLocation: 0 = m_y, 1 = m_c, 2 = m_valA, 3 = m_valB (int VectorGraphPoint) + unsigned int getAutomatedAttribLocation(unsigned int pointLocation); + unsigned int getEffectedAttribLocation(unsigned int pointLocation); + // returns true when m_effectPoints is true or + // when getEffectedAttribLocation() > 0 (y is uneffected) + bool getEffectPoints(unsigned int pointLocation); + // returns true when m_effectLines is true and + // when getEffectedAttribLocation() == 0 (y is effected) + bool getEffectLines(unsigned int pointLocation); + // returns the effect type of the selected id or slot + // effectSlot: which effect slot (m_effectTypeA / B / C) + unsigned int getEffect(unsigned int pointLocation, unsigned int effectSlot); + // true when the automationModel's value changed since last check + bool getIsAutomationValueChanged(unsigned int pointLocation); + // can return nullptr + FloatModel* getAutomationModel(unsigned int pointLocation); + + + // get: ------------------- + // returns -1 when position is not found + int getLocation(float searchX); + // gets the nearest data location to the position, + // foundOut is true when the nearest position = searchXIn, + // reurns -1 when search failed + int getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut); + + + // returns the latest updated graph values + // targetSizeIn is the retuned vector's size + void getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut); + // returns m_bakedSamples without updating + void getLastSamples(std::vector* sampleBufferOut); + std::vector getEffectorArrayLocations(); + + + // set: ------------------- + // sets / adds m_dataArray points + // .first = x, .second = y coords + // isCurved -> should set curve automatically + // clear -> clear m_dataArray before setting + // clamp -> clamp input positions + // rescale -> scale input positions + // sort -> sort input positions + // callDataChanged -> call dataChanged() after -> paintEvent() + // PointF = std::pair + // ()the std::vector* inputDataArray modifies the array) + void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged); + void setDataArray(std::vector* inputDataArray, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); + void setDataArray(float* inputDataArray, unsigned int size, bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged); + + + // set attribute: ------------------- + // checks m_isFixedX (== false) + // sets x position, returns final location + // returns the location of found point if there is a point already at newX + unsigned int setX(unsigned int pointLocation, float newX); + // checks m_isFixedY (== false) + // sets y position + void setY(unsigned int pointLocation, float newY); + // checks m_isEditableAttrib + // sets curve + void setC(unsigned int pointLocation, float newC); + // checks m_isEditableAttrib + // sets 1. attribute value + void setValA(unsigned int pointLocation, float fValue); + // checks m_isEditableAttrib + // sets 2. attribute value + void setValB(unsigned int pointLocation, float fValue); + // checks m_isEditableAttrib + // sets line type + void setType(unsigned int pointLocation, unsigned int newType); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets what attribute gets automated (by point's FloatModel) + void setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets what attribute gets effected (by effector array) + void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // if bValue is true then the effector array will effect the point's attributes + void setEffectPoints(unsigned int pointLocation, bool bValue); + // checks m_isAutomatableEffectable and m_isEditableAttribs + // if bValue is true then the effector array will effect the line's individual samples (only when y is effected) + void setEffectLines(unsigned int pointLocation, bool bValue); + // checks m_isAutomatableEffectable and m_isEditableAttrib + // sets the point's effect type + // effectSlot: which effect slot (m_effectTypeA / B / C), effectType: what kind of effect (add, exct) + void setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType); + // checks m_isAutomatableEffectable + // if bValue is true then make a new FloatModel and connect it, else delete + // the currently used FloatModel + void setAutomated(unsigned int pointLocation, bool bValue); + + +// signals: // not qt + void dataChanged(); + // runs when m_dataArray.size() gets to 0 + void clearedEvent(); + // color + void styleChanged(); +private: + // returns m_automationModelArray + std::vector* getAutomationModelArray(); + // delete automationModels in m_automationModelArray + // that are not used by points (there should be 0 cases like this) + void deleteUnusedAutomation(); + // encodes m_dataArray to QString + QString getSavedDataArray(); + // decodes and sets m_dataArray from QString + void loadDataArray(QString data, unsigned int arraySize, bool callDataChanged); + + class VectorGraphPoint + { + public: + inline VectorGraphPoint() + { + } + inline VectorGraphPoint(float x, float y) + { + m_x = x; + m_y = y; + } + // 0 - 1 + float m_x = 0.0f; + // -1 - 1, getAutomatedAttrib() -> 0 + float m_y = 0.0f; + // curve, -1 - 1, getAutomatedAttrib() -> 1 + float m_c = 0.0f; + // valueA, -1 - 1, getAutomatedAttrib() -> 2 + float m_valA = 0.0f; + // valueB, -1 - 1, getAutomatedAttrib() -> 3 + float m_valB = 0.0f; + // line type: + // 0 - none + // 1 - sine + // 2 - sineB + // 3 - peak + // 4 - steps + // 5 - random + unsigned int m_type = 0; + // the automated attrib location and + // the effected attrib location is + // stored here + // use getAutomatedAttrib or getEffectedAttrib to get it + unsigned int m_automatedEffectedAttribLocations = 0; + + // what effect will be applyed if effected + // effects: + // 0 - none + // 1 - add + // 2 - subtract + // 3 - multiply + // 4 - divide + // 5 - power + // 6 - log + // 7 - sine + // 8 - lower clamp + // 9 - upper clamp + unsigned int m_effectTypeA = 0; + unsigned int m_effectTypeB = 0; + unsigned int m_effectTypeC = 0; + + // if the point attributes should be effected, + // getEffectPoints() will return true when + // effected attrib location > 0 + bool m_effectPoints = false; + // if the line (each sample) should be effected (only works when y is effected) + bool m_effectLines = true; + + /* + bool m_effectAdd = false; + bool m_effectSubtract = false; + bool m_effectMultiply = false; + bool m_effectDivide = false; + bool m_effectPower = false; + bool m_effectLog = false; + bool m_effectSine = false; + bool m_effectClampLower = false; + bool m_effectClampUpper = false; + */ + + // stores m_automationModel->value(), used in getSamples() when updating + float m_bufferedAutomationValue = 0.0f; + // automation: connecting to floatmodels, -1 when it isn't conntected + int m_automationModel = -1; + }; + // deletes the point's automation model + // if modelLocation == point location + void deleteAutomationModel(int modelLocation, bool callDataChanged); + // swapping values, "shouldShiftBetween" moves the values (between) once left or right to keep the order + // handle m_isFixedEndPoints when using this + void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween); + // returns the curve value at a given x coord, does clamp + float processCurve(float yBefore, float yAfter, float curve, float xIn); + // returns effected attribute value from base attribValue (input attribute value), does clamp + // this function applies the point Effects (like add effect) based on attribValue and effectValue + float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); + float processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, float attribValue, float effectValue); + // returns automated attribute value from base attribValue (input attribute value), does clamp + float processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation); + + // line types, m_type is used for this + // fadeInStartVal: from what relative x value should the line type fade out + // linking: valA: sineAmp, valB: sineFreq + void processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float sineAmp, float sineFreq, float fadeInStartVal); + // linking: valA: sineAmp, valB: sineFreq, curve: sinePhase + void processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal); + // linking: valA: amp, valB: x coord, curve: width + void processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float peakAmp, float peakX, float peakWidth, float fadeInStartVal); + // linking: y: yArray, valA: stepCount, valB: stepCurve + void processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal); + // linking: valA: randomAmp, valB: randomCount, curve: randomSeed + void processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float randomAmp, float randomCount, float randomSeed, float fadeInStartVal); + + // updating + // adds the m_dataArray points that are + // effected by the changed effector array points. + // ONLY WORKS IN SORTED ARRAYS + void getUpdatingFromEffector(std::vector* updatingPointLocations); + // if pointLocation >= 0 -> adds the location to m_needsUpdating + // else it will update the whole m_dataArray and m_bakedSamples + // changes in the size of m_dataArray (addtition, deletion, ect.) + // should to cause a full update + void getUpdatingFromPoint(int pointLocation); + // adds the points that are changed because their + // automation is changed + void getUpdatingFromAutomation(); + // recalculates and sorts m_needsUpdating so + // every point is in there only once + void getUpdatingOriginals(); + + // real getSamples processing + void getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, + std::vector* updatingValuesOut, std::vector* sampleBufferOut); + // redraw lines + void getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize); + bool isEffectedPoint(unsigned int pointLocation); + + // checks m_isFixedEndPoints, does not call dataChanged() + void formatDataArrayEndPoints(); + + // can new data be added or removed + bool m_isFixedSize; + // can the positions be changed + bool m_isFixedX; + // can the values be changed + bool m_isFixedY; + // if true then it makes the last point coordinate 1, 1, the first point coordinate -1, 0 + bool m_isFixedEndPoints; + // can VectorGraphView select this + bool m_isSelectable; + // can the point attributes be edited + // every attribute outside of x and y + // automation can be changed + bool m_isEditableAttrib; + // can the points be automated or effected + // (can these settings be changed) + bool m_isAutomatableEffectable; + // if VectorGraphDataArray is allowed to save this + bool m_isSaveable; + // can values be less than 0 + bool m_isNonNegative; + + QColor m_lineColor; + QColor m_activeColor; + QColor m_fillColor; + QColor m_automatedColor; + + VectorGraphModel* m_parent; + // simple id system for setEffectorArrayLocation + int m_id; + + // which VectorGraphDataArray can effect this one, -1 if not effected + int m_effectorLocation; + // is this VectorGraphDataArray effects others? + bool m_isAnEffector; + + // ordered array of VectorGraphPoints + std::vector m_dataArray; + + + // baking + + // getSamples() will return m_bakedSamples if lines are unchanged + // else it will recalculate the changed line's values, update m_bakedSamples + // getSamples() needs to know where did lines change so it updates + // m_needsUpdating by running getUpdatingFromEffector() + // if m_isDataChanged is true, then getSamples recalculates all the lines/samples + // getSamples() clears m_needsUpdating after it has run + // updating a line means recalculating m_bakedSamples in getSamples() + // based on the changed points (stored in m_needsUpdating) + // changes in a point will causes its line to update (line started by the point) + // changes in position needs to cause the line before to update too + // addition or deletion needs to cause all the lines to update + + // if we want to update all (the full line in getSamples()) + bool m_isDataChanged; + // array containing output final float values for optimalization + std::vector m_bakedSamples; + // used for updating m_bakedSamples fast + std::vector m_updatingBakedSamples; + // unsorted array of locations in m_dataArray + // that need to be updated + // sorted in getUpdatingOriginals() because some functions need this to be sorted + std::vector m_needsUpdating; + + // this stores all the FloatModels, unsorted, should only contain currently used FloatModels + // used for automation + std::vector m_automationModelArray; + + // used in lineType calculations to store + // large amount of floats without reallocation + std::vector m_universalSampleBuffer; + + // used for saving + friend class lmms::VectorGraphModel; +}; + +} // namespace lmms + +#endif // LMMS_GUI_VECTORGRAPHMODEL_H diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp new file mode 100644 index 00000000000..b3a6b0cab16 --- /dev/null +++ b/src/core/VectorGraphModel.cpp @@ -0,0 +1,2357 @@ +/* + * VectorGraphModel.cpp - Vector graph model and helper class implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 "VectorGraphModel.h" + +#include // sort +#include +#include // sine +#include // rand +#include +#include // locking when getSamples + +#include "AutomatableModel.h" +#include "base64.h" +#include "GuiApplication.h" // getGUI +#include "JournallingObject.h" +#include "MainWindow.h" // getting main window for control dialog +#include "ProjectJournal.h" + +//#define VECTORGRAPH_DEBUG_USER_INTERACTION +//#define VECTORGRAPH_DEBUG_PAINT_EVENT + +namespace lmms +{ + +VectorGraphModel::VectorGraphModel(unsigned int arrayMaxLength, Model* parent, bool defaultConstructed) : + Model(parent, tr("VectorGraphModel"), defaultConstructed) +{ + m_maxLength = arrayMaxLength; + //m_dataArrays +} + +VectorGraphModel::~VectorGraphModel() +{ + m_dataArrays.clear(); +} + +unsigned int VectorGraphModel::addDataArray() +{ + VectorGraphDataArray tempArray( + false, false, false, false, false, false, false, + false, true, this, getDataArrayNewId()); + m_dataArrays.push_back(tempArray); + emit dataChanged(); + return m_dataArrays.size() - 1; +} + +void VectorGraphModel::deleteDataArray(unsigned int arrayLocation) +{ + std::vector effectorArrayLocations(m_dataArrays.size()); + for (unsigned int i = arrayLocation; i < m_dataArrays.size() - 1; i++) + { + m_dataArrays[i] = m_dataArrays[i + 1]; + } + m_dataArrays.pop_back(); + // reset effector locations to the correct locations + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + effectorArrayLocations[i] = m_dataArrays[i].getEffectorArrayLocation(); + if (m_dataArrays[i].getEffectorArrayLocation() == static_cast(arrayLocation)) + { + effectorArrayLocations[i] = -1; + } + else if (effectorArrayLocations[i] >= static_cast(arrayLocation)) + { + effectorArrayLocations[i]--; + } + // effectorLocations are cleared to avoid the + // dataArrays detecting loops and then not setting + m_dataArrays[i].setEffectorArrayLocation(-1, false); + } + // setting updated locations + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + m_dataArrays[i].setEffectorArrayLocation(effectorArrayLocations[i], false); + } + emit dataChanged(); + emit updateGraphView(false); +} + +void VectorGraphModel::dataArrayChanged() +{ + emit dataChanged(); + emit updateGraphView(false); +} +void VectorGraphModel::updateGraphModel(bool shouldUseGetLastSamples) +{ + // connects to external update signal + emit updateGraphView(shouldUseGetLastSamples); +} +void VectorGraphModel::dataArrayClearedEvent(int arrayId) +{ + // TODO needs testing + int location = getDataArrayLocationFromId(arrayId); + emit clearedEvent(location); + emit dataChanged(); + emit updateGraphView(false); +} + +void VectorGraphModel::dataArrayStyleChanged() +{ + emit styleChanged(); +} +int VectorGraphModel::getDataArrayLocationFromId(int arrayId) +{ + int output = -1; + + if (arrayId < 0) { return output; } + + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + if (m_dataArrays[i].getId() == arrayId) + { + output = i; + break; + } + } + return output; +} +int VectorGraphModel::getDataArrayNewId() +{ + int maxId = 0; + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + if (m_dataArrays[i].getId() > maxId) + { + maxId = m_dataArrays[i].getId(); + } + } + maxId++; + return maxId; +} +void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element, const QString& name) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("saveSettings start"); +#endif + + // getting the models saving name + QString saveName("VectorGraphModel"); + if (name.size() > 0) + { + saveName = name; + } + + QDomElement me = doc.createElement(saveName); + me.setAttribute("DataArrayCount", static_cast(m_dataArrays.size())); + for (unsigned int i = 0; i < m_dataArrays.size(); i++) + { + // getting rid of nullptr FloatMdoels + // (there should be 0) + for (unsigned int j = 0; j < m_dataArrays[i].size(); j++) + { + if (m_dataArrays[i].getAutomationModel(j) == nullptr) + { + m_dataArrays[i].setAutomated(j, false); + } + } + // delete automation that is in the automationModelArray + // but not used by a point (there should be 0 cases like this) + m_dataArrays[i].deleteUnusedAutomation(); + + // getting the start of the attribute name + QString readLocation = "a" + QString::number(i) + "-"; + std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); + bool isSaveable = m_dataArrays[i].getIsSaveable(); + // general saving attributes + me.setAttribute(readLocation + "DataArraySize", isSaveable == true ? static_cast(m_dataArrays[i].size()) : 0); + me.setAttribute(readLocation + "AutomationSize", isSaveable == true ? static_cast(automationModels->size()) : 0); + + if (isSaveable == true && m_dataArrays[i].size() > 0) + { + // saving the DataArray + me.setAttribute(readLocation + "DataArray", m_dataArrays[i].getSavedDataArray()); + + // saving the FloatModels + for (unsigned int j = 0; j < automationModels->size(); j++) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("saveSettings saved automatinModel dataArray (i): %d, model (j): %d", i, j); +#endif + QString readLocationB = QString::number(j) + "-"; + (*automationModels)[j]->saveSettings(doc, me, readLocation + readLocationB + "AutomationModel"); + } + } + } + element.appendChild(me); +} +void VectorGraphModel::loadSettings(const QDomElement& element, const QString& name) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadSettings start"); +#endif + QString loadName("VectorGraphModel"); + if (name.size() > 0) + { + loadName = name; + } + + QDomNode node = element.namedItem(loadName); + + if(node.isNull() == true) + { + for(QDomElement othernode = element.firstChildElement(); + !othernode.isNull(); + othernode = othernode.nextSiblingElement()) + { + if((!othernode.hasAttribute("DataArrayCount") && + othernode.nodeName() == loadName)) + { + node = othernode; + break; + } + } + } + + QDomElement curElement = node.toElement(); + if (curElement.hasAttribute("DataArrayCount") == true) + { + unsigned int loadSize = curElement.attribute("DataArrayCount").toInt(); + for (unsigned int i = 0; i < loadSize; i++) + { + // getting the start of the attribute name + QString readLocation = "a" + QString::number(i) + "-"; + if (i < m_dataArrays.size() && curElement.hasAttribute(readLocation + "DataArraySize") == true) + { + unsigned int dataArraySize = curElement.attribute(readLocation + "DataArraySize").toInt(); + unsigned int automationSize = curElement.attribute(readLocation + "AutomationSize").toInt(); + // load m_dataArray + if (dataArraySize > 0) + { + m_dataArrays[i].loadDataArray(curElement.attribute(readLocation + "DataArray"), dataArraySize, true); + } + + // load automationModelDataArray + std::vector* automationModels = m_dataArrays[i].getAutomationModelArray(); + for (unsigned int j = 0; j < automationSize; j++) + { + QString readLocationB = QString::number(j) + "-"; + FloatModel* curModel = new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, this, QString(), false); + curModel->loadSettings(curElement, readLocation + readLocationB + "AutomationModel"); + automationModels->push_back(curModel); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadSettings loaded automatinModel: arrayLocation (i): %d, model (j): %d", i, j); +#endif + } + } + else + { + break; + } + } + } +} +void VectorGraphModel::lockGetSamplesAccess() +{ + m_getSamplesAccess.lock(); +} +void VectorGraphModel::unlockGetSamplesAccess() +{ + m_getSamplesAccess.unlock(); +} +void VectorGraphModel::lockBakedSamplesAccess() +{ + m_bakedSamplesAccess.lock(); +} +void VectorGraphModel::unlockBakedSamplesAccess() +{ + m_bakedSamplesAccess.unlock(); +} +void VectorGraphModel::saveSettings(QDomDocument& doc, QDomElement& element) +{ + saveSettings(doc, element, QString("")); +} +void VectorGraphModel::loadSettings(const QDomElement& element) +{ + loadSettings(element, QString("")); +} +void VectorGraphModel::modelAddJournalCheckPoint() +{ + addJournalCheckPoint(); +} + +// VectorGraphDataArray ------ + +VectorGraphDataArray::VectorGraphDataArray() +{ + m_isFixedSize = false; + m_isFixedY = false; + m_isFixedX = false; + m_isFixedEndPoints = false; + m_isSelectable = false; + m_isEditableAttrib = false; + m_isAutomatableEffectable = false; + m_isSaveable = false; + m_isNonNegative = false; + + m_lineColor = QColor(200, 200, 200, 255); + m_activeColor = QColor(255, 255, 255, 255); + // fill color is not enabled by default + // (if alpha = 0) + m_fillColor = QColor(0, 0, 0, 0); + m_automatedColor = QColor(0, 0, 0, 0); + + m_effectorLocation = -1; + + // m_dataArray + m_isDataChanged = false; + // m_bakedSamples; + // m_updatingBakedSamples + // m_needsUpdating; + // m_automationModelArray; + + m_id = -1; +} + +VectorGraphDataArray::VectorGraphDataArray( + bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, + bool isSaveable, VectorGraphModel* parent, int arrayId) +{ + m_isFixedSize = isFixedSize; + m_isFixedY = isFixedX; + m_isFixedX = isFixedY; + m_isFixedEndPoints = isFixedEndPoints; + m_isSelectable = isSelectable; + m_isEditableAttrib = isEditableAttrib; + m_isAutomatableEffectable = isAutomatableEffectable; + m_isSaveable = isSaveable; + m_isNonNegative = isNonNegative; + + m_lineColor = QColor(200, 200, 200, 255); + m_activeColor = QColor(255, 255, 255, 255); + // fill color is not enabled by default + // (if alpha = 0) + m_fillColor = QColor(0, 0, 0, 0); + + m_effectorLocation = -1; + m_isAnEffector = false; + + // m_dataArray; + m_isDataChanged = false; + // m_bakedSamples; + // m_updatingBakedSamples + // m_needsUpdating; + // m_automationModelArray; + // m_universalSampleBuffer + + m_id = arrayId; + updateConnections(parent); +} + +VectorGraphDataArray::~VectorGraphDataArray() +{ + for (unsigned int i = 0; i < m_automationModelArray.size(); i++) + { + if (m_automationModelArray[i] != nullptr) + { + delete m_automationModelArray[i]; + } + } + m_automationModelArray.clear(); +} + +void VectorGraphDataArray::updateConnections(VectorGraphModel* parent) +{ + // call VectorGraphModel signals without qt + m_parent = parent; + m_id = m_parent->getDataArrayNewId(); + // reseting effectors + setEffectorArrayLocation(-1, true); +} + +void VectorGraphDataArray::setIsFixedSize(bool bValue) +{ + m_isFixedSize = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsFixedX(bool bValue) +{ + m_isFixedX = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsFixedY(bool bValue) +{ + m_isFixedY = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsFixedEndPoints(bool bValue) +{ + m_isFixedEndPoints = bValue; + formatDataArrayEndPoints(); + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsSelectable(bool bValue) +{ + m_isSelectable = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsEditableAttrib(bool bValue) +{ + m_isEditableAttrib = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsAutomatableEffectable(bool bValue) +{ + m_isAutomatableEffectable = bValue; + if (bValue == false) + { + // setEffectorArray will call dataChanged() + setEffectorArrayLocation(-1, true); + } + else + { + getUpdatingFromPoint(-1); + dataChanged(); + } +} +void VectorGraphDataArray::setIsSaveable(bool bValue) +{ + m_isSaveable = bValue; +} +void VectorGraphDataArray::setIsNonNegative(bool bValue) +{ + m_isNonNegative = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setLineColor(QColor bValue) +{ + m_lineColor = bValue; + styleChanged(); +} +void VectorGraphDataArray::setActiveColor(QColor color) +{ + m_activeColor = color; + styleChanged(); +} +void VectorGraphDataArray::setFillColor(QColor color) +{ + m_fillColor = color; + styleChanged(); +} +void VectorGraphDataArray::setAutomatedColor(QColor color) +{ + m_automatedColor = color; + styleChanged(); +} +bool VectorGraphDataArray::setEffectorArrayLocation(int arrayLocation, bool callDataChanged) +{ + bool found = true; + if (arrayLocation >= 0) + { + // if there is no valid id + if (m_id < 0) + { + m_id = m_parent->getDataArrayNewId(); + } + int searchArrayLocation = arrayLocation; + found = false; + // checking if the effector chain has this dataArray in it + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + int arrayId = m_parent->getDataArray(searchArrayLocation)->getId(); + searchArrayLocation = m_parent->getDataArray(searchArrayLocation)->getEffectorArrayLocation(); + if(arrayId == m_id) + { + found = true; + break; + } + if (searchArrayLocation == -1) + { + break; + } + } + // if the effector chain does not contain this dataArray + if (found == false) + { + m_effectorLocation = arrayLocation; + m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(true); + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } + } + } + else + { + if (m_effectorLocation != -1) + { + // checking if this VectorGraphDataArray's effector is an effector for an other VectorGraphDataArray + bool foundB = false; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + if (m_parent->getDataArray(i)->getId() != m_id && m_parent->getDataArray(i)->getEffectorArrayLocation() == m_effectorLocation) + { + foundB = true; + break; + } + } + // setting the correct state for the effector array's m_isAnEffector + m_parent->getDataArray(m_effectorLocation)->setIsAnEffector(foundB); + m_effectorLocation = -1; + + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } + } + } + return !found; +} +void VectorGraphDataArray::setIsAnEffector(bool bValue) +{ + m_isAnEffector = bValue; + // do not need to update anything after +} + +bool VectorGraphDataArray::getIsFixedSize() +{ + return m_isFixedSize; +} +bool VectorGraphDataArray::getIsFixedX() +{ + return m_isFixedX; +} +bool VectorGraphDataArray::getIsFixedY() +{ + return m_isFixedY; +} +bool VectorGraphDataArray::getIsFixedEndPoints() +{ + return m_isFixedEndPoints; +} +bool VectorGraphDataArray::getIsSelectable() +{ + return m_isSelectable; +} +bool VectorGraphDataArray::getIsEditableAttrib() +{ + return m_isEditableAttrib; +} +bool VectorGraphDataArray::getIsAutomatableEffectable() +{ + return m_isAutomatableEffectable; +} +bool VectorGraphDataArray::getIsSaveable() +{ + return m_isSaveable; +} +bool VectorGraphDataArray::getIsNonNegative() +{ + return m_isNonNegative; +} +QColor* VectorGraphDataArray::getLineColor() +{ + return &m_lineColor; +} +QColor* VectorGraphDataArray::getActiveColor() +{ + return &m_activeColor; +} +QColor* VectorGraphDataArray::getFillColor() +{ + return &m_fillColor; +} +QColor* VectorGraphDataArray::getAutomatedColor() +{ + return &m_automatedColor; +} +int VectorGraphDataArray::getEffectorArrayLocation() +{ + return m_effectorLocation; +} +bool VectorGraphDataArray::getIsAnEffector() +{ + return m_isAnEffector; +} +int VectorGraphDataArray::getId() +{ + return m_id; +} + + +// array: + +int VectorGraphDataArray::add(float newX) +{ + int location = -1; + if (m_isFixedSize == true || m_dataArray.size() >= m_parent->getMaxLength()) { return location; } + + bool found = false; + bool isBefore = false; + location = getNearestLocation(newX, &found, &isBefore); + if (found == false) + { + int targetLocation = -1; + bool dataChangedVal = false; + // if getNearestLocation returned a value + if (location >= 0) + { + targetLocation = location; + // shift the new data if the closest data x is bigger + // (done for swaping) + if (isBefore == true) + { + // we are adding one value, so dataArray.size() will be a valid location + if (targetLocation < m_dataArray.size()) + { + targetLocation++; + } + } + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); + swap(m_dataArray.size() - 1, targetLocation, true); + dataChangedVal = true; + } + else if (m_dataArray.size() <= 0) + { + m_dataArray.push_back(VectorGraphPoint(newX, 0.0f)); + targetLocation = 0; + dataChangedVal = true; + } + location = targetLocation; + + if (m_dataArray.size() <= 2) + { + formatDataArrayEndPoints(); + dataChangedVal = true; + } + if (dataChangedVal == true) + { + // addtition breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); + } + } + return location; +} + +void VectorGraphDataArray::deletePoint(unsigned int pointLocation) +{ + if (m_isFixedSize == true || pointLocation >= m_dataArray.size()) { return; } + + // deleting the points automationModel + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); + // swaping the point to the last location + // in m_dataArray + swap(pointLocation, m_dataArray.size() - 1, true); + m_dataArray.pop_back(); + if (pointLocation == 0 || pointLocation == m_dataArray.size()) + { + formatDataArrayEndPoints(); + } + // calling clearedEvent + if (m_dataArray.size() == 0) + { + clearedEvent(); + } + // deletion breaks the order of the locations + // in m_needsUpdating, so we update the whole m_dataArray + getUpdatingFromPoint(-1); + dataChanged(); +} + +void VectorGraphDataArray::formatArray(std::vector* dataArrayOut, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) +{ + if (shouldRescale == true) + { + // scale + float minX = 0.0f; + float maxX = 1.0f; + float minY = -1.0f; + float maxY = 1.0f; + for (unsigned int i = 0; i < dataArrayOut->size(); i++) + { + if ((*dataArrayOut)[i].first < minX) + { + minX = (*dataArrayOut)[i].first; + } + if ((*dataArrayOut)[i].first > maxX) + { + maxX = (*dataArrayOut)[i].first; + } + if ((*dataArrayOut)[i].second < minY) + { + minY = (*dataArrayOut)[i].second; + } + if ((*dataArrayOut)[i].second > maxY) + { + maxY = (*dataArrayOut)[i].second; + } + } + maxX = (maxX - minX); + minX = -minX; + maxY = (maxY - minY) * 0.5f; + minY = -minY; + if (minX != 0.0f || maxX != 1.0f) + { + for (unsigned int i = 0; i < dataArrayOut->size(); i++) + { + (*dataArrayOut)[i].first = ((*dataArrayOut)[i].first + minX) / maxX; + } + } + if (minY != -1.0f || maxY != 1.0f) + { + for (unsigned int i = 0; i < dataArrayOut->size(); i++) + { + (*dataArrayOut)[i].second = ((*dataArrayOut)[i].second + minY) / maxY - 1.0f; + } + } + } + if (shouldClamp == true || shouldRescale == true) + { + // clamp + for (unsigned int i = 0; i < dataArrayOut->size(); i++) + { + if ((*dataArrayOut)[i].first < 0.0f) + { + (*dataArrayOut)[i].first = 0.0f; + } + if ((*dataArrayOut)[i].first > 1.0f) + { + (*dataArrayOut)[i].first = 1.0f; + } + if ((*dataArrayOut)[i].second < -1.0f) + { + (*dataArrayOut)[i].second = -1.0f; + } + if ((*dataArrayOut)[i].second > 1.0f) + { + (*dataArrayOut)[i].second = 1.0f; + } + } + formatDataArrayEndPoints(); + } + + // sort + if (shouldSort == true) + { + std::sort(dataArrayOut->begin(), dataArrayOut->end(), + [](PointF a, PointF b) + { + return a.first < b.first; + }); + } + + // delete duplicates + float lastPos = -1.0f; + if (dataArrayOut->size() > 0) + { + lastPos = (*dataArrayOut)[0].first; + } + for (unsigned int i = 1; i < dataArrayOut->size(); i++) + { + if ((*dataArrayOut)[i].first == lastPos) + { + deletePoint(i); + } + else + { + lastPos = (*dataArrayOut)[i].first; + } + } + // calling clearedEvent is not needed + // because all of the values can not be cleared here + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } +} + +int VectorGraphDataArray::getLocation(float searchX) +{ + bool found = false; + bool isBefore = false; + int location = getNearestLocation(searchX, &found, &isBefore); + if (found == false) + { + return -1; + } + return location; +} + +int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bool* isBeforeOut) +{ + // modified binary search + if (m_dataArray.size() > 0) + { + int start = 0; + int end = m_dataArray.size() - 1; + int mid = 0; + // binary search + while (start < end) + { + mid = start + (end - start) / 2; + if (m_dataArray[mid].m_x == searchXIn) + { + *foundOut = true; + *isBeforeOut = false; + return mid; + } + else if (m_dataArray[mid].m_x < searchXIn) + { + start = mid + 1; + } + else + { + end = mid - 1; + } + } + int outputDif = 0; + mid = start + (end - start) / 2; + if (m_dataArray[mid].m_x > searchXIn && mid > 0) + { + mid = mid - 1; + } + if (mid + 1 < m_dataArray.size() && + std::abs(m_dataArray[mid].m_x - searchXIn) > + std::abs(m_dataArray[mid + 1].m_x - searchXIn)) + { + outputDif = 1; + } + *foundOut = searchXIn == m_dataArray[mid + outputDif].m_x; + *isBeforeOut = searchXIn >= m_dataArray[mid + outputDif].m_x; + return mid + outputDif; + } + *foundOut = false; + *isBeforeOut = false; + return -1; +} + +void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector* sampleBufferOut) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamples start: targetSizeIn: %d", targetSizeIn); +#endif + + if (sampleBufferOut != nullptr) + { + if (sampleBufferOut->size() != targetSizeIn) + { + sampleBufferOut->resize(targetSizeIn); + } + for (unsigned int i = 0; i < targetSizeIn; i++) + { + (*sampleBufferOut)[i] = 0; + } + + m_parent->lockGetSamplesAccess(); + getSamplesInner(targetSizeIn, nullptr, nullptr, sampleBufferOut); + m_parent->unlockGetSamplesAccess(); + } + else + { + // this needs to be allocated for getSamplesInner to work + // because every effector VectorGraphDataArray uses this to return its m_bakedValues directly + std::vector updatingSampleArray(targetSizeIn); + + m_parent->lockGetSamplesAccess(); + getSamplesInner(targetSizeIn, nullptr, nullptr, &updatingSampleArray); + m_parent->unlockGetSamplesAccess(); + } +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamples end"); +#endif +} +void VectorGraphDataArray::getLastSamples(std::vector* sampleBufferOut) +{ + m_parent->lockBakedSamplesAccess(); + *sampleBufferOut = m_bakedSamples; + m_parent->unlockBakedSamplesAccess(); +} +std::vector VectorGraphDataArray::getEffectorArrayLocations() +{ + // getting the effector array chain + std::vector output; + int currentLocation = m_effectorLocation; + for (unsigned int i = 0; i < m_parent->getDataArraySize(); i++) + { + if (currentLocation == -1) + { + break; + } + else + { + output.push_back(m_effectorLocation); + currentLocation = m_parent->getDataArray(currentLocation)->getEffectorArrayLocation(); + } + } + return output; +} + +void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool shouldSort, bool callDataChanged) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("setDataArray start"); +#endif + if (shouldClear == true) + { + m_dataArray.clear(); + } + m_dataArray.resize(inputDataArray->size()); + if (m_dataArray.size() == 0) + { + clearedEvent(); + } + if (shouldClamp == true || shouldRescale == true || shouldSort == true) + { + formatArray(inputDataArray, shouldClamp, shouldRescale, shouldSort, false); + } + bool noneBefore = true; + bool isNegativeBefore = false; + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + m_dataArray[i].m_x = (*inputDataArray)[i].first; + m_dataArray[i].m_y = (*inputDataArray)[i].second; + // calculating curves + if (shouldCurve == true && i > 0) + { + // TODO take in to account x coords + float diff = m_dataArray[i - 1].m_y - m_dataArray[i].m_y; + // if before is bigger than after + bool isNegative = diff >= 0; + float direction = 0; + if (noneBefore == true) + { + direction = isNegative == true ? 1.0f : -1.0f; + } + else + { + direction = isNegative == isNegativeBefore ? 1.0f : isNegative == true ? -1.0f : 1.0f; + } + + diff = diff * diff * 10.0f * direction; + diff = std::clamp(diff, -0.7f, 0.7f); + m_dataArray[i - 1].m_c = diff; + + noneBefore = diff < 0.1f && diff > -0.1f; + isNegativeBefore = isNegative; + } + } + // the whole m_dataArray needs to be updated + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } +} +void VectorGraphDataArray::setDataArray(std::vector* inputDataArray, + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) +{ + std::vector convertedDataArray(inputDataArray->size()); + float stepSize = 1.0f / static_cast(convertedDataArray.size()); + for (unsigned int i = 0; i < inputDataArray->size(); i++) + { + convertedDataArray[i].first = i * stepSize; + convertedDataArray[i].second = (*inputDataArray)[i]; + } + setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); +} +void VectorGraphDataArray::setDataArray(float* inputDataArray, unsigned int size, + bool shouldCurve, bool shouldClear, bool shouldClamp, bool shouldRescale, bool callDataChanged) +{ + std::vector convertedDataArray(size); + float stepSize = 1.0f / static_cast(size); + for (unsigned int i = 0; i < size; i++) + { + convertedDataArray[i].first = i * stepSize; + convertedDataArray[i].second = inputDataArray[i]; + } + setDataArray(&convertedDataArray, shouldCurve, shouldClear, shouldClamp, shouldRescale, false, callDataChanged); +} + +unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) +{ + int location = pointLocation; + if (m_isFixedX == false && newX <= 1.0f) + { + bool found = false; + bool isBefore = false; + location = getNearestLocation(newX, &found, &isBefore); + // if an other point was not found exactly at newX + // and if dataArray end points are changeable + if (found == false && ((m_isFixedEndPoints == true && + pointLocation < m_dataArray.size() - 1 && pointLocation > 0) || + m_isFixedEndPoints == false)) + { + int targetLocation = location; + // bool dataChangedVal = false; + // if getNearestLocation returned a value + if (location >= 0) + { + if (location < pointLocation && isBefore == true) + { + if (targetLocation + 1 < m_dataArray.size()) + { + targetLocation++; + } + } + else if (location > pointLocation && isBefore == false) + { + if (targetLocation > 0) + { + targetLocation--; + } + } + m_dataArray[pointLocation].m_x = newX; + swap(pointLocation, targetLocation, true); + location = targetLocation; + + getUpdatingFromPoint(-1); + // changes in the position can change lines before + // so the point before this is updated + if (location > 0) + { + getUpdatingFromPoint(location - 1); + } + dataChanged(); + } + else + { + location = pointLocation; + } + } + else + { + location = pointLocation; + } + } + return location; +} + +void VectorGraphDataArray::setY(unsigned int pointLocation, float newY) +{ + if (m_isFixedY == true) { return; } + + m_dataArray[pointLocation].m_y = newY; + getUpdatingFromPoint(pointLocation); + // changes in the position can change lines before + // so the point before this is updated + if (pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); + } + if (m_isFixedEndPoints == true && + (pointLocation <= 0 || pointLocation >= m_dataArray.size() - 1)) + { + formatDataArrayEndPoints(); + getUpdatingFromPoint(0); + getUpdatingFromPoint(m_dataArray.size() - 1); + } + dataChanged(); +} + +void VectorGraphDataArray::setC(unsigned int pointLocation, float newC) +{ + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_c = newC; + getUpdatingFromPoint(pointLocation); + dataChanged(); +} +void VectorGraphDataArray::setValA(unsigned int pointLocation, float fValue) +{ + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_valA = fValue; + getUpdatingFromPoint(pointLocation); + dataChanged(); +} +void VectorGraphDataArray::setValB(unsigned int pointLocation, float fValue) +{ + if (m_isEditableAttrib == false) { return; } + + m_dataArray[pointLocation].m_valB = fValue; + getUpdatingFromPoint(pointLocation); + dataChanged(); +} +void VectorGraphDataArray::setType(unsigned int pointLocation, unsigned int newType) +{ + if (m_isEditableAttrib == false) { return; } + + // set the type without changing the automated attribute location + m_dataArray[pointLocation].m_type = newType; + getUpdatingFromPoint(pointLocation); + dataChanged(); +} +void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation) +{ + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + // clamp only 4 attributes can be automated (y, c, valA, valB) + attribLocation = attribLocation > 3 ? 0 : attribLocation; + // set automated location correctly (effected_location = automatedEffectedLocation % 4) + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation * 4 + getEffectedAttribLocation(pointLocation); + + getUpdatingFromPoint(pointLocation); + // the line before this can get added later + // in getUpdatingFromAutomation + // so the point before this is not updated here + + dataChanged(); +} +void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation) +{ + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + // clamp only 4 attributes can be automated (y, c, valA, valB) + attribLocation = attribLocation > 3 ? 0 : attribLocation; + // set effected location correctly + m_dataArray[pointLocation].m_automatedEffectedAttribLocations = attribLocation + getAutomatedAttribLocation(pointLocation) * 4; + + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectPoints(pointLocation) == false && pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); + } + dataChanged(); +} +unsigned int VectorGraphDataArray::getAutomatedAttribLocation(unsigned int pointLocation) +{ + return m_dataArray[pointLocation].m_automatedEffectedAttribLocations / 4; +} +unsigned int VectorGraphDataArray::getEffectedAttribLocation(unsigned int pointLocation) +{ + return m_dataArray[pointLocation].m_automatedEffectedAttribLocations % 4; +} +bool VectorGraphDataArray::getEffectPoints(unsigned int pointLocation) +{ + // be careful with changing this + return (m_dataArray[pointLocation].m_effectPoints == true || getEffectedAttribLocation(pointLocation) > 0); +} +bool VectorGraphDataArray::getEffectLines(unsigned int pointLocation) +{ + // be careful with changing this + // m_effectLines ought to be false if lines (each sample) can not be changed + return (m_dataArray[pointLocation].m_effectLines == true && getEffectedAttribLocation(pointLocation) == 0); +} +void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bValue) +{ + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + if (m_dataArray[pointLocation].m_effectPoints != bValue) + { + // getEffectPoints does not return m_effectePoints + bool dataChangedValue = getEffectPoints(pointLocation); + m_dataArray[pointLocation].m_effectPoints = bValue; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectPoints(pointLocation)) + { + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectedAttribLocation(pointLocation) <= 0 && pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); + } + } + dataChanged(); + } +} +void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValue) +{ + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + if (m_dataArray[pointLocation].m_effectLines != bValue) + { + // getEffectLines does not return m_effectLines + bool dataChangedValue = getEffectLines(pointLocation); + m_dataArray[pointLocation].m_effectLines = bValue; + // this change does effect the main output if this + // data array is an effector of an other so dataChanged() + // and getUpdatingFromPoint is called + if (dataChangedValue != getEffectLines(pointLocation)) + { + getUpdatingFromPoint(pointLocation); + } + dataChanged(); + } +} +unsigned int VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigned int effectSlot) +{ + switch (effectSlot) + { + case 0: + return m_dataArray[pointLocation].m_effectTypeA; + case 1: + return m_dataArray[pointLocation].m_effectTypeB; + case 2: + return m_dataArray[pointLocation].m_effectTypeC; + } + return 0; +} +void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType) +{ + if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + + switch (effectSlot) + { + case 0: + m_dataArray[pointLocation].m_effectTypeA = effectType; + break; + case 1: + m_dataArray[pointLocation].m_effectTypeB = effectType; + break; + case 2: + m_dataArray[pointLocation].m_effectTypeC = effectType; + break; + } + getUpdatingFromPoint(pointLocation); + // if the current point can effect the line before it + // update the point before it + if (getEffectPoints(pointLocation) == true && pointLocation > 0) + { + getUpdatingFromPoint(pointLocation - 1); + } + dataChanged(); +} +bool VectorGraphDataArray::getIsAutomationValueChanged(unsigned int pointLocation) +{ + if (getAutomationModel(pointLocation) != nullptr && + m_dataArray[pointLocation].m_bufferedAutomationValue != getAutomationModel(pointLocation)->value()) + { + m_dataArray[pointLocation].m_bufferedAutomationValue = getAutomationModel(pointLocation)->value(); + return true; + } + return false; +} +void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setAutomated start"); +#endif + if (m_isAutomatableEffectable == false) { return; } + + if (bValue == true) + { + // if it is not already automated + if (m_dataArray[pointLocation].m_automationModel == -1) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setAutomated: make new floatModel, location: %d", pointLocation); +#endif + m_automationModelArray.push_back(new FloatModel(0.0f, -1.0f, 1.0f, 0.01f, m_parent, QString(), false)); + m_dataArray[pointLocation].m_automationModel = m_automationModelArray.size() - 1; + getUpdatingFromPoint(pointLocation); + dataChanged(); + } + } + else + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setAutomated: delete floatModel, location: %d, size: %d", pointLocation, static_cast(m_automationModelArray.size())); +#endif + // dataChanged() is called in this function + // this function check if the current point has an automationModel + deleteAutomationModel(m_dataArray[pointLocation].m_automationModel, true); + } +} +FloatModel* VectorGraphDataArray::getAutomationModel(unsigned int pointLocation) +{ + if (m_dataArray[pointLocation].m_automationModel != -1) + { + return m_automationModelArray[m_dataArray[pointLocation].m_automationModel]; + } + return nullptr; +} + +// private: +std::vector* VectorGraphDataArray::getAutomationModelArray() +{ + return &m_automationModelArray; +} +void VectorGraphDataArray::deleteUnusedAutomation() +{ + bool dataChangedVal = false; + std::vector usedAutomation; + for (auto i : m_dataArray) + { + if (i.m_automationModel != -1) + { + usedAutomation.push_back(i.m_automationModel); + } + } + for (unsigned int i = 0; i < m_automationModelArray.size(); i++) + { + bool found = false; + for (unsigned int j = 0; j < usedAutomation.size(); j++) + { + if (i == usedAutomation[j]) + { + found = true; + break; + } + } + if (found == false) + { + dataChangedVal = true; + deleteAutomationModel(i, false); + } + } + + // getUpdatingFromPoint() is called in deleteAutomationModel() + if (dataChangedVal == true) + { + dataChanged(); + } +} +QString VectorGraphDataArray::getSavedDataArray() +{ + QString output; + base64::encode((const char *)(m_dataArray.data()), + m_dataArray.size() * sizeof(VectorGraphPoint), output); + return output; +} +void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, bool callDataChanged) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("loadDatatArray start: arraySize: %d", arraySize); +#endif + int size = 0; + char* dst = 0; + base64::decode(data, &dst, &size); + + if (size == arraySize * sizeof(VectorGraphPoint)) + { + m_dataArray.resize(arraySize); + + VectorGraphPoint* points = (VectorGraphPoint*)dst; + for (unsigned int i = 0; i < arraySize; i++) + { + m_dataArray[i] = points[i]; + } + } + + delete[] dst; + getUpdatingFromPoint(-1); + if (callDataChanged == true) + { + dataChanged(); + } +} + +void VectorGraphDataArray::deleteAutomationModel(int modelLocation, bool callDataChanged) +{ + if (modelLocation < 0 || modelLocation >= m_automationModelArray.size()) { return; } + + FloatModel* curModel = m_automationModelArray[modelLocation]; + + // copy the last FloatModel* to the current location + m_automationModelArray[modelLocation] = + m_automationModelArray[m_automationModelArray.size() - 1]; + + m_automationModelArray.pop_back(); + + // replace all m_auttomationModel-s in the current copyed location with -1 + // replace all last m_automationModel-s to the currently copyed location + // there should be only 2 points changed but because of safety + // all of them are checked + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (m_dataArray[i].m_automationModel == modelLocation) + { + m_dataArray[i].m_automationModel = -1; + getUpdatingFromPoint(i); + if (i > 0) + { + getUpdatingFromPoint(i - 1); + } + } + if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) + { + m_dataArray[i].m_automationModel = modelLocation; + } + } + if (curModel != nullptr) + { + delete curModel; + curModel = nullptr; + } + + if (callDataChanged == true) + { + dataChanged(); + } +} + +void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween) +{ + if (pointLocationA == pointLocationB) { return; } + + if (shouldShiftBetween == true) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("swap: -------"); + qDebug("first point location: %d, second point locaiton: %d", pointLocationA, pointLocationB); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); + } +#endif + + if (pointLocationA < pointLocationB) + { + VectorGraphPoint swap = m_dataArray[pointLocationA]; + for (unsigned int i = pointLocationA; i < pointLocationB; i++) + { + m_dataArray[i] = m_dataArray[i + 1]; + } + m_dataArray[pointLocationB] = swap; + } + else + { + VectorGraphPoint swap = m_dataArray[pointLocationA]; + for (unsigned int i = pointLocationA; i > pointLocationB; i--) + { + m_dataArray[i] = m_dataArray[i - 1]; + } + m_dataArray[pointLocationB] = swap; + } + +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug(" --------- "); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + qDebug(" - i: %d - x: %f", i, m_dataArray[i].m_x); + } +#endif + } + else + { + // normal swap + VectorGraphPoint swap = m_dataArray[pointLocationA]; + m_dataArray[pointLocationA] = m_dataArray[pointLocationB]; + m_dataArray[pointLocationB] = swap; + } + getUpdatingFromPoint(pointLocationB - 1 > 0 ? pointLocationB - 1 : 0); + getUpdatingFromPoint(pointLocationA - 1 > 0 ? pointLocationA - 1 : 0); + getUpdatingFromPoint(pointLocationA); + getUpdatingFromPoint(pointLocationB); + dataChanged(); +} +float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float x) +{ + // calculating line curve + float absCurveIn = std::abs(curve); + float pow = curve < 0.0f ? 1.0f - x : x; + pow = std::pow(pow, 1.0f - absCurveIn) - pow; + + float output = yBefore + (yAfter - yBefore) * x; + output = curve > 0.0f ? output + pow * (yAfter - yBefore) : output - pow * (yAfter - yBefore); + // clamp + if (yBefore > yAfter) + { + output = std::clamp(output, yAfter, yBefore); + } + else + { + output = std::clamp(output, yBefore, yAfter); + } + return output; +} + +float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attribValue, + unsigned int attribLocation, float effectValue) +{ + // calculating an effect on attribValue + float output = attribValue; + // effects + if (getEffectedAttribLocation(pointLocation) == attribLocation) + { + output = processSingleEffect(pointLocation, 0, output, effectValue); + output = processSingleEffect(pointLocation, 1, output, effectValue); + output = processSingleEffect(pointLocation, 2, output, effectValue); + + // clamp + output = std::clamp(output, -1.0f, 1.0f); + } + return output; +} + +float VectorGraphDataArray::processSingleEffect(unsigned int pointLocation, unsigned int effectSlot, + float attribValue, float effectValue) +{ + // calculating an effect on attribValue + float output = attribValue; + + // none + if (getEffect(pointLocation, effectSlot) == 0) { return output; } + + // effects + if (getEffect(pointLocation, effectSlot) == 1) + { + // add + output += effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 2) + { + // subtract + output -= effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 3) + { + // multiply + output = output * 5.0f * effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 4 && effectValue != 0.0f) + { + // divide + output = output / 5.0f / effectValue; + } + else if (getEffect(pointLocation, effectSlot) == 5 && output > 0.0f) + { + // power + output = std::pow(output, effectValue * 5.0f); + output = std::clamp(output, -1.0f, 1.0f); + } + else if (getEffect(pointLocation, effectSlot) == 6 && output > 0.0f && effectValue > 0.0f) + { + // log + output = std::log(output) / std::log(effectValue); + output = std::clamp(output, -1.0f, 1.0f); + } + else if (getEffect(pointLocation, effectSlot) == 7) + { + // sine + output = output + std::sin(effectValue * 100.0f); + } + else if (getEffect(pointLocation, effectSlot) == 8) + { + // clamp lower + output = std::max(effectValue, output); + } + else if (getEffect(pointLocation, effectSlot) == 9) + { + // clamp upper + output = std::min(effectValue, output); + } + return output; +} + +float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float attribValue, unsigned int attribLocation) +{ + // adding the automation value to attribValue + float output = 0.0f; + // if automated + FloatModel* automationModel = getAutomationModel(pointLocation); + if (automationModel != nullptr) + { + if (getAutomatedAttribLocation(pointLocation) == attribLocation) + { + output += automationModel->value(); + } + } + output += attribValue; + + output = std::clamp(output, -1.0f, 1.0f); + return output; +} + +void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float sineAmp, float sineFreq, float fadeInStartVal) +{ + processLineTypeArraySineB(samplesOut, xArray, startLoc, endLoc, + sineAmp, sineFreq, 0.0f, fadeInStartVal); +} +void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal) +{ + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; + int count = static_cast(endLoc) - static_cast(startLoc); + if (count < 0) + { + count = 0; + } + float tValB = 0.001f + ((sineFreq + 1.0f) / 2.0f) * 0.999f; + // calculating how many samples are needed to 1 complete wave + // we have "count" amount of samples and "tValB * 100.0f" amount of waves + int end = static_cast(std::floor(count / (tValB * 100.0f))); + if (count <= 0) + { + end = 0; + } + else + { + end = end > count ? count : end + 1; + } + // "allocate" "end" amount of floats + // for 1 whole sine wave + // in the universal buffer + if (m_universalSampleBuffer.size() < end) + { + m_universalSampleBuffer.resize(end); + } + + // calculate 1 wave of sine + for (unsigned int i = 0; i < end; i++) + { + // 628.318531f = 100.0f * 2.0f * pi + // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) + m_universalSampleBuffer[i] = sineAmp * std::sin( + (*xArray)[startLoc + i] * 628.318531f * tValB + sinePhase * 100.0f); + } + // copy the first wave until the end + for (int i = 0; i < count; i += end) + { + int endB = i + end >= count ? count - i : end; + for (unsigned int j = 0; j < endB; j++) + { + (*samplesOut)[startLoc + j + i] += m_universalSampleBuffer[j]; + } + } + + // fade in + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) + { + float x = (*xArray)[i] / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); + } + // fade out + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) + { + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); + } +} +void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float peakAmp, float peakX, float peakWidth, float fadeInStartVal) +{ + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; + int count = static_cast(endLoc) - static_cast(startLoc); + if (count < 0) + { + count = 0; + } + for (unsigned int i = 0; i < count; i++) + { + (*samplesOut)[startLoc + i] += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, + std::abs((*xArray)[startLoc + i] - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; + } + + // fade in + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) + { + float x = (*xArray)[i] / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); + } + // fade out + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) + { + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); + } +} +void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal) +{ + float startLocVal = (*samplesOut)[startLoc]; + float endLocVal = (*samplesOut)[endLoc > 0 ? endLoc - 1 : 0]; + int count = static_cast(endLoc) - static_cast(startLoc); + if (count < 0) + { + count = 0; + } + + float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; + for (unsigned int i = 0; i < count; i++) + { + float y = (*yArray)[startLoc + i] + 1.0f; + float diff = std::round(y * stepCountB) - y * stepCountB; + float smooth = 1.0f - std::abs(diff) * (1.0f - (stepCurve + 1.0f) / 2.0f) * 2.0f; + (*samplesOut)[startLoc + i] += diff / stepCountB * smooth; + } + + // fade in + unsigned int fadeInEndLoc = static_cast(fadeInStartVal * static_cast(count)); + for (unsigned int i = startLoc; i < startLoc + fadeInEndLoc; i++) + { + float x = (*xArray)[i] / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + startLocVal * (1.0f - x); + } + // fade out + for (unsigned int i = endLoc - 1; i > endLoc - fadeInEndLoc; i--) + { + float x = (1.0f - (*xArray)[i]) / fadeInStartVal; + (*samplesOut)[i] = (*samplesOut)[i] * x + endLocVal * (1.0f - x); + } +} +void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float randomAmp, float randomCount, float randomSeed, float fadeInStartVal) +{ + int count = static_cast(endLoc) - static_cast(startLoc); + if (count < 0) + { + count = 0; + } + + unsigned int randomValuesSize = static_cast(50.0f * (randomCount + 1.0f)) * 2; + + if (randomValuesSize <= 0) { return; } + + // "allocate" "randomValuesSize" amount of floats + // for generating random values + // in the universal buffer + if (m_universalSampleBuffer.size() < randomValuesSize) + { + m_universalSampleBuffer.resize(randomValuesSize); + } + + float blend = 10.0f + randomSeed * 10.0f; + int randomSeedB = static_cast(blend); + blend = blend - randomSeedB; + + std::srand(randomSeedB); + + // getting the random values + // generating 2 seeds and blending in between them + for (unsigned int i = 0; i < randomValuesSize / 2; i++) + { + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + std::srand(randomSeedB + 1); + for (unsigned int i = randomValuesSize / 2; i < randomValuesSize; i++) + { + m_universalSampleBuffer[i] = std::fmod((static_cast(rand()) / 10000.0f), 2.0f) - 1.0f; + } + + // blending + // real size + float size = static_cast(randomValuesSize / 2); + for (unsigned int i = 0; i < count; i++) + { + float randomValueX = (*xArray)[startLoc + i] * size; + float randomValueLocation = std::floor(randomValueX); + (*samplesOut)[startLoc + i] += -((randomValueX - randomValueLocation) - 1.0f) * (randomValueX - randomValueLocation) * 4.0f * + (m_universalSampleBuffer[static_cast(randomValueLocation)] * (1.0f - blend) + m_universalSampleBuffer[static_cast(randomValueLocation + size)] * blend) * randomAmp; + } +} + +void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) +{ + /* + * here m_needsUpdating points are decided + * firstly we get changed points from the effector graph (updatingPointLocations) + * we get a segment consisting of changed effector points that come after each other + * this will be useful because we can update the current graph's points between this segment (segment start = i, segment end = updatingEnd) + * secondly we get a (current graph's) point before the segment start and after the segment end + * so we get locationBefore and locationAfter which will be added to m_needsUpdating + * thirdly we finalyze locationBefore and locationAfter, clamp them and start adding the points between them to m_needsUpdating + * if the (current graph's) point is not effected, we avoid adding it to m_needsUpdating + */ + VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); + for (unsigned int i = 0; i < updatingPointLocations->size(); i++) + { + // since updatingPointLocations is a sorted list, we can get the end + // location and update everithing between them + // starting effector location is i, end effector location is updatingEnd + unsigned int updatingEnd = i; + for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) + { + // we can not skip gaps because + // every updatingPointLocations point effects their line only + // (the line that starts with the point) + if ((*updatingPointLocations)[updatingEnd] + 1 >= + (*updatingPointLocations)[j]) + { + updatingEnd = j; +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: new updatingEnd: %d, start (i): %d", updatingEnd, i); +#endif + } + else + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, + ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); +#endif + break; + } + } + // getting the point that comes after updatingEnd + // this is done because updatingEnd was changed so the line directly after updatingEnd point was changed + // so every (current graph's) point before updatingEnd + 1 needs to be changed + int updatingEndSlide = 0; + if (updatingEnd + 1 < effector->size()) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: updatingEndSlide = 1"); +#endif + updatingEndSlide = 1; + } + + // translating the effector data array locations to m_dataArray locations + bool found = false; + bool isBefore = false; + // this can return -1 + int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); +#endif + if (isBefore == true && locationBefore > 0 && getEffectPoints(locationBefore) == true) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: locationBefore = %d - 1", locationBefore); +#endif + // the line (or point) before might be effected if the current nearest point + // is effected in some way + // so subtract 1 + // remember points control the line after (connected to) them + // but in this case changes in the points position can effect the line before it + locationBefore--; + // now (here) locationBefore is Always before (*updatingPointLocations)[i] + } + // clamp + locationBefore = locationBefore < 0 ? 0 : + m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; + + isBefore = false; + int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, + effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); +#endif + if (isBefore == false) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: locationAfter = %d - 1", locationAfter); +#endif + // if the nearest point is after ([updatingEnd] + upadtingEndSlide) (where updating ends) + locationAfter--; + } + // updating everything before if i -> 0 + if ((*updatingPointLocations)[i] == 0) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector updating everything before"); +#endif + locationBefore = 0; + } + // if updatingEnd is the last point in effecor, then + // update everithing after + if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector updating everything after"); +#endif + locationAfter = m_dataArray.size() - 1; + } + // clamp + locationAfter = locationAfter < 0 ? 0 : + m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; + +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: final start: %d, final end: %d, i: %d", locationBefore, locationAfter, i); +#endif + + // if the last point was updated (ture in case of j = 0) + bool lastUpdated = true; + // adding the values between locationBefore, locationAfter + for (unsigned int j = locationBefore; j <= locationAfter; j++) + { + // update only if effected + if (isEffectedPoint(j) == true && (getEffectPoints(j) == true || getEffectLines(j) == true)) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromEffector: i: %d, updating: %d", i, j); +#endif + m_needsUpdating.push_back(j); + if (lastUpdated == false && getEffectPoints(j) == true) + { + m_needsUpdating.push_back(j - 1); + } + lastUpdated = true; + } + else + { + lastUpdated = false; + } + } + if (i < updatingEnd) + { + i = updatingEnd; + } + } +} +void VectorGraphDataArray::getUpdatingFromPoint(int pointLocation) +{ + // changes in position need to cause updates before the changed point + // changes in m_dataArray.size() needs to cause getUpdatingFromPoint(-1) + if (m_isDataChanged == false && pointLocation >= 0) + { + m_needsUpdating.push_back(pointLocation); + if (m_needsUpdating.size() > m_dataArray.size() * 3) + { + m_isDataChanged = true; + } + } + else if (pointLocation < 0) + { + m_isDataChanged = true; + } +} +void VectorGraphDataArray::getUpdatingFromAutomation() +{ + // adding points with changed automation values + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + if (getIsAutomationValueChanged(i) == true) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getUpdatingFromAutomation: point location: %d, attrib location: %d", i, getAutomatedAttribLocation(i)); +#endif + m_needsUpdating.push_back(i); + // if the automatable value effects the y (so the position) + // the point before this is updated too + if (i > 0 && getAutomatedAttribLocation(i) == 0) + { + m_needsUpdating.push_back(i - 1); + } + } + } +} +void VectorGraphDataArray::getUpdatingOriginals() +{ + // selecting only original values and sorting + +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + qDebug("getUpatingOriginals before: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); + } +#endif + + // sorting the array + // this is done becaues functions that use m_needsUpdating + // are optimized for a sorted array + std::sort(m_needsUpdating.begin(), m_needsUpdating.end(), + [](unsigned int a, unsigned int b) + { + return a < b; + }); + + // removing duplicates + int sizeDiff = 0; + for (int i = 1; i < m_needsUpdating.size(); i++) + { + if (m_needsUpdating[i - 1 + sizeDiff] == m_needsUpdating[i + sizeDiff]) + { + for (unsigned int j = i + sizeDiff; j < m_needsUpdating.size() - 1 + sizeDiff; j++) + { + m_needsUpdating[j] = m_needsUpdating[j + 1]; + } + sizeDiff--; + } + } + m_needsUpdating.resize(m_needsUpdating.size() + sizeDiff); + + // removing invalid locations + // because sometimes deleted locations can be in m_needsUpdating + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + if (m_needsUpdating[i] >= m_dataArray.size()) + { + m_needsUpdating.resize(i); + break; + } + } + +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + qDebug("getUpatingOriginals final: m_needsUpdating[%d] -> %d (point)", i, m_needsUpdating[i]); + } +#endif +} +void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isChangedOut, + std::vector* updatingValuesOut, std::vector* sampleBufferOut) +{ + bool effectorIsChanged = false; + //std::shared_ptr> effectorUpdatingValues = std::make_shared>(); + std::vector effectorUpdatingValues; + // sampleBufferOut will serve as the effector's sampleBufferOut until the new m_bakedSamples gets made + bool isEffected = m_effectorLocation >= 0; + if (isEffected == true) + { + m_parent->getDataArray(m_effectorLocation)->getSamplesInner(targetSizeIn, &effectorIsChanged, &effectorUpdatingValues, sampleBufferOut); + } +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: id: %d", m_id); +#endif + + m_isDataChanged = m_isDataChanged || targetSizeIn != m_updatingBakedSamples.size(); + + // deciding if the whole dataArray should be updated + // if the whole effectorDataArray was updated + int effectedCount = 0; + if (effectorIsChanged == true) + { + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + effectedCount += isEffectedPoint(i) == true? 1 : 0; + } + if (effectedCount > m_dataArray.size() / 2) + { + m_isDataChanged = m_isDataChanged || effectorIsChanged; + } + } + + // updating m_needsUpdating + if (m_isDataChanged == false && targetSizeIn == m_updatingBakedSamples.size()) + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: get updating"); +#endif + if (isEffected == true && effectorUpdatingValues.size() > 0 && + (effectorIsChanged == false || effectedCount > 0)) + { + // effectorUpdatingValues needs to be sorted + // before use (in this case it is already sorted) + getUpdatingFromEffector(&effectorUpdatingValues); + } + getUpdatingFromAutomation(); + // sort and select only original + // values + getUpdatingOriginals(); + } + else + { +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: update all points"); +#endif + m_parent->lockBakedSamplesAccess(); + if (targetSizeIn != m_bakedSamples.size()) + { + m_bakedSamples.resize(targetSizeIn); + } + m_parent->unlockBakedSamplesAccess(); + if (targetSizeIn != m_updatingBakedSamples.size()) + { + m_updatingBakedSamples.resize(targetSizeIn); + } + m_needsUpdating.resize(m_dataArray.size()); + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + m_needsUpdating[i] = i; + } + } + + float stepSize = 1.0f / static_cast(targetSizeIn); + // calculating point data and lines + if (m_needsUpdating.size() > 0 && m_updatingBakedSamples.size() > 0) + { + // calculating the relative X locations (in lines) of the output samples + // sampleXLocations[sample_location] is equal to 0.0f if it is at the start of a line + // and it is equal to 1.0f if it is at the end of a line + std::vector sampleXLocations(targetSizeIn); + for (unsigned int i = 0; i < m_dataArray.size(); i++) + { + unsigned int start = static_cast + (std::ceil(m_dataArray[i].m_x / stepSize)); + if (i + 1 < m_dataArray.size()) + { + unsigned int end = static_cast + (std::ceil(m_dataArray[i + 1].m_x / stepSize)); + for (unsigned int j = start; j < end; j++) + { + sampleXLocations[j] = (stepSize * static_cast(j) - m_dataArray[i].m_x) / (m_dataArray[i + 1].m_x - m_dataArray[i].m_x); + } + } + } + + // getting effectorDataArray pointer + VectorGraphDataArray* effector = nullptr; + if (m_effectorLocation >= 0 && m_parent->getDataArray(m_effectorLocation)->size() > 0) + { + effector = m_parent->getDataArray(m_effectorLocation); + } + +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner: updatingsize: %d", static_cast(m_needsUpdating.size())); +#endif + + // calculate final lines + for (unsigned int i = 0; i < m_needsUpdating.size(); i++) + { + // sampleBufferOut contains the effector m_bakedValues here + getSamplesUpdateLines(effector, sampleBufferOut, &sampleXLocations, i, stepSize); + } + + m_parent->lockBakedSamplesAccess(); + m_bakedSamples = m_updatingBakedSamples; + m_parent->unlockBakedSamplesAccess(); + } + + // setting outputs + if (isChangedOut != nullptr) + { + *isChangedOut = m_isDataChanged; + } + if (m_needsUpdating.size() > 0) + { + if (updatingValuesOut != nullptr) + { + *updatingValuesOut = m_needsUpdating; + } + + // clearing the updated values + m_needsUpdating.clear(); + } + m_parent->lockBakedSamplesAccess(); + *sampleBufferOut = m_bakedSamples; + m_parent->unlockBakedSamplesAccess(); + + m_isDataChanged = false; +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesInner end"); +#endif +} +void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, std::vector* effectorSamples, + std::vector* sampleXLocations, unsigned int pointLocation, float stepSize) +{ + unsigned int effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[pointLocation]].m_x / stepSize)); +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesUpdatinLines: m_needsUpdating[%d]: %d (point)\neffectYLocation: %d", pointLocation, m_needsUpdating[pointLocation], effectYLocation); +#endif + // current effector output Y near m_needsUpdating[pointLocation] point + float curEffectY = (*effectorSamples)[effectYLocation]; + float nextEffectY = (*effectorSamples)[effectYLocation]; + + // getting the final automatable / effectable point values + float curY = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_y, 0); + float curC = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_c, 1); + float curValA = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valA, 2); + float curValB = processAutomation(m_needsUpdating[pointLocation], m_dataArray[m_needsUpdating[pointLocation]].m_valB, 3); + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation]) == true && getEffectLines(m_needsUpdating[pointLocation]) == false) + { + curY = processEffect(m_needsUpdating[pointLocation], curY, 0, curEffectY); + curC = processEffect(m_needsUpdating[pointLocation], curC, 1, curEffectY); + curValA = processEffect(m_needsUpdating[pointLocation], curValA, 2, curEffectY); + curValB = processEffect(m_needsUpdating[pointLocation], curValB, 3, curEffectY); + } + // from where to update line + int start = effectYLocation; + int end = start; + + float nextY = curY; + + if (m_needsUpdating[pointLocation] + 1 < m_dataArray.size()) + { + effectYLocation = static_cast + (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); + // where updating line ends (+1) + end = effectYLocation; + nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); + + bool isCurEffected = isEffectedPoint(m_needsUpdating[pointLocation]); + // if the next point (y location) can be effected + // and the current point's line is uneffected + if (effector != nullptr && getEffectPoints(m_needsUpdating[pointLocation] + 1) == true && + (getEffectLines(m_needsUpdating[pointLocation]) == false || isCurEffected == false)) + { + nextEffectY = (*effectorSamples)[effectYLocation]; + nextY = processEffect(m_needsUpdating[pointLocation] + 1, nextY, 0, nextEffectY); + } + } + // calculating line ends + if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) + { + // if this point is at the last location in m_dataArray + for (int j = end; j < m_updatingBakedSamples.size(); j++) + { + m_updatingBakedSamples[j] = curY; + } + } + if (m_needsUpdating[pointLocation] == 0) + { + // if this point is at the 0 location in m_dataArray + for (int j = 0; j < start; j++) + { + m_updatingBakedSamples[j] = curY; + } + } + + float fadeInStart = 0.05f; + unsigned int type = m_dataArray[m_needsUpdating[pointLocation]].m_type; +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("getSamplesUpdatinLines: point: [%d] start: %d, end: %d, line type: %d, --- attribs: y: %f, next y: %f, curve %f, valA %f, valB %f", + pointLocation, start, end, type, curY, nextY, curC, curValA, curValB); +#endif + + // calculate final updated line + if (type == 0) + { + // calculate curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + } + // no line type + } + else if (type == 1) + { + // curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + } + // line type + processLineTypeArraySine(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, fadeInStart); + } + else if (type == 2) + { + // curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); + } + // line type + processLineTypeArraySineB(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); + } + else if (type == 3) + { + // curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); + } + // line type + processLineTypeArrayPeak(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); + } + else if (type == 4) + { + // curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + } + // line type + processLineTypeArraySteps(&m_updatingBakedSamples, sampleXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); + } + else if (type == 5) + { + // curve + for (int j = start; j < end; j++) + { + m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); + } + // line type + processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); + } + if (effector != nullptr && getEffectLines(m_needsUpdating[pointLocation]) == true) + { + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + // process line effect + // if it is enabled + for (int j = startB; j < endB; j++) + { + m_updatingBakedSamples[j] = processEffect(m_needsUpdating[pointLocation], m_updatingBakedSamples[j], 0, (*effectorSamples)[j]); + } + } + // clamp + for (int j = start; j < end; j++) + { + if (m_updatingBakedSamples[j] > 1.0f) + { + m_updatingBakedSamples[j] = 1.0f; + } + else if (m_updatingBakedSamples[j] < -1.0f) + { + m_updatingBakedSamples[j] = -1.0f; + } + } + if (m_isNonNegative == true) + { + int startB = m_needsUpdating[pointLocation] == 0 ? 0 : start; + int endB = m_needsUpdating[pointLocation] >= m_dataArray.size() - 1 ? m_updatingBakedSamples.size() : end; + for (int j = startB; j < endB; j++) + { + m_updatingBakedSamples[j] = m_updatingBakedSamples[j] / 2.0f + 0.5f; + } + } +} + +bool VectorGraphDataArray::isEffectedPoint(unsigned int pointLocation) +{ + // return true when 1 or more effects are active + return (getEffect(pointLocation, 0) + getEffect(pointLocation, 1) + getEffect(pointLocation, 2)) != 0; +} +void VectorGraphDataArray::formatDataArrayEndPoints() +{ + if (m_isFixedEndPoints == true && m_dataArray.size() > 0) + { + m_dataArray[m_dataArray.size() - 1].m_x = 1; + m_dataArray[m_dataArray.size() - 1].m_y = 1.0f; + m_dataArray[0].m_x = 0; + m_dataArray[0].m_y = -1.0f; + // dataChanged is called in functions using this function + // so this function does not call it + } +} + +void VectorGraphDataArray::dataChanged() +{ + m_parent->dataArrayChanged(); +} +void VectorGraphDataArray::clearedEvent() +{ + m_parent->dataArrayClearedEvent(m_id); +} +void VectorGraphDataArray::styleChanged() +{ + m_parent->dataArrayStyleChanged(); +} + +} // namespace lmms From 3690a48991ae668d3a08cb19245c0cc7999332f0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:21:12 +0200 Subject: [PATCH 154/184] VectorGraphView_separated_view_class --- include/VectorGraphView.h | 239 +++++ src/gui/widgets/VectorGraphView.cpp | 1312 +++++++++++++++++++++++++++ 2 files changed, 1551 insertions(+) create mode 100644 include/VectorGraphView.h create mode 100644 src/gui/widgets/VectorGraphView.cpp diff --git a/include/VectorGraphView.h b/include/VectorGraphView.h new file mode 100644 index 00000000000..9a4c8200dd3 --- /dev/null +++ b/include/VectorGraphView.h @@ -0,0 +1,239 @@ +/* + * VecorGraph.h - Vector graph widget implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 LMMS_GUI_VECTORGRAPHVIEW_H +#define LMMS_GUI_VECTORGRAPHVIEW_H + +#include +#include +#include +#include +#include +#include +#include + +#include "VectorGraphViewBase.h" +#include "VectorGraphModel.h" +#include "Model.h" +#include "ModelView.h" +#include "lmms_basics.h" +#include "AutomatableModel.h" +#include "JournallingObject.h" +#include "SubWindow.h" + +namespace lmms +{ + +//class VectorGraphView; +class VectorGraphModel; +class VectorGraphDataArray; +//class FloatModel; + +using PointF = std::pair; +using PointInt = std::pair; + +namespace gui +{ +class LMMS_EXPORT VectorGraphView : public VectorGraphViewBase, public ModelView +{ + Q_OBJECT + // set default VectorGraph css colors and styles + Q_PROPERTY(QColor vectorGraphDefaultAutomatedColor MEMBER m_vectorGraphDefaultAutomatedColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultLineColor MEMBER m_vectorGraphDefaultLineColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultActiveColor MEMBER m_vectorGraphDefaultActiveColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphDefaultFillColor MEMBER m_vectorGraphDefaultFillColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryLineColor MEMBER m_vectorGraphSecondaryLineColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryActiveColor MEMBER m_vectorGraphSecondaryActiveColor NOTIFY changedDefaultColors) + Q_PROPERTY(QColor vectorGraphSecondaryFillColor MEMBER m_vectorGraphSecondaryFillColor NOTIFY changedDefaultColors) + + Q_PROPERTY(int fontSize MEMBER m_fontSize) +public: + + VectorGraphView(QWidget* parent, int widgetWidth, int widgetHeight, unsigned int pointSize, + unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors); + ~VectorGraphView(); + + void setLineColor(QColor color, unsigned int dataArrayLocation); + void setActiveColor(QColor color, unsigned int dataArrayLocation); + void setFillColor(QColor color, unsigned int dataArrayLocation); + void setAutomatedColor(QColor color, unsigned int dataArrayLocation); + void applyDefaultColors(); + void setPointSize(unsigned int pointSize); + void setControlHeight(unsigned int controlHeight); + + + inline VectorGraphModel* model() + { + return castModel(); + } + + + // draws estimated line, does not call getSamples() + // does not fill graphs with VectorGraphDataArray FillColor + void setIsSimplified(bool isSimplified); + bool getIsSimplified(); + + // returns -1.0f at .first when nothing is selected + PointF getSelectedData(); + // returns -1 it can not return an array location + int getLastSelectedArray(); + // sets the position of the currently selected point + void setSelectedData(PointF data); + // sets the background pixmap + void setBackground(const QPixmap backgound); + + // if this function is called + // paintEvent will not call getSamples() (optimization) + // insted calls getLastSamples + // resets after every paint event + void useGetLastSamples(); +signals: + // emited after paintEvent + void drawn(); + void changedDefaultColors(); +protected: + void paintEvent(QPaintEvent* pe) override; + void mousePressEvent(QMouseEvent* me) override; + void mouseMoveEvent(QMouseEvent* me) override; + void mouseReleaseEvent(QMouseEvent* me) override; + void mouseDoubleClickEvent(QMouseEvent* me) override; + + void leaveEvent(QEvent *event) override; +protected slots: + void updateGraph(); + void updateGraph(bool shouldUseGetLastSamples); + void updateDefaultColors(); +private: + void paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer); + void paintEditing(QPainter* p); + + void modelChanged() override; + + // utility + // calculate graph coords from screen space coords + PointF mapMousePos(int x, int y); + // calculate gui curve point's position + PointF mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve); + PointInt mapDataCurvePos(int xA, int yA, int xB, int yB, float curve); + // calculate screen space coords from graph coords + // isNonNegative can only be true when graph line / getSamples() is mapped + PointInt mapDataPos(float x, float y, bool isNonNegative); + // map where each Control is displayed when m_isEdtitingActive is true + int mapControlInputX(float inputValue, unsigned int displayLength); + + float getDistance(int xA, int yA, int xB, int yB); + float getDistanceF(float xA, float yA, float xB, float yB); + + // adds point to the selected VectorGraphDataArray + bool addPoint(unsigned int arrayLocation, int mouseX, int mouseY); + + // editing menu / controls + // returns true if the graph was clicked + bool isGraphPressed(int mouseY); + // returns true if the control window was clicked while in editing mode + bool isControlWindowPressed(int mouseY); + void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving); + // returns -1 if no control / input was clicked + // returns displayed absolute control / input location based on inputCount + int getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount); + // returns a float attrib value + float getInputAttribValue(unsigned int controlArrayLocation); + // sets the selected point's attrib (controlArrayLocation) to floatValue + void setInputAttribValue(unsigned int controlArrayLocation, float floatValue); + // calculates the ideal text color + QColor getTextColorFromBaseColor(QColor baseColor); + // calculates a replacement background fill color + QColor getFillColorFromBaseColor(QColor baseColor); + + SubWindow* m_controlDialog; + + // selection + // searches VectorGraphDataArray-s to select + // near clicked location + void selectData(int mouseX, int mouseY); + // searches for point in a given VectorGraphDataArray + // returns found location, when a point + // was found in the given distance + // else it returns -1 + int searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved); + + // if the mouse is not moved + bool m_mousePress; + // decides addition or deletion + bool m_addition; + + // radius, rx = ry + unsigned int m_pointSize; + unsigned int m_fontSize; + // draw simplified lines + bool m_isSimplified; + // true when applyDefaultColors is called, used when defaultColors are loading + bool m_isDefaultColorsApplyed; + QPixmap m_background; + // for 1 draw, it will use the VectorGraphDataArray + // m_bakedSamples without calling getSamples() + bool m_useGetLastSamples; + + // if m_isLastSelectedArray == true then + // m_selectedArray can be used + // else if m_isSelected == false then + // m_selectedLocation and m_selectedArray should not be used + unsigned int m_selectedLocation; + unsigned int m_selectedArray; + bool m_isSelected; + bool m_isCurveSelected; + // if m_selectedArray was the last array selected + bool m_isLastSelectedArray; + + unsigned int m_graphHeight; + unsigned int m_controlHeight; + // displayed control count (+1 because of the ">>" button in editing mode) + unsigned int m_controlDisplayCount; + bool m_isEditingActive; + const std::array m_controlText = + { + tr("edit point"), tr("switch graph") + }; + + PointInt m_lastTrackPoint; + PointInt m_lastScndTrackPoint; + + // default VectorGraphDataArray colors + // applyed in constructor + QColor m_vectorGraphDefaultAutomatedColor; + + QColor m_vectorGraphDefaultLineColor; + QColor m_vectorGraphDefaultActiveColor; + QColor m_vectorGraphDefaultFillColor; + QColor m_vectorGraphSecondaryLineColor; + QColor m_vectorGraphSecondaryActiveColor; + QColor m_vectorGraphSecondaryFillColor; + + friend class lmms::gui::VectorGraphCotnrolDialog; +}; + +} // namespace gui +} // namespace lmms + +#endif // LMMS_GUI_VECTORGRAPHVIEW_H diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp new file mode 100644 index 00000000000..8874cefbc9b --- /dev/null +++ b/src/gui/widgets/VectorGraphView.cpp @@ -0,0 +1,1312 @@ +/* + * VectorGraph.cpp - Vector graph widget class implementation + * + * Copyright (c) 2024 szeli1 TODO + * + * 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 "VectorGraphView.h" +#include "VectorGraphViewBase.h" + +#include +#include +#include +#include +#include + +#include "AutomatableModel.h" +#include "GuiApplication.h" // getGUI +#include "MainWindow.h" // getting main window for control dialog +#include "ProjectJournal.h" + +//#define VECTORGRAPH_DEBUG_USER_INTERACTION +//#define VECTORGRAPH_DEBUG_PAINT_EVENT + +namespace lmms +{ + +namespace gui +{ +VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHeight, unsigned int pointSize, + unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : + VectorGraphViewBase(parent), + ModelView(new VectorGraphModel(2048, nullptr, false), this), + m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this))) +{ + resize(widgetWidth, widgetHeight); + + m_controlDialog->hide(); + Qt::WindowFlags flags = m_controlDialog->windowFlags(); + flags &= ~Qt::WindowMaximizeButtonHint; + m_controlDialog->setWindowFlags(flags); + + m_mousePress = false; + m_addition = false; + + m_pointSize = pointSize; + // gets set in style + //m_fontSize = 12; // set in css + m_isSimplified = false; + m_isDefaultColorsApplyed = false; + //m_background; + m_useGetLastSamples = false; + + m_selectedLocation = 0; + m_selectedArray = 0; + m_isSelected = false; + m_isCurveSelected = false; + m_isLastSelectedArray = false; + + m_graphHeight = height(); + m_controlHeight = controlHeight; + m_controlDisplayCount = 2; + m_isEditingActive = false; + // set in .h + //m_controlText + //m_controlLineTypeText + //m_controlIsFloat + + m_lastTrackPoint.first = -1; + m_lastTrackPoint.second = 0; + m_lastScndTrackPoint.first = 0; + m_lastScndTrackPoint.second = 0; + + setCursor(Qt::CrossCursor); + + modelChanged(); + + // connect loading of default colors to applyDefaultColors + QObject::connect(this, &VectorGraphView::changedDefaultColors, + this, &VectorGraphView::updateDefaultColors); + + if (shouldApplyDefaultVectorGraphColors == true) + { + applyDefaultColors(); + } +} +VectorGraphView::~VectorGraphView() +{ + if (m_controlDialog != nullptr) + { + delete m_controlDialog; + } +} + +void VectorGraphView::setLineColor(QColor color, unsigned int dataArrayLocation) +{ + if (model()->getDataArraySize() > dataArrayLocation) + { + model()->getDataArray(dataArrayLocation)->setLineColor(color); + updateGraph(); + } +} +void VectorGraphView::setActiveColor(QColor color, unsigned int dataArrayLocation) +{ + if (model()->getDataArraySize() > dataArrayLocation) + { + model()->getDataArray(dataArrayLocation)->setActiveColor(color); + updateGraph(); + } +} +void VectorGraphView::setFillColor(QColor color, unsigned int dataArrayLocation) +{ + if (model()->getDataArraySize() > dataArrayLocation) + { + model()->getDataArray(dataArrayLocation)->setFillColor(color); + updateGraph(); + } +} +void VectorGraphView::setAutomatedColor(QColor color, unsigned int dataArrayLocation) +{ + if (model()->getDataArraySize() > dataArrayLocation) + { + model()->getDataArray(dataArrayLocation)->setAutomatedColor(color); + updateGraph(); + } +} +void VectorGraphView::applyDefaultColors() +{ + m_isDefaultColorsApplyed = true; + unsigned int size = model()->getDataArraySize(); + if (size > 0) + { + setLineColor(m_vectorGraphDefaultLineColor, 0); + setActiveColor(m_vectorGraphDefaultActiveColor, 0); + setFillColor(m_vectorGraphDefaultFillColor, 0); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 0); + if (size > 1) + { + setLineColor(m_vectorGraphSecondaryLineColor, 1); + setActiveColor(m_vectorGraphSecondaryActiveColor, 1); + setFillColor(m_vectorGraphSecondaryFillColor, 1); + setAutomatedColor(m_vectorGraphDefaultAutomatedColor, 1); + } + } +} +void VectorGraphView::setPointSize(unsigned int pointSize) +{ + m_pointSize = pointSize; + updateGraph(); +} +void VectorGraphView::setControlHeight(unsigned int controlHeight) +{ + m_controlHeight = controlHeight; + updateGraph(); +} + +void VectorGraphView::setIsSimplified(bool isSimplified) +{ + m_isSimplified = isSimplified; +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setIsSimplified %d", m_isSimplified); +#endif +} +bool VectorGraphView::getIsSimplified() +{ + return m_isSimplified; +} + +PointF VectorGraphView::getSelectedData() +{ + PointF output(-1.0f, 0.00); + if (m_isSelected == true) + { + output.first = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + output.second = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); + } + return output; +} +int VectorGraphView::getLastSelectedArray() +{ + if (m_isLastSelectedArray == true) + { + return m_selectedArray; + } + return -1; +} +void VectorGraphView::setSelectedData(PointF data) +{ + if (m_isSelected == true) + { + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, data.second); + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, data.first); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setSelectedData (x, y): %f, %f", data.first, data.second); +#endif + } +} +void VectorGraphView::setBackground(const QPixmap background) +{ + m_background = background; +} +void VectorGraphView::useGetLastSamples() +{ + m_useGetLastSamples = true; +} + +void VectorGraphView::mousePressEvent(QMouseEvent* me) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("\n\nmousePressEvent start ---------"); +#endif + // get position + int x = me->x(); + int y = me->y(); + m_addition = false; + m_mousePress = false; + + // a point's FloatModel might be deleted after this + // cleaning up connected Knob in the dialog + reinterpret_cast(m_controlDialog->widget())->hideAutomation(); + m_controlDialog->hide(); + if (m_isSelected == true) + { + FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + if (curFloatModel != nullptr && curFloatModel->isAutomatedOrControlled() == false) + { + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, false); + } + } + + if(me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && m_isSelected == true) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mousePressEvent automation connecting"); +#endif + // connect to AutomationTrack + model()->getDataArray(m_selectedArray)->setAutomated(m_selectedLocation, true); + FloatModel* curFloatModel = model()->getDataArray(m_selectedArray)->getAutomationModel(m_selectedLocation); + // (VectorGraphViewBase method:) + connectToAutomationTrack(me, curFloatModel, widget()); + } + else + { + if (me->button() == Qt::LeftButton) + { + // add + m_addition = true; + m_mousePress = true; + } + else if (me->button() == Qt::RightButton) + { + // delete + m_addition = false; + m_mousePress = true; + } + if (isGraphPressed(m_graphHeight - y) == true) + { + // try selecting the clicked point (if it is near) + selectData(x, m_graphHeight - y); + // avoid triggering editing window while deleting + // points are only deleted when + // m_isSelected == true -> m_isEditingActive = true + // so m_isEditingActive is set to false + if (m_isSelected == true && m_addition == false) + { + m_isEditingActive = false; + } + if (m_isSelected == true) + { + setCursor(Qt::ArrowCursor); + } + else + { + setCursor(Qt::CrossCursor); + } + } + } +} + +void VectorGraphView::mouseMoveEvent(QMouseEvent* me) +{ + // get position + // the x coord is clamped because + // m_lastTrackPoint.first < 0 is used + int x = me->x() >= 0 ? me->x() : 0; + int y = me->y(); + + bool startMoving = false; + if (m_lastTrackPoint.first < 0) + { + m_lastTrackPoint.first = m_lastScndTrackPoint.first = x; + m_lastTrackPoint.second = m_lastScndTrackPoint.second = m_graphHeight - y; + m_mousePress = true; + } + + if (m_mousePress == true) + { + // the mouse needs to move a bigger distance + // before it is registered as dragging (-> m_mousePress = false) + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) + { + m_mousePress = false; + startMoving = true; + + model()->modelAddJournalCheckPoint(); + } + } + + // if the mouse was not moved a lot + if (m_mousePress == true) { return; } + + if (isGraphPressed(m_lastScndTrackPoint.second) == true) + { + if (m_isSelected == true && m_addition == true) + { + if (m_isCurveSelected == false) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseMoveEvent point drag"); +#endif + // dragging point + PointF convertedCoords = mapMousePos(x, m_graphHeight - y); + convertedCoords.first = std::clamp(convertedCoords.first, 0.0f, 1.0f); + convertedCoords.second = std::clamp(convertedCoords.second, -1.0f, 1.0f); + setSelectedData(convertedCoords); + } + else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseMoveEvent curve drag"); +#endif + // dragging curve + PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); + float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; + curveValue = std::clamp(curveValue, -1.0f, 1.0f); + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); + } + } + else if (m_addition == false) + { + // deleting points + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) + { + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + m_isSelected = false; + selectData(x, m_graphHeight - y); + if (m_isSelected == true) + { + model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); + m_isSelected = false; + m_isEditingActive = false; + } + } + } + else + { + // adding points + if (startMoving == true && m_isLastSelectedArray == true) + { + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); + } + float curDistance = getDistance(x, m_graphHeight - y, + m_lastTrackPoint.first, m_lastTrackPoint.second); + if (curDistance > m_pointSize) + { + // calculating angle + // getting the angle between (lastScndTrackPoint and lastTrackPoint) + // and (lastTrackPoint and x and y) + float curAngle = static_cast( + (m_lastTrackPoint.second - m_lastScndTrackPoint.second) * + (m_graphHeight - y - m_lastTrackPoint.second) + + (m_lastTrackPoint.first - m_lastScndTrackPoint.first) * + (x - m_lastTrackPoint.first)); + curAngle = std::acos(curAngle / curDistance / + getDistance(m_lastScndTrackPoint.first, m_lastScndTrackPoint.second, + m_lastTrackPoint.first, m_lastTrackPoint.second)); + // if the angle difference is bigger than 0.3 rad + if (std::abs(curAngle) * curDistance * curDistance / static_cast(m_pointSize * m_pointSize) > 0.3f) + { + m_lastScndTrackPoint.first = m_lastTrackPoint.first; + m_lastScndTrackPoint.second = m_lastTrackPoint.second; + + if (m_isLastSelectedArray == true) + { + // trying to add to the last selected array + addPoint(m_selectedArray, x, m_graphHeight - y); + } + } + m_lastTrackPoint.first = x; + m_lastTrackPoint.second = m_graphHeight - y; + } + // else m_mousePress does not change + } + } + else if (isControlWindowPressed(m_lastScndTrackPoint.second) == true) + { + processControlWindowPressed(m_lastTrackPoint.first, m_graphHeight - m_lastScndTrackPoint.second, true, startMoving); + } +} + +void VectorGraphView::mouseReleaseEvent(QMouseEvent* me) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent start"); +#endif + // get position + int x = me->x(); + int y = me->y(); + // if did not drag and graph is pressed + if (m_mousePress == true && isGraphPressed(m_graphHeight - y) == true) + { + model()->modelAddJournalCheckPoint(); + // add/delete point + if (m_isSelected == false && m_addition == true) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent add point, dataArray count: %d", static_cast(model()->getDataArraySize())); +#endif + // if selection failed and addition + // get the first editable daraArray and add value + bool success = false; + if (m_isLastSelectedArray == true) + { + // trying to add to the last selected array + success = addPoint(m_selectedArray, x, m_graphHeight - y); + } + if (success == false) + { + // trying to add to all the selected arrays + for(unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + success = addPoint(i, x, m_graphHeight - y); + if (success == true) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + break; + } + } + } + } + else if (m_isSelected == true && m_addition == false) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent delete point"); +#endif + // if selection was successful -> deletion + model()->getDataArray(m_selectedArray)->deletePoint(m_selectedLocation); + m_isSelected = false; + m_isEditingActive = false; + } + } + else if (m_mousePress == true && isControlWindowPressed(m_graphHeight - y) == true) + { + model()->modelAddJournalCheckPoint(); + processControlWindowPressed(x, m_graphHeight - y, false, false); + } + m_mousePress = false; + m_addition = false; + // reset trackpoint + m_lastTrackPoint.first = -1; + updateGraph(false); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent end"); +#endif +} + +void VectorGraphView::mouseDoubleClickEvent(QMouseEvent * me) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseDoubleClickEvent start"); +#endif + // get position + //int x = me->x(); + int y = me->y(); + + // if a data/sample is selected then show input dialog to change the data + if (isGraphPressed(m_graphHeight - y) == true) + { + if (m_isSelected == true && me->button() == Qt::LeftButton) + { + // display dialog + PointF curData = showCoordInputDialog(getSelectedData()); + // change data + setSelectedData(curData); + } + } +} +void VectorGraphView::leaveEvent(QEvent *event) +{ + hideHintText(); +} + +void VectorGraphView::paintEvent(QPaintEvent* pe) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintEvent start"); +#endif + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing, true); + + m_graphHeight = m_isEditingActive == true ? height() - m_controlHeight : height(); + + // paint background + if (m_background.isNull() == false) + { + p.drawPixmap(0, 0, m_background); + } + + // paint outline + p.setPen(QPen(QColor(127, 127, 127, 255), 1)); + p.drawLine(0, 0, width() - 1, 0); + p.drawLine(width() - 1, 0, width() - 1, height() - 1); + p.drawLine(0, height() - 1, width() - 1, height() - 1); + p.drawLine(0, 0, 0, height() - 1); + + std::vector sampleBuffer; + + // updating the VectorGraphDataArray samples before draw + if (m_useGetLastSamples == false || m_isSimplified == true) + { + // updating arrays that do not effect other arrays first + // (this step will run getSamples() on effector arrays (-> every array will be updated about once)) + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + if (model()->getDataArray(i)->getIsAnEffector() == false) + { + // this updates the array and its effector arrays + // with width() sample count + model()->getDataArray(i)->getSamples(width(), nullptr); + } + } + } + + // draw the updated VectorGraphDataArray samples in order + // sometimes an other getSamples() call elsewhere can + // change the sample count between updating and drawing + // causing badly drawn output (if sample count is low) + for (int i = model()->getDataArraySize() - 1; i >= 0; i--) + { + paintGraph(&p, i, &sampleBuffer); + } + + paintEditing(&p); + + m_useGetLastSamples = false; +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintEvent end"); +#endif + emit drawn(); +} + +void VectorGraphView::paintGraph(QPainter* p, unsigned int arrayLocation, std::vector* sampleBuffer) +{ +#ifdef VECTORGRAPH_DEBUG_PAINT_EVENT + qDebug("paintGraph start: data arrayLocation: %d", arrayLocation); +#endif + VectorGraphDataArray* dataArray = model()->getDataArray(arrayLocation); + unsigned int length = dataArray->size(); + if (length <= 0) { return; } + + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(QBrush(*dataArray->getLineColor(), Qt::NoBrush)); + + PointInt posA(0, 0); + PointInt posB(0, 0); + PointInt startPos(mapDataPos(0.0f, dataArray->getY(0), false)); + // draw line + if (m_isSimplified == false) + { + QPainterPath pt; + posA = startPos; + pt.moveTo(startPos.first + 1, m_graphHeight - startPos.second); + + // get the currently drawed VectorGraphDataArray samples + dataArray->getLastSamples(sampleBuffer); + + for (unsigned int j = 0; j < sampleBuffer->size(); j++) + { + // if nonNegative then only the dataArray output (getDataValues) + // is bigger than 0 so it matters only here + posB = mapDataPos(0, (*sampleBuffer)[j], dataArray->getIsNonNegative()); + posB.first = static_cast((j * width()) / static_cast(sampleBuffer->size())); + + if (posA.first != posB.first) + { + pt.lineTo(posB.first, m_graphHeight - posB.second); + // pt replaces drawing with path + //p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + } + posA = posB; + } + + // final draw line, fill + if (dataArray->getFillColor()->alpha() > 0) + { + // getting the line for + // drawing later + QPainterPath ptline(pt); + pt.lineTo(width() - 1, posB.second); + pt.lineTo(width() - 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, m_graphHeight - 1); + pt.lineTo(startPos.first + 1, startPos.second); + // draw fill + p->fillPath(pt, QBrush(*dataArray->getFillColor())); + // draw line + p->drawPath(ptline); + } + else + { + p->drawPath(pt); + } + } + + // draw points + if (dataArray->getIsSelectable() == true || m_isSimplified == true) + { + posA = startPos; + + int squareSize = m_pointSize; + + QColor automatedFillColor(getFillColorFromBaseColor(*dataArray->getAutomatedColor())); + bool drawPoints = dataArray->getIsSelectable() && width() / length > m_pointSize * 2; + bool resetColor = false; + for (unsigned int j = 0; j < length; j++) + { + posB = mapDataPos(dataArray->getX(j), dataArray->getY(j), false); + // draw point + if (drawPoints == true) + { + // set point color + if (dataArray->getAutomationModel(j) != nullptr) + { + // if automated + p->setPen(QPen(*dataArray->getAutomatedColor(), 2)); + p->setBrush(QBrush(automatedFillColor, Qt::SolidPattern)); + resetColor = true; + } + else if (m_isSelected == true && m_selectedArray == arrayLocation && m_selectedLocation == j) + { + // if selected + p->setBrush(QBrush(*dataArray->getFillColor(), Qt::SolidPattern)); + resetColor = true; + } + + p->drawEllipse(posB.first - m_pointSize, m_graphHeight - posB.second - m_pointSize, m_pointSize * 2, m_pointSize * 2); + + // reset point color + if (resetColor == true) + { + p->setPen(QPen(*dataArray->getLineColor(), 2)); + p->setBrush(Qt::NoBrush); + resetColor = false; + } + + if (j > 0) + { + if (dataArray->getIsEditableAttrib() == true) + { + PointInt posC = mapDataCurvePos(posA.first, posA.second, posB.first, posB.second, dataArray->getC(j - 1)); + p->drawRect(posC.first - squareSize / 2, + m_graphHeight - posC.second - squareSize / 2, squareSize, squareSize); + } + } + } + + // draw simplified line + if (m_isSimplified == true) + { + p->drawLine(posA.first, m_graphHeight - posA.second, posB.first, m_graphHeight - posB.second); + } + posA = posB; + } + } + // draw last simplified line + if (m_isSimplified == true) + { + p->drawLine(posB.first, m_graphHeight - posB.second, width(), m_graphHeight - posB.second); + } +} +void VectorGraphView::paintEditing(QPainter* p) +{ + p->setFont(QFont("Arial", m_fontSize)); + if (m_isEditingActive == true) + { + VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); + QColor textColor = getTextColorFromBaseColor(*dataArray->getLineColor()); + // background of float values + QColor foreColor = *dataArray->getLineColor(); + if (dataArray->getFillColor()->alpha() > 0) + { + foreColor = *dataArray->getFillColor(); + } + + int controlTextCount = m_controlText.size(); + if (dataArray->getIsEditableAttrib() == false) + { + // x, y + controlTextCount = 2; + } + else if (dataArray->getIsAutomatableEffectable() == false) + { + // x, y, curve, valA, valB, switch type + controlTextCount = 6; + } + + int segmentLength = width() / (m_controlDisplayCount); + // draw inputs + p->setPen(QPen(textColor, 1)); + for (unsigned int i = 0; i < m_controlDisplayCount; i++) + { + QColor curForeColor = *dataArray->getFillColor(); + p->fillRect(i * segmentLength, m_graphHeight, segmentLength, m_controlHeight, curForeColor); + p->drawText(i * segmentLength, m_graphHeight + (m_controlHeight - m_fontSize) / 2 + m_fontSize, m_controlText[i]); + } + + // draw outline + p->setPen(QPen(*dataArray->getLineColor(), 1)); + p->drawLine(0, m_graphHeight, width(), m_graphHeight); + for (unsigned int i = 1; i < m_controlDisplayCount; i++) + { + if (i < controlTextCount || i >= m_controlDisplayCount) + { + p->drawLine(i * segmentLength, m_graphHeight, i * segmentLength, height()); + } + } + } + if (m_isLastSelectedArray == true) + { + // draw selected array number + p->setPen(QPen(QColor(127, 127, 127, 255), 2)); + p->drawText(2, (m_controlHeight - m_fontSize) / 2 + m_fontSize, QString::number(m_selectedArray)); + } +} + +void VectorGraphView::modelChanged() +{ + auto gModel = model(); + QObject::connect(gModel, SIGNAL(updateGraphView(bool)), + this, SLOT(updateGraph(bool))); + QObject::connect(gModel, SIGNAL(styleChanged()), + this, SLOT(updateGraph())); +} + +void VectorGraphView::updateGraph() +{ + update(); +} +void VectorGraphView::updateGraph(bool shouldUseGetLastSamples) +{ + m_useGetLastSamples = shouldUseGetLastSamples; + update(); +} +void VectorGraphView::updateDefaultColors() +{ + if (m_isDefaultColorsApplyed == true) + { + applyDefaultColors(); + } +} + +PointF VectorGraphView::mapMousePos(int x, int y) +{ + // mapping the position to 0 - 1, -1 - 1 using qWidget width and height + return PointF( + static_cast(x / static_cast(width())), + static_cast(y) * 2.0f / static_cast(m_graphHeight) - 1.0f); +} +PointInt VectorGraphView::mapDataPos(float x, float y, bool isNonNegative) +{ + // mapping the point/sample positon to mouse/view position + if (isNonNegative == true) + { + return PointInt( + static_cast(x * width()), + static_cast(y * m_graphHeight)); + } + else + { + return PointInt( + static_cast(x * width()), + static_cast((y + 1.0f) * static_cast(m_graphHeight) / 2.0f)); + } +} +PointF VectorGraphView::mapDataCurvePosF(float xA, float yA, float xB, float yB, float curve) +{ + return PointF( + (xA + xB) / 2.0f, + yA + (curve / 2.0f + 0.5f) * (yB - yA)); +} +PointInt VectorGraphView::mapDataCurvePos(int xA, int yA, int xB, int yB, float curve) +{ + return PointInt( + (xA + xB) / 2, + yA + static_cast((curve / 2.0f + 0.5f) * (yB - yA))); +} +int VectorGraphView::mapControlInputX(float inputValue, unsigned int displayLength) +{ + return (inputValue / 2.0f + 0.5f) * displayLength; +} + +float VectorGraphView::getDistance(int xA, int yA, int xB, int yB) +{ + return std::sqrt(static_cast((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB))); +} +float VectorGraphView::getDistanceF(float xA, float yA, float xB, float yB) +{ + return std::sqrt((xA - xB) * (xA - xB) + (yA - yB) * (yA - yB)); +} + +bool VectorGraphView::addPoint(unsigned int arrayLocation, int mouseX, int mouseY) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("addPoint: arrayLocation: %d, position (x, y): %d, %d", arrayLocation, mouseX, mouseY); +#endif + // mouseY is calculated like this: + // m_graphHeight - y + bool output = false; + PointF curMouseCoords = mapMousePos(mouseX, mouseY); + curMouseCoords.first = std::clamp(curMouseCoords.first, 0.0f, 1.0f); + curMouseCoords.second = std::clamp(curMouseCoords.second, -1.0f, 1.0f); + int location = model()->getDataArray(arrayLocation)->add(curMouseCoords.first); + + // if adding was not successful + if (location < 0) { return output; } + + output = true; + model()->getDataArray(arrayLocation)->setY(location, curMouseCoords.second); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("addPoint: point location: %d, positionF (x, y): %f, %f, new dataArray size: %d", + location, curMouseCoords.first, curMouseCoords.second, static_cast(model()->getDataArray(arrayLocation)->size())); +#endif + return output; +} + +bool VectorGraphView::isGraphPressed(int mouseY) +{ + return !isControlWindowPressed(mouseY); +} +bool VectorGraphView::isControlWindowPressed(int mouseY) +{ + bool output = false; + // mouseY is calculated like this: + // m_graphHeight - y + if (m_isEditingActive == true && mouseY <= 0) + { + output = true; + } + return output; +} +void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving) +{ + // mouseY is calculated like this: + // m_graphHeight - y + setCursor(Qt::ArrowCursor); + +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("processControlWindowPressed: mouse (x, y): %d, %d, isDragging: %d, startMoving: %d", mouseX, mouseY, isDragging, startMoving); +#endif + + if (m_isEditingActive == false) { return; } + + int pressLocation = getPressedControlInput(mouseX, m_graphHeight - mouseY, m_controlDisplayCount); +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("processControlWindowPressed: pressLocation: %d", pressLocation); +#endif + if (isDragging == false || (isDragging == true && startMoving == false)) + { + if (pressLocation == 0) + { + m_isEditingActive = false; + m_controlDialog->show(); + if (m_isSelected == true) + { + reinterpret_cast(m_controlDialog->widget())->switchPoint(m_selectedArray, m_selectedLocation); + } + hideHintText(); + } + else if (pressLocation == 1) + { + // if the "switch graph" button was pressed in editing mode + unsigned int oldSelectedArray = m_selectedArray; + m_selectedLocation = 0; + m_selectedArray = 0; + m_isLastSelectedArray = false; + m_isSelected = false; + m_isEditingActive = false; + m_isCurveSelected = false; + + // looping throught the data arrays to get a new + // selected data array + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray: i: [%d], m_selectedArray: %d, oldSelectedArray: %d", i, m_selectedArray, oldSelectedArray); +#endif + if (model()->getDataArray(i)->getIsSelectable() == true) + { + // if this data array is the first one that is selectable + if (m_isLastSelectedArray == false) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + } + // if this data array's location is bigger than the old location + // if this is false then m_selectedArray will equal to the first selectable array + if (i > oldSelectedArray) + { + m_selectedArray = i; + m_isLastSelectedArray = true; + break; + } + } + } +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("mouseReleaseEvent select dataArray final: %d", m_selectedArray); +#endif + + // hint text + if (m_selectedArray != oldSelectedArray) + { + showHintText(widget(), tr("selected graph changed"), 5, 3500); + } + else + { + showHintText(widget(), tr("unable to select other graph"), 5, 3500); + } + } + } +} +int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount) +{ + int output = -1; + if (m_isEditingActive == true && mouseY > m_graphHeight) + { + output = mouseX * controlCount / width(); + } + if (output > controlCount) + { + output = controlCount; + } + return output; +} +float VectorGraphView::getInputAttribValue(unsigned int controlArrayLocation) +{ + float output = 0.0f; + if (m_isSelected == false) { return output; } + + switch (controlArrayLocation) + { + case 0: + output = model()->getDataArray(m_selectedArray)->getX(m_selectedLocation); + break; + case 1: + output = model()->getDataArray(m_selectedArray)->getY(m_selectedLocation); + break; + case 2: + output = model()->getDataArray(m_selectedArray)->getC(m_selectedLocation); + break; + case 3: + output = model()->getDataArray(m_selectedArray)->getValA(m_selectedLocation); + break; + case 4: + output = model()->getDataArray(m_selectedArray)->getValB(m_selectedLocation); + break; + case 5: + // type + output = model()->getDataArray(m_selectedArray)->getType(m_selectedLocation); + break; + case 6: + // automation location + output = model()->getDataArray(m_selectedArray)->getAutomatedAttribLocation(m_selectedLocation); + break; + case 7: + // effect location + output = model()->getDataArray(m_selectedArray)->getEffectedAttribLocation(m_selectedLocation); + break; + case 8: + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 0); + break; + case 9: + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 1); + break; + case 10: + output = model()->getDataArray(m_selectedArray)->getEffect(m_selectedLocation, 2); + break; + case 11: + output = model()->getDataArray(m_selectedArray)->getEffectPoints(m_selectedLocation) ? 1.0f : 0.0f; + break; + case 12: + output = model()->getDataArray(m_selectedArray)->getEffectLines(m_selectedLocation) ? 1.0f : 0.0f; + break; + } + return output; +} +void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, float floatValue) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("setInputAttribute start: control input: %d, set floatValue: %f", controlArrayLocation, floatValue); +#endif + if (m_isSelected == false) { return; } + + float clampedValue = std::clamp(floatValue, -1.0f, 1.0f); + unsigned int clampedValueB = 0; + switch (controlArrayLocation) + { + case 0: + m_selectedLocation = model()->getDataArray(m_selectedArray)->setX(m_selectedLocation, std::max(clampedValue, 0.0f)); + break; + case 1: + model()->getDataArray(m_selectedArray)->setY(m_selectedLocation, clampedValue); + break; + case 2: + model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, clampedValue); + break; + case 3: + model()->getDataArray(m_selectedArray)->setValA(m_selectedLocation, clampedValue); + break; + case 4: + model()->getDataArray(m_selectedArray)->setValB(m_selectedLocation, clampedValue); + break; + case 5: + // type + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); + model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); + break; + case 6: + // automation location + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + model()->getDataArray(m_selectedArray)->setAutomatedAttrib(m_selectedLocation, clampedValueB); + break; + case 7: + // effect location + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 4.0f)); + model()->getDataArray(m_selectedArray)->setEffectedAttrib(m_selectedLocation, clampedValueB); + break; + case 8: + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 0, clampedValueB); + break; + case 9: + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 1, clampedValueB); + break; + case 10: + clampedValueB = static_cast(floatValue); + model()->getDataArray(m_selectedArray)->setEffect(m_selectedLocation, 2, clampedValueB); + break; + case 11: + model()->getDataArray(m_selectedArray)->setEffectPoints(m_selectedLocation, floatValue >= 0.5f); + break; + case 12: + model()->getDataArray(m_selectedArray)->setEffectLines(m_selectedLocation, floatValue >= 0.5f); + break; + } +} +QColor VectorGraphView::getTextColorFromBaseColor(QColor baseColor) +{ + QColor output(255, 255, 255, 255); + int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); + // > 127 * 3 + if (colorSum > 382) + { + output = QColor(0, 0, 0, 255); + } + return output; +} +QColor VectorGraphView::getFillColorFromBaseColor(QColor baseColor) +{ + QColor output; + int colorSum = baseColor.red() + baseColor.green() + baseColor.blue(); + int brighten = 0; + int alpha = baseColor.alpha(); + if (alpha == 0) + { + alpha = 255; + } + if (std::abs(colorSum - 382) > 191) + { + brighten = 45; + } + // > 127 * 3 + if (colorSum > 382) + { + // (red * 0.6f + avg * 0.4f / 3.0f) * 0.7 + output = QColor(static_cast(static_cast(baseColor.red()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColor.green()) * 0.42f + colorSum * 0.09f) - brighten, + static_cast(static_cast(baseColor.blue()) * 0.42f + colorSum * 0.09f) - brighten, 255); + } + else + { + // (red * 0.6f + avg * 0.4f / 3.0f) * 1.3 + output = QColor(static_cast(static_cast(baseColor.red()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColor.green()) * 0.78f + colorSum * 0.17f) + brighten, + static_cast(static_cast(baseColor.blue()) * 0.78f + colorSum * 0.17f) + brighten, 255); + } + return output; +} + +void VectorGraphView::selectData(int mouseX, int mouseY) +{ +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("selectData start: mouse (x, y): %d, %d", mouseX, mouseY); +#endif + + m_isSelected = false; + + // trying to select the last selected array + if (m_isLastSelectedArray == true) + { + VectorGraphDataArray* dataArray = model()->getDataArray(m_selectedArray); + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); + if (location > -1) + { + m_selectedLocation = location; + // m_selectedArray - do not set + m_isSelected = true; + m_isCurveSelected = false; + m_isEditingActive = true; + } + } + + if (m_isSelected == false) + { + m_selectedLocation = 0; + // m_selectedArray can not be set to 0 in case of + // m_isLastSelectedArray is active + // m_selectedArray = 0; - do not reset + m_isSelected = false; + m_isCurveSelected = false; + m_isEditingActive = false; + //m_isLastSelectedArray = false; + + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + VectorGraphDataArray* dataArray = model()->getDataArray(i); + if (dataArray->getIsSelectable() == true) + { + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, false); + if (location > -1) + { + m_selectedLocation = location; + m_selectedArray = i; + m_isSelected = true; + m_isCurveSelected = false; + m_isLastSelectedArray = true; + m_isEditingActive = true; + break; + } + } + } + if (m_isSelected == false) + { + for (unsigned int i = 0; i < model()->getDataArraySize(); i++) + { + VectorGraphDataArray* dataArray = model()->getDataArray(i); + if (dataArray->getIsSelectable() == true) + { + int location = searchForData(mouseX, mouseY, static_cast(m_pointSize) / width(), dataArray, true); + if (location > -1) + { + m_selectedLocation = location; + m_selectedArray = i; + m_isSelected = true; + m_isCurveSelected = true; + m_isLastSelectedArray = true; + m_isEditingActive = true; + break; + } + } + } + } + } +#ifdef VECTORGRAPH_DEBUG_USER_INTERACTION + qDebug("selectData end: m_selectedArray: %d, m_selectedLocation %d", m_selectedArray, m_selectedLocation); +#endif +} + +int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, VectorGraphDataArray* dataArray, bool isCurved) +{ + int output = -1; + maxDistance = maxDistance * 2.0f; + + PointF transformedMouse = mapMousePos(mouseX, mouseY); + + // unused bool + bool found = false; + bool isBefore = false; + // get the nearest data to the mouse pos (x) in an optimalized way + int location = dataArray->getNearestLocation(transformedMouse.first, &found, &isBefore); + + // if getNearestLocation was not successful + if (location < 0) { return output; } + + float dataX = dataArray->getX(location); + float dataY = dataArray->getY(location); + // this is set to one when isCurved == true + // and isBefore == false + int curvedBefore = 0; + // if isCurved then get the closest curved coord + if (isCurved == true && dataArray->size() > 1) + { + if (isBefore == false && 1 < location) + { + curvedBefore = 1; + } + if (location - curvedBefore < dataArray->size() - 1) + { + PointF curvedDataCoords = mapDataCurvePosF( + dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), + dataArray->getX(location - curvedBefore + 1), dataArray->getY(location - curvedBefore + 1), + dataArray->getC(location - curvedBefore)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; + } + } + // check distance against x coord + if (std::abs(dataX - transformedMouse.first) <= maxDistance) + { + // calculate real distance (x and y) + float curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); + + if (curDistance <= maxDistance) + { + output = location - curvedBefore; + } + else + { + // sometimes the mouse x and the nearest point x + // coordinates are close but the y coords are not + // calculating and testing all near by point distances + int searchStart = 0; + int searchEnd = dataArray->size() - 1; + // from where we need to search the data + for (int i = location - curvedBefore - 1; i > 0; i--) + { + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) + { + // if it is isCurved, then subtract 1 + // add 1 to i because [i] > maxDistance + searchStart = i + 1 - (i > 0 && isCurved == true ? 1 : 0); + break; + } + } + // getting where the search needs to end + for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) + { + if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) + { + searchEnd = i - 1 - (i > 0 && isCurved == true ? 1 : 0); + break; + } + } + // calculating real distances from the point coords + for (int i = searchStart; i <= searchEnd; i++) + { + if (i != location) + { + dataX = dataArray->getX(i); + dataY = dataArray->getY(i); + if (isCurved == true && dataArray->size() > 1) + { + if (dataArray->size() - 1 > i) + { + PointF curvedDataCoords = mapDataCurvePosF( + dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), + dataArray->getC(i)); + dataX = curvedDataCoords.first; + dataY = curvedDataCoords.second; + } + } + curDistance = getDistanceF(transformedMouse.first * 2.0f, transformedMouse.second, + dataX * 2.0f, dataY); + if (curDistance <= maxDistance) + { + output = i; + break; + } + } + } + } + } + return output; +} + +} // namespace gui + +} // namespace lmms From b6850c03076e29666967704fc3daf906ced7ba14 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:22:18 +0200 Subject: [PATCH 155/184] WaveShaper_updated_incudes --- plugins/WaveShaper/WaveShaper.cpp | 2 +- plugins/WaveShaper/WaveShaper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaper.cpp b/plugins/WaveShaper/WaveShaper.cpp index 7fae145f28e..08574645cb1 100644 --- a/plugins/WaveShaper/WaveShaper.cpp +++ b/plugins/WaveShaper/WaveShaper.cpp @@ -28,7 +28,7 @@ #include "lmms_math.h" #include "embed.h" #include "interpolation.h" -#include "VectorGraph.h" +#include "VectorGraphModel.h" #include "plugin_export.h" diff --git a/plugins/WaveShaper/WaveShaper.h b/plugins/WaveShaper/WaveShaper.h index c56e43b2065..70e1a63596d 100644 --- a/plugins/WaveShaper/WaveShaper.h +++ b/plugins/WaveShaper/WaveShaper.h @@ -29,7 +29,7 @@ #include "Effect.h" #include "WaveShaperControls.h" -#include "VectorGraph.h" +#include "VectorGraphModel.h" namespace lmms { From a4cfccce0c23a8fbf1d8d07f4947f4e3f99388de Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:22:47 +0200 Subject: [PATCH 156/184] WaveShaperControlDialog --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 3 ++- plugins/WaveShaper/WaveShaperControlDialog.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 3b851272949..9d10bbeaaa9 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -29,7 +29,8 @@ #include "WaveShaperControls.h" #include "embed.h" #include "Graph.h" -#include "VectorGraph.h" +#include "VectorGraphView.h" +#include "VectorGraphModel.h" #include "Knob.h" #include "PixmapButton.h" #include "LedCheckBox.h" diff --git a/plugins/WaveShaper/WaveShaperControlDialog.h b/plugins/WaveShaper/WaveShaperControlDialog.h index 155df83cc4f..7a786f058a9 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.h +++ b/plugins/WaveShaper/WaveShaperControlDialog.h @@ -27,7 +27,7 @@ #define _WAVESHAPER_CONTROL_DIALOG_H #include "EffectControlDialog.h" -#include "VectorGraph.h" +#include "VectorGraphView.h" namespace lmms { From a24f8d5c8633a954fa8cf438f7a3065b4d6154f3 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sat, 29 Jun 2024 12:23:16 +0200 Subject: [PATCH 157/184] WaveShaperControls_updated_includes --- plugins/WaveShaper/WaveShaperControls.cpp | 2 +- plugins/WaveShaper/WaveShaperControls.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index be0848ecae7..2f12e25100e 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -29,7 +29,7 @@ #include "WaveShaperControls.h" #include "WaveShaper.h" -#include "VectorGraph.h" +#include "VectorGraphModel.h" #include "Engine.h" #include "Song.h" #include "base64.h" diff --git a/plugins/WaveShaper/WaveShaperControls.h b/plugins/WaveShaper/WaveShaperControls.h index 6452bbc9bdf..784a1b1d35c 100644 --- a/plugins/WaveShaper/WaveShaperControls.h +++ b/plugins/WaveShaper/WaveShaperControls.h @@ -30,7 +30,7 @@ #include "EffectControls.h" #include "WaveShaperControlDialog.h" -#include "VectorGraph.h" +#include "VectorGraphModel.h" namespace lmms { From 03c6021a9bd167d0b2dd8fbcc69c2635276de0c1 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:08:11 +0200 Subject: [PATCH 158/184] WaveShaperControls_updated_comment --- plugins/WaveShaper/WaveShaperControls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 2f12e25100e..070237f0be1 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -50,7 +50,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphSampleBuffer(200) { unsigned int arrayLocation = m_vectorGraphModel.addDataArray(); - // see other settings avalible for VectorGraphDataArray in VectorGraph.h + // see other settings avalible for VectorGraphDataArray in VectorGraphModel.h m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); From 31f03a293ec32f71a5751eae864254c5a255e734 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:11:07 +0200 Subject: [PATCH 159/184] VectorGraphViewBase_hide_unused_controls --- include/VectorGraphViewBase.h | 2 + src/gui/widgets/VectorGraphViewBase.cpp | 95 ++++++++++++++++++++----- 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 5866aa14e31..f4ae7357cbe 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -135,6 +135,8 @@ protected slots: std::vector m_controlModelArray; + std::vector m_hideableKnobs; + std::vector m_hideableComboBoxes; }; } // namespace gui diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index c61757447bd..accc325e043 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -116,7 +116,6 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV m_effectModelB(nullptr, "", false), m_effectModelC(nullptr, "", false) { - auto makeKnob = [this](const QString& label, const QString& hintText, const QString& unit, FloatModel* model) { Knob* newKnob = new Knob(KnobType::Bright26, this); @@ -127,11 +126,10 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV return newKnob; }; - /* - setWindowIcon(embed::getIconPixmap("setup_audio")); - setWindowTitle(tr("Connection Settings")); - //setModal(true); -*/ + //m_controlModelArray + //m_hideableKnobs + //m_hideableComboBoxes + setWindowTitle(tr("vector graph settings")); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); @@ -157,6 +155,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV Knob* newKnob = makeKnob(m_controlFloatText[i + 1], m_controlFloatText[i], "%", curModel); knobLayout->addWidget(newKnob); knobLayout->setAlignment(newKnob, Qt::AlignHCenter); + m_hideableKnobs.push_back(newKnob); connect(curModel, &AutomatableModel::setValueEvent, this, &VectorGraphCotnrolDialog::controlValueChanged); @@ -196,6 +195,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV lineTypeComboBox->show(); settingLayout->addWidget(lineTypeComboBox); settingLayout->setAlignment(lineTypeComboBox, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(lineTypeComboBox); QLabel* automatedAttribLabel = new QLabel(tr("automated attribute:")); automatedAttribLabel->setFixedSize(130, 20); @@ -207,6 +207,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV automatedAttribComboBox->show(); settingLayout->addWidget(automatedAttribComboBox); settingLayout->setAlignment(automatedAttribComboBox, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(automatedAttribComboBox); QLabel* effectedAttribLabel = new QLabel(tr("effected attribute:")); effectedAttribLabel->setFixedSize(130, 20); @@ -218,6 +219,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV effectedAttribComboBox->show(); settingLayout->addWidget(effectedAttribComboBox); settingLayout->setAlignment(effectedAttribComboBox, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(effectedAttribComboBox); QLabel* effectedLabelA = new QLabel(tr("1. effect:")); effectedLabelA->setFixedSize(100, 20); @@ -229,6 +231,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV effectedComboBoxA->show(); settingLayout->addWidget(effectedComboBoxA); settingLayout->setAlignment(effectedComboBoxA, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(effectedComboBoxA); QLabel* effectedLabelB = new QLabel(tr("2. effect:")); effectedLabelB->setFixedSize(100, 20); @@ -240,6 +243,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV effectedComboBoxB->show(); settingLayout->addWidget(effectedComboBoxB); settingLayout->setAlignment(effectedComboBoxB, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(effectedComboBoxB); QLabel* effectedLabelC = new QLabel(tr("3. effect:")); effectedLabelC->setFixedSize(100, 20); @@ -251,6 +255,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV effectedComboBoxC->show(); settingLayout->addWidget(effectedComboBoxC); settingLayout->setAlignment(effectedComboBoxC, Qt::AlignHCenter); + m_hideableComboBoxes.push_back(effectedComboBoxC); m_automationLayout = new QVBoxLayout(nullptr); @@ -320,6 +325,7 @@ void VectorGraphCotnrolDialog::hideAutomation() m_curAutomationModelKnob = nullptr; } } + void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned int selectedLocation) { m_curSelectedArray = selectedArray; @@ -328,25 +334,31 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned m_vectorGraphView->model()->getDataArray(selectedArray)->setAutomated(selectedLocation, true); m_curAutomationModel = m_vectorGraphView->model()->getDataArray(selectedArray)->getAutomationModel(selectedLocation); - if (m_curAutomationModel == nullptr) { hideAutomation(); return; } - - if (m_curAutomationModelKnob != nullptr) + if (m_curAutomationModel != nullptr) { - if (m_curAutomationModel != m_curAutomationModelKnob->model()) + if (m_curAutomationModelKnob != nullptr) + { + if (m_curAutomationModel != m_curAutomationModelKnob->model()) + { + m_curAutomationModelKnob->setModel(m_curAutomationModel); + } + } + else { + m_curAutomationModelKnob = new Knob(KnobType::Bright26, this); m_curAutomationModelKnob->setModel(m_curAutomationModel); + m_curAutomationModelKnob->setLabel(tr("automation knob")); + m_curAutomationModelKnob->setHintText(tr("automate this to automate a value of the vector graph"), "%"); + m_curAutomationModelKnob->setVolumeKnob(false); + + m_automationLayout->addWidget(m_curAutomationModelKnob); + m_automationLayout->setAlignment(m_curAutomationModelKnob, Qt::AlignHCenter); } } else { - m_curAutomationModelKnob = new Knob(KnobType::Bright26, this); - m_curAutomationModelKnob->setModel(m_curAutomationModel); - m_curAutomationModelKnob->setLabel(tr("automation knob")); - m_curAutomationModelKnob->setHintText(tr("automate this to automate a value of the vector graph"), "%"); - m_curAutomationModelKnob->setVolumeKnob(false); - - m_automationLayout->addWidget(m_curAutomationModelKnob); - m_automationLayout->setAlignment(m_curAutomationModelKnob, Qt::AlignHCenter); + hideAutomation(); + m_isValidSelection = true; } updateControls(); } @@ -367,9 +379,10 @@ void VectorGraphCotnrolDialog::effectedLineClicked(bool isChecked) float currentValue = m_vectorGraphView->getInputAttribValue(12); m_vectorGraphView->setInputAttribValue(12, currentValue >= 0.5f ? 0.0f : 1.0f); } + void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) { - if (m_isValidSelection == false) { hideAutomation(); return; } + if (m_isValidSelection == false) { hideAutomation(); return; } bool swapIsValidSelection = m_isValidSelection; hideAutomation(); @@ -396,6 +409,50 @@ void VectorGraphCotnrolDialog::updateControls() m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i)); } + for (Knob* i : m_hideableKnobs) + { + if (i != nullptr) + { + i->show(); + } + } + for (ComboBox* i : m_hideableComboBoxes) + { + if (i != nullptr) + { + i->show(); + } + } + + // hiding different parts of the gui + // to not confuse the user + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsFixedX() == true && m_hideableKnobs[0] != nullptr) + { + m_hideableKnobs[0]->hide(); + } + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsFixedY() == true && m_hideableKnobs[1] != nullptr) + { + m_hideableKnobs[1]->hide(); + } + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsEditableAttrib() == false) + { + if (m_hideableKnobs[1] != nullptr) { m_hideableKnobs[1]->hide(); } + if (m_hideableKnobs[2] != nullptr) { m_hideableKnobs[2]->hide(); } + if (m_hideableKnobs[3] != nullptr) { m_hideableKnobs[3]->hide(); } + if (m_hideableKnobs[4] != nullptr) { m_hideableKnobs[4]->hide(); } + if (m_hideableComboBoxes[0] != nullptr) { m_hideableComboBoxes[0]->hide(); } + if (m_hideableComboBoxes[1] != nullptr) { m_hideableComboBoxes[1]->hide(); } + if (m_hideableComboBoxes[2] != nullptr) { m_hideableComboBoxes[2]->hide(); } + } + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsAutomatableEffectable() == false) + { + if (m_hideableComboBoxes[1] != nullptr) { m_hideableComboBoxes[1]->hide(); } + if (m_hideableComboBoxes[2] != nullptr) { m_hideableComboBoxes[2]->hide(); } + if (m_hideableComboBoxes[3] != nullptr) { m_hideableComboBoxes[3]->hide(); } + if (m_hideableComboBoxes[4] != nullptr) { m_hideableComboBoxes[4]->hide(); } + if (m_hideableComboBoxes[5] != nullptr) { m_hideableComboBoxes[5]->hide(); } + } + m_lineTypeModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(5)); m_automatedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(6)); m_effectedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(7)); From 9a81d7e022f00fdff5a8758bad3a658028fdea16 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 30 Jun 2024 16:26:44 +0200 Subject: [PATCH 160/184] VectorGraphView_improved_point_curve_editing --- src/gui/widgets/VectorGraphView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index 8874cefbc9b..6c7b342ab60 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -346,10 +346,10 @@ void VectorGraphView::mouseMoveEvent(QMouseEvent* me) else if (model()->getDataArray(m_selectedArray)->getIsEditableAttrib() == true) { #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION - qDebug("mouseMoveEvent curve drag"); + qDebug("mouseMoveEvent curve drag: mouse (x, y): (%d, %d), last track point (x, y): (%d, %d)", x, (m_graphHeight - y), m_lastTrackPoint.first, m_lastTrackPoint.second); #endif // dragging curve - PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, m_graphHeight - y + m_lastTrackPoint.second); + PointF convertedCoords = mapMousePos(x - m_lastTrackPoint.first, (m_graphHeight - y) - m_lastTrackPoint.second + m_graphHeight / 2); float curveValue = convertedCoords.second + convertedCoords.first * 0.1f; curveValue = std::clamp(curveValue, -1.0f, 1.0f); model()->getDataArray(m_selectedArray)->setC(m_selectedLocation, curveValue); From cd481ccb28cbace6fdc7976e97b6d832a232fc84 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:08:59 +0200 Subject: [PATCH 161/184] VectorGraphModel_renaming_getUpdatingFromEffector_function_input --- include/VectorGraphModel.h | 14 +----------- src/core/VectorGraphModel.cpp | 41 ++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h index da0776adb5e..1f10a8c356b 100644 --- a/include/VectorGraphModel.h +++ b/include/VectorGraphModel.h @@ -410,18 +410,6 @@ class LMMS_EXPORT VectorGraphDataArray // if the line (each sample) should be effected (only works when y is effected) bool m_effectLines = true; - /* - bool m_effectAdd = false; - bool m_effectSubtract = false; - bool m_effectMultiply = false; - bool m_effectDivide = false; - bool m_effectPower = false; - bool m_effectLog = false; - bool m_effectSine = false; - bool m_effectClampLower = false; - bool m_effectClampUpper = false; - */ - // stores m_automationModel->value(), used in getSamples() when updating float m_bufferedAutomationValue = 0.0f; // automation: connecting to floatmodels, -1 when it isn't conntected @@ -464,7 +452,7 @@ class LMMS_EXPORT VectorGraphDataArray // adds the m_dataArray points that are // effected by the changed effector array points. // ONLY WORKS IN SORTED ARRAYS - void getUpdatingFromEffector(std::vector* updatingPointLocations); + void getUpdatingFromEffector(std::vector* effectorUpdatedPoints); // if pointLocation >= 0 -> adds the location to m_needsUpdating // else it will update the whole m_dataArray and m_bakedSamples // changes in the size of m_dataArray (addtition, deletion, ect.) diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index b3a6b0cab16..6382a7869b2 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -1777,32 +1777,32 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample } } -void VectorGraphDataArray::getUpdatingFromEffector(std::vector* updatingPointLocations) +void VectorGraphDataArray::getUpdatingFromEffector(std::vector* effectorUpdatingPoints) { /* - * here m_needsUpdating points are decided - * firstly we get changed points from the effector graph (updatingPointLocations) + * here we decide m_needsUpdating points from an effector array's updated points (effectorUpdatingPoints is the location of these points) + * firstly we get changed points from the effector graph (effectorUpdatingPoints) * we get a segment consisting of changed effector points that come after each other - * this will be useful because we can update the current graph's points between this segment (segment start = i, segment end = updatingEnd) - * secondly we get a (current graph's) point before the segment start and after the segment end - * so we get locationBefore and locationAfter which will be added to m_needsUpdating + * this will be useful because we can update this graph's points between this segment (segment start = i, segment end = updatingEnd) + * secondly we find a (this graph's) point before the segment start and after the segment end + * so we get locationBefore and locationAfter, everything between them will be added to m_needsUpdating * thirdly we finalyze locationBefore and locationAfter, clamp them and start adding the points between them to m_needsUpdating - * if the (current graph's) point is not effected, we avoid adding it to m_needsUpdating + * if the (this graph's) point is not effected, we avoid adding it to m_needsUpdating */ VectorGraphDataArray* effector = m_parent->getDataArray(m_effectorLocation); - for (unsigned int i = 0; i < updatingPointLocations->size(); i++) + for (unsigned int i = 0; i < effectorUpdatingPoints->size(); i++) { - // since updatingPointLocations is a sorted list, we can get the end + // since effectorUpdatingPoints is a sorted list, we can get the end // location and update everithing between them // starting effector location is i, end effector location is updatingEnd unsigned int updatingEnd = i; - for (unsigned int j = i + 1; j < updatingPointLocations->size(); j++) + for (unsigned int j = i + 1; j < effectorUpdatingPoints->size(); j++) { // we can not skip gaps because - // every updatingPointLocations point effects their line only + // every effectorUpdatingPoints point effects their line only // (the line that starts with the point) - if ((*updatingPointLocations)[updatingEnd] + 1 >= - (*updatingPointLocations)[j]) + if ((*effectorUpdatingPoints)[updatingEnd] + 1 >= + (*effectorUpdatingPoints)[j]) { updatingEnd = j; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT @@ -1813,7 +1813,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: updatingEnd: %d brake: %d < %d [j = %d]", updatingEnd, - ((*updatingPointLocations)[updatingEnd] + 1), (*updatingPointLocations)[j], j); + ((*effectorUpdatingPoints)[updatingEnd] + 1), (*effectorUpdatingPoints)[j], j); #endif break; } @@ -1834,7 +1834,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up bool found = false; bool isBefore = false; // this can return -1 - int locationBefore = getNearestLocation(effector->getX((*updatingPointLocations)[i]), &found, &isBefore); + int locationBefore = getNearestLocation(effector->getX((*effectorUpdatingPoints)[i]), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation before: %d, i: %d", locationBefore, i); #endif @@ -1849,17 +1849,17 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // remember points control the line after (connected to) them // but in this case changes in the points position can effect the line before it locationBefore--; - // now (here) locationBefore is Always before (*updatingPointLocations)[i] + // now (here) locationBefore is Always before (*effectorUpdatingPoints)[i] } // clamp locationBefore = locationBefore < 0 ? 0 : m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; - int locationAfter = getNearestLocation(effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), &found, &isBefore); + int locationAfter = getNearestLocation(effector->getX((*effectorUpdatingPoints)[updatingEnd] + updatingEndSlide), &found, &isBefore); #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: getNearestLocation after: %d, updatingEnd: %d (+ %d), effector x: %f, dataArray x: %f", locationAfter, updatingEnd, updatingEndSlide, - effector->getX((*updatingPointLocations)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); + effector->getX((*effectorUpdatingPoints)[updatingEnd] + updatingEndSlide), m_dataArray[locationAfter].m_x); #endif if (isBefore == false) { @@ -1870,7 +1870,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up locationAfter--; } // updating everything before if i -> 0 - if ((*updatingPointLocations)[i] == 0) + if ((*effectorUpdatingPoints)[i] == 0) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything before"); @@ -1879,7 +1879,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up } // if updatingEnd is the last point in effecor, then // update everithing after - if ((*updatingPointLocations)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) + if ((*effectorUpdatingPoints)[updatingEnd] + updatingEndSlide + 1 >= effector->size()) { #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector updating everything after"); @@ -1897,6 +1897,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* up // if the last point was updated (ture in case of j = 0) bool lastUpdated = true; // adding the values between locationBefore, locationAfter + // (including locationBefore and locationAfter) to m_needsUpdating for (unsigned int j = locationBefore; j <= locationAfter; j++) { // update only if effected From d154dd6c1ff769c7daf5c3b54ed35154378f859f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:31:34 +0200 Subject: [PATCH 162/184] VectorGraphViewBase_ComboBox_Height_replaced_with_DEFAULT_HEIGHT --- src/gui/widgets/VectorGraphViewBase.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index accc325e043..341872f6dce 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -191,7 +191,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(lineTypeLabel, Qt::AlignHCenter); ComboBox* lineTypeComboBox = new ComboBox(this); lineTypeComboBox->setModel(&m_lineTypeModel); - lineTypeComboBox->setFixedSize(100, 20); + lineTypeComboBox->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); lineTypeComboBox->show(); settingLayout->addWidget(lineTypeComboBox); settingLayout->setAlignment(lineTypeComboBox, Qt::AlignHCenter); @@ -203,7 +203,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(automatedAttribLabel, Qt::AlignHCenter); ComboBox* automatedAttribComboBox = new ComboBox(this); automatedAttribComboBox->setModel(&m_automatedAttribModel); - automatedAttribComboBox->setFixedSize(100, 20); + automatedAttribComboBox->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); automatedAttribComboBox->show(); settingLayout->addWidget(automatedAttribComboBox); settingLayout->setAlignment(automatedAttribComboBox, Qt::AlignHCenter); @@ -215,7 +215,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(effectedAttribLabel, Qt::AlignHCenter); ComboBox* effectedAttribComboBox = new ComboBox(this); effectedAttribComboBox->setModel(&m_effectedAttribModel); - effectedAttribComboBox->setFixedSize(100, 20); + effectedAttribComboBox->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); effectedAttribComboBox->show(); settingLayout->addWidget(effectedAttribComboBox); settingLayout->setAlignment(effectedAttribComboBox, Qt::AlignHCenter); @@ -227,7 +227,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(effectedLabelA, Qt::AlignHCenter); ComboBox* effectedComboBoxA = new ComboBox(this); effectedComboBoxA->setModel(&m_effectModelA); - effectedComboBoxA->setFixedSize(100, 20); + effectedComboBoxA->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); effectedComboBoxA->show(); settingLayout->addWidget(effectedComboBoxA); settingLayout->setAlignment(effectedComboBoxA, Qt::AlignHCenter); @@ -239,7 +239,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(effectedLabelB, Qt::AlignHCenter); ComboBox* effectedComboBoxB = new ComboBox(this); effectedComboBoxB->setModel(&m_effectModelB); - effectedComboBoxB->setFixedSize(100, 20); + effectedComboBoxB->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); effectedComboBoxB->show(); settingLayout->addWidget(effectedComboBoxB); settingLayout->setAlignment(effectedComboBoxB, Qt::AlignHCenter); @@ -251,7 +251,7 @@ VectorGraphCotnrolDialog::VectorGraphCotnrolDialog(QWidget* parent, VectorGraphV settingLayout->setAlignment(effectedLabelC, Qt::AlignHCenter); ComboBox* effectedComboBoxC = new ComboBox(this); effectedComboBoxC->setModel(&m_effectModelC); - effectedComboBoxC->setFixedSize(100, 20); + effectedComboBoxC->setFixedSize(100, ComboBox::DEFAULT_HEIGHT); effectedComboBoxC->show(); settingLayout->addWidget(effectedComboBoxC); settingLayout->setAlignment(effectedComboBoxC, Qt::AlignHCenter); From 91e8bc54dc7d15577f8f659f99dc187b52b0d1f2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:42:49 +0200 Subject: [PATCH 163/184] VectorGraphModel_style_changes --- include/VectorGraphModel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h index 1f10a8c356b..017d7e02aba 100644 --- a/include/VectorGraphModel.h +++ b/include/VectorGraphModel.h @@ -182,8 +182,8 @@ class LMMS_EXPORT VectorGraphDataArray QColor* getActiveColor(); QColor* getFillColor(); QColor* getAutomatedColor(); - // returns -1 if it has no effector + // returns -1 if it has no effector int getEffectorArrayLocation(); bool getIsAnEffector(); int getId(); From 3c3afbddd3a6172271eb2024488ba7bf1b02fab8 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Wed, 31 Jul 2024 14:04:55 +0200 Subject: [PATCH 164/184] VectorGraphViewBase_adding_comments --- include/VectorGraphViewBase.h | 7 +++++++ src/gui/widgets/VectorGraphViewBase.cpp | 24 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index f4ae7357cbe..fca75340bcf 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -81,18 +81,25 @@ class LMMS_EXPORT VectorGraphCotnrolDialog : public QWidget, public ModelView VectorGraphCotnrolDialog(QWidget* parent, VectorGraphView* targetVectorGraphView); ~VectorGraphCotnrolDialog(); + // deletes m_curAutomationModelKnob connected to the VectorGraphDataArray::m_automationModelArray void hideAutomation(); + // connects or adds m_curAutomationModelKnob to the gui, sets the selected point void switchPoint(unsigned int selectedArray, unsigned int selectedLocation); public slots: void controlValueChanged(); + // slots for buttons void effectedPointClicked(bool isChecked); void effectedLineClicked(bool isChecked); void deleteAutomationClicked(bool isChecked); protected slots: + // needs to be used + // to not delete this control dialog widget when closing void closeEvent(QCloseEvent * ce); private: + // loads in the selected point's values, settings and attributes void updateControls(); + // sets the selected point's values to the control knob's values void updateVectorGraphAttribs(); VectorGraphView* m_vectorGraphView; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 341872f6dce..36c522430cf 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -328,9 +328,12 @@ void VectorGraphCotnrolDialog::hideAutomation() void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned int selectedLocation) { + // set current point location m_curSelectedArray = selectedArray; m_curSelectedLocation = selectedLocation; + // enable all of the control dialog settings by turning this on m_isValidSelection = true; + // get a FloatModel for the selected point m_vectorGraphView->model()->getDataArray(selectedArray)->setAutomated(selectedLocation, true); m_curAutomationModel = m_vectorGraphView->model()->getDataArray(selectedArray)->getAutomationModel(selectedLocation); @@ -338,6 +341,8 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned { if (m_curAutomationModelKnob != nullptr) { + // if m_curAutomationKnob exists + // update its model to the selected point's automationModel if (m_curAutomationModel != m_curAutomationModelKnob->model()) { m_curAutomationModelKnob->setModel(m_curAutomationModel); @@ -345,6 +350,8 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned } else { + // if m_curAutomationKnob doesn't exist + // create new m_curAutomationModelKnob = new Knob(KnobType::Bright26, this); m_curAutomationModelKnob->setModel(m_curAutomationModel); m_curAutomationModelKnob->setLabel(tr("automation knob")); @@ -357,7 +364,10 @@ void VectorGraphCotnrolDialog::switchPoint(unsigned int selectedArray, unsigned } else { + // if can not be automated hideAutomation(); + // turn back on this + // so ohter functions can still work m_isValidSelection = true; } updateControls(); @@ -386,6 +396,7 @@ void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) bool swapIsValidSelection = m_isValidSelection; hideAutomation(); + // remove automationModel (FloatModel) from the selected point m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->setAutomated(m_curSelectedLocation, false); m_isValidSelection = swapIsValidSelection; } @@ -404,11 +415,7 @@ void VectorGraphCotnrolDialog::updateControls() { if (m_isValidSelection == false) { hideAutomation(); return; } - for (size_t i = 0; i < m_controlModelArray.size(); i++) - { - m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i)); - } - + // show every control for (Knob* i : m_hideableKnobs) { if (i != nullptr) @@ -453,6 +460,12 @@ void VectorGraphCotnrolDialog::updateControls() if (m_hideableComboBoxes[5] != nullptr) { m_hideableComboBoxes[5]->hide(); } } + // load selected point's values into knobs + for (size_t i = 0; i < m_controlModelArray.size(); i++) + { + m_controlModelArray[i]->setAutomatedValue(m_vectorGraphView->getInputAttribValue(i)); + } + m_lineTypeModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(5)); m_automatedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(6)); m_effectedAttribModel.setAutomatedValue(m_vectorGraphView->getInputAttribValue(7)); @@ -465,6 +478,7 @@ void VectorGraphCotnrolDialog::updateVectorGraphAttribs() { if (m_isValidSelection == false) { hideAutomation(); return; } + // set / load knob's values into the selected point's values for (size_t i = 0; i < m_controlModelArray.size(); i++) { m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value()); From 02bb332ca4e33c68c05f45f08f39cf7b68aeaf3a Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:57:48 +0200 Subject: [PATCH 165/184] VectorGraphModel_adding_bezier_curves --- include/VectorGraphModel.h | 26 ++++---- src/core/VectorGraphModel.cpp | 120 ++++++++++++++++++++++------------ 2 files changed, 91 insertions(+), 55 deletions(-) diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h index 017d7e02aba..3bfc9a4e362 100644 --- a/include/VectorGraphModel.h +++ b/include/VectorGraphModel.h @@ -375,11 +375,12 @@ class LMMS_EXPORT VectorGraphDataArray float m_valB = 0.0f; // line type: // 0 - none - // 1 - sine - // 2 - sineB - // 3 - peak - // 4 - steps - // 5 - random + // 1 - bezier + // 2 - sine + // 3 - sineB + // 4 - peak + // 5 - steps + // 6 - random unsigned int m_type = 0; // the automated attrib location and // the effected attrib location is @@ -421,8 +422,7 @@ class LMMS_EXPORT VectorGraphDataArray // swapping values, "shouldShiftBetween" moves the values (between) once left or right to keep the order // handle m_isFixedEndPoints when using this void swap(unsigned int pointLocationA, unsigned int pointLocationB, bool shouldShiftBetween); - // returns the curve value at a given x coord, does clamp - float processCurve(float yBefore, float yAfter, float curve, float xIn); + // returns effected attribute value from base attribValue (input attribute value), does clamp // this function applies the point Effects (like add effect) based on attribValue and effectValue float processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue); @@ -432,19 +432,21 @@ class LMMS_EXPORT VectorGraphDataArray // line types, m_type is used for this // fadeInStartVal: from what relative x value should the line type fade out - // linking: valA: sineAmp, valB: sineFreq + // samplesOut: output for the line type functions + // xArray: exact sorted x coordinates of samples between 0 and 1 + // startLoc: from where to apply line type + // endLoc: where to stop applying line type + // other inputs: mostly between -1 and 1 + void processBezier(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float yBefore, float yAfter, float targetYBefore, float targetYAfter, float curveStrength); void processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float fadeInStartVal); - // linking: valA: sineAmp, valB: sineFreq, curve: sinePhase void processLineTypeArraySineB(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float sinePhase, float fadeInStartVal); - // linking: valA: amp, valB: x coord, curve: width void processLineTypeArrayPeak(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float peakAmp, float peakX, float peakWidth, float fadeInStartVal); - // linking: y: yArray, valA: stepCount, valB: stepCurve void processLineTypeArraySteps(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, std::vector* yArray, float stepCount, float stepCurve, float fadeInStartVal); - // linking: valA: randomAmp, valB: randomCount, curve: randomSeed void processLineTypeArrayRandom(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float randomAmp, float randomCount, float randomSeed, float fadeInStartVal); diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index 6382a7869b2..fb40126a453 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -1476,26 +1476,6 @@ void VectorGraphDataArray::swap(unsigned int pointLocationA, unsigned int pointL getUpdatingFromPoint(pointLocationB); dataChanged(); } -float VectorGraphDataArray::processCurve(float yBefore, float yAfter, float curve, float x) -{ - // calculating line curve - float absCurveIn = std::abs(curve); - float pow = curve < 0.0f ? 1.0f - x : x; - pow = std::pow(pow, 1.0f - absCurveIn) - pow; - - float output = yBefore + (yAfter - yBefore) * x; - output = curve > 0.0f ? output + pow * (yAfter - yBefore) : output - pow * (yAfter - yBefore); - // clamp - if (yBefore > yAfter) - { - output = std::clamp(output, yAfter, yBefore); - } - else - { - output = std::clamp(output, yBefore, yAfter); - } - return output; -} float VectorGraphDataArray::processEffect(unsigned int pointLocation, float attribValue, unsigned int attribLocation, float effectValue) @@ -1594,6 +1574,47 @@ float VectorGraphDataArray::processAutomation(unsigned int pointLocation, float return output; } +void VectorGraphDataArray::processBezier(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, + float yBefore, float yAfter, float targetYBefore, float targetYAfter, float curveStrength) +{ + // note: targetYBefore and targetYAfter can be bigger than 1 + curveStrength = std::abs(curveStrength); + // draw bezier + if (curveStrength != 0.0f) + { + for (unsigned int i = startLoc; i < endLoc; i++) + { + // bezier B(t), "t" is a number between 0 and 1 + float t = (*xArray)[i]; + // inverse t + float iT = (1.0f - t); + (*samplesOut)[i] = (std::pow(iT, 3.0f) * yBefore) + + (3.0f * iT * iT * t * targetYBefore) + + (3.0f * iT * t * t * targetYAfter) + + (std::pow(t, 3.0f) * yAfter); + (*samplesOut)[i] = std::clamp((*samplesOut)[i] * curveStrength, -1.0f, 1.0f); + } + } + else + { + // if no bezier is drawn, reset the line's contents to 0 + // (so a drawn line can be added later) + for (unsigned int i = startLoc; i < endLoc; i++) + { + (*samplesOut)[i] = 0.0f; + } + } + + // draw line + if (curveStrength < 1.0f) + { + for (unsigned int i = startLoc; i < endLoc; i++) + { + (*samplesOut)[i] += (yBefore + (yAfter - yBefore) * (*xArray)[i]) * (1.0f - curveStrength); + } + } +} + void VectorGraphDataArray::processLineTypeArraySine(std::vector* samplesOut, std::vector* xArray, unsigned int startLoc, unsigned int endLoc, float sineAmp, float sineFreq, float fadeInStartVal) { @@ -2191,7 +2212,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, { effectYLocation = static_cast (std::ceil(m_dataArray[m_needsUpdating[pointLocation] + 1].m_x / stepSize)); - // where updating line ends (+1) + // where to end updating line (+1) end = effectYLocation; nextY = processAutomation(m_needsUpdating[pointLocation] + 1, m_dataArray[m_needsUpdating[pointLocation] + 1].m_y, 0); @@ -2234,59 +2255,72 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, if (type == 0) { // calculate curve - for (int j = start; j < end; j++) + float curveStrength = std::abs(curC); + float curveTarget = curY + (nextY - curY) * (curC + 1.0f) / 2.0f; + if (curveStrength > 0.0f) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + curveStrength = std::clamp(std::sqrt(curveStrength), -1.0f, 1.0f); } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curveTarget, curveTarget, curveStrength); // no line type } else if (type == 1) + { + // don't calculate curve + // line type + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curY + curValA * 2.0f, nextY + curValB * 2.0f, (curC + 1.0f) / 2.0f); + } + else if (type == 2) { // curve - for (int j = start; j < end; j++) + float curveStrength = std::abs(curC); + float curveTarget = curY + (nextY - curY) * (curC + 1.0f) / 2.0f; + if (curveStrength > 0.0f) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + curveStrength = std::clamp(std::sqrt(curveStrength), -1.0f, 1.0f); } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curveTarget, curveTarget, curveStrength); // line type processLineTypeArraySine(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, fadeInStart); } - else if (type == 2) + else if (type == 3) { // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curY, nextY, 0.0f); // line type processLineTypeArraySineB(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } - else if (type == 3) + else if (type == 4) { // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curY, nextY, 0.0f); // line type processLineTypeArrayPeak(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } - else if (type == 4) + else if (type == 5) { // curve - for (int j = start; j < end; j++) + float curveStrength = std::abs(curC); + float curveTarget = curY + (nextY - curY) * (curC + 1.0f) / 2.0f; + if (curveStrength > 0.0f) { - m_updatingBakedSamples[j] = processCurve(curY, nextY, curC, (*sampleXLocations)[j]); + curveStrength = std::clamp(std::sqrt(curveStrength), -1.0f, 1.0f); } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curveTarget, curveTarget, curveStrength); // line type processLineTypeArraySteps(&m_updatingBakedSamples, sampleXLocations, start, end, &m_updatingBakedSamples, curValA, curValB, fadeInStart); } - else if (type == 5) + else if (type == 6) { // curve - for (int j = start; j < end; j++) - { - m_updatingBakedSamples[j] = processCurve(curY, nextY, 0.0f, (*sampleXLocations)[j]); - } + processBezier(&m_updatingBakedSamples, sampleXLocations, start, end, + curY, nextY, curY, nextY, 0.0f); // line type processLineTypeArrayRandom(&m_updatingBakedSamples, sampleXLocations, start, end, curValA, curValB, curC, fadeInStart); } From 48832d238f0e73f1902482987d073180ffcb55a0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:59:35 +0200 Subject: [PATCH 166/184] VectorGraphViewBase_adding_new_line_type_option --- include/VectorGraphViewBase.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index fca75340bcf..48698a27e20 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -127,8 +127,9 @@ protected slots: tr("x coordinate"), "x", tr("y coordinate"), "y", tr("curve"), tr("curve"), tr("1. attribute value"), tr("1. attribute"), tr("2. attribute value"), tr("2. attribute") }; - const std::array m_controlLineTypeText = { + const std::array m_controlLineTypeText = { tr("none"), + tr("bézier"), tr("sine"), tr("phase changable sine"), tr("peak"), From c4f2e5a638b9d4629fdc0ac2a5ba4a1ef965267f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 14:59:59 +0200 Subject: [PATCH 167/184] VectorGraphView_adding_new_line_type --- src/gui/widgets/VectorGraphView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index 6c7b342ab60..e1b28c2ce78 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -1044,7 +1044,7 @@ void VectorGraphView::setInputAttribValue(unsigned int controlArrayLocation, flo break; case 5: // type - clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 5.0f)); + clampedValueB = static_cast(std::clamp(floatValue, 0.0f, 6.0f)); model()->getDataArray(m_selectedArray)->setType(m_selectedLocation, clampedValueB); break; case 6: From ec842be9bacee95545218bb9f00ddef12356cea4 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:42:08 +0200 Subject: [PATCH 168/184] VectorGraphModel_separated_m_isAutomatableEffectable --- include/VectorGraphModel.h | 29 +++++++++++++----------- src/core/VectorGraphModel.cpp | 42 ++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h index 3bfc9a4e362..b1aa7387e2b 100644 --- a/include/VectorGraphModel.h +++ b/include/VectorGraphModel.h @@ -142,8 +142,8 @@ class LMMS_EXPORT VectorGraphDataArray VectorGraphDataArray(); VectorGraphDataArray( bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, - bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parent, int arrayId); + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatable, + bool isEffectable, bool isSaveable, VectorGraphModel* parent, int arrayId); ~VectorGraphDataArray(); void updateConnections(VectorGraphModel* parent); @@ -155,7 +155,8 @@ class LMMS_EXPORT VectorGraphDataArray void setIsFixedEndPoints(bool bValue); void setIsSelectable(bool bValue); void setIsEditableAttrib(bool bValue); - void setIsAutomatableEffectable(bool bValue); + void setIsAutomatable(bool bValue); + void setIsEffectable(bool bValue); void setIsSaveable(bool bValue); void setIsNonNegative(bool bValue); void setLineColor(QColor color); @@ -175,7 +176,8 @@ class LMMS_EXPORT VectorGraphDataArray bool getIsFixedEndPoints(); bool getIsSelectable(); bool getIsEditableAttrib(); - bool getIsAutomatableEffectable(); + bool getIsAutomatable(); + bool getIsEffectable(); bool getIsSaveable(); bool getIsNonNegative(); QColor* getLineColor(); @@ -313,23 +315,23 @@ class LMMS_EXPORT VectorGraphDataArray // checks m_isEditableAttrib // sets line type void setType(unsigned int pointLocation, unsigned int newType); - // checks m_isAutomatableEffectable and m_isEditableAttrib + // checks m_isAutomatable and m_isEditableAttrib // sets what attribute gets automated (by point's FloatModel) void setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation); - // checks m_isAutomatableEffectable and m_isEditableAttrib + // checks m_isEffectable and m_isEditableAttrib // sets what attribute gets effected (by effector array) void setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation); - // checks m_isAutomatableEffectable and m_isEditableAttrib + // checks m_isEffectable and m_isEditableAttrib // if bValue is true then the effector array will effect the point's attributes void setEffectPoints(unsigned int pointLocation, bool bValue); - // checks m_isAutomatableEffectable and m_isEditableAttribs + // checks m_isEffectable and m_isEditableAttribs // if bValue is true then the effector array will effect the line's individual samples (only when y is effected) void setEffectLines(unsigned int pointLocation, bool bValue); - // checks m_isAutomatableEffectable and m_isEditableAttrib + // checks m_isEffectable and m_isEditableAttrib // sets the point's effect type // effectSlot: which effect slot (m_effectTypeA / B / C), effectType: what kind of effect (add, exct) void setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType); - // checks m_isAutomatableEffectable + // checks m_isAutomatable // if bValue is true then make a new FloatModel and connect it, else delete // the currently used FloatModel void setAutomated(unsigned int pointLocation, bool bValue); @@ -492,9 +494,10 @@ class LMMS_EXPORT VectorGraphDataArray // every attribute outside of x and y // automation can be changed bool m_isEditableAttrib; - // can the points be automated or effected - // (can these settings be changed) - bool m_isAutomatableEffectable; + // can the points be automated + bool m_isAutomatable; + // can the points be effected + bool m_isEffectable; // if VectorGraphDataArray is allowed to save this bool m_isSaveable; // can values be less than 0 diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index fb40126a453..ed32adc64b2 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -60,7 +60,7 @@ unsigned int VectorGraphModel::addDataArray() { VectorGraphDataArray tempArray( false, false, false, false, false, false, false, - false, true, this, getDataArrayNewId()); + false, false, true, this, getDataArrayNewId()); m_dataArrays.push_back(tempArray); emit dataChanged(); return m_dataArrays.size() - 1; @@ -312,7 +312,8 @@ VectorGraphDataArray::VectorGraphDataArray() m_isFixedEndPoints = false; m_isSelectable = false; m_isEditableAttrib = false; - m_isAutomatableEffectable = false; + m_isAutomatable = false; + m_isEffectable = false; m_isSaveable = false; m_isNonNegative = false; @@ -337,8 +338,8 @@ VectorGraphDataArray::VectorGraphDataArray() VectorGraphDataArray::VectorGraphDataArray( bool isFixedSize, bool isFixedX, bool isFixedY, bool isNonNegative, - bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatableEffectable, - bool isSaveable, VectorGraphModel* parent, int arrayId) + bool isFixedEndPoints, bool isSelectable, bool isEditableAttrib, bool isAutomatable, + bool isEffectable, bool isSaveable, VectorGraphModel* parent, int arrayId) { m_isFixedSize = isFixedSize; m_isFixedY = isFixedX; @@ -346,7 +347,8 @@ VectorGraphDataArray::VectorGraphDataArray( m_isFixedEndPoints = isFixedEndPoints; m_isSelectable = isSelectable; m_isEditableAttrib = isEditableAttrib; - m_isAutomatableEffectable = isAutomatableEffectable; + m_isAutomatable = isAutomatable; + m_isEffectable = isEffectable; m_isSaveable = isSaveable; m_isNonNegative = isNonNegative; @@ -429,9 +431,15 @@ void VectorGraphDataArray::setIsEditableAttrib(bool bValue) getUpdatingFromPoint(-1); dataChanged(); } -void VectorGraphDataArray::setIsAutomatableEffectable(bool bValue) +void VectorGraphDataArray::setIsAutomatable(bool bValue) { - m_isAutomatableEffectable = bValue; + m_isAutomatable = bValue; + getUpdatingFromPoint(-1); + dataChanged(); +} +void VectorGraphDataArray::setIsEffectable(bool bValue) +{ + m_isEffectable = bValue; if (bValue == false) { // setEffectorArray will call dataChanged() @@ -569,9 +577,13 @@ bool VectorGraphDataArray::getIsEditableAttrib() { return m_isEditableAttrib; } -bool VectorGraphDataArray::getIsAutomatableEffectable() +bool VectorGraphDataArray::getIsAutomatable() +{ + return m_isAutomatable; +} +bool VectorGraphDataArray::getIsEffectable() { - return m_isAutomatableEffectable; + return m_isEffectable; } bool VectorGraphDataArray::getIsSaveable() { @@ -1119,7 +1131,7 @@ void VectorGraphDataArray::setType(unsigned int pointLocation, unsigned int newT } void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsigned int attribLocation) { - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + if (m_isAutomatable == false || m_isEditableAttrib == false) { return; } // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocation = attribLocation > 3 ? 0 : attribLocation; @@ -1135,7 +1147,7 @@ void VectorGraphDataArray::setAutomatedAttrib(unsigned int pointLocation, unsign } void VectorGraphDataArray::setEffectedAttrib(unsigned int pointLocation, unsigned int attribLocation) { - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + if (m_isEffectable == false || m_isEditableAttrib == false) { return; } // clamp only 4 attributes can be automated (y, c, valA, valB) attribLocation = attribLocation > 3 ? 0 : attribLocation; @@ -1172,7 +1184,7 @@ bool VectorGraphDataArray::getEffectLines(unsigned int pointLocation) } void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bValue) { - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + if (m_isEffectable == false || m_isEditableAttrib == false) { return; } if (m_dataArray[pointLocation].m_effectPoints != bValue) { @@ -1197,7 +1209,7 @@ void VectorGraphDataArray::setEffectPoints(unsigned int pointLocation, bool bVal } void VectorGraphDataArray::setEffectLines(unsigned int pointLocation, bool bValue) { - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + if (m_isEffectable == false || m_isEditableAttrib == false) { return; } if (m_dataArray[pointLocation].m_effectLines != bValue) { @@ -1229,7 +1241,7 @@ unsigned int VectorGraphDataArray::getEffect(unsigned int pointLocation, unsigne } void VectorGraphDataArray::setEffect(unsigned int pointLocation, unsigned int effectSlot, unsigned int effectType) { - if (m_isAutomatableEffectable == false || m_isEditableAttrib == false) { return; } + if (m_isEffectable == false || m_isEditableAttrib == false) { return; } switch (effectSlot) { @@ -1267,7 +1279,7 @@ void VectorGraphDataArray::setAutomated(unsigned int pointLocation, bool bValue) #ifdef VECTORGRAPH_DEBUG_USER_INTERACTION qDebug("setAutomated start"); #endif - if (m_isAutomatableEffectable == false) { return; } + if (m_isAutomatable == false) { return; } if (bValue == true) { From 4ef824687617a187a221a1fb72d789a343efd4b3 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:42:56 +0200 Subject: [PATCH 169/184] VectorGraphView_removed_unused_drawing_code --- src/gui/widgets/VectorGraphView.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index e1b28c2ce78..b55a13df3a7 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -716,16 +716,6 @@ void VectorGraphView::paintEditing(QPainter* p) } int controlTextCount = m_controlText.size(); - if (dataArray->getIsEditableAttrib() == false) - { - // x, y - controlTextCount = 2; - } - else if (dataArray->getIsAutomatableEffectable() == false) - { - // x, y, curve, valA, valB, switch type - controlTextCount = 6; - } int segmentLength = width() / (m_controlDisplayCount); // draw inputs From 6317c963267b0ea2fa13729ebcb23ab3145d674b Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:44:02 +0200 Subject: [PATCH 170/184] VectorGraphViewBase_adding_better_control_widget_hiding --- src/gui/widgets/VectorGraphViewBase.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index 36c522430cf..d47f005cc71 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -451,9 +451,12 @@ void VectorGraphCotnrolDialog::updateControls() if (m_hideableComboBoxes[1] != nullptr) { m_hideableComboBoxes[1]->hide(); } if (m_hideableComboBoxes[2] != nullptr) { m_hideableComboBoxes[2]->hide(); } } - if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsAutomatableEffectable() == false) + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsAutomatable() == false) { if (m_hideableComboBoxes[1] != nullptr) { m_hideableComboBoxes[1]->hide(); } + } + if (m_vectorGraphView->model()->getDataArray(m_curSelectedArray)->getIsEffectable() == false) + { if (m_hideableComboBoxes[2] != nullptr) { m_hideableComboBoxes[2]->hide(); } if (m_hideableComboBoxes[3] != nullptr) { m_hideableComboBoxes[3]->hide(); } if (m_hideableComboBoxes[4] != nullptr) { m_hideableComboBoxes[4]->hide(); } From c86ac04f437432887540297951117b05b909e201 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 16:44:54 +0200 Subject: [PATCH 171/184] WaveShaperControls_updated_VectorGraph_config --- plugins/WaveShaper/WaveShaperControls.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 070237f0be1..9e5e65b80eb 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -53,14 +53,15 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : // see other settings avalible for VectorGraphDataArray in VectorGraphModel.h m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); - m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsAutomatable(true); + m_vectorGraphModel.getDataArray(arrayLocation)->setIsEffectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); unsigned int arrayLocationB = m_vectorGraphModel.addDataArray(); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); - m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatableEffectable(true); + m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSaveable(true); // connect VectorGraphDataArrays so the 2. VectorGraphDataArray will be able to effect the 1.: From 25607ad0a6187ebb5103f48f6dad39bab6fdcc4f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:32:28 +0200 Subject: [PATCH 172/184] VectorGraphModel_limiting_universalSampleBuffer --- src/core/VectorGraphModel.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index ed32adc64b2..5b723e21e90 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -878,6 +878,13 @@ void VectorGraphDataArray::getSamples(unsigned int targetSizeIn, std::vector 10000) + { + m_universalSampleBuffer.resize(10000); + } + if (sampleBufferOut != nullptr) { if (sampleBufferOut->size() != targetSizeIn) From 169633abb5c31f734219140fe5c524c905daebb2 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:48:29 +0200 Subject: [PATCH 173/184] VectorGraphModel_fixing_casting --- src/core/VectorGraphModel.cpp | 54 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index 5b723e21e90..30d7d4b7336 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -646,7 +646,7 @@ int VectorGraphDataArray::add(float newX) if (isBefore == true) { // we are adding one value, so dataArray.size() will be a valid location - if (targetLocation < m_dataArray.size()) + if (targetLocation < static_cast(m_dataArray.size())) { targetLocation++; } @@ -857,7 +857,7 @@ int VectorGraphDataArray::getNearestLocation(float searchXIn, bool* foundOut, bo { mid = mid - 1; } - if (mid + 1 < m_dataArray.size() && + if (mid + 1 < static_cast(m_dataArray.size()) && std::abs(m_dataArray[mid].m_x - searchXIn) > std::abs(m_dataArray[mid + 1].m_x - searchXIn)) { @@ -1041,14 +1041,14 @@ unsigned int VectorGraphDataArray::setX(unsigned int pointLocation, float newX) // if getNearestLocation returned a value if (location >= 0) { - if (location < pointLocation && isBefore == true) + if (location < static_cast(pointLocation) && isBefore == true) { - if (targetLocation + 1 < m_dataArray.size()) + if (targetLocation + 1 < static_cast(m_dataArray.size())) { targetLocation++; } } - else if (location > pointLocation && isBefore == false) + else if (location > static_cast(pointLocation) && isBefore == false) { if (targetLocation > 0) { @@ -1337,12 +1337,12 @@ void VectorGraphDataArray::deleteUnusedAutomation() usedAutomation.push_back(i.m_automationModel); } } - for (unsigned int i = 0; i < m_automationModelArray.size(); i++) + for (size_t i = 0; i < m_automationModelArray.size(); i++) { bool found = false; - for (unsigned int j = 0; j < usedAutomation.size(); j++) + for (size_t j = 0; j < usedAutomation.size(); j++) { - if (i == usedAutomation[j]) + if (static_cast(i) == usedAutomation[j]) { found = true; break; @@ -1377,7 +1377,7 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, b char* dst = 0; base64::decode(data, &dst, &size); - if (size == arraySize * sizeof(VectorGraphPoint)) + if (size == static_cast(arraySize * sizeof(VectorGraphPoint))) { m_dataArray.resize(arraySize); @@ -1398,7 +1398,7 @@ void VectorGraphDataArray::loadDataArray(QString data, unsigned int arraySize, b void VectorGraphDataArray::deleteAutomationModel(int modelLocation, bool callDataChanged) { - if (modelLocation < 0 || modelLocation >= m_automationModelArray.size()) { return; } + if (modelLocation < 0 || modelLocation >= static_cast(m_automationModelArray.size())) { return; } FloatModel* curModel = m_automationModelArray[modelLocation]; @@ -1423,7 +1423,7 @@ void VectorGraphDataArray::deleteAutomationModel(int modelLocation, bool callDat getUpdatingFromPoint(i - 1); } } - if (m_dataArray[i].m_automationModel == m_automationModelArray.size()) + if (m_dataArray[i].m_automationModel == static_cast(m_automationModelArray.size())) { m_dataArray[i].m_automationModel = modelLocation; } @@ -1651,27 +1651,27 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples count = 0; } float tValB = 0.001f + ((sineFreq + 1.0f) / 2.0f) * 0.999f; - // calculating how many samples are needed to 1 complete wave + // calculating how many samples are needed for 1 complete wave // we have "count" amount of samples and "tValB * 100.0f" amount of waves int end = static_cast(std::floor(count / (tValB * 100.0f))); - if (count <= 0) + if (count < 0) { end = 0; } - else + else if (end > 0) { end = end > count ? count : end + 1; } // "allocate" "end" amount of floats // for 1 whole sine wave // in the universal buffer - if (m_universalSampleBuffer.size() < end) + if (static_cast(m_universalSampleBuffer.size()) < end) { m_universalSampleBuffer.resize(end); } // calculate 1 wave of sine - for (unsigned int i = 0; i < end; i++) + for (int i = 0; i < end; i++) { // 628.318531f = 100.0f * 2.0f * pi // (1 sine wave is 2pi long and we have 1 * 100 * sineFreq waves) @@ -1682,7 +1682,7 @@ void VectorGraphDataArray::processLineTypeArraySineB(std::vector* samples for (int i = 0; i < count; i += end) { int endB = i + end >= count ? count - i : end; - for (unsigned int j = 0; j < endB; j++) + for (int j = 0; j < endB; j++) { (*samplesOut)[startLoc + j + i] += m_universalSampleBuffer[j]; } @@ -1712,7 +1712,7 @@ void VectorGraphDataArray::processLineTypeArrayPeak(std::vector* samplesO { count = 0; } - for (unsigned int i = 0; i < count; i++) + for (size_t i = 0; i < static_cast(count); i++) { (*samplesOut)[startLoc + i] += std::pow((peakWidth + 1.0f) * 0.2f + 0.01f, std::abs((*xArray)[startLoc + i] - (peakX + 1.0f) * 0.5f) * 10.0f) * peakAmp; @@ -1744,7 +1744,7 @@ void VectorGraphDataArray::processLineTypeArraySteps(std::vector* samples } float stepCountB = (1.0f + stepCount) / 2.0f * 19.0f + 1.0f; - for (unsigned int i = 0; i < count; i++) + for (size_t i = 0; i < static_cast(count); i++) { float y = (*yArray)[startLoc + i] + 1.0f; float diff = std::round(y * stepCountB) - y * stepCountB; @@ -1808,7 +1808,7 @@ void VectorGraphDataArray::processLineTypeArrayRandom(std::vector* sample // blending // real size float size = static_cast(randomValuesSize / 2); - for (unsigned int i = 0; i < count; i++) + for (size_t i = 0; i < static_cast(count); i++) { float randomValueX = (*xArray)[startLoc + i] * size; float randomValueLocation = std::floor(randomValueX); @@ -1893,7 +1893,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* ef } // clamp locationBefore = locationBefore < 0 ? 0 : - m_dataArray.size() - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; + static_cast(m_dataArray.size()) - 1 < locationBefore ? m_dataArray.size() - 1 : locationBefore; isBefore = false; int locationAfter = getNearestLocation(effector->getX((*effectorUpdatingPoints)[updatingEnd] + updatingEndSlide), &found, &isBefore); @@ -1928,7 +1928,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* ef } // clamp locationAfter = locationAfter < 0 ? 0 : - m_dataArray.size() - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; + static_cast(m_dataArray.size()) - 1 < locationAfter ? m_dataArray.size() - 1 : locationAfter; #ifdef VECTORGRAPH_DEBUG_PAINT_EVENT qDebug("getUpdatingFromEffector: final start: %d, final end: %d, i: %d", locationBefore, locationAfter, i); @@ -1938,7 +1938,7 @@ void VectorGraphDataArray::getUpdatingFromEffector(std::vector* ef bool lastUpdated = true; // adding the values between locationBefore, locationAfter // (including locationBefore and locationAfter) to m_needsUpdating - for (unsigned int j = locationBefore; j <= locationAfter; j++) + for (int j = locationBefore; j <= locationAfter; j++) { // update only if effected if (isEffectedPoint(j) == true && (getEffectPoints(j) == true || getEffectLines(j) == true)) @@ -2023,7 +2023,7 @@ void VectorGraphDataArray::getUpdatingOriginals() // removing duplicates int sizeDiff = 0; - for (int i = 1; i < m_needsUpdating.size(); i++) + for (int i = 1; i < static_cast(m_needsUpdating.size()); i++) { if (m_needsUpdating[i - 1 + sizeDiff] == m_needsUpdating[i + sizeDiff]) { @@ -2079,9 +2079,9 @@ void VectorGraphDataArray::getSamplesInner(unsigned int targetSizeIn, bool* isCh { for (unsigned int i = 0; i < m_dataArray.size(); i++) { - effectedCount += isEffectedPoint(i) == true? 1 : 0; + effectedCount += isEffectedPoint(i) == true ? 1 : 0; } - if (effectedCount > m_dataArray.size() / 2) + if (effectedCount > static_cast(m_dataArray.size() / 2)) { m_isDataChanged = m_isDataChanged || effectorIsChanged; } @@ -2249,7 +2249,7 @@ void VectorGraphDataArray::getSamplesUpdateLines(VectorGraphDataArray* effector, if (m_needsUpdating[pointLocation] + 1 >= m_dataArray.size()) { // if this point is at the last location in m_dataArray - for (int j = end; j < m_updatingBakedSamples.size(); j++) + for (int j = end; j < static_cast(m_updatingBakedSamples.size()); j++) { m_updatingBakedSamples[j] = curY; } From d28d23ed8db6769689bbfa452ec4633f8b9bb873 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:57:22 +0200 Subject: [PATCH 174/184] VectorGraphView_fixing_casting --- include/VectorGraphView.h | 6 +++--- src/gui/widgets/VectorGraphView.cpp | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/VectorGraphView.h b/include/VectorGraphView.h index 9a4c8200dd3..1ef88b123c8 100644 --- a/include/VectorGraphView.h +++ b/include/VectorGraphView.h @@ -156,7 +156,7 @@ protected slots: void processControlWindowPressed(int mouseX, int mouseY, bool isDragging, bool startMoving); // returns -1 if no control / input was clicked // returns displayed absolute control / input location based on inputCount - int getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount); + int getPressedControlInput(int mouseX, int mouseY, size_t controlCount); // returns a float attrib value float getInputAttribValue(unsigned int controlArrayLocation); // sets the selected point's attrib (controlArrayLocation) to floatValue @@ -208,8 +208,8 @@ protected slots: unsigned int m_graphHeight; unsigned int m_controlHeight; - // displayed control count (+1 because of the ">>" button in editing mode) - unsigned int m_controlDisplayCount; + // displayed control count + size_t m_controlDisplayCount; bool m_isEditingActive; const std::array m_controlText = { diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index b55a13df3a7..6ebc2491f98 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -715,7 +715,7 @@ void VectorGraphView::paintEditing(QPainter* p) foreColor = *dataArray->getFillColor(); } - int controlTextCount = m_controlText.size(); + size_t controlTextCount = m_controlText.size(); int segmentLength = width() / (m_controlDisplayCount); // draw inputs @@ -730,7 +730,7 @@ void VectorGraphView::paintEditing(QPainter* p) // draw outline p->setPen(QPen(*dataArray->getLineColor(), 1)); p->drawLine(0, m_graphHeight, width(), m_graphHeight); - for (unsigned int i = 1; i < m_controlDisplayCount; i++) + for (size_t i = 1; i < m_controlDisplayCount; i++) { if (i < controlTextCount || i >= m_controlDisplayCount) { @@ -941,14 +941,14 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i } } } -int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, unsigned int controlCount) +int VectorGraphView::getPressedControlInput(int mouseX, int mouseY, size_t controlCount) { int output = -1; - if (m_isEditingActive == true && mouseY > m_graphHeight) + if (m_isEditingActive == true && mouseY > static_cast(m_graphHeight)) { output = mouseX * controlCount / width(); } - if (output > controlCount) + if (output > static_cast(controlCount)) { output = controlCount; } @@ -1217,7 +1217,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve { curvedBefore = 1; } - if (location - curvedBefore < dataArray->size() - 1) + if (location - curvedBefore < static_cast(dataArray->size()) - 1) { PointF curvedDataCoords = mapDataCurvePosF( dataArray->getX(location - curvedBefore), dataArray->getY(location - curvedBefore), @@ -1257,7 +1257,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve } } // getting where the search needs to end - for (int i = location - curvedBefore + 1; i < dataArray->size(); i++) + for (int i = location - curvedBefore + 1; i < static_cast(dataArray->size()); i++) { if (std::abs(dataArray->getX(i) - transformedMouse.first) > maxDistance) { @@ -1274,7 +1274,7 @@ int VectorGraphView::searchForData(int mouseX, int mouseY, float maxDistance, Ve dataY = dataArray->getY(i); if (isCurved == true && dataArray->size() > 1) { - if (dataArray->size() - 1 > i) + if (static_cast(dataArray->size()) - 1 > i) { PointF curvedDataCoords = mapDataCurvePosF( dataArray->getX(i), dataArray->getY(i), dataArray->getX(i + 1), dataArray->getY(i + 1), From 7a9c3c01160db6f7c9ddc92a9d680b5431170982 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 17:38:02 +0100 Subject: [PATCH 175/184] CmakeLists_adding_svg_textures --- plugins/WaveShaper/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/WaveShaper/CMakeLists.txt b/plugins/WaveShaper/CMakeLists.txt index 50cd18bb63a..445acd1649c 100644 --- a/plugins/WaveShaper/CMakeLists.txt +++ b/plugins/WaveShaper/CMakeLists.txt @@ -1,3 +1,3 @@ INCLUDE(BuildPlugin) -BUILD_PLUGIN(waveshaper WaveShaper.cpp WaveShaperControls.cpp WaveShaperControlDialog.cpp MOCFILES WaveShaperControls.h WaveShaperControlDialog.h EMBEDDED_RESOURCES *.png) +BUILD_PLUGIN(waveshaper WaveShaper.cpp WaveShaperControls.cpp WaveShaperControlDialog.cpp MOCFILES WaveShaperControls.h WaveShaperControlDialog.h EMBEDDED_RESOURCES *.png *.svg) From 77f8f8732bf88508ed933a766f1d3b6ae28b8370 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 17:38:39 +0100 Subject: [PATCH 176/184] WaveShaperControlDialog_updating_gui_layout --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 9d10bbeaaa9..8cdbebd1901 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -49,21 +49,21 @@ WaveShaperControlDialog::WaveShaperControlDialog( pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( "artwork" ) ); setPalette( pal ); - setFixedSize( 224, 274 ); + setFixedSize(462, 500); - m_vectorGraphWidget = new VectorGraphView(this, 204, 205, 8, 30, false); + m_vectorGraphWidget = new VectorGraphView(this, 450, 450, 8, 30, false); m_vectorGraphWidget->setModel(&_controls->m_vectorGraphModel); m_vectorGraphWidget->setBackground(PLUGIN_NAME::getIconPixmap("wavegraph")); // this can cause problems with custom colors m_vectorGraphWidget->applyDefaultColors(); // custom colors can be set this way (but this garph uses applyDefaultColros()): // example: m_vectorGraphWidget->setLineColor(QColor(210, 50, 50, 255), arrayLocation); - m_vectorGraphWidget->move(10, 6); + m_vectorGraphWidget->move(6, 5); auto inputKnob = new Knob(KnobType::Bright26, this); inputKnob -> setVolumeKnob( true ); inputKnob -> setVolumeRatio( 1.0 ); - inputKnob -> move( 26, 225 ); + inputKnob->move(26, 462); inputKnob->setModel( &_controls->m_inputModel ); inputKnob->setLabel( tr( "INPUT" ) ); inputKnob->setHintText( tr( "Input gain:" ) , "" ); @@ -71,27 +71,27 @@ WaveShaperControlDialog::WaveShaperControlDialog( auto outputKnob = new Knob(KnobType::Bright26, this); outputKnob -> setVolumeKnob( true ); outputKnob -> setVolumeRatio( 1.0 ); - outputKnob -> move( 76, 225 ); + outputKnob->move(76, 462); outputKnob->setModel( &_controls->m_outputModel ); outputKnob->setLabel( tr( "OUTPUT" ) ); outputKnob->setHintText( tr( "Output gain:" ), "" ); auto resetButton = new PixmapButton(this, tr("Reset wavegraph")); - resetButton -> move(162, 225); + resetButton->move(190, 462); resetButton -> resize( 13, 46 ); resetButton -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_active" ) ); resetButton -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "reset_inactive" ) ); resetButton->setToolTip(tr("Reset wavegraph")); auto simplifyButton = new PixmapButton(this, tr("Simplify graph displayed")); - simplifyButton->move(112, 225); + simplifyButton->move(130, 462); simplifyButton->resize(13, 46); simplifyButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("simplify_active")); simplifyButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("simplify_inactive")); simplifyButton->setToolTip(tr("Simplify the graph display for performance")); auto clipInputToggle = new LedCheckBox("Clip input", this, tr("Clip input"), LedCheckBox::LedColor::Green); - clipInputToggle -> move( 131, 252 ); + clipInputToggle->move(130, 483); clipInputToggle -> setModel( &_controls -> m_clipModel ); clipInputToggle->setToolTip(tr("Clip input signal to 0 dB")); From 436258c35b55e31ce6ec74dfb5c221a1f2c4e000 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 17:39:18 +0100 Subject: [PATCH 177/184] WaveShaper_updating_assets --- plugins/WaveShaper/artwork.png | Bin 1367 -> 11821 bytes plugins/WaveShaper/simplify_active.png | Bin 9675 -> 9650 bytes plugins/WaveShaper/simplify_inactive.png | Bin 9948 -> 10072 bytes plugins/WaveShaper/wavegraph.png | Bin 1505 -> 0 bytes plugins/WaveShaper/wavegraph.svg | 282 +++++++++++++++++++++++ 5 files changed, 282 insertions(+) delete mode 100644 plugins/WaveShaper/wavegraph.png create mode 100644 plugins/WaveShaper/wavegraph.svg diff --git a/plugins/WaveShaper/artwork.png b/plugins/WaveShaper/artwork.png index be099b1781412d7a0d969e697c9f9a34b7436007..32c2b79efcfedc04b024ce9fa1e0c90715f550bc 100644 GIT binary patch literal 11821 zcmYjXc|4Te`yOR`wa}tO;*Ai|VlCMcHOi2&XA9Yvv1b=)v7}70FD2X9%93n@3dvey zi807F*=65-?`PiMAHO~(Jo7x~+~>Zp`?{`k#xqUKjRP#4EGQJ}0Q%;2Efk8b4PHyk zjBurdsnr*L39(gH)yYC;(Y8{0GM_&b*Ul57s{LAlhyUYFi@uE|?No6wjF`V`ke9eWV9=+G)7&i{|IrD!GUl+=L z6T#x})wT=$;YH^5qo}}d%eO|gzUeUXHSQsF@Ky%QE38rSb>cWyqd)(Xwps5YuNu@L z){!UMw)$a2LL+EM9G6kH-Nkre8|_n_U;jMln-tE4()~(q$d!rX!6i$qX9lnO8%@+e z`=3Nt#a+>k%JJpyzQ&2YFWwYrN!Ql>d%^JCv`4Dfs{6{yT)b|e!kas;<*yG5XF*jM z&2Qbf4&UM5x^iV8eESD?)4&ad65~T&bPqBVJmDgfJ6c_ZX=3jlwi9Rik4B`xr4#Nd z`tHikj*j=8+)>J|_wTvix8(J*b+_TYfmYYldwB3T3dM^;Usuw8&^JTr)#K75uKcx* ztR#Xnulxy-q^EClGT1!eZlG4zpjGHjbYe>P3b zS?7Oc3=xXCF1Jihf0pu1_$MxX$FZd+?q*SR%lo-!;)8SY))K>9HMMD}y1R`T^>uRF+zcD*y16*z2zw;0J?PyyDC~a8?u+EDI@LY?h>p3aAB^tAFMrtAo>zqDH zmWo~o<1h8CQOs{q8s+!!4Ln%+BI?tc!7BCrVCeLmiqjttVgH9=#G$X_KCDLt<-1={ zUmOS;U5q>uB{}*p|jM(}35XK-TtA?ZswQ6nuX?zQWsrV9eP!@p{l7#%y$ zC#<*Zja02-Ob_@s|Fe_j;X;FjV5;kv=S>e}|Evx&bUn3bCw_d>Kq>4~iodute1GpL z+YWoX?RteZ^MtBDah6MjV;0#h+U;OlEQ zz6>VrtbUrCvD=)jbC~-Tfqs-%sdPyyzGkPolP6dzac-|ES-ay#_h55G4IQT|riFfP z?4@*;z#?a)ypZ^P%dqIoj4J-#kCyF>^i<~-M#dN0{YXbD#BbSWZ|1LaP&tTp1!(7tI-P+5C{lkz| zQQhINAiriVimBTT-Os(c+P)pLB^l=Ip9zIByKd8W9rsgvA4-ue!Hy2ak=0Y<&6RW=o}v3~>k|@U{-Y6Q*4NdQ=z@?; zTsV=tn9oX`vA-V&?XYq1fV5kd-|ww>8K;h6>_cfxuM5Ecx*x z5YPoNxkw~Nj`k&COfcl3X#qb(k1|Ud*u%U~hxUWD6Z`ou(V^nfCi#)IQK^aw>_xZ`7m*Eqpb|gyuVO}a(WJEiU0Bm9az?d zaTgf&GBR7oTddZ*n}@j!_M$FyXJz&k#65>c<9=;P$Os8$rbB!Y_VM?xfV3UyO!}}7 zBSOna)3@tlG8Py}ma>P!w&cQYRuqg?=Nf%?ELmj$f*fOFI)N0oAv2Q$W~}8e&v~i_ zx8Ta^(7OUCRJs9qALe+%BM9!xdS>5O7|Bcm89FX)bgNVQRu`nvto|$k!AA(*u^t8a z;rF^h2e?tjmm>FRzET67y%49)D2Rn0m~&+!_qEz$5M-S=Tl7)SMd~sSl$%A}0Er{m zpgasqtN$%^3#0n8$hB*q#fQ&9b!weO#$WgEMWIGm+DvesmruZBaM!z=7pZ$tLGxip zAgzMd*WIDk-<(An5V&1)#lFlymTdO&O%9ZFC>s9@Y8D-aJ?smqWz%#VcutU9XlABE z1^xJq#)?Av(vTaUg}`XH*^<7(!XMV1K%ZMW2zbHKp!tYN5Q|ilSLVbWNEv+{S{$Am zIdL3N!W)r6dz^qlA{VGdV8skS1>_G|c0oV_$S)U^aEFsoC{2i9zUv}411bnDf>8yG z!W)KnydbX6T1esVLF1r4Uyxx&p^(v#M|U!|RJ##`j~IM-DTzYib(3G_S!Q1WTyiBG z_J;^=KVo2m;Di8zs5*H5|6a8`^!CUMbRsG(zoDD*`d(cOb2zU=hpPQ!NBS;&NlXQP z{Ph<97$UxgB^`#LV4<`IoOZOM{mN+Ff}rz}xP#>ZRPA+I$L2{nBdMZ)Lc8_N)>X`B zNOvu*7<>=|@Be$PeKGTbcKa_Y0!Pm50MV#^ps|FECt${`X!PAM#1@y~1!JJuAOz&K z#e#He?K^hCkPyhifBkc*Y!?}x`Je_3{4byWfx1Q*&1s0JgwX&s`Z`O}Nn4c99&Y-K zba}%wd|lJ55X5@Xbx|e}%?cxZq^&^YGN1I@?xQl? zfb*u-fzxxUMci%BfP5#;2xAzT=uj7=F7q{SsiRPP3{(U@L_pa&WFgPYXXeo;zJHQYpzY}SQYIASVMTW1jIAeO*kV5--nJVrd1>C zzl5|P8fS=pyabpG+AfiW>Txs*nVUhP@d!upz8{jHNz1W>=yU0awpciS5idd>WIJar z47b10p^-l`RjLRGZ{!-bEF^>`Jr5of<#PbpnBkDY=mphFp>q!>9op32i()&O)Lj$> z&0SY#DZg^STI?^ybrh4@tUk`B`XZ^uk^6EcwIW2Uuyga^VK zs<)P5EkSA1mI^R)!^GsryQC!q{-}{=^&?nhoeiImvDvg;)R0VEK>whD2!Ax0mY9SD zdI*ZnHT5%1EBDZdLx!S_Go&@qtE68DIk)G@pkaa6R7yxNgsK=jf zB;jPzYa~)tHD?h4nl=h{HQGY=!T1+mmA7I{UHT4E=>Z>G?ne=}RedinsjUe8Wy-4Sm&1-7BhH4TuF(-6+ZDxHU@$Bs2l6 zbz9TpXC-jW1E-Z>JObno5v-VFfP6ED^4?q-nq%phr}1Y;R;D4cgy0K^wp?^5Tm27( z``ZUzq&-F4#NUXCNJ41|VvC@1T9$dVr0P?0z9Ffjf0Z=ZIwE0?xQUT)b@a!wd=3?; z^K58IBV?~k6>}L<>1GpmETL!ZG;*fs*;8Uzgb1B!^v-mv_ zN_+GwxeTZmA-X)71AGXZtGC~L?Ml1Z<-{2UFow!sqwhD#K|Ql&@@Lc$tfiMn=GkU3 zpm?udbxyQvf`!3*6XSq~n_tgDFjbS5`B2$C%8ODmzJc%n-x>wsJ{yXLj-UweB-`gG zLPk9Fv>8ono^~QCW>%vAECwP_)a*j&P*JEExq6!;X%r}^4vAawL0!%_M5NhXCq$oS zfq6f3pkKbphk??3=@0?$4ZqSq&fJfqZ=P?E~%)G=hpvaz#96(8b&5 zWg=-=(We=DMVxB`jUf*qc;bB=nFpHrX;`9~jR6XvPtKLer(w#beqy(K%o3U`DX|e< zO3TbKL!^7zl9HMt^Ky{p5m9>t2&oIoW216w{P4j{kRHcWzLrI zf8}}!Zfv-T=!My7smt7r5RhK6_eQ>;1PQxbWpFQn0U+l3hQq!+LCzO(Jch zxeSh^fz9r2zG+YSt`vdnUp`$|RYg?iq4`-?k$;g0YT3jDBaa%8OdkXHJ+j2+|7RV) zix(Bp!{U_pVqG8?>VAh&s3q~wD0q2SK4}pGd0)jd{g4N=8kj(4fO?7ZFAt$w;uv zL3EQKbzc;@fJdAa^SxJyoS+`tHy0kij==coK({%>pV4{|d8f0thcWZn5R1;pXZ(u<8C}pL#lt~L1Be5(aF+q!nw?bMc8;iPypIdlbNgi}pjJT+}?q^bNB<69B;-r_15nOYD zC>PeN0x@E!N=m`5+l$ap2Ay1;vBgv|YO592+S0^qlv@tO?otmD$edETBii!#~f73UbFG_VAICg){c>0q#{aQOmyQHM#U3~lrl{@_Q`G)zgIU^q*WM$RK?NT*qSzNCYjtL`l5fs`WSN8c= zlAk*{Ik^V}6r`u~bxkdI*7tLyyO!rc6g=0u4JA1bblFMf=jGYlzpqknerMfpfazMk zE~&2WA!lSmEe=O@@b>l|EidS@gGw$@udF8>JAPb8=;#&|CKeMD+qwt=2Hx)J>A4~= z-wlt!Y^sb_O;CeNo?(9G@$)8YR$s5ZNfXpa`O}sxOSB6c(Qj;Q+*qfk>J;|q2*;FESLeet z$jp#;y$7?@N|tPsLi>C7lw@UP0S?`iO0VV7CVZz#)eoCLPj~`4nwrpqi@s~~Z)OK; z3UhMK4la3ndLmQ(`Sa)I&l$5MCe~9n{{F`G=0BKjE$An-W!G!vy|L7PW&twg@yx%?HzD4!& z^xXJdCs!63d4N4!1)f~*aBn~V+=53tLknG5S!pN1=}+z8jxE&%%-BgK_Wk;$nWMcB zljoafS4!yZHJF*5CGLjw!K6Z9$SS%J=^@^<1rF&LC-8pLO z<73!m*TsWfFhZAM9aH4}38kfytt~A}+_Cm*VnQt5DYzG<=MKZC(MqZ*~R5Y zplP*9PqpvrmVLa#IA(wutkBwNmy@f;RnR@qDSjMdi{5fROE)2)oWk&tUr*lVo}Q&t z#_sTl@a|nwv2}Y1k(fddGd?qZO{ll#xXR1IqG%mkt>WJ4&8?P}h*R=@ z*=iZlEF16;Qhw3|(gqu|m2=u+vDh~qcBP#Y?tZw+#*~BvtqiRn3kyZ8do3bPDFoy> z*K9*U&Pt|bQJiwgGaEr}3ST(VfnR{8pt*q`pbepeI@5Sp#f?KxG=A9KanNsVYs(bw z0w$RwZi?xwTW?0R=aKB|(Fxh@n|^8S5VS67!d zu41*eug{R6^0vz^hvFm>+q^zWDmBxFtmWsg54ltAtgHk)7GJefODifSol$wENM_g9 z*T3!P1|O-tZWQ|J0Ji5*Tsw6cAOYZ63B{I?m$%c(jWAqXT!yBm8lfG3|9*fz1EN~W zQrJe@+uP?T@dN${U3Sngmm1c>9Y1PZ3Omhnt#{sYI|xlCll%Jm7P=Bkb&nrE?z6L1 zj?vKYx2edK?}_zxcYg=u>2ZZy^xQccH#aQw`|j-?o}_ka*MxgXMFpWTiYMz@aj(PV zNMjUH!5!ez+}vzvVzNT*JJ9LE5*qw{tjNmR8r#n2{nslbZxq-I)1f0w%U`~;%RYineU?PYoSQ?jcuL-ZF89p8hFRQ)1dDgUo=Lbv#pjs`w2jlMS5O*M$8_PbF8X~Yt4xLs3 zL!EzBRaL*&$dJO4s7`usUKGc!{=w`;3@c5+g!(4<-|bR1}OcAz@3LeuLCH?ZTx z=;&8z11k}Xbp4l53Mos&ANy9eP1-0&>Wq-%>)6=s5AIjEfq5_rJ8KqpmQIzF zQ!-j*q=|1F>Gkz0Ku=3L!*`BOfMG*0Q}+NW6A}{ASxfMm8(3#)mm~{>3~g;0AzC~; zTd=zY`RtqVoILp{D7$AW?Cnit>9sfokrN33uhqFh4M|d?OI~yHEgtjPxajsm^33G? zyyh+xYCD-0_4txFzG_KytD0FYM8GrIl)-LACgX*SljuewAT|%Wp{TsLSvO) za~tEgrSm^;-(KzKw{>y30~EQeKjV3qN8Ya^QQBE6N1HXR#TC26B+Yl@o@keb_Vur(_%gIJabYfy+&aoh? z;+*Ymf5g8ndNwBc1r&r14-cCUxd0~o*XETJKqqPsRgHvTqs_$_QJ=4o)K@eHdQ($V z?L9nnprl>X(|L2sS0Uqou^OQic*EPE$f&jZm ziSK3^b1ZY478l(DUwSI=ZA#9XmlKHv`T3%OAIiE3y1BO2);FNF65`|kh8RcRyC5f* zKUcGB61cONilsK{#Pr&cxT7i`ehY~5HObIw(un*8mRKHl_hd=oNkKBtPb2I0#WbwgAKx}Kg-v>1-l7^_afg{fdE0x{RU$bM+4>t z{iXARk+JavU}^_GIn&i5IT`5~oI9p- z?pWg~NXDe4}cHvl1L;&79I%<+IGs~@AG{l?kF>9Tls#L{S~zlRLX4OEkwW6y6h z9d*}4q4sSce+v-maJlVD5t z$mGJ|ef#-C7Qq?q6zmKSUn?}NfnA`6@l9tZC&XWIo=xDM{yjc@X7i-+B4unW1C(ql zu**&dF%W7+y15yI0@%k@peltCl?T_b69+q0*!BeMtXl^@Y#VdUp;MZ@e3FM}YJA*k zI`c;ZN2#Ic_CoXdokb`Uv8G*=tL)RKZ1WFsoXZLMB}T=zS){+%ThR~QfPqOQ5|P)X zna;|Yv;S%n;>)5=$*D2ug8>K9p7isoG?w#Tc;`$^=bFX}9R(fUJQj}&SKZI@39OU0 z&V_2!!A&p~Do?%cziVVPooiQEP|(muI?0pdaF&txMP-oS`99E!o#9bN z-1OYs6e7i<<>LtlD50GPP-+;irncRPkzcDX{kPVBXq?aoRH5se;R( z+L;p*wxXh<>$~9MW(wV627#CmbvQf+?gc!;UBO?W*ag)_{~2&_Qc_axyF1(3Hd2Y| z)dAav2-@IOKp}Q8aMz#kY(R4L)X9@;TqzFqlgEtO8DHI%1YeQq^jz%xc>uuR@mgr$ zQbYCK?ZI8S_kl9L7Nbt%{XXTr!fV6BpQDU2bB@&(e&O{0pAQ!N8 z`w6>00DOXvlM}rI;32#~@XKdztS4uLeP-**jY?q`H#c#~REg&nP>(zCq(;7}FG53( zju`<~a4?Ykq_nh@Xtg{Yd|=iMSe*nagEbuldcxt-z+1xBws21JcH3^N{A==)&g5J? z{>aSS9LVi*>siNA!+?8F&$D1|VMT*bPB>N1c!@@a4xm7&CS72{XoJTvYj=~OkyD@Oz}e;%Z0UH|}s+LFwMhX+q`Cx2wTU*r!kH%lkOibjOnVFdw zYmP;>DoaZxrWr!zSDth2AKh~$>}_X5o0DQE)WTmf$vDPZzox)lR>7m=GaDT8gpE8f zOU&YGNV@ z*_(f`ZttqE4>hUw$$$hY^j)ds$xfVHD0h=4)ggaz^Y8I+ljT>{aotlM)!vH&UAGga zz0^!T9Xxn&3D!ikQYouwOS8ICW)sBqBD$TrNidM+;J?YRsA-lywT=b?BvhD|e&4>K1_C!$`XZfXtoXW@nn$6(6rKF{?QNKMEPe|yz zf$i_cMuqc>b|_M5ak2QqI>7eN47rT>Osc$9&s9DrcXWX0pU6VzrTo5zcAy3}YK>vR zSTfeAmIwzAD*b`$W5>aU$$MbZg%(1d8Ih*y>Xb~y^QThtd#3#FmX`O-E-h&z9=o&i z6{|*BVuWub>%oKCg*_g?dfKKrxoH&drnY)eqmF@r6tGFq?v8IMK!hG18L<9ppJjrx zdl7$)E51}0&U98|1f}yl6KyK*a~AuP%Z=LRSQDz6);L>BqAlOnH1}0lvhpXpxWFIZ zkXbJopetl|EEOvxZxy$CMXK^iQuw&OgS+bM?_V063f=%ift+#5%fn%ifB4f%s~#nF zoVd97-Yj%dYAWmg`MhgyhRRljW7Op7jY6jx$wo#-5lI#@3JQg48N*Dg{IR0$zPEtm zK)k2c);<+ZNW$63LuDu2ok|Kg!ILs7Ut0h1*nOS%2T!%Ku=pZfs(NR%eHH8nk0m~T zsb5SQX4{xD-6ep9-3+TD&)C7HaCg~scPw_!&Hr68rt$nf8JjlSmCHxNRp8{r4$i3b zQk;~$%4+N0*Y_G1<6M8Q7T&Q9U}>vq>bnJ}Ej1}zH}OU|isRw!!n_jvRB6TgTLorE zH)KLQ?OptXXDXoRrhHNh&qk@ ziH3mV34Ie2OuibJelQSHIJ=fz$wSWYu?~O#Tc)NTB~A(*flSE99|A=mKaOWrep3H9 zwd^yvWdt9qp(su#{XIO!Zd`)hX?1n=pdXG@6ZUK;HP7(^;TVdIjk95`wV>G7cE^Ni zam$C@+T`a?Yk9Rq=_5O#(Q`HTYRas>)x>{YJ+LVoU|M)_C!_yrTj2+H3eOdp)`)jw z1J=ZDwQGOlqL_^TM7$fsW++U?sgLi;y?C558Y(;L+Y%SP@~J0BcH_m3Z4U9_v8I63 z6MrRH{DgO=T>09X(iTVLV;&R;a8|7pJ!?p^zy~Cmu6`FElDjZk&M?UAE?(1>Jdld- zzqzH`zFU?Oy?$B2`KJLN{br3RPFOI0{ZLKbUuz={M&m!}=O46;_T2bV6KKO&uS|&e z=TzmK62ATHsh6j}5Mo{EHrc-n+RUeNx*p(JaSkCm5A}Ra=b_qPYFgDhcfxlwMYn8~ z${)38A8PqZzM+$fH|^oZ>0Kfiel*<~;MiEV`8+ox(6%Xr<#W;^N>s@z7rNs8=d{mX k&3gPuNNL@9W_Pd5AC~?lu%}vcK0dg4_oQqNu zOHxx5$}>wc6x=<115)%-*%=sEc6+)whE&{od-rbMtq75Zi+krfU)s6iikI@)-}~=p zm`t_$%boU}$w^H}VD_yUZCmxcE{E-P__gJ{;WG>Se?P-RLm8%DujEdUoT=$x!1yqY zdCULi)DYM3nfEv%7TH%jY+z?$WMTs07W4Icf1FHjGMLXS|8wgKA-R}CjpuY656TI= zVLa?4l6Hqljw_&~V4>~;RgD|WAU#bCj0EwatA!@EGa3{e9FTB=lkTBr%S6shrY2Pl z4gmoLd^kq;d>ezX01F2PUc4@Nb;pO=3Ij&Rh6V-%K42o_%ddvl0#wWMrafnF;^bgr zVc{^}!roJ0VymO%>#%`^6&g&i;KEJAg5?lzM&LYN#%>K^0Ubxjh67K(H_Q_x%`Ks~ z|F8SDpJDTfjytK-{28mvSYkYE&+oX~xM$je1b(n1K@MeNNxSs#f3rVxqFtqi1OJPb z(;D6Zz?cQe;CA-oH+@S!%&pk5r$_AEl7`d@GnO07Ft@|#L$fdT{qs$833W+Jaaj|_ zUs!%$$@uOrHul+_D^|UzU-S6m$KPg?SAAw$v+Bg%*Rk0j{~d0xsQ7-oc*cQ)3%~xo zef`Jx`TLXi#>v;HJ=nncW7DySyZgJ(9-Di+KxxVi{=JRPt9pO0Z`4eF>F2xm@9JL( zG4;&L6K1PsPk5m3=a5kL_DbqhBZkBsGWOiQ4mzZK;ys_`7=hV z*=l(n{u7tjE-G`&`}?c5pvr=}&dYBY8!dUFo1&TzEt&k@^1!Oc-`BkTzeg*EtJOGZ z&E$IXFL43)549@JJhPF7_1GHQ>@EiLjeFfTOYUC78fQ}C*5E&TpH*@)=d%aJ&dW>I zuT6`sZ2Zh6bE)qe;Mjh^v{tyC&)# zFr((3rKEHncW%gy154JmUb?LGAVquYO&8vn z_HD`k*OjddP5DwQ|G)O1$lX}!y~o;Sb8XNv`)l=U-+l9vtdn>8-b(C_&G27e`(L8= z{|ni+g}--)w};+jKD20J6}Lk}!Q`m2*pU0XcQAZBc8J=1SiF=fYw9 kOgvO@=I!d$(b*q`@BEcu=KH3c2rAz^UHx3vIVCg!0AKpv3;+NC diff --git a/plugins/WaveShaper/simplify_active.png b/plugins/WaveShaper/simplify_active.png index 19aee18e8ef9a4ae336bbdbc2ff8ff0bbc709a4b..ebbcd952a6c5708280887437782720b024cf498d 100644 GIT binary patch delta 6339 zcmaKQWmFUn@a>XIvxKxXk_)>m3%f{n3IdV>(j}dOuz+;>BbSmcfu#|orIBt$O1cGC zq8b1ute*JxUYa7&^8G@4T{~f~hJLQ*=g$_zJ zXzk%F@S0`)kAvq66r3nrjw$^a|<`0U;%IZh?Zp8I3=eX*c=$<|ZC}Ma0&!1K} z^SJOj|G0I|=1;}sXh=Gh<{VvBshe1j(0T20I*gxpAWC+#UPz$^P_yIaWh^L0Zj<~b z`jLDW^~olfbAUbb*jwsPJN>U>lW#92Zn1cO0|i0rXIX%S^hRKgUBJ%mf6K#apHB-G zczf8oEm2an3WQav-^^^Om+qLX7qLL<;Z(qB(qm;em5a(NHJ!LkeX^Ipst_GeKPj*F->3TO!4>5RGXO#o8eOtcm zqP;N#x$*ze=Ue=!TbMBO`vyO1xnT`DDNReJtNGq^I8}ML#Ra@Y9AiH*Y#s0iK{8DF;vc&qelhCejYPZw7~7)u$b5v$c_4r9Yqi@xbq1n7MYI z@!+%*UVajtb>qF-_4T_aifM+|rdAkRpi+2)>F-;(es;s+ls1~hsTYYSsP?vw&MG{f>_Z4Z=CHPsPe~L^A2^fZ|-(_ zRwg^wCH&(nv0IZ$chiM!7~2S&GYs{3ipJw_rqLYPBXHb-yk5Z1v%{3P^4t&b-Bzy) z9ADG7Wl@7&7_77e)Y^IVQl$KTwxd?JiR#|^V6k6z$>;LW{NeTNMy>x{qjq%n>YqvR z$M@oS*UqaVu#nyu7AzmQC+)(~A3pgs23U3oi5tVb$P_%?ba^r;)Zi*ZtE4Hm7gYqpJqAZ3gA?i7e7`ZcHP$hR=-WyCCY@2aMZ_J4O-K|OhstFHOd(L z@sS{`o{b3n9tGNS*pBkbi^{BLS*Y9m;gI(F(q z*Z0ST$1We9ysMymzEsL4qgnv)00rVCR`dMzCFYl3)_Q9C!~w*;P2D_hV7g@XlYtZ` z=*=@b1sW!u%|V&P>C~j6|KgI~?y#5u?P%@#yt2`Y=h~&mK4n;Ly`}B6e_H%_Xj9kJ@B8$Nru5?Z5 zgAlGeM|#w8VVSc~!*?|KV0HBE$-LmcyuH#r?MwV+C9bKkBE8CocrWzROz-7_)@*^! zjMl3Jd~g4c?2R+=c&ys)*%JBaC~j^>f3#T+$bQ3t3g@^~#f(oYhKStI!B5fM~Q1-mT{ zUJe33}yI^}8!4$%_h>Fw~Sqxx$DtTl=t1i;j@QMa=Zt zli#5LSQ7%I%J36^UFV|Zl9Ro}M#-;S3Njx16xNASH1&pqFW0BJ{TW}xSt!$C(m7(Le1fz)3I_k?EONIEb@q_AKsEm0{aD|!z%!AsOJ z`4Qd#JC$BPuiAU6+3-GwUkhLV)2HmwDS9#4Wp(+5lJ9hn^6hQC@Ob_qF6wcu?!8W> zoQ?vTkng&B+LB1awa#(UfeG(c{V0TrQ%{a+*&~jYy4hXnttb+y&&qo{kS6ynY(-^? zN;5i8+N(}DGW?H@>1UdZ?jbHRi+x8_9aV?LO-EKF+^YQ76Vhwa2K(M|7Iu27ZoTn$ zm(2Efw#Qp3J$@%6tmc=Y$BDk#AF?hq*dHsP^xqUxlv&X?Q5@x>lje@wD$RWcPoLCIUb zQnm`;0@j)hJTJJ&lG#c;7gu+tr;_Xn4oLhe4TMsN=Sf?I`p_kQx969WCHbV{4fEcR zkY?%kr+knaK(ZWt&bF!3X1)#GX&x2QM_zl+-kLXcwjOi$fE<&?E?p*UFI`+}{gsTh&tXqX>i3eS9^YYQzDvKbV9>d9B&`ytV={#s zcPDC#Ku>;{hhobh3D&L{ysW$K<2xDnjd_Q`_9aus!Ou~>kpGm{7p z+BaFG7pLgtzyL!9}|!SCNY7|H^znbX`yz zgf|D^whes_1qp;xtJ?4jPz(!obcpA|_bX!2nqu@`lb}rwYR_LNAV0iw`FxXlGGbrMJ7#pUSbT^sQsy0 z&TVivX302YedL4UJyc13o?X%vTNCj`5&9B7=XVtCP-jE;J?e!Y1NV3)MAcC~mi_6r zjJG$D4J@8DeCA*$rB0Y3a!Ibjf`p(VD~oPTEP%k`vAqE-2U>t#OB+%PN2O(sE~m7d#N%N( z?6y(hb6X=4&hLRjJdU*%=$?{-bjAlFVTwt`pDs0;)Q1IHEOAu-ReZ<8DD&O$%iPu@ zUAU6#l`K%gcyEmH%TxmOxCk!8R7o_>DIR@dP-6KMDsw(tmtMcMC$f5A5gFm(?@5WI zT1s|^zlwduO}osc+%RmboKP_Ro+1oDJr$@`fz7(teJ(=&0{S_I>cXj%&f$>W2rp6& z-(1;WFry@bYtxCMVk91yD-*_fy`P^u`pas%Uho-;ce<7@5)-(_+|_v{5h0+Pe7%7; zPO@If^o6M0xWGfe-kf_{8b^5bSAX$?yL>PwhFBwrQRnwDCoOt(Udq3z=>u-)YhjIU znX~xCTRGU(8Pebv(RtFxSF3n0d=^EP;uSkr?mCupW9qpVLCKEkk2))d`A;fjc=>(k zmgP-Qh2oeVX5yR8%Zv{&V(NtLkjZ;n5x7r%{w;-EZ5$5Q9&uXrpBJ0it0V7OHwuYA zZ;EY&J$h$~fu%4j)iEN2Z)_S^9^{=NId?d-1)@zrx6>|)kOV!my2N4*Ny5hsx<^w? zU!KVNMxt>n(Z8T4JW(wbL%1(2=YY%Qi_OfaCwT-LXG9gbadK+d%mQ~OWkd1KUb4%+ zwBF-aFE8{io7xH;=^wO*)8qMAE5%zW&nnWj)w~SKRK#s4K(unpFY;`-Iy!DEAm|cz(H%zpYy2h#JZJ_ zjh0Y;;D=s$VO~7(7{vhsn}Q(2!ZNHfP9q=J1K_jWxmtpr!dsOW{b_=HeS62#}AyTboDXq#f~oTyo|TGWfz0U$|9Ti zB)9BUFT7$yq~A`oEi~={6Z$ACwpz=<+rC@jPk}r*GWb_9lgQ$>byXVO@{j=K3hInK zCD|f1VJ+26@gJ-}!jn)z_J{2I`(vyUP=4D|8RuE2E)IXzO&Y@v`yI-4J91_Sx}F@y z#ZDR96~n|$d1mMw8B<<)f2WIm$GR{_hzS&Epwnk$XK#Jm`u*@JTdnCHagJP9g(}@p z;IEE2`>y50k5>}4sgC)2%kMIJei7{fu5s1EmMtueruK7U-Wckl-r-c_An$_sd8i6R zH6GUI9nFx$5(U3p<>*j_20fM$3~l{xH?Dh}GNrb(sq2A8_xcZ!MtEhsuuxeH6SFFF zk>ty8xnpi;OAkLu#l~l1Mng*aVDw%SWhW_rB;n6h;*Yu;pj>YfnXZ_8(l~$C1KL7u z6WzE;MxN~BSXlq2C5zibReD$h`|90ggAMUM#NcU2%92lM%RZ_DtG&yU?9-C0Vay}u zUQ0$jZS;r@b3fjTzB<{k13c(i#(h6qsBCOwpx-t3^0-A=)EiAkV8zJu#U!~6A22l1 zPYd~eILg|lHP23Y0Jmk>p1d1#S`v_)G|Yet)=ZzZ|Oi08WWd@>K`96_BmrbRGS>*(zD zK{ejdJKiiQU^c5X0W{3D4vbLl#ol<(Jvs@0YxjUszwbNTC}+ETfawZvCXg@xbi$Ew zJ+KtNqMx(1pD8DrB3)h|8>S*~$#E9Obf39ztnK;Qpwf*(qrw3IoNy;aMO}48#sB+; z`uBXw4gODBtxt|+z*4`IGo8W@BoDd;c+%(6nwRuH@I=x%)(H8#S;g8Bt8Xx;n}6 znmV6GC)-EojM_pEL4fT>Obj7F-wD2J4_(Rl&^JP1 zOnY_%@Z|}BODF2}D2BF#KTV_OhA~(lhoOsraIs@m@&*wM@S1zELx@1&KN)38>pb~= z61KW}FFm_|3e@5DLd!}12?PKr%o^utRdKnk;nr|lI8qdBgS4{+i;3IA!AK+w0Tzc? zBdx@&kVpg+kt$2i#tnr-#1IfGYcLEhfdq?5z(v7GgdGwr0TH!=z~EL0D;wL?aC%;D zguT5DMBEMz7DFN>z+!Mwaj+E>2?axKtZnVBpw{A|aA@i{y&0bv1POyepfCxz1Og_( zNy5&~uBxuBD`{xw9{>}fNof^du$t`Xp4v`SGhk)%7Hg^B^ zlduL`{WAtEYGY$>3l*~ww?ZIOMHux-p#MgQ{?7=J)Jg_xZV4L+F)LA+1Q-hcXNj1- zgbf%8wUq$d*-D7PpklUGqN29{>Xd2VUDsBug~ED|d9yT!%J2XwIbRxu7VB zy66Qvr=ykkPx$&pSU8l2<-{!ec zQ%T^&&j+c8T_k1nLl91ZE+2{rP1l~1&aF;8?(A9|e4$HdG$aO0xU@i&5fblYn} zY8KxJcF8M~(wpaNYodY+3RgWeJCmMNphdjvL?qn#5j|We%q(^R*YD5VQfeQ1SZ}MG zx4Hu;NRqZ{*ruzzhgZ#_7%5+oB?Qe-UQhkhdq){6-fRSQb>>~J$49~F1j?xJPv+o9 zL*00wK%;^u(Ji?+!|yaXU!U}oWq6w1IPc`J0Uh3_;SGW;EJLquy)3$yw2of){`jq? zpd8Ie$t{A)Wb@m5bBifmD$ZmI1|UD8SabEO!FXdxsRxMQ!4NMDZ0)EKabe@FdC3j&e%Ph)x`vP8) zrQ_grGQOR=N}iC0T#rkFpWoY-QWeQ%=FO8i__!}^R{o(MrDGJ%>9$tej}aFuCtm)o znb+cG02rGHVF6M4Z20?IQRX>>8>w>Scdo`eZsLAXHAnyU_o}H}VIfRo8k-`z_=E^EztJYf#I#Ei?|?2w_;7`gc)!VBK38Sx5f1g1ENZ z(cJ2`=5gL`rf-opME!fei;RVy<)G3v4DSgt2dFV15lZXlfPbN`{7ea>@GAWO0GHCp AdjJ3c delta 6524 zcmV-?8H47sOUp};BYzVVdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+NGLTawIvH zMgOsiUIMgO4y4)aV3yzK!ktW#$!@cnAuGwChdaa*S0Kvl|NWn1{>4|Uu9}!i%`Iok zS8TEQ&WmcFuYP|z8}HBi<@fuZ`+nWn^}gY`6!;yUKWl#P|9`mdJ_mSybzY?}1J(Jy zF}}ai;yZr*G0;0v(26`S-i4U<4ixq_SS-GMAKC^qvm7gvF?C`wE|3ATMpwA(Z1KK0M<6Q+>MWfG@`DVxl>B0m zK8BFVO@H;8nn#MexBBF{Y`6}Xk%<&?DCDMvPO@T5)K7_(8tN&em{Q8Aq?%glIpmmA z&befPVlSaYQ&P#Llv-NpHPl#B&9&58TkXxa0BEL`TWPhm);n`{M(#Y_xuN&rM;LJ= zGx8{-jyC$Fd}f?!=2>Q)ZT96?Sm4LXtE{@(>VMm9N@>TPcHU*z-F82e+6m^wlTJS6 z)YDG?%-WmQzrO!L*4&#le>0^U%V*ZOTFS=|PH>WxGZN-abY#3J1r)Sb&TMrtdSy;I zv(3{L$+O6$oGqt}k-@l~Pse@a&iE&z%H01eZ>Gd=dGr6*%o(NbA7<|Fy#1E7B^sJH zV}DN|tUsn{)0LQ}F zMNAN8I5Q72dg3^X<<7c%9s3>9FlLB$Qx^H0oYO96(mjd~6>+$ksHXLC`MsFwh1J5x zs$wW+DVgt@b9IxX57sz-TVvwCwR1VF=g%6;UgY1LlEU#S__C;7xoqyX_iWF$ds`<@*vFOQDPHGye3p2_cozs8YKaJo{bc6m#e8He^>K$_+e&bV zYb%K>F?t>St}m5eqv%uv=9gr*uOs@hsHTt9*JX>sNVh3k;ZL*-d*&IxDfw@EX3KN2 z8e85}6UH7wd4s4KBdAZiKS?z|lYh;B`)42-)MnzPE1%;iJ;%4R-JORRQOxI~(!Xso zQenS0k2|CMDa)X28Li{Vcw4m<{~rs}zAgDZb8kb|W8RRu@g=^?rW?`!)I9N{V!sS( zK1ThhB&N=%r!Q&hH}iVn%R;|ozWv?(sgr{Jr?KPrP%JCxV8MIt?cE~(v47NwUY@m^ zUJzL%iR26zsf?9{x&Zh-Htn!HwE=XDxm&32JlPCgN}hcLSL_8$Lnm-YT+5zhSKMp$ zEEGRbN`hbFKFQ6^ns-?G-AJ-S(BCF!0rl9wuMI zCCVw;lbc;9u9?$F>(rcKhJWm#j#aZELn}gTp;cm}y-zz~Eo!2%;kndt#ND1JdkGXd z)!v`2?*P%U9=puCH!M1c*mvhJGkK`|!^#BJ)t#X9iWixiiH5ixw^4`#Tk_;10o-Gm z2G+T}PKbH-6fGFlJgnVj-NeI>HrLo-exG3@k6DLnE0j&|9KXSc0)IagdJTC4Pp@%$ z&I7i9=wayM;mlb|wrdskBQ{kESOFxNQYHDwkL^OPzSO;pHU?bIhST$`%&$>fW?Zti zfw|guivA4hlG{<*AYVInk9+})yDPvIrh#t<02`@xqDvdZJ|&HEt%^ON)3%^`g4Sjm zrL26YXlk*u6miN5)PK9NgfNZ(t;4cD@cD^Fc+YN!9d58zDpbKHM?VA+O%W8-MJKh-#$85u{GhOXk!X zz!6l;Xe6@gEfoPWdM!5&B}1942V}^5G^n_>M#zK$;>iK9XEESSEcZ#u;5duqK@0%_ z@Bo3#ROfM{xG{X`d7roq63Tgm*D7h1OlJD1t9s?hmOclP=A^R1>C28HoJJ0ga@ZBjxTrIW)0bncSTu88;O9S|E5)Z#O~E6&jAABqi0 zOC~@LL!a&%5O-}@KPmByPeulhOnHF%f#x2x7WLCh&Ed9|2$+TX$#sGe=`S!Fkne;3 zVBeTO8h@FB-nH2m@cOeZzrgG1Z{uLf85MxLpcq4@eGSMixvYTr<0M$OWqP-(nx~)} zND7n!Y$t35J%I_pShbEnC|YMd9pPipOGTX1^RbPBrFexilms?};^n0ub5*eTskP~5 z$&ls(#Dp*idC&)a1PP)7>ExCKn@TJ&4H5zUTYtQU_gFxulHM3+H)@NXk+Uw!KH(4sjlY|++JzY4Z7WKF&f*o#2v)#M`c8Djj1Bm8~y}N&-wOK%=3~1UY#M%!B;(=Zc)cMc*8y+O{YBUVZmF}zu{hT^2 zur0~VhzPnu-AQjYO0g%;4xvJI3legG9XPbvata%K#eD)XSYL9IZH%ju5EkUBfl5^k zkzV$h67P_Wr)LmP3C2AWH3p+66j&}ggns~bDpHcQgUb%~$(^Rgib_AChu{gS?x@Z8 zK20qbC{J))x@mUT!O9p0h=97NG0gxn9;qbzymA%t$(knb@Db?jb}NH{aDTlr z*|BuNWKb`KMjcW4KyU7-`FS7@#2=BZL0%7$MKPeeX^^pY8WsgHkQW4-vIQQBdJ(~i ztRX&x9qT$!Bi?hr^boQr!P(~kp<|*d=-)KYHEG@<#TE(&Z{WKN)Fr(JR9cN)90dkf z+}bJhZXIr-+$Io+Mr7USUyya9M1SgGZJ;CuPF6cZXa=~A%fiJn?*uUmAE4qHC0~zp z0$__6D841fGPgzUA&xd=J}5uRpi&$LaTMW9=nry=c{PZK9_(xBfVw~=Oy6<#J-Adz z<@U%4Di`AgDxeuqGVrR&wRlO9upmR|2kReuPPs*$r7XnH$fbcPKu~8UKz|l&X!4~8 z{D94hSOa8>;%FLlzRGz+VDuq4(1 z+_z-f)jk(lIw-i?)(#TEV4}AtU2X zl`Jc*Q*{&Iq`^T@h_pFskX%`uz3LPW5F3e$?t12fUt%LT&EORVh7|xQDY;oJ^;Hj*y}Hh=(D^9x6cGT>oQ0jS$pM*uCF5Z&iIA7a3Q0Q9 zI27Nb9JmcU+SC`NrFZs`CnSX>Do>jsTwJ>FWL&VP#&0dD#hM>c*?2At4=>fal&>^N+Rk1_c zg@R5lGO$-RWQZBG>f0lRn?%9#2HCb8dXnvf*uZ5X;~nEktwG3>re>9Vc^iS(0obGQ zL8RDp%6~{b#?N7nKWgLEDW8==)-js6W`7IMzlHbKUBV%zu74gZaIe#;UqUnDg3-i6U}2M=g>Da#?&)+VvlI`+vRgl95f3Q{jO*g?8)JZ_)j z%jv$VSujJ@A>|pWiPCxOno+ro(xC4o~hb%W$?VfJici{6rB=dvN0vx7w z&pNEuQQmcc$$xkvXezr$@SUPF$q*q*R<$r|_neFe@;!)}bT-;M1Q;Z)aV&<@SHK|gaHHBRh+c} zwNCE@Bb8nw8AFU>eP*@$ML}ViKC}cX$mIiI^PX_L?>DI=51{Cvjr7-{kEteaA;`M0 z9s~q6pcxR!A?~Tqh?=XtGs}iDAVnRDRLmX+@sg4q(F=q&%UxPpr&N}z& zb5ir!XKX*D8gm*I+g0#;#wCd#T1s4|4G}_jfA)Stb_K4878w>P({mLkc&KP1Js@@D zHtMA(gW6c0(6hJg!&*p$L4n|vZQ8D`1Z-9vn1ARK7aTs=OIO$$%3vyrN@GJq2BE*td=cuiW&}Qb0Q13W07r`r!WT=j1kk$raLo*UFul zilGn@So6B8hF+%fX;4KQng1ppj-w;!JAZw|v?aY@-*j8apbQEeBAcepOh~mNV}Mmk z7VXX0TH3?}x&uD9DSCk?V7ERHGS5`eVD2&Qh+}=iiOgJ7U`=GF6D??$2{4vm#bQ-1 z?RIk%_w@E7LrEDjpDCgvrN{?eh!~}U5X0=oYkyh)GeLxh=@S)U-DC##;F1TLG=GVS z_mhDmnqkU^qID8^f2ZV~2m2>#enjV$+8<$c(QSt6I&GsV}RIDY-;5;bV05EYDQg#>}3Zw0`sY<67 zumK`wuOen25h(f`0M4;spQ{cXAOIng(u@p<9D}2r!Rfutjx-Nw47X@chJQ;DJk_~b zI#^loL7z6#F-XZi-t|#)O9F2tX9iQ!QTp;!1r_Z z+@9EB*!35p#QY4Nlgxjzkw@I4vTO>Mj$W}Da zJ+%&gOia-suo~{A^KFuPpTgZ6 zz3FIS1fji8At*qMXGon!r)TnJ=hp$&yCnOuB!kSg`Dg?P<{8xLe@KzID+2E%DeitU z4CJ_tc3ACs*y0PHk!mvQoxM5$y`xG|(a*;(wbvdS^bMhsf&0ISKw26U=b{4)^KY!7 zUbKKbeB=NC0fUo=5*>d_rBod3AmWgrx@bXE#8InIgbJZnXw|{w(l2OYNK#xJ1=oUu zAB$B77iV1^Tm?b!1H{?ENzp}0{9jUN5#zyeKi=JY+`R*YMwMw+*BGGbwwXyK#awZa;~#MS61fy|RlvwGj}2&$ zT|f9A{O;B&PK)|5TqatG*tGGtSBr65hASOnhB=$rCD-z^YX^?GaVZTH z&%3)jd;9lHtG^!>a&m%UxYj`c01X;xR9JLaO-wptZ*8+66g&bXWH2@}GBRa1Eip1? zHZ3$aHa0C`HDWL=H#cHpFkv<}G-hKtlYkZkWpZUBpEjeLiH7ztWV=yf^V`MNbIAUfpVL3E4WjHW4ld%~^6ErO_H7zhV zR53L=H8eUfF)J`Kvk4k&2n3fm2~U%FA~1jG1qTf_0hKqlHUIzvgGod|R7l5dmd|b+ zMG(e+)iZ1F#_L!{B(|@-Kyr)3pR8@3AV3i2e-1&2_u&KwkOCGs1Q8@S;@t>E-0}ik zu?<8@NMh{WnJNy|J=3#zq|x@ybX9*<_0?A+48x`M^A{f+K0JZ|2w;H5UyIL(zxjXr zbQMHfY4;kS*7{JOw$?^~B5n?GoqU^h&(E&)=hry=`{=T)Jhx&O);1U{or}Q44bL!Y zKrt7T071HY5`cVf?o;OP9C&6+7sv6lXFUA#i1P8j|FAS&!BRl?HqmcK{(lf)P@q3>O9cBO~TIDvr&M4J@Sn7yfoqFuTUGhJ93}Ij8@XptAOxE*Khdno>y|_84lOS z=oc>$Zr*o1*Y+_BO7c`nd$CES%U^PuWq09V z^>*~z*u}u=mM-Dr`{*|#!p?sL%+OjvjS>T`mGIUW{q%}ESzho=<^0aUD1@D{XY}oH zlj+1o{rqLe`ragKY-xKWoE@Zo`HI_J`^77dcmT9Y59kD5BqfsnD-;mknZT(!T`KeaReXP0CEyiUqKYYe zw@vdz4ZE_|l_jN(J}Jah<62wi;D=8$6-iV{d=44tT;FHfRiC6vv}>&u3`%OyO3{xd zlwVziCo>rK2p_~okqj)^I%TxTiZYD>OtWAj%BF!66>94So9w3AN^Kf$X#qRuB}JvV>~iNNEY%Gwf_(j6}OP?EXnocyLL6jAqs zxJ?B%GtLi(2n%v)MT?)F z^K##ACX<;=z9f@}Bs1Td&a!SYJF4er4koCRADsjh?8Sz%6Jw&^3z&esKSp@)aiyQiSZ zr~4lbC)W`N6+OSsADi}q*W=E?hv*Zmwi(3* z5{p(?-T>KNs6-dvJK2iWMg&n;ne&wQ*-qix+K!!@C+T(efx|W=40}V5=@c$T@#~SG z(rUg!hytnQ8l_7xPp|k^Dj_58)VFR3H!Q?K6>Awbe^# z7y~urz2D?9%d_xD?HuB62c^i&dGxt_mKQcTb;Kf-6K=;C;Z559Eg3kB$RdKUbUX@>5EpZNTg)8jGDAH4I_x$9`&oP>`Q)0f`;PtM`RWicKw+#+>X~uM!T^g#8ijVK=!1j)? z`INN=EsNRsf-ZN@B&fKOyLBH9$Er+e57%O^K(EA{T;?_CR^zmKZT+HS_Xor@@K(rS z(FDRY$i%hC5IjN2N;l$t;2EZ-soH$UUD-JHr9D^nDR$>~V`Q%XaIrV|SIDp0$&WIE z!fyDP-{^c-wo-wbas`v{pwU@_737KLDZBU5$<~Q9@rL9wKQxfGoGLvLTu+;E>nD1L zfTslNiod!oZj0V6}P9uM>k0-i#?5<2%e16Q_YYd@+ zo#dLFW$~Apydbmo%T%D%UtVN%FMac&jAeH}Ctvy{C-c~^>b6CpDKp)%h!5T8(^>lu zFzBM_FTuwqXz5+(R-V}8E&fZjQP{R?LAmq2De zwTJ^{=zZZ%s`trhg2Lb4?Xv2eieZ2TNAx2IOT(4a%oe2<25t#1-MxRgx0efn6n?Nqf25cN0#SOO7TVCOgR{a_e%5B z9(}af?#)uX5)jZzVsW#Vt*v3WuvAa3w>M28KE@Jh;%~IpOaD>1a<-)ns5*^JK7V{y z1!e8w(`in3mYxr>hze0!p5s?;wdiNz_%2G^_NTC3G<3S(g^-UBegT?ejbj;Z7i?8# zVX%t2pAuKMDkv{phCkUWlFos9=|qSurmV!_O~Q5&OZ>$$xoTBSs4$g(xN1v>g- zo)B!J_63#Cuh(S;i8>%jXLqb;%QzJsh^WNY({j??N^D1|mS<+kx4JwJOt@kusu1k0 z+?(|!#I2&mV&9>WTa>Er|NBgp4U#41j<`U#0N4ri5JWlvA2MCAer9v^`5`pe{bs`q zX~yCih!)AO|1m%YJy0go*#It1QrIx`wvYs%)Wbgb5CNOi6=gx)}_V^K0Qc(54& z0(ESs_f&PBjQn0txym^bnMvUkAO_5^DCs&L*zOh<=1@M);b@$Bc|*`;ps6e#D$A8% zJ2!+9da_p-^5r}#7fxGkZA_p4!?(_qJ8k(W;9DD22y7>z0M$??%7l}#mk{sgL+ z;hUtQ?T`Z6{76;KZffNFx=dQF}JT z56r5;uyz(bEk<^+hPXZ%^it+ehs!WFzj@iz?w$xp}+l(X&I-}U_46OLHo ztw@6>N-1{gj<4Z->8)JlHz(2RnR}70zju3GRI^K~ZI9QmqJcQ4mKJ3R{lWd=-&kBX zw1XToFwc5mZd-Lw)btz;gs?PQqdaBigkg=FlQJlHjTO5@z@363{rfeJ`oHtmMuPoO zU0OUTczDs>X2s*u2Sbzwl+8u2Xb|R=v3|0U;0;{4;T@3$)tc}czNBak{b_6w?r=Pr zV$v84w&agGj#wq>iJmao$Woa{urPz&NsPnOcH{fdaA%;TPIPcmhip45yM1zQuavcF zdO;uT^K_g6sud{xYe2}S^6D11fmd`F8=pTuXj(XKJA&v2a-8NC$9FvR=6idPIF=yl zk{RpH%%;S|^R@+SrEqX1!)Wy8;ZH>^a!R=P7CHH!TW(cbew}z_l7>QscF7C)e~BNG znN{E8**&zbEg|vsOJu1BhwL))9UNa_E7&N_{%^jZfUq)A?j@ z;(cgr;;b(#Po&QgKi-(qZ9Lo!KN#0V%sX*)F5OxY7BOxrZgl%6`N(_hS9s-WL zf{+j*?1bq=@n_ccu^|njH0D8aVGX;T)@c2p5c9W&!o`|d5#YGIn;bu^&l(>Z{+L6> zWmt(6_zXuEG^q+aUsXlJdhOt3{kRdc8ipYusbyj%5BwA1f zTEDcvnNJjR*jKjKmo@00M(P=?(ZNs!B5))b-JAz!IT#P04fC*a`PiDzg*`|BAk22-S;1z+86J3*h9Q614!thW3t7|3 z0n%}jJW>XiXB}WpOFqB4QPxyfKJ3?xVMy&Ev)FiR@ZU$0KFj4N%AOo)lfO1W(HbTQ zQ>rc3lZ(f}X6k&J5Flo*hU!u*Y#}&IQKsjet)d{@>baQX5f&^8k`#YEm(9 zNKZ0c{hp;M?=q)l=H=Ls$d~ga6GDsB;_4q6Qm!-Ljrdv|F1;}PM}om4FN~#?Lvf$y zha@09T-j0g<4w=<*1QwWu^?u`&h!Ng=Ug{;9gLY4{Rk_GJt358Cur96E|jM2&FXM82vPr^MdxO7`E zrScM(n&hjnp7z>}ok@s8oU+p~@I#8$Ojf>lRH} zk%T+=88PeHNSS_w$T@$(~F<4xLAOI?3*)`MSi9r(55!PySO#3+n zC<`90k)ix^3be!6Q-iA}WdhpdI7zX%)Q3V8|1C&^God33)`n*(o1cYA_4B_4j8#rU z+rProEk|{K{J_3WR!O^QAl#Z;r@nOPqV35$sCy}oSnBbw2Dz##?K$7I5-n4wCP2My zcr)9M3hT`CzWyAKDi^lD%p-ce|9AZBTW+^t?ct!rqJ3Gx6;S0wB2wwy>&BRV=#PL+oCK{U zN`Hq9>z-)y*wQjED`ckH&6p)8^h2#@?Lig865)8b^MW>_$!x`rlXU`69H3LL%rrzAZ|k6V-eh*%XYA1^P!I|Ihuw$Eh&f-m1r6G zC?^u<|J#H~DqQn8;4k~^nx9`rtuSop&_P9sFv@n;b;Qj#{;FPpkUr&?yPqXuS?52E@awY zbD-+9O}cH-!7IMD+d_L)#| zBo=a_)YW5yE3q-QnkefhmicUeN8XAOZDtnq4h|UWqo&ECPcRkG8xJi_X)+*O1@V>Gj?YlkXE* zJB61???^)!NOYu@>5(|p-#M+6%o1uSiFws6IW;UvvWmH?GkhoKmwkgv@&T*%sH*TR^Rc$I_OVvB_Obhi z01AtNfFdBEu(6OhNK70gBE|<40s(>lSMC4s?zT?$f&YJW(*=M46;4M3W*34;*a=Gs zK?ESyBEkZqb~a)HlENbYTuEzd5fK|HTPaBi_*WVgaxnp*h`|5rD*mr)(;M?1<+FOZ2yFr+i^|4k2PHMl?LU{t*V`iA#3ddXLPGM5n}%HV!)I zV{fm@#mVV&QdK9ogT#)f{~hqQBdfHc!A#qxAyZdZ=V*7g*z&uNlo1o&`a*cG!oQlB z^F+)L?hMGxb_8Eyi&|70{{5c%?@hr6&%%$-t7#X#(_QSe2^V*;OP^e6EpDHT@a|{JYAdo@2-Nd%#K3Li zcgaq_(be-a-L>zu-BemE%;1{8)M+jR$*S|yYG<@Dfr659_Hkb>n+QA0ukVlF5x#+(+SeFCkhGSAvpb%}u?(cSHzmA;RO|HklGe*{kN&9h0ho%*e4sd+@KMJp> zBU|!r7F|kCT3XA_S0HVn#RY03!K!%nhoq>e=#yf>nq^PB&rs9SD1zbfYKKykA_hAH`i*V)s;_2I*YVnu1|nMof9tlXDz2cW3q{?)lkj|S{572KQ5I~`h2%) zqN%Bwne(;(;M(hC@ee^~^yYPtxmi64sf9(7SLF`D=Of2R$JrQu>NEH$G63+G4I|7c z%LnTt@l1y7e{NG)js~7Q;$IWqSh^JlJOzD+ew#36zt`W`sT}KOvv!fo(_^Sr^Ju>` t9UN~@)`SSKQ-AF1qwh1he52vK2Q7rAN9^yX-Jtvv4HaGGTE+h&{s(dXcoF~r delta 6643 zcmV-7iE zQ-Po1d06x7`uFqhv%vGC^IQ6|P@S(ojPHMF@wI;avC!*AK@oX=c?ExB+H0ZUpFgu*aEb{YlEM#vbo($ga-~yQnA-n+{B? z->Y&{|NYMH)h6GcZ_a-|5&g)%zRp?o+1y6)VuT8zTcz@%%!BV<)HH4OJ;VZF3 zxu1>CN>@*+w(PWn&*```LX3VJPp!Q7(}(+HrFPBFp!!99y5mb| zVTDSO=Pi2-{u7J4w{3Qsd$-D+m*Z0JSj_Q~fBk9x?F-J)C^&zoT)qlGT;40$grUmm zJC{)rcV0G0{IIR(gM^r;uVwDW{TZYN_XtV@^5ek_C#rgc40jC6`iaX{FatV@);JQfqCs zH{SxFnObh8)z(_?+_STC=hdAHdLMp-5l1p3k230Lqfgpr#+hcGW!BkdUw(xJeyqI8 zs;jNO-KLdx+-c`scHM3FL#v%&PCV)4Q%*hY^iS1ZW&MBa^IufWy{hJKrF3EWRE=j# zc`xAvCrLGdic!1S$gY8}Vt^j?%u56Qx3ci zlnOKfVT81Nj~jrRipBNZ(u}Lk4Q!nRL^O85mGfDpl{28DzyC0LamAhr#w}KzqwYE4 zo(`xip|hc&tHaiJQquL))D^VgT@R+yil6ns-FSa?9dVtJX5+WhKngqBPsP*nb zTCf5Wt5VDx*I|bgX7DX>8|oBKOozOEThFDr^LPhgzDLo*KSjrGpXl15e^|KFDTFqk z(2{v}yUu&Bb@{54dSxzu%UmL$aH#E0vHRW5az(YCo(0XS|5yn@=ih}$uJ{|;IJ)W` znz?^z^Z85KURm=HVEA>DM~ieS>c)E|S4?R2UC|#4{jAID`4X9p#I{K2UQgaq^=22p zOJtk|H+M?b_oXtaIpN#$cd2(J8#|oT$c+A_n6!TCgi8mMcL#twiujl1sz08H7+SJ# zNdKozhSh4ic>G#`n1AmzPp_FzhzNuBL@4&1HMA&lfglJMr|wr6cW>R_d!Fx}t86U&-95R|ld;5A~oTc1zpYgZMI|u4#XZ zo|$8M@3GlM>`K4jsi+xcgVp(m3cD#YL$lT(pTu7a3tXVCH;@pWu6XMY$cEeIkBnn}I)o~*h zYB^LQj*xmcVIWmg!39P{14e(wrOnU|me|LIO|{jIRr^h+v1Pm0g2WqtC8Zb^SbavA z*88z0xuBDPx~xJgaxiokR6!+$WZdECpO%P0J9@tOoqd7~;j5ISV5tjBI1po_bhePkJl7c~V#WGq#swIyC@zHKP4r+f$v*s_b*-HN< zOLL#R&&ZUQC&FoMC*)b3gU-e@4?v}qei*-80G=AP6_C(%N_so`zFrwRZr;a8Vm2}l zQVcb^b7rAMH-I^W}VJuOSDa)b_^Q^5ti_2 z+%>56UEGs3Sb>sIFf3=~s?I=If;EdP4@kuKyupTfXxq}It4qy;tmrrkbV)@Ju1Jp1Hdj(iwB_6Y`pDTaynDRJua@6t3L}sQi zYK7OD13g`WGnpA-4bV#}wqg`2j#BT`?^wdRO)22X=LI~uVK_vP+^9@o+|A)5bCj4P zQVYI%TN|^zX(-PXAdL_}T?Q5~Lis&~4A#ONL((C_MpEJq#9E6jWHve%3r#z5Bfj8; zaS^H!&>v|*GK+u9)Fh2Yg$=y|PE6_NZ$su!$8H6W3czc~)_}KQy#<6;qAQ#L)Y31c zmPs}Ks#*$x*=bd$!wusvT<07r!Y4@0w~UMmP3*FZ%;r4y?K{1!+X>g*%a6$^F)&*%qg zBb63MrS4pxg>#tW3jDaHR|W>9&oga(xZ-M}H6AeoCq-0AqetoUDhQTF@=Zh$mbQFIBq_oQNQexRh@2?W{m2{#egF%5kctb9B09IgTx1aYDR_F95%*#+{9L);&k}@yzEB! zR$^KWl=K;SO=IpkhvXcCUh*&&R0+f5t`96w1kisZbj%c~%c5liW{W%ucE@Iju%)jq zJD&XsznOt$MssKy_>mC-mvnmB=@rNxy9^=Gu&kLieLSkoB~W>whh^hi@=%0Dg${#C zE5JVO0QfKuSk~IuevQD=EaX8HO-*d zJ28KmvNlkw0;@_X_{AO=w}Cmot&tk7j+ms`Kw~peQ$f5o1IlX)isrftaF>&U zsgn89*{F8#e9L^0?%EoTOeUCdL=H311%!WB%~@WDBY1Wnwz7cTr($s}HH?65t&a9% z1`fRMGwKy)0prl#Qj-iHl@wymPI6$61C)H^D4kq|N=6Ou8BG{eG9C>k6zQYU0)Pop z0i2(n(S;vq{es~L@b}0TT87@mV?J*~yThn?#jB;JWM`rk4nCxKcraswLkItsV)GcH;T1wrMj*sdskS zQCd4_XkE0ZS*|6!1>VQWh1F;~vT*GQgNTr~^^gFHH_ z>~a=;Mfb}s$`9EBSk7lT@IbJY2dIC7sRTSX9@1XCn(ZDS(1Q*;fYfynH)FGyi)uU_ zLivDFd*6|@U_hVmVo50YJ1khv4_LiH8(2H! z4`>O`g6*sh8AO9ws(=*`fvOA#Q55Ts1<8F85K9|oK(=AhF-Dy@zztXk;yHf?V^nmu z2Kjla-qB$WZmrB3p3HJzCSz~UHX0_FQAc}{P(%xzH(@#~Jufo}uhpX^YUUojuy;cC zRFUw!9uH8p>qXbvi06K(m= zotE)YO&Aq)dagsQ`p?QidScA~@F z6TWB@l=YbFNjGLo_HV%kl2RZ9T@0Hv$ zGia$lVx)p3$dZ4V)R#!INLj=2PzB&+=rPb~-Zv$%x}veje7R+pl{$!CM>KTk8j0qo znc!b!&_ReT_@r|=eybU#&m&KA0Ssru0bAeJjIyFKgh*MugtUHw2*=*07r-cmr9WtW#sol1V(=pCzy<$A#uKTNJQ_!$Q;v9 z@gy>CpOj)2XbkIkZ5{Eh2Usr%FnU^8#g9UG9TBKxEw4i?Jpf`I4IDVPPtpS_2zIBMH zKw+|ol+b_MN~q4FJ0f#+@UiM0}8n_#Om%#?|nrb zWFvFpO)C7f8aqq$(qu=7zo4Y7b-H_=!D zkr=Z^n$4*Z1OX*!WP4>8;~4apu*Pz0hjUv>*kYUF)dL+V5 zG|fOUSVJfGIMus4IcqvB*82+2ajJj*eMhHZpocJ_3?jxtK=^7;39ObJ_zuPzM_rwy zQel8tQ}PkdiGF1OJD?oZ3Pr^FP&jh@+V|U%n26f%|2i3Ih;wDivdMq0`CL($6U@*1 zWqMET>!L~jqcrFR8NW-@-7-yMwBx>Cbl+M1a;vIqu3d(v6tUi1<~j4{$@G8yB`l>%Qhp}J^6RK!uMP=pGhR%q41U>Kk4HiaQzaw6mnI-$T5!% zXpmh$_#gc4)+$bndr8qG5PET(k0Btu3pDGF^L^|%%@ZK_3|#4L|3(9t{v^HL*5XG% z?>2C8-PV*n;Bp7(e==lKcBLRqp;!do&*+=-K;JD8S@n8r?c*l&0mxEU=^NnS5Ew2| z_L|STyE}XP_e`t59~N?Qf?>GUK>z>^8nZAJiUK4sH8y55VKFx?F*rA4Ei^e|VJ$dg zI4~_YGG;YlVK6shVl+6D-WR4QF*PtbFfcVTIX5{lF)$(uARr(|Nlj2XR%LQ?X>V>l zA~G&9FfKDNldKpxvqBjP0kba~UUU;q9bH4fJ{Q1rZz=aDJ?8%cShzKHrnPFzA zDgYvXLi4o0n;9a4b1wTfwrv{#RYg^^Pvh5MHW-a<Llul8AKnM{v!&GZ>l1V$~>TDQ>AqdWYJA55I=LECU5jQhpjyT!QiAx6;!F!Jg zwXdSOjJPdNgY%we&z|8roeohWuf2MP`Tl^}_yLFW5o@n^Qwl|Rw3y&s0zaIOD7?ql zWDDGs4Beo6yAFTV>I}M8@o4&Q8A3!c)-=o9s*q3>>&bmP&t?m zxqf30GjQUVPX+*ZpA7mReTtbe8$V#X*RRVWWyny(QvR-P?xc*R1$O%%6IF>JqN;3c z?{V+vANl0=9cJSpS2ug8rM`0_lAADprByLiHnw(Cegq!Q$4Fg^0NcGj2m8O_M40an z+1dM$7oT=h!a+0d#=)JTXCjgi}5e92-uV!PK*-(oscp{kfhHnw*7 z>4)#}-gEBUIktB`K!fGJ6qcK6jBIS~u$WJ{zSYZ-rjEvF@GAgYH+EZXr7aA9LvR^a zNPg3C%G~8E*HbV>2vxOIr5Ml{Ff$4>BgRNsR^0mR4kE&vYj5z)*I)7N-S03<8>ne+ z?hpepL@r<1K*X_P9)K8QCLCf!)o?AfXbV)65H-a#EpBY>P*oKngw)8+QP#w(swBpx zq`D?Oe>|LFsyImmZr<$Ir;M3@R6{IO6;-Gx%ZjQhsX_t|^}DP}%Cf9C3%ORDYls_W zE!+??xvItvF%Uw?{xL?P1~kSL@uqHW-Ts`#e4pdvW6qvEOK-1F2q8;hld`lyMHM5a zhI5j`SC&xT!k?El`S_lY6Cgj<#sRS3iwF$3>3XDHO`u_i8moleKrFTO>w zQn1=tMKxxfPIZ=)!*Wweefs4TO!DaSA)D_2h4&PN&l5KVs#b=2CNwy))qG}2>%H?h zFKDzHH}dyieLV<5ZT(I)&Q|pL7*csIMWKI8`VA5yMH^YJGj(9zTA3>aNldcyXTYxON^yaAWqkFQ&m|ER_30JW^y19q`zx; zK}yRoU=f}kvz-d>NBSV)xcmEvw;&K`Y7Axbo{XONeY(_=z1YXELR!{@D>n9}N*OO1PZv>G9P|Qj)n&pEe(F5^n1gN-{k^A&oUvhI? zhu)0cQl2y*koamrD0PQ6-4%tUypEG|R)Qx-;3q_<#-D3+303WUjX~AYz*$ zL@&Q#p-2kEj6Dbp!{_V4OjwgM@)^IKQB=`9Uiry=xOSaGIo{Bw>z~|>D9t)_PHrft z4!JOfkFVR3PhjYFq~#mY)3(%zgu-279v5BTqQ8ug#G-tkDk##ok85uw~z1>LACE<`GrvO24p>_L_kk85$pO7ww8y& z4%+&duNTY_l?1q(UrBVkPLBsCxVX~nwpf1G47c{Msix7*eaQrz>=AH`j>9ly6p|wP zB8yeHuvv`@6Xa31`HX5?Xo~3FQ-0uR#9QOW8kIjis@EJ=Y#FID#MUVp85?EireKe) Wh~)Z#`3Jzy7!pI>LAevf68sHFVyYzo diff --git a/plugins/WaveShaper/wavegraph.svg b/plugins/WaveShaper/wavegraph.svg new file mode 100644 index 00000000000..e05dc097811 --- /dev/null +++ b/plugins/WaveShaper/wavegraph.svg @@ -0,0 +1,282 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 57ea1d38c1f97cbec5726f2b5c56c6abd34ea249 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:02:52 +0100 Subject: [PATCH 178/184] WaveShaperControls_fixing_style --- plugins/WaveShaper/WaveShaperControls.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControls.cpp b/plugins/WaveShaper/WaveShaperControls.cpp index 9e5e65b80eb..44464da3140 100644 --- a/plugins/WaveShaper/WaveShaperControls.cpp +++ b/plugins/WaveShaper/WaveShaperControls.cpp @@ -25,14 +25,16 @@ #include + #include #include "WaveShaperControls.h" -#include "WaveShaper.h" -#include "VectorGraphModel.h" + +#include "base64.h" #include "Engine.h" #include "Song.h" -#include "base64.h" +#include "VectorGraphModel.h" +#include "WaveShaper.h" namespace lmms { @@ -49,7 +51,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_clipModel( false, this ), m_vectorGraphSampleBuffer(200) { - unsigned int arrayLocation = m_vectorGraphModel.addDataArray(); + size_t arrayLocation = m_vectorGraphModel.addDataArray(); // see other settings avalible for VectorGraphDataArray in VectorGraphModel.h m_vectorGraphModel.getDataArray(arrayLocation)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsEditableAttrib(true); @@ -58,7 +60,7 @@ WaveShaperControls::WaveShaperControls( WaveShaperEffect * _eff ) : m_vectorGraphModel.getDataArray(arrayLocation)->setIsSaveable(true); m_vectorGraphModel.getDataArray(arrayLocation)->setIsNonNegative(true); - unsigned int arrayLocationB = m_vectorGraphModel.addDataArray(); + size_t arrayLocationB = m_vectorGraphModel.addDataArray(); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsSelectable(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsEditableAttrib(true); m_vectorGraphModel.getDataArray(arrayLocationB)->setIsAutomatable(true); @@ -135,7 +137,7 @@ std::vector* WaveShaperControls::getGraphSamples() void WaveShaperControls::setDefaultShape() { - for (unsigned int i = 0; i < m_vectorGraphModel.getDataArraySize(); i++) + for (size_t i = 0; i < m_vectorGraphModel.getDataArraySize(); i++) { // clearing the VectorGraphDataArray-s insied VectorGraphModel m_vectorGraphModel.getDataArray(i)->clear(); From aa9dd2fdec9607ee5388dd54a96bcd176fc61a70 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:03:02 +0100 Subject: [PATCH 179/184] WaveShaperControlDialog_fixing_style --- plugins/WaveShaper/WaveShaperControlDialog.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/WaveShaper/WaveShaperControlDialog.cpp b/plugins/WaveShaper/WaveShaperControlDialog.cpp index 8cdbebd1901..39403da5217 100644 --- a/plugins/WaveShaper/WaveShaperControlDialog.cpp +++ b/plugins/WaveShaper/WaveShaperControlDialog.cpp @@ -26,14 +26,15 @@ #include "WaveShaperControlDialog.h" -#include "WaveShaperControls.h" + #include "embed.h" #include "Graph.h" -#include "VectorGraphView.h" -#include "VectorGraphModel.h" #include "Knob.h" -#include "PixmapButton.h" #include "LedCheckBox.h" +#include "PixmapButton.h" +#include "VectorGraphModel.h" +#include "VectorGraphView.h" +#include "WaveShaperControls.h" namespace lmms::gui { From 4847b71bf312fcb67a368205b51aae0f8b68ecab Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:03:30 +0100 Subject: [PATCH 180/184] VectorGraphView_fixing_style --- include/VectorGraphView.h | 21 +++++++++++---------- src/gui/widgets/VectorGraphView.cpp | 19 ++++++++----------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/include/VectorGraphView.h b/include/VectorGraphView.h index 1ef88b123c8..2f845d31a4c 100644 --- a/include/VectorGraphView.h +++ b/include/VectorGraphView.h @@ -1,7 +1,7 @@ /* * VecorGraph.h - Vector graph widget implementation * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -25,22 +25,23 @@ #ifndef LMMS_GUI_VECTORGRAPHVIEW_H #define LMMS_GUI_VECTORGRAPHVIEW_H -#include #include -#include -#include +#include + #include #include #include +#include +#include -#include "VectorGraphViewBase.h" -#include "VectorGraphModel.h" -#include "Model.h" -#include "ModelView.h" -#include "lmms_basics.h" #include "AutomatableModel.h" #include "JournallingObject.h" +#include "lmms_basics.h" +#include "Model.h" +#include "ModelView.h" #include "SubWindow.h" +#include "VectorGraphModel.h" +#include "VectorGraphViewBase.h" namespace lmms { @@ -230,7 +231,7 @@ protected slots: QColor m_vectorGraphSecondaryActiveColor; QColor m_vectorGraphSecondaryFillColor; - friend class lmms::gui::VectorGraphCotnrolDialog; + friend class lmms::gui::VectorGraphControlDialog; }; } // namespace gui diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index 6ebc2491f98..59bc59b288c 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -1,7 +1,7 @@ /* * VectorGraph.cpp - Vector graph widget class implementation * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -22,23 +22,22 @@ * */ -#include "VectorGraphView.h" -#include "VectorGraphViewBase.h" #include #include + #include #include #include +#include "VectorGraphView.h" +#include "VectorGraphViewBase.h" + #include "AutomatableModel.h" #include "GuiApplication.h" // getGUI #include "MainWindow.h" // getting main window for control dialog #include "ProjectJournal.h" -//#define VECTORGRAPH_DEBUG_USER_INTERACTION -//#define VECTORGRAPH_DEBUG_PAINT_EVENT - namespace lmms { @@ -48,7 +47,7 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : VectorGraphViewBase(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this), - m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphCotnrolDialog(getGUI()->mainWindow(), this))) + m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphControlDialog(getGUI()->mainWindow(), this))) { resize(widgetWidth, widgetHeight); @@ -80,8 +79,6 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe m_isEditingActive = false; // set in .h //m_controlText - //m_controlLineTypeText - //m_controlIsFloat m_lastTrackPoint.first = -1; m_lastTrackPoint.second = 0; @@ -234,7 +231,7 @@ void VectorGraphView::mousePressEvent(QMouseEvent* me) // a point's FloatModel might be deleted after this // cleaning up connected Knob in the dialog - reinterpret_cast(m_controlDialog->widget())->hideAutomation(); + reinterpret_cast(m_controlDialog->widget())->hideAutomation(); m_controlDialog->hide(); if (m_isSelected == true) { @@ -885,7 +882,7 @@ void VectorGraphView::processControlWindowPressed(int mouseX, int mouseY, bool i m_controlDialog->show(); if (m_isSelected == true) { - reinterpret_cast(m_controlDialog->widget())->switchPoint(m_selectedArray, m_selectedLocation); + reinterpret_cast(m_controlDialog->widget())->switchPoint(m_selectedArray, m_selectedLocation); } hideHintText(); } From 8448f4d843a47c82471faf59723ff1cf7c906db0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 18:03:58 +0100 Subject: [PATCH 181/184] VectorGraphViewBase_fixing_style_and_typo --- include/VectorGraphViewBase.h | 33 ++++++--------- src/gui/widgets/VectorGraphViewBase.cpp | 54 ++++++++++++------------- 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 48698a27e20..9b2e6f0ecc0 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -1,7 +1,7 @@ /* * VectorGraphViewBase.h - contains implementations of lmms widget classes for VectorGraph * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -25,17 +25,17 @@ #ifndef LMMS_GUI_VECTORGRAPHVIEWBASE_H #define LMMS_GUI_VECTORGRAPHVIEWBASE_H -#include #include -#include #include +#include +#include -#include "ModelView.h" -#include "SimpleTextFloat.h" #include "AutomatableModel.h" -#include "Knob.h" -#include "ComboBoxModel.h" #include "ComboBox.h" +#include "ComboBoxModel.h" +#include "Knob.h" +#include "ModelView.h" +#include "SimpleTextFloat.h" namespace lmms { @@ -59,32 +59,26 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget // AutomationTrack void connectToAutomationTrack(QMouseEvent* me, FloatModel* automationModel, QWidget* thisWidget); - // context menu - //void showContextMenu(const QPoint point, FloatModel* automationModel, QString displayName, QString controlName); - // inputDialog std::pair showCoordInputDialog(std::pair pointPosition); private: - // context menu - //void addDefaultActions(QMenu* menu, QString controlDisplayText); - SimpleTextFloat* m_hintText; }; class VectorGraphView; -class LMMS_EXPORT VectorGraphCotnrolDialog : public QWidget, public ModelView +class LMMS_EXPORT VectorGraphControlDialog : public QWidget, public ModelView { Q_OBJECT public: - VectorGraphCotnrolDialog(QWidget* parent, VectorGraphView* targetVectorGraphView); - ~VectorGraphCotnrolDialog(); + VectorGraphControlDialog(QWidget* parent, VectorGraphView* targetVectorGraphView); + ~VectorGraphControlDialog(); // deletes m_curAutomationModelKnob connected to the VectorGraphDataArray::m_automationModelArray void hideAutomation(); // connects or adds m_curAutomationModelKnob to the gui, sets the selected point - void switchPoint(unsigned int selectedArray, unsigned int selectedLocation); + void switchPoint(size_t selectedArray, size_t selectedLocation); public slots: void controlValueChanged(); @@ -110,9 +104,9 @@ protected slots: // VectorGraphView should run hideAutomation() // to notify that these are invalid // selected VectorGraphDataArray - unsigned int m_curSelectedArray; + size_t m_curSelectedArray; // selected VectorGraphPoint - unsigned int m_curSelectedLocation; + size_t m_curSelectedLocation; bool m_isValidSelection; ComboBoxModel m_lineTypeModel; @@ -141,7 +135,6 @@ protected slots: tr("\"power\" effect"), tr("\"log\" effect"), tr("\"sine\" effect"), tr("\"clamp lower\" effect"), tr("\"clamp upper\" effect") }; - std::vector m_controlModelArray; std::vector m_hideableKnobs; std::vector m_hideableComboBoxes; diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index d47f005cc71..ce302c178b0 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -1,7 +1,7 @@ /* * VectorGraphViewBase.cpp - contains implementations of lmms widget classes for VectorGraph * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -23,23 +23,23 @@ */ -#include "VectorGraphViewBase.h" -#include "VectorGraphView.h" - #include + #include // showInputDialog() #include #include #include +#include "VectorGraphViewBase.h" +#include "VectorGraphView.h" -#include "StringPairDrag.h" +#include "AutomatableModel.h" +#include "ComboBox.h" #include "embed.h" // context menu #include "GuiApplication.h" // getGUI -#include "SimpleTextFloat.h" -#include "AutomatableModel.h" #include "Knob.h" -#include "ComboBox.h" +#include "SimpleTextFloat.h" +#include "StringPairDrag.h" namespace lmms @@ -101,7 +101,7 @@ std::pair VectorGraphViewBase::showCoordInputDialog(std::pairgetInputAttribValue(11); m_vectorGraphView->setInputAttribValue(11, currentValue >= 0.5f ? 0.0f : 1.0f); } -void VectorGraphCotnrolDialog::effectedLineClicked(bool isChecked) +void VectorGraphControlDialog::effectedLineClicked(bool isChecked) { float currentValue = m_vectorGraphView->getInputAttribValue(12); m_vectorGraphView->setInputAttribValue(12, currentValue >= 0.5f ? 0.0f : 1.0f); } -void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) +void VectorGraphControlDialog::deleteAutomationClicked(bool isChecked) { if (m_isValidSelection == false) { hideAutomation(); return; } @@ -401,7 +401,7 @@ void VectorGraphCotnrolDialog::deleteAutomationClicked(bool isChecked) m_isValidSelection = swapIsValidSelection; } -void VectorGraphCotnrolDialog::closeEvent(QCloseEvent * ce) +void VectorGraphControlDialog::closeEvent(QCloseEvent * ce) { // we need to ignore this event // because Qt::WA_DeleteOnClose was activated by MainWindow::addWindowedWidget @@ -411,7 +411,7 @@ void VectorGraphCotnrolDialog::closeEvent(QCloseEvent * ce) parentWidget()->hide(); } -void VectorGraphCotnrolDialog::updateControls() +void VectorGraphControlDialog::updateControls() { if (m_isValidSelection == false) { hideAutomation(); return; } @@ -477,14 +477,14 @@ void VectorGraphCotnrolDialog::updateControls() m_effectModelC.setAutomatedValue(m_vectorGraphView->getInputAttribValue(10)); } -void VectorGraphCotnrolDialog::updateVectorGraphAttribs() +void VectorGraphControlDialog::updateVectorGraphAttribs() { if (m_isValidSelection == false) { hideAutomation(); return; } // set / load knob's values into the selected point's values for (size_t i = 0; i < m_controlModelArray.size(); i++) { - m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value()); + m_vectorGraphView->setInputAttribValue(static_cast(i), m_controlModelArray[i]->value()); } m_vectorGraphView->setInputAttribValue(5, m_lineTypeModel.value()); From 0c2af78e410c0bd92860b42ed5d3832d83dcc661 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:00:16 +0100 Subject: [PATCH 182/184] GraphModel_fixing_includes --- include/VectorGraphModel.h | 30 +++++++++++++++++------------- src/core/VectorGraphModel.cpp | 6 ++---- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/VectorGraphModel.h b/include/VectorGraphModel.h index b1aa7387e2b..6e9f8caaaef 100644 --- a/include/VectorGraphModel.h +++ b/include/VectorGraphModel.h @@ -1,7 +1,7 @@ /* - * VecorGraph.h - Vector graph model implementation + * VecorGraphModel.h - Vector graph model implementation * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -25,27 +25,30 @@ #ifndef LMMS_GUI_VECTORGRAPHMODEL_H #define LMMS_GUI_VECTORGRAPHMODEL_H -#include #include -#include -#include +#include + #include #include #include +#include +#include -#include "VectorGraphView.h" -#include "Model.h" -#include "ModelView.h" -#include "lmms_basics.h" #include "AutomatableModel.h" #include "JournallingObject.h" +#include "lmms_basics.h" +#include "Model.h" +#include "ModelView.h" #include "SubWindow.h" +//#include "VectorGraphView.h" + namespace lmms { -class VectorGraphDataArray; class FloatModel; +class VectorGraphDataArray; +//class lmms::gui::VectorGraphView; using PointF = std::pair; @@ -105,6 +108,9 @@ Q_OBJECT void unlockGetSamplesAccess(); void lockBakedSamplesAccess(); void unlockBakedSamplesAccess(); + + // addJournalCheckpoint + void modelAddJournalCheckPoint(); signals: // point changed inside VectorGraphDataArray m_dataArray or m_maxLength changed void dataChanged(); @@ -121,8 +127,6 @@ public slots: void dataArrayClearedEvent(int arrayId); void dataArrayStyleChanged(); private: - // addJournalCheckpoint - void modelAddJournalCheckPoint(); std::vector m_dataArrays; unsigned int m_maxLength; @@ -131,7 +135,7 @@ public slots: // a dataArray's getSamples() at the same time QMutex m_getSamplesAccess; QMutex m_bakedSamplesAccess; - friend class lmms::gui::VectorGraphView; + //friend class lmms::gui::VectorGraphView; }; class LMMS_EXPORT VectorGraphDataArray diff --git a/src/core/VectorGraphModel.cpp b/src/core/VectorGraphModel.cpp index 30d7d4b7336..06acd55e54a 100644 --- a/src/core/VectorGraphModel.cpp +++ b/src/core/VectorGraphModel.cpp @@ -1,7 +1,7 @@ /* * VectorGraphModel.cpp - Vector graph model and helper class implementation * - * Copyright (c) 2024 szeli1 TODO + * Copyright (c) 2024 - 2025 szeli1 TODO * * This file is part of LMMS - https://lmms.io * @@ -29,6 +29,7 @@ #include // sine #include // rand #include + #include // locking when getSamples #include "AutomatableModel.h" @@ -38,9 +39,6 @@ #include "MainWindow.h" // getting main window for control dialog #include "ProjectJournal.h" -//#define VECTORGRAPH_DEBUG_USER_INTERACTION -//#define VECTORGRAPH_DEBUG_PAINT_EVENT - namespace lmms { From f6ee4f1354e760ed687fa4b3a0c463a7342180a0 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:00:36 +0100 Subject: [PATCH 183/184] VectorGraphView_fixing_includes --- include/VectorGraphView.h | 7 +++---- src/gui/widgets/VectorGraphView.cpp | 5 +++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/VectorGraphView.h b/include/VectorGraphView.h index 2f845d31a4c..64fdda2b0ae 100644 --- a/include/VectorGraphView.h +++ b/include/VectorGraphView.h @@ -40,16 +40,15 @@ #include "Model.h" #include "ModelView.h" #include "SubWindow.h" + #include "VectorGraphModel.h" #include "VectorGraphViewBase.h" namespace lmms { -//class VectorGraphView; -class VectorGraphModel; -class VectorGraphDataArray; -//class FloatModel; +//class VectorGraphDataArray; +//class VectorGraphModel; using PointF = std::pair; using PointInt = std::pair; diff --git a/src/gui/widgets/VectorGraphView.cpp b/src/gui/widgets/VectorGraphView.cpp index 59bc59b288c..0a167c81b8c 100644 --- a/src/gui/widgets/VectorGraphView.cpp +++ b/src/gui/widgets/VectorGraphView.cpp @@ -1,5 +1,5 @@ /* - * VectorGraph.cpp - Vector graph widget class implementation + * VectorGraphView.cpp - Vector graph widget class implementation * * Copyright (c) 2024 - 2025 szeli1 TODO * @@ -32,6 +32,7 @@ #include "VectorGraphView.h" #include "VectorGraphViewBase.h" +#include "VectorGraphModel.h" #include "AutomatableModel.h" #include "GuiApplication.h" // getGUI @@ -47,7 +48,7 @@ VectorGraphView::VectorGraphView(QWidget * parent, int widgetWidth, int widgetHe unsigned int controlHeight, bool shouldApplyDefaultVectorGraphColors) : VectorGraphViewBase(parent), ModelView(new VectorGraphModel(2048, nullptr, false), this), - m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphControlDialog(getGUI()->mainWindow(), this))) + m_controlDialog(getGUI()->mainWindow()->addWindowedWidget(new VectorGraphControlDialog(this, this))) { resize(widgetWidth, widgetHeight); From a3928d5dc26ecdc9cde3857203b0c12bfedd6a5f Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Sun, 2 Mar 2025 23:00:57 +0100 Subject: [PATCH 184/184] VectorGraphViewBase_fixing_includes --- include/VectorGraphViewBase.h | 6 +++--- src/gui/widgets/VectorGraphViewBase.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/VectorGraphViewBase.h b/include/VectorGraphViewBase.h index 9b2e6f0ecc0..8b948cfab70 100644 --- a/include/VectorGraphViewBase.h +++ b/include/VectorGraphViewBase.h @@ -40,11 +40,13 @@ namespace lmms { -class VectorGraphView; class FloatModel; namespace gui { + +class VectorGraphView; + class LMMS_EXPORT VectorGraphViewBase : public QWidget { Q_OBJECT @@ -66,8 +68,6 @@ class LMMS_EXPORT VectorGraphViewBase : public QWidget SimpleTextFloat* m_hintText; }; -class VectorGraphView; - class LMMS_EXPORT VectorGraphControlDialog : public QWidget, public ModelView { Q_OBJECT diff --git a/src/gui/widgets/VectorGraphViewBase.cpp b/src/gui/widgets/VectorGraphViewBase.cpp index ce302c178b0..793a22feb2e 100644 --- a/src/gui/widgets/VectorGraphViewBase.cpp +++ b/src/gui/widgets/VectorGraphViewBase.cpp @@ -22,6 +22,7 @@ * */ +#include "VectorGraphViewBase.h" #include @@ -30,9 +31,6 @@ #include #include -#include "VectorGraphViewBase.h" -#include "VectorGraphView.h" - #include "AutomatableModel.h" #include "ComboBox.h" #include "embed.h" // context menu @@ -40,6 +38,8 @@ #include "Knob.h" #include "SimpleTextFloat.h" #include "StringPairDrag.h" +#include "VectorGraphModel.h" +#include "VectorGraphView.h" namespace lmms @@ -101,10 +101,10 @@ std::pair VectorGraphViewBase::showCoordInputDialog(std::pair