-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathDspObject.h
170 lines (132 loc) · 7.1 KB
/
DspObject.h
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* Copyright 2009,2010,2011,2012 Reality Jockey, Ltd.
* http://rjdj.me/
*
* This file is part of ZenGarden.
*
* ZenGarden is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZenGarden 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with ZenGarden. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _DSP_OBJECT_H_
#define _DSP_OBJECT_H_
#include <queue>
#include "ArrayArithmetic.h"
#include "MessageObject.h"
#if __SSE__
// allocate memory aligned to 16-bytes memory boundary
#define ALLOC_ALIGNED_BUFFER(_numBytes) (float *) _mm_malloc(_numBytes, 16)
#define FREE_ALIGNED_BUFFER(_buffer) _mm_free(_buffer)
#else
// NOTE(mhroth): valloc seems to work well, but is deprecated!
#define ALLOC_ALIGNED_BUFFER(_numBytes) (float *) valloc(_numBytes)
#define FREE_ALIGNED_BUFFER(_buffer) free(_buffer)
#endif
typedef std::pair<PdMessage *, unsigned int> MessageLetPair;
/**
* A <code>DspObject</code> is the abstract superclass of any object which processes audio.
* <code>DspObject</code> is a subclass of <code>MessageObject</code>, such that all of the former
* can implicitly also process <code>PdMessage</code>s.
*/
class DspObject : public MessageObject {
public:
/** The nominal constructor. */
DspObject(int numMessageInlets, int numDspInlets, int numMessageOutlets, int numDspOutlets, PdGraph *graph);
/**
* This constructor is used exclusively by <code>PdGraph</code>.
* <code>DspObject</code> requires the blocksize in order to instantiate, however <code>PdGraph</code>
* is a subclass of <code>DspObject</code> and thus the fields of the latter are not yet initialised
* when the fomer fields are filled in.
*/
DspObject(int numMessageInlets, int numDspInlets, int numMessageOutlets, int numDspOutlets,
int blockSize, PdGraph *graph);
virtual ~DspObject();
virtual void receiveMessage(int inletIndex, PdMessage *message);
/* Override MessageObject::shouldDistributeMessageToInlets() */
virtual bool shouldDistributeMessageToInlets() { return false; }
/** Process audio buffers in this block. */
void (*processFunction)(DspObject *dspObject, int fromIndex, int toIndex);
/** Returns the connection type of the given outlet. */
virtual ConnectionType getConnectionType(int outletIndex);
/** Get and set buffers at inlets and outlets. */
virtual void setDspBufferAtInlet(float *buffer, unsigned int inletIndex);
virtual void setDspBufferAtOutlet(float *buffer, unsigned int outletIndex);
virtual float *getDspBufferAtInlet(int inletIndex);
virtual float *getDspBufferAtOutlet(int outletIndex);
/** Return true if a buffer from the Buffer Pool should set set at the given outlet. False otherwise. */
virtual bool canSetBufferAtOutlet(unsigned int outletIndex) { return true; }
virtual void addConnectionFromObjectToInlet(MessageObject *messageObject, int outletIndex, int inletIndex);
virtual void addConnectionToObjectFromOutlet(MessageObject *messageObject, int inletIndex, int outletIndex);
virtual void removeConnectionFromObjectToInlet(MessageObject *messageObject, int outletIndex, int inletIndex);
virtual void removeConnectionToObjectFromOutlet(MessageObject *messageObject, int inletIndex, int outletIndex);
virtual bool doesProcessAudio() { return true; }
virtual bool isLeafNode();
virtual list<DspObject *> getProcessOrder();
virtual unsigned int getNumInlets() {
return max(incomingMessageConnections.size(), incomingDspConnections.size());
}
virtual unsigned int getNumOutlets() {
return max(outgoingMessageConnections.size(), outgoingDspConnections.size());
}
virtual unsigned int getNumDspInlets() { return incomingDspConnections.size(); }
virtual unsigned int getNumDspOutlets() { return outgoingDspConnections.size(); }
/**
* Returns <i>all</i> incoming connections to the given inlet. This includes both message and
* dsp connections.
*/
virtual list<ObjectLetPair> getIncomingConnections(unsigned int inletIndex);
/** Returns only incoming dsp connections to the given inlet. */
virtual list<ObjectLetPair> getIncomingDspConnections(unsigned int inletIndex);
/**
* Returns <i>all</i> outgoing connections from the given outlet. This includes both message and
* dsp connections.
*/
virtual list<ObjectLetPair> getOutgoingConnections(unsigned int outletIndex);
/** Returns only outgoing dsp connections from the given outlet. */
virtual list<ObjectLetPair> getOutgoingDspConnections(unsigned int outletIndex);
static const char *getObjectLabel() { return "obj~"; }
protected:
static void processFunctionDefaultNoMessage(DspObject *dspObject, int fromIndex, int toIndex);
static void processFunctionMessage(DspObject *dspObject, int fromIndex, int toIndex);
/* IMPORTANT: one of these two functions MUST be overridden (or processFunction()) */
virtual void processDspWithIndex(double fromIndex, double toIndex);
virtual void processDspWithIndex(int fromIndex, int toIndex);
/**
* DspObject subclasses are informed that a connection change has happened to an inlet. A
* message or signal connection has been added or removed. They may which to reconfigure their
* (optimised) codepath with this new information.
*/
virtual void onInletConnectionUpdate(unsigned int inletIndex);
/** Immediately deletes all messages in the message queue without executing them. */
void clearMessageQueue();
// both float and int versions of the blocksize are stored as different internal mechanisms
// require different number formats
int blockSizeInt;
/** The local message queue. Messages that are pending for the next block. */
queue<MessageLetPair> messageQueue;
/* An array of pointers to resolved dsp buffers at each inlet. */
float *dspBufferAtInlet[3];
/* An array of pointers to resolved dsp buffers at each outlet. */
float *dspBufferAtOutlet[3];
/** List of all dsp objects connecting to this object at each inlet. */
vector<list<ObjectLetPair> > incomingDspConnections;
/** List of all dsp objects to which this object connects at each outlet. */
vector<list<ObjectLetPair> > outgoingDspConnections;
/** The process function to use when acting on a message. */
void (*processFunctionNoMessage)(DspObject *dspObject, int fromIndex, int toIndex);
private:
/** This function encapsulates the common code between the two constructors. */
void init(int numDspInlets, int numDspOutlets, int blockSize);
};
#endif // _DSP_OBJECT_H_