-
Notifications
You must be signed in to change notification settings - Fork 0
/
vstnode.cpp
122 lines (97 loc) · 3.32 KB
/
vstnode.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "vstnode.h"
#include "nodegroup.h"
#include "core.h"
namespace En
{
VstNode::~VstNode()
{
delete m_editorWindow;
m_vstInstance->dispatcher (m_vstInstance, effClose, 0, 0, 0, 0);
// TODO: how the f do we delete this once we're done with it?
//delete m_vstInstance; // this SIGABRTs
//free(m_vstInstance);// this malloc errors: pointer being freed was not allocated.
m_vstInstance = 0;
}
void VstNode::queueMidiEvent(const QByteArray &midiEvent)
{
VstMidiEvent event = {kVstMidiType, sizeof(VstMidiEvent), 0, kVstMidiEventIsRealtime, 0, 0, {0, 0, 0, 0}, 0, 0, 0, 0};
qCopy(midiEvent.begin(), midiEvent.end(), &event.midiData[0]);
// Not sure why the copy is necessary... terser way of doing this right?
VstMidiEvent* pEvent = new VstMidiEvent(event);
queueEvent(reinterpret_cast<VstEvent*>(pEvent));
}
Node* VstNode::Factory::create(Host* host)
{
return new VstNode(host, Core::instance()->vstModule(m_vstName));
}
void VstNode::setInput(Node* node)
{
//qDebug() << "setting input to" << node;
m_input = node;
nodeGroup()->emitNodeInputsChanged(this);
}
void VstNode::removeInput(Node* node)
{
if (m_input == node) {
m_input = 0;
nodeGroup()->emitNodeInputsChanged(this);
}
}
void VstNode::openEditorWindow()
{
if (!m_editorWindow) {
m_editorWindow = new NodeWindow(this);
}
m_editorWindow->show();
m_editorWindow->raise();
}
void VstNode::processAudio()
{
int numInputOutputChannels = 0;
if (input()) {
numInputOutputChannels = input()->numOutputChannels();
}
int numInputChannels = this->numInputChannels();
const float* inputFloats[numInputChannels];
for (int c = 0; c < numInputChannels; ++c) {
if (c < numInputOutputChannels) {
inputFloats[c] = input()->outputChannelBufferConst(c);
} else {
inputFloats[c] = s_nullInputBuffer;
}
}
int numOutputChannels = this->numOutputChannels();
float* outputFloats[numOutputChannels];
for (int c = 0; c < numOutputChannels; ++c) {
outputFloats[c] = outputChannelBuffer(c);
}
if (input()) {
foreach (const auto& event, input()->midiEvents()) {
queueMidiEvent(event);
}
}
// Take a reference to the event queue, and buffer swap
QMutexLocker locker(&m_eventQueueMutex);
QVector<VstEvent*>& eventQueue = m_eventQueue[m_eventQueueWriteIndex];
m_eventQueueWriteIndex = !m_eventQueueWriteIndex;
locker.unlock();
size_t numEvents = eventQueue.size();
VstEvents* events = 0;
if (numEvents) {
//qDebug() << "processing events" << numEvents;
events = (VstEvents*)malloc(sizeof(VstEvents) + sizeof(VstEvent*) * numEvents);
events->numEvents = numEvents;
events->reserved = 0;
std::copy(eventQueue.begin(), eventQueue.end(), &events->events[0]);
eventQueue.clear();
events->events[numEvents] = 0;
vstInstance()->dispatcher (vstInstance(), effProcessEvents, 0, 0, events, 0);
}
vstInstance()->processReplacing(vstInstance(), const_cast<float**>(inputFloats), outputFloats, blockSize());
// Think I need to free the events here. This could be done in a different thread?
for (unsigned i = 0; i < numEvents; ++i) {
free(events->events[i]);
}
free(events);
}
}