Jamoma API  0.6.0.a19
TTMixer.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspMathLib
4  *
5  * @brief #TTMixer is a Jamoma DSP Audio Mixer Object
6  *
7  * @details
8  *
9  * @authors Tim Place, Nathan Wolek, Trond Lossius
10  *
11  * @copyright Copyright © 2010, Timothy Place @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 
17 #include "TTMixer.h"
18 #ifdef TT_PLATFORM_WIN
19 #include <algorithm>
20 #endif
21 
22 #define thisTTClass TTMixer
23 #define thisTTClassName "mixer"
24 #define thisTTClassTags "audio, mixer"
25 
26 
27 TT_AUDIO_CONSTRUCTOR,
28  mInterpolated(0),
29  mNumInputs(1),
30  mNumOutputs(1)
31 {
32 
35  addAttribute(Interpolated, kTypeBoolean);
36 
37  addMessageWithArguments(setGain);
38  addMessageWithArguments(setLinearGain);
39  addMessageWithArguments(setMidiGain);
40 
41  //registerMessageWithArgument(updateMaxNumChannels);
42  addMessage(clear);
43  mGainMatrix.set("type", "float64");
44  oldGainMatrix.set("type", "float64");
45  tempGainMatrix.set("type","float64");
46  TTValue v(1, 1);
47  mGainMatrix.set("dimensions", v);
48  oldGainMatrix.set("dimensions", v);
49  tempGainMatrix.set("dimensions", v);
50  clear();
51  setProcessMethod(processAudio);
52 }
53 
54 
55 TTMixer::~TTMixer()
56 {
57 }
58 
59 
60 // conceptually:
61 // columns == inputs
62 // rows == outputs
63 
64 
66 {
67  TTChannelCount numInputs = newValue;
68  TTValue v(numInputs, mNumOutputs);
69 
70  if (numInputs != mNumInputs) {
71  mNumInputs = numInputs;
72  TTMatrixBase::copy(*mGainMatrix.instance(), *tempGainMatrix.instance()); //1. copy mGainMtrix to tempGainMatrix;
73  mGainMatrix.set("dimensions", v); //2. resize
74  oldGainMatrix.set("dimensions", v);
75  clear(); //3. clear mGainMatrix
76  restoreMatrix(); //4. element-wise copy tempGainMatrix content over to mGainMatrix
77  }
78  return kTTErrNone;
79 }
80 
81 
83 {
84  TTChannelCount numOutputs = newValue;
85  TTValue v(mNumInputs, numOutputs);
86 
87  if (numOutputs != mNumOutputs) {
88  mNumOutputs = numOutputs;
89  TTMatrixBase::copy(*mGainMatrix.instance(), *tempGainMatrix.instance()); //1. copy mGainMtrix to tempGainMatrix;
90  mGainMatrix.set("dimensions", v);
91  oldGainMatrix.set("dimensions", v);
92  clear(); //3. clear mGainMatrix
93  restoreMatrix(); //4. element-wise copy tempGainMatrix content over to mGainMatrix
94  }
95  return kTTErrNone;
96 }
97 
99 {
100  TTValue dim;
101  TTFloat64 tempValue;
102  TTChannelCount xx, yy;
103  tempGainMatrix.get("dimensions", dim);
104  xx = dim[0];
105  yy = dim[1];
106  TTLimit(xx,(TTChannelCount) 1, mNumInputs); // in case xx or yy is greater than the current mGainMatrix ...
107  TTLimit(yy,(TTChannelCount) 1, mNumOutputs);
108  for (TTUInt16 y=0; y < yy; y++) {
109  for (TTChannelCount x=0; x < xx; x++) {
110  tempGainMatrix.get2d(x, y, tempValue);
111  mGainMatrix.set2d( x, y, tempValue);
112  oldGainMatrix.set2d( x, y, tempValue);
113  }
114  }
115  return kTTErrNone;
116 }
117 
118 
120 {
121  mGainMatrix.clear();
123  return kTTErrNone;
124 }
125 
127 //this function will resize mGainMatrix if necessary while preserving its content
128 {
129  if (x > (mNumInputs-1)){
130  if (y > (mNumOutputs-1))
131  mNumOutputs = y+1;
132  setNumInputs(x+1);
133  }
134  else{
135  if (y > (mNumOutputs-1))
136  setNumOutputs(y+1);
137  }
138  return kTTErrNone;
139 }
140 
141 
142 
143 
145 {
146  TTChannelCount x;
147  TTChannelCount y;
148  TTFloat64 gainValue;
149 
150  if (newValue.size() != 3)
151  return kTTErrWrongNumValues;
152 
153  x = newValue[0];
154  y = newValue[1];
155  gainValue = newValue[2];
156 
157  checkMatrixSize(x,y);
158 
159  mGainMatrix.set2d(x, y, TTDecibelsToLinearGain(gainValue));
160 
161  if (mInterpolated)
163  return kTTErrNone;
164 }
165 
166 
168 {
169  TTChannelCount x;
170  TTChannelCount y;
171  TTFloat64 gainValue;
172 
173  if (newValue.size() != 3)
174  return kTTErrWrongNumValues;
175 
176  x = newValue[0];
177  y = newValue[1];
178  gainValue = newValue[2];
179 
180  checkMatrixSize(x,y);
181 
182  mGainMatrix.set2d(x, y, gainValue);
183  if (mInterpolated)
185  return kTTErrNone;
186 }
187 
188 
190 {
191  TTChannelCount x;
192  TTChannelCount y;
193  TTFloat64 gainValue;
194 
195  if (newValue.size() != 3)
196  return kTTErrWrongNumValues;
197 
198  x = newValue[0];
199  y = newValue[1];
200  gainValue = newValue[2];
201 
202  checkMatrixSize(x,y);
203  mGainMatrix.set2d(x, y, TTMidiToLinearGain(gainValue));
204 
205  if (mInterpolated)
207  return kTTErrNone;
208 }
209 
210 
211 // Here we are mixing channels within a signal rather than between multiple signals
213 {
214 
215  TTAudioSignal& in = inputs->getSignal(0);
216  TTAudioSignal& out = outputs->getSignal(0);
217  TTUInt16 vs = in.getVectorSizeAsInt();
218  TTSampleValuePtr inSample;
219  TTSampleValuePtr outSample;
220  TTChannelCount numInputChannels = in.getNumChannelsAsInt();
221  TTChannelCount numOutputChannels = out.getNumChannelsAsInt();
222  TTChannelCount outChannel;
223  TTChannelCount inChannel;
224  TTSampleValue gainValue;
225 
226  if (numInputChannels > mNumInputs) {
227  numInputChannels = mNumInputs;
228  //setNumInputs(numInputChannels);
229  }
230  if (numOutputChannels != mNumOutputs) {
231  TTValue v = mNumOutputs;
232 
233  out.setMaxNumChannels(v);
234  out.setNumChannels(v);
235  numOutputChannels = mNumOutputs;
236  }
237  out.clear();
238 
239  // TODO: this multiply-nested for-loop has got to be horrendously slow, there should be a much faster way to do this?
240 
241  for (outChannel=0; outChannel<numOutputChannels; outChannel++) {
242  outSample = out.mSampleVectors[outChannel];
243  for (inChannel=0; inChannel<numInputChannels; inChannel++) {
244  mGainMatrix.get2d(inChannel, outChannel, gainValue);
245  if (gainValue != 0.0){
246  inSample = in.mSampleVectors[inChannel];
247  for (int i=0; i<vs; i++) {
248  outSample[i] += inSample[i] * gainValue;
249  }
250  }
251  }
252  }
253  return kTTErrNone;
254 }
255 
256 
258 {
259 
260  TTAudioSignal& in = inputs->getSignal(0);
261  TTAudioSignal& out = outputs->getSignal(0);
262  TTUInt16 vs = in.getVectorSizeAsInt();
263  TTSampleValuePtr inSample;
264  TTSampleValuePtr outSample;
265  TTChannelCount numInputChannels = in.getNumChannelsAsInt();
266  TTChannelCount numOutputChannels = out.getNumChannelsAsInt();
267  TTChannelCount outChannel;
268  TTChannelCount inChannel;
269  TTSampleValue gainValue, increment;
270 
271  if (numInputChannels > mNumInputs) {
272  numInputChannels = mNumInputs;
273  }
274 
275  if (numOutputChannels != mNumOutputs) {
276  TTValue v = mNumOutputs;
277 
278  out.setMaxNumChannels(v);
279  out.setNumChannels(v);
280  numOutputChannels = mNumOutputs;
281  }
282 
283  out.clear();
284  TTSampleValue value, oldValue;
285  // TODO: this multiply-nested for-loop has got to be horrendously slow, there should be a much faster way to do this?
286 
287  for (outChannel=0; outChannel<numOutputChannels; outChannel++) {
288  outSample = out.mSampleVectors[outChannel];
289  for (inChannel=0; inChannel<numInputChannels; inChannel++) {
290  mGainMatrix.get2d(inChannel, outChannel, value);
291  //if (value != 0.0){ // this condition caused a click when the destination value is 0
292  oldGainMatrix.get2d(inChannel, outChannel, oldValue);
293  increment = (value-oldValue)/vs;
294  TTAntiDenormal(increment); // TODO: necessary if we use flush-to-zero compiling flag?
295  gainValue = oldValue;
296  inSample = in.mSampleVectors[inChannel];
297  for (int i=0; i<vs; i++) {
298  gainValue += increment;
299  outSample[i] += inSample[i] * gainValue;
300  }
301  //}
302  oldGainMatrix.set2d(inChannel, outChannel, value);
303  }
304  }
306  return kTTErrNone;
307 }
308 
TTFloat64 TTDecibelsToLinearGain(TTFloat64 value)
Convert decibels into linear ampliude.
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
TTErr get2d(TTRowID i, TTColumnID j, T &data) const
Get the value of a component located at (i,j) in a 2-dimensional matrix.
TTErr set2d(TTRowID i, TTColumnID j, T data)
Set the value of a component located at (i,j) in a 2-dimensional matrix.
TTMixer is a Jamoma DSP Audio Mixer Object
#define addAttribute(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom getter...
Definition: TTAttribute.h:29
TTErr setNumOutputs(const TTValue &newValue)
Set the number of audio output channels from the mixer.
Definition: TTMixer.cpp:82
TTBoolean mInterpolated
A flag determine if we will be interpolating towards new matrix values whenever a gain value is being...
Definition: TTMixer.h:30
TTErr setLinearGain(const TTValue &newValue, TTValue &)
Set the gain as linear amplitude for one inlet to one outlet.
Definition: TTMixer.cpp:167
size_type size() const noexcept
Return the number of elements.
static TTErr copy(const TTMatrixBase &source, TTMatrixBase &dest)
Copy the data from one matrix into another.
The wrong number of values were passed to a method or attribute.
Definition: TTBase.h:350
#define setProcessMethod(methodName)
A convenience macro to be used by subclasses for setting the process method.
TTMatrix oldGainMatrix
Required for the process of resizing when changing the number of inputs or outputs.
Definition: TTMixer.h:31
TTMatrixBase * instance() const
Get a pointer to the wrapped TTMatrixBase instance.
Definition: TTMatrix.h:37
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
16-bit unsigned integer, range is 0 through 65,535.
Definition: TTBase.h:276
TTErr restoreMatrix()
Restore matrix coefficients.
Definition: TTMixer.cpp:98
TTErr get(const TTSymbol aName, T &aReturnedValue) const
Get an attribute value for an object.
TTErr clear()
Zero out all of the sample values in the audio signal.
TTErr setMaxNumChannels(const TTValue &newMaxNumChannels)
Attribute accessor.
TTErr set(const TTSymbol aName, T aValue)
Set an attribute value for an object.
Boolean (1/0) or (true/false) flag.
Definition: TTBase.h:281
The TTAudioSignal class represents N vectors of audio samples for M channels.
Definition: TTAudioSignal.h:57
TTErr checkMatrixSize(const TTChannelCount x, const TTChannelCount y)
Check what the current mixer size is.
Definition: TTMixer.cpp:126
#define addMessageWithArguments(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:27
TTMatrix mGainMatrix
A NxM matrix of mixing coefficients.
Definition: TTMixer.h:29
TTSampleValue ** mSampleVectors
An array of pointers to the first sample in each vector. Declared Public for fast access...
Definition: TTAudioSignal.h:74
TTUInt16 TTChannelCount
Data type used when counting the number of channels in multi-channel audio signals and processes...
Definition: TTAudioSignal.h:31
TTFloat64 TTMidiToLinearGain(TTFloat64 value)
Convert midi into linear amplitude.
A simple container for an array of TTAudioSignal pointers.
TTChannelCount mNumInputs
The number of audio inputs.
Definition: TTMixer.h:33
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTErr processAudioInterpolated(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
Process audio with interpolation.
Definition: TTMixer.cpp:257
TTChannelCount mNumOutputs
The number of audio outputs.
Definition: TTMixer.h:34
TTErr setGain(const TTValue &newValue, TTValue &)
Set the gain as desibel for one inlet to one outlet.
Definition: TTMixer.cpp:144
#define addAttributeWithSetter(name, type)
A convenience macro to be used by subclasses for registering attributes with a custom setter...
Definition: TTAttribute.h:47
#define addMessage(name)
A convenience macro to be used by subclasses for registering messages.
Definition: TTMessage.h:19
TTErr processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
Process audio.
Definition: TTMixer.cpp:212
No Error.
Definition: TTBase.h:343
TTErr setNumInputs(const TTValue &newValue)
Set the number of audio input channels to the mixer.
Definition: TTMixer.cpp:65
TTErr clear()
Clear the matrix by setting all gain coefficients to 0.
Definition: TTMixer.cpp:119
TTFloat64 TTSampleValue
A value representing a single audio sample.
Definition: TTBase.h:230
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
void clear()
Set all components of a matrix to zero.
Definition: TTMatrix.cpp:18
TTMatrix tempGainMatrix
Required for the process of resizing when changing the number of inputs or outputs.
Definition: TTMixer.h:32
TTErr setMidiGain(const TTValue &newValue, TTValue &)
Set the gain as midi value for one inlet to one outlet.
Definition: TTMixer.cpp:189