Jamoma API  0.6.0.a19
TTBalance.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup dspEffectsLib
4  *
5  * @brief #TTBalance balance the gain level according to a side band signal.
6  *
7  * @details Based on an algorithm from Dodge & Jerse (1997): Computer Music -
8  Synthesis, Composition, and Performance. 2nd edition. Schirmer.@n
9  @n
10  In fact, this processor can work on a number of channels, provided that the number of input channels is twice the number of output channels. In this case the first N/2 input channels are considered as the A source and the last N/2 input channels are considered the B source.
11  *
12  * @authors Trond Lossius
13  *
14  * @copyright Copyright © 2008, Trond Lossius @n
15  * This code is licensed under the terms of the "New BSD License" @n
16  * http://creativecommons.org/licenses/BSD/
17  */
18 
19 
20 #include "TTBalance.h"
21 
22 #define thisTTClass TTBalance
23 #define thisTTClassName "balance"
24 #define thisTTClassTags "dspEffectsLib, audio, processor, dynamics"
25 
26 
27 TT_AUDIO_CONSTRUCTOR
28 {
29  TTChannelCount initialMaxNumChannels = arguments;
30 
31  // register attributes
33 
34  // register for notifications from the parent class so we can allocate memory as required
35  addUpdates(MaxNumChannels);
36  // register for notifications from the parent class so we can recalculate coefficients as required
37  addUpdates(SampleRate);
38  // make the clear method available to the outside world
39  addMessage(clear);
40 
41  // Set Defaults...
42  setAttributeValue(kTTSym_maxNumChannels, initialMaxNumChannels); // This attribute is inherited
43  setAttributeValue(TT("frequency"), 10.0); // Default frequency is 10 Hz
44  setProcessMethod(processAudio);
45 }
46 
47 
48 TTBalance::~TTBalance()
49 {;}
50 
51 
53 {
54  xm1A.resize(mMaxNumChannels);
55  xm2A.resize(mMaxNumChannels);
56  ym1A.resize(mMaxNumChannels);
57  ym2A.resize(mMaxNumChannels);
58  xm1B.resize(mMaxNumChannels);
59  xm2B.resize(mMaxNumChannels);
60  ym1B.resize(mMaxNumChannels);
61  ym2B.resize(mMaxNumChannels);
62  return clear();
63 }
64 
65 
67 {
69  return setFrequency(v);
70 }
71 
72 
74 {
75  xm1A.assign(mMaxNumChannels, 0.0);
76  xm2A.assign(mMaxNumChannels, 0.0);
77  ym1A.assign(mMaxNumChannels, 0.0);
78  ym2A.assign(mMaxNumChannels, 0.0);
79  xm1B.assign(mMaxNumChannels, 0.0);
80  xm2B.assign(mMaxNumChannels, 0.0);
81  ym1B.assign(mMaxNumChannels, 0.0);
82  ym2B.assign(mMaxNumChannels, 0.0);
83  return kTTErrNone;
84 }
85 
86 
88 {
89  mFrequency = (double)newValue;
90  TTLimit(mFrequency, 1., (sr*0.45));
91 
92  c = 1 / ( tan( kTTPi*(mFrequency/sr) ) );
93  a0 = 1 / (1 + kTTSqrt2*c + c*c);
94  a1 = 2*a0;
95  a2 = a0;
96  b1 = 2*a0*( 1 - c*c );
97  b2 = a0 * (1 - kTTSqrt2*c + c*c);
98  return kTTErrNone;
99 }
100 
101 
103 {
104  TTAudioSignal& in = inputs->getSignal(0);
105  TTAudioSignal& out = outputs->getSignal(0);
106  TTUInt16 vs;
107  TTSampleValue *inSampleA,
108  *inSampleB,
109  *outSample;
110  TTFloat64 tempxA,
111  absTempxA,
112  tempxB,
113  absTempxB,
114  tempyA,
115  tempyB;
116  TTChannelCount channel;
117  TTChannelCount numChannels;
118 
119  // Twice as many input channels are expected as output channels
120  numChannels = TTAudioSignal::getNumChannels(in) / 2;
121  if (TTAudioSignal::getNumChannels(out) < numChannels)
122  numChannels = TTAudioSignal::getNumChannels(out);
123 
124  // This outside loop works through each channel one at a time
125  for (channel=0; channel<numChannels; channel++) {
126  // We first expect all channels of inputSignalA, then all channels of inputSignalB
127  inSampleA = in.mSampleVectors[channel];
128  inSampleB = in.mSampleVectors[channel+numChannels];
129  outSample = out.mSampleVectors[channel];
130  vs = in.getVectorSizeAsInt();
131 
132  // This inner loop works through each sample within the channel one at a time
133  while (vs--) {
134  tempxA = *inSampleA++;
135  absTempxA = fabs(tempxA);
136  tempxB = *inSampleB++;
137  absTempxB = fabs(tempxB);
138  // Lopass filter left and right signals
139  tempyA = a0*absTempxA + a1*xm1A[channel] + a2*xm2A[channel] - b1*ym1A[channel] - b2*ym2A[channel];
140  TTZeroDenormal(tempyA);
141  tempyB = a0*absTempxB + a1*xm1B[channel] + a2*xm2B[channel] - b1*ym1B[channel] - b2*ym2B[channel];
142  TTZeroDenormal(tempyB);
143  // Scale left input to produce output, avoid dividing by zero
144  if (tempyA)
145  *outSample++ = tempxA * (tempyB/tempyA);
146  else
147  *outSample++ = 0.;
148  // Update filter values
149  xm2A[channel] = xm1A[channel];
150  xm1A[channel] = absTempxA;
151  ym2A[channel] = ym1A[channel];
152  ym1A[channel] = tempyA;
153  xm2B[channel] = xm1B[channel];
154  xm1B[channel] = absTempxB;
155  ym2B[channel] = ym1B[channel];
156  ym1B[channel] = tempyB;
157  }
158  }
159  return kTTErrNone;
160 }
TTErr clear()
This algorithm depends on the use of an IIR filter, meaning that it relies on feedback.
Definition: TTBalance.cpp:73
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
TTErr processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
Standard audio processing method as used by TTBlue objects.
Definition: TTBalance.cpp:102
TTChannelCount mMaxNumChannels
This is the maximum number of channels that can be guaranteed to work.
#define setProcessMethod(methodName)
A convenience macro to be used by subclasses for setting the process method.
double TTFloat64
64 bit floating point number
Definition: TTBase.h:188
static TTChannelCount getNumChannels(const TTAudioSignal &signal)
Use this class method to determine the number of channels of an input or output signal.
#define TT
This macro is defined as a shortcut for doing a lookup in the symbol table.
Definition: TTSymbol.h:155
TTErr updateMaxNumChannels(const TTValue &oldMaxNumChannels, TTValue &)
Receives notifications when there are changes to the inherited maxNumChannels attribute.
Definition: TTBalance.cpp:52
64-bit floating point
Definition: TTBase.h:272
TTErr setFrequency(const TTValue &value)
Setter for the frequency attribute.
Definition: TTBalance.cpp:87
TTSampleVector ym2B
previous input and output values of signal to be compared with
Definition: TTBalance.h:42
TTSampleVector ym2A
previous input and output values of signal to be balanced
Definition: TTBalance.h:41
The TTAudioSignal class represents N vectors of audio samples for M channels.
Definition: TTAudioSignal.h:57
TTFOUNDATION_EXPORT const TTFloat64 kTTSqrt2
Pre-calculated square-root of 2 (1.4142).
Definition: TTBase.cpp:25
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
A simple container for an array of TTAudioSignal pointers.
TTBalance balance the gain level according to a side band signal.
TTErr
Jamoma Error Codes Enumeration of error codes that might be returned by any of the TTBlue functions a...
Definition: TTBase.h:342
TTErr updateSampleRate(const TTValue &oldSampleRate, TTValue &)
Receives notifications when there are changes to the inherited sr attribute.
Definition: TTBalance.cpp:66
#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
No Error.
Definition: TTBase.h:343
TTFOUNDATION_EXPORT const TTFloat64 kTTPi
[doxygenAppendixC_constExample]
Definition: TTBase.cpp:23
TTFloat64 TTSampleValue
A value representing a single audio sample.
Definition: TTBase.h:230
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
TTFloat64 mFrequency
filter cutoff frequency of inherent lowpass filter
Definition: TTBalance.h:39
TTFloat64 b2
filter coefficients
Definition: TTBalance.h:40
#define addUpdates(updateName)
An 'update' is a message sent to a subclass instance from its parent class.
Definition: TTMessage.h:44
TTUInt32 sr
Current sample rate being used by this object.