parent
d9f344e4e0
commit
575979796a
@ -0,0 +1,19 @@
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# 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; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
*
|
||||
* 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; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
#include <flatbuffers/flatbuffers.h>
|
||||
|
||||
#include "noisicaa/core/flatbuffers.h"
|
||||
#include "noisicaa/engine/block_context.h"
|
||||
#include "noisicaa/engine/buffers.h"
|
||||
#include "noisicaa/node_lib/adsr/audio.h"
|
||||
#include "noisicaa/node_lib/adsr/node_message_generated.h"
|
||||
|
||||
namespace noisicaa::engine::adsr {
|
||||
|
||||
Node::Node(EngineImpl* engine, uint64_t id, const char* logger_name)
|
||||
: FaustNode(engine, id, logger_name) {}
|
||||
|
||||
Status Node::init(const NodeDescription* description) {
|
||||
RETURN_IF_ERROR(FaustNode::init(description));
|
||||
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Status Node::run(BlockContext* ctxt, const std::vector<Buffer*>* buffers) {
|
||||
RETURN_IF_ERROR(FaustNode::run(ctxt, buffers));
|
||||
|
||||
float* time = (float*)buffers->at(2)->data();
|
||||
|
||||
FlatBufferAllocator allocator;
|
||||
flatbuffers::FlatBufferBuilder fbs(allocator.buf_size, &allocator);
|
||||
|
||||
NodeMessageBuilder msg_builder(fbs);
|
||||
msg_builder.add_pos(time[0] / ctxt->sample_rate);
|
||||
fbs.Finish(msg_builder.Finish());
|
||||
|
||||
push_node_message(ctxt, fbs.GetBufferPointer(), fbs.GetSize());
|
||||
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
// -*- mode: c++ -*-
|
||||
/*
|
||||
* @begin:license
|
||||
*
|
||||
* Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
*
|
||||
* 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; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* @end:license
|
||||
*/
|
||||
|
||||
#ifndef _NOISICAA_NODE_LIB_ASDR_AUDIO_H
|
||||
#define _NOISICAA_NODE_LIB_ASDR_AUDIO_H
|
||||
|
||||
#include "noisicaa/engine/faust_node.h"
|
||||
|
||||
namespace noisicaa::engine {
|
||||
|
||||
class EngineImpl;
|
||||
|
||||
namespace adsr {
|
||||
|
||||
class Node : public noisicaa::engine::FaustNode {
|
||||
public:
|
||||
Node(EngineImpl* engine, uint64_t id, const char* logger_name);
|
||||
|
||||
Status init(const NodeDescription* description) override;
|
||||
Status run(BlockContext* ctxt, const std::vector<Buffer*>* buffers) override;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
} // namespace adsr
|
||||
} // namespace noisicaa::engine
|
||||
#endif
|
@ -0,0 +1,27 @@
|
||||
// @begin:license
|
||||
//
|
||||
// Copyright (c) 2015-2021, Ben Niemann <pink@odahoda.de>
|
||||
//
|
||||
// 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; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// @end:license
|
||||
|
||||
namespace noisicaa.engine.adsr;
|
||||
|
||||
table NodeMessage {
|
||||
pos : float;
|
||||
}
|
||||
|
||||
root_type NodeMessage;
|
@ -0,0 +1,46 @@
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# 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; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from PySide2 import QtCore
|
||||
|
||||
from noisicaa.ui.GraphNode import GraphNode
|
||||
from . import node_message_generated as node_message_fb
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Node(GraphNode):
|
||||
posChanged = QtCore.Signal(float)
|
||||
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
super().__init__(**kwargs)
|
||||
|
||||
self.setNodeMessageHandler(self.__handleNodeMessage)
|
||||
|
||||
def __handleNodeMessage(self, msg_serialized: bytes) -> None:
|
||||
msg = node_message_fb.NodeMessage(msg_serialized)
|
||||
self.posChanged.emit(msg.pos)
|
||||
|
||||
|
||||
URI = 'builtin://adsr'
|
||||
CLASS = Node
|
@ -0,0 +1,190 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import noisicaa.ui.components 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
Logger {
|
||||
id: logger
|
||||
name: "noisicaa.node_lib.adsr.ui"
|
||||
}
|
||||
|
||||
property QtObject d
|
||||
property color bgColor: ApplicationWindow.window ? ApplicationWindow.window.color : "#ffffff"
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
||||
ColumnLayout {
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 80
|
||||
|
||||
color: Qt.lighter(root.bgColor, 1.2)
|
||||
border.width: 1
|
||||
border.color: Qt.tint(
|
||||
Qt.hsva(color.hsvHue, color.hsvSaturation, 1.0 - color.hsvValue, 1.0),
|
||||
"#80808080")
|
||||
|
||||
Plot {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 3
|
||||
backgroundColor: parent.color
|
||||
xMin: -0.05
|
||||
xMax: 1.05
|
||||
yMin: -0.05
|
||||
yMax: 1.05
|
||||
showCursor: true
|
||||
cursorColor: Qt.hsva(backgroundColor.hsvHue, backgroundColor.hsvSaturation, 1.0 - backgroundColor.hsvValue, 0.8)
|
||||
|
||||
PointPlot {
|
||||
property var baseColor: Qt.lighter(root.bgColor, 1.2)
|
||||
id: plotPoints
|
||||
pointColor: Qt.hsva(baseColor.hsvHue, baseColor.hsvSaturation, 1.0 - baseColor.hsvValue, 0.5)
|
||||
pointSize: 3.0
|
||||
}
|
||||
|
||||
LinePlot {
|
||||
property var baseColor: Qt.lighter(root.bgColor, 1.2)
|
||||
id: plotLines
|
||||
lineColor: Qt.hsva(baseColor.hsvHue, baseColor.hsvSaturation, 1.0 - baseColor.hsvValue, 1.0)
|
||||
lineWidth: 1.0
|
||||
}
|
||||
|
||||
function updatePlot() {
|
||||
var at = d.port("attack").port.controlValue;
|
||||
var dc = d.port("decay").port.controlValue;
|
||||
var su = d.port("sustain").port.controlValue;
|
||||
var rl = d.port("release").port.controlValue;
|
||||
|
||||
xMax = at + dc + rl + 0.05;
|
||||
|
||||
plotLines.clearPoints();
|
||||
plotLines.addPoint(0.0, 0.0);
|
||||
plotLines.addPoint(at, 1.0);
|
||||
plotLines.addPoint(at + dc, su);
|
||||
plotLines.addPoint(at + dc + rl, 0);
|
||||
|
||||
plotPoints.clearPoints();
|
||||
plotPoints.addPoint(at, 1.0);
|
||||
plotPoints.addPoint(at + dc, su);
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
d.posChanged.connect(function (pos) {
|
||||
cursorPos = pos;
|
||||
});
|
||||
|
||||
updatePlot();
|
||||
d.port("attack").port.controlValueChanged.connect(updatePlot);
|
||||
d.port("decay").port.controlValueChanged.connect(updatePlot);
|
||||
d.port("sustain").port.controlValueChanged.connect(updatePlot);
|
||||
d.port("release").port.controlValueChanged.connect(updatePlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: attackControl
|
||||
property QtObject port: d.port("attack")
|
||||
|
||||
Label {
|
||||
text: "attack"
|
||||
}
|
||||
RowLayout {
|
||||
Text {
|
||||
text: attackControl.port.port.controlValue.toFixed(2)
|
||||
}
|
||||
Slider {
|
||||
orientation: Qt.Horizontal
|
||||
from: 0
|
||||
to: 10
|
||||
stepSize: 0.001
|
||||
snapMode: Slider.SnapAlways
|
||||
|
||||
enabled: attackControl.port.numConnections == 0
|
||||
value: attackControl.port.port.controlValue
|
||||
onValueChanged: attackControl.port.setControlValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: decayControl
|
||||
property QtObject port: d.port("decay")
|
||||
|
||||
Label {
|
||||
text: "decay"
|
||||
}
|
||||
RowLayout {
|
||||
Text {
|
||||
text: decayControl.port.port.controlValue.toFixed(2)
|
||||
}
|
||||
Slider {
|
||||
orientation: Qt.Horizontal
|
||||
from: 0
|
||||
to: 10
|
||||
stepSize: 0.001
|
||||
snapMode: Slider.SnapAlways
|
||||
|
||||
enabled: decayControl.port.numConnections == 0
|
||||
value: decayControl.port.port.controlValue
|
||||
onValueChanged: decayControl.port.setControlValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: releaseControl
|
||||
property QtObject port: d.port("release")
|
||||
|
||||
Label {
|
||||
text: "release"
|
||||
}
|
||||
RowLayout {
|
||||
Text {
|
||||
text: releaseControl.port.port.controlValue.toFixed(2)
|
||||
}
|
||||
Slider {
|
||||
orientation: Qt.Horizontal
|
||||
from: 0
|
||||
to: 10
|
||||
stepSize: 0.001
|
||||
snapMode: Slider.SnapAlways
|
||||
|
||||
enabled: releaseControl.port.numConnections == 0
|
||||
value: releaseControl.port.port.controlValue
|
||||
onValueChanged: releaseControl.port.setControlValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: sustainControl
|
||||
property QtObject port: d.port("sustain")
|
||||
|
||||
Label {
|
||||
text: "sustain"
|
||||
}
|
||||
RowLayout {
|
||||
Text {
|
||||
text: sustainControl.port.port.controlValue.toFixed(2)
|
||||
}
|
||||
Slider {
|
||||
orientation: Qt.Horizontal
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.001
|
||||
snapMode: Slider.SnapAlways
|
||||
|
||||
enabled: sustainControl.port.numConnections == 0
|
||||
value: sustainControl.port.port.controlValue
|
||||
onValueChanged: sustainControl.port.setControlValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue