Jamoma API  0.6.0.a19
j.gain~.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxExternalsDSP
4  *
5  * @brief j.gain~ : wraps the #TTGain class as a a Jamoma external for MSP
6  *
7  * @details
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright © 2005 by 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 #include "TTClassWrapperMax.h"
17 #include "ext.h" // Max Header
18 #include "z_dsp.h" // MSP Header
19 #include "ext_strings.h" // String Functions
20 #include "commonsyms.h" // Common symbols used by the Max 4.5 API
21 #include "ext_obex.h" // Max Object Extensions (attributes) Header
22 
23 #include "TTDSP.h"
24 #define MAX_NUM_CHANNELS 32
25 
26 // Data Structure for this object
27 typedef struct _gain {
28  t_pxobject obj;
29  TTAudioObject* xfade; // crossfade object from the Jamoma DSP library
30  TTAudioObject* gain; // gain control object the Jamoma DSP library
31  TTAudio* signalIn;
32  TTAudio* signalOut;
33  TTAudio* signalTemp;
34  TTUInt16 numChannels;
35  char attrBypass; // toggle 1 = bypass
36  float attrMix; // mix in %
37  float attrGain; // gain in midi units
38 } t_gain;
39 
40 
41 // Prototypes for methods
42 void* gain_new(t_symbol *s, long argc, t_atom *argv); // New Object Creation Method
43 void gain_free(t_gain *x); // Object Deletion Method
44 void gain_dsp64(t_gain *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags); // DSP64 Method
45 void gain_assist(t_gain *x, void *b, long m, long a, char *s); // Assistance Method
46 t_int* gain_perform(t_int *w); // MSP Perform Method
47 t_max_err attr_set_gain(t_gain *x, void *attr, long argc, t_atom *argv);
48 t_max_err attr_set_mix(t_gain *x, void *attr, long argc, t_atom *argv);
49 t_max_err attr_set_bypass(t_gain *x, void *attr, long argc, t_atom *argv);
50 
51 
52 // Globals
53 static t_class* s_gain_class;
54 
55 
56 /************************************************************************************/
57 // Define our class
58 
59 int C74_EXPORT main(void)
60 {
61  t_class *c;
62 
63  TTDSPInit();
64  common_symbols_init();
65 
66  c = class_new("j.gain~", (method)gain_new, (method)gain_free, sizeof(t_gain), (method)0L, A_GIMME, 0);
67 
68  // Make methods accessible for our class:
69  class_addmethod(c, (method)gain_dsp64, "dsp64", A_CANT, 0);
70  class_addmethod(c, (method)gain_assist, "assist", A_CANT, 0L);
71 
72  CLASS_ATTR_CHAR(c, "bypass", 0, t_gain, attrBypass);
73  CLASS_ATTR_ACCESSORS(c, "bypass", NULL, attr_set_bypass);
74 
75  CLASS_ATTR_FLOAT(c, "mix", 0, t_gain, attrBypass);
76  CLASS_ATTR_ACCESSORS(c, "mix", NULL, attr_set_mix);
77 
78  CLASS_ATTR_FLOAT(c, "gain", 0, t_gain, attrBypass);
79  CLASS_ATTR_ACCESSORS(c, "gain", NULL, attr_set_gain);
80 
81  // Setup our class to work with MSP
82  class_dspinit(c);
83 
84  // Finalize our class
85  class_register(CLASS_BOX, c);
86  s_gain_class = c;
87  return 0;
88 }
89 
90 
91 /************************************************************************************/
92 // Object Life
93 
94 // Create
95 void* gain_new(t_symbol* s, long argc, t_atom* argv)
96 {
97  long attrstart = attr_args_offset(argc, argv); // support normal arguments
98  short i;
99  t_gain* x = (t_gain*)object_alloc(s_gain_class);
100 
101  if (x) {
102  x->numChannels = 1;
103  if (attrstart && argv) {
104  int argument = atom_getlong(argv);
105  x->numChannels = TTClip(argument, 1, MAX_NUM_CHANNELS);
106  }
107 
108  dsp_setup((t_pxobject*)x, x->numChannels * 2); // Create Object and Inlets
109  x->obj.z_misc = Z_NO_INPLACE; // ESSENTIAL!
110  for (i=0; i < x->numChannels; i++)
111  outlet_new((t_pxobject*)x, "signal"); // Create a signal Outlet
112 
113  x->xfade = new TTAudioObject("crossfade", x->numChannels);
114  x->gain = new TTAudioObject("gain", x->numChannels);
115  x->signalTemp = new TTAudio(x->numChannels);
116  x->signalOut = new TTAudio(x->numChannels);
117  x->signalIn = new TTAudio(x->numChannels*2);
118 
119  x->xfade->set("position", 1.0); // defaults
120  x->gain->set("linearGain", 0.0);
121 
122  x->attrBypass = 0;
123  x->attrGain = 0;
124 
125  attr_args_process(x, argc, argv); // handle attribute args
126  }
127  return (x); // Return the pointer
128 }
129 
130 // Destroy
131 void gain_free(t_gain *x)
132 {
133  dsp_free((t_pxobject *)x); // Always call dsp_free first in this routine
134  delete x->xfade;
135  delete x->gain;
136  delete x->signalTemp;
137  delete x->signalOut;
138  delete x->signalIn;
139 }
140 
141 /************************************************************************************/
142 // Methods bound to input/inlets
143 
144 // Method for Assistance Messages
145 void gain_assist(t_gain *x, void *b, long msg, long arg, char *dst)
146 {
147  if (msg==1) { // Inlets
148  if (arg == 0)
149  snprintf(dst, 256, "(signal) raw audio (ch. %ld), control messages", arg+1);
150  else if (arg < x->numChannels)
151  snprintf(dst, 256, "(signal) raw audio (ch. %ld)", arg+1);
152  else if (arg >= x->numChannels)
153  snprintf(dst, 256, "(signal) wet audio (ch. %ld)", arg-x->numChannels+1);
154  }
155  else if (msg==2) // Outlets
156  snprintf(dst, 256, "(signal) processed audio (ch. %ld)", arg+1);
157 }
158 
159 
160 
161 // ATTRIBUTE: gain
162 t_max_err attr_set_gain(t_gain *x, void *attr, long argc, t_atom *argv)
163 {
164  x->attrGain = atom_getfloat(argv);
165  x->gain->set("midiGain", x->attrGain);
166  return MAX_ERR_NONE;
167 }
168 
169 
170 // ATTRIBUTE: mix
171 t_max_err attr_set_mix(t_gain *x, void *attr, long argc, t_atom *argv)
172 {
173  x->attrMix = atom_getfloat(argv);
174  if (x->attrBypass == 0)
175  x->xfade->set("position", x->attrMix * 0.01);
176  return MAX_ERR_NONE;
177 }
178 
179 
180 // ATTRIBUTE: bypass
181 t_max_err attr_set_bypass(t_gain *x, void *attr, long argc, t_atom *argv)
182 {
183  x->attrBypass = atom_getlong(argv);
184  if (x->attrBypass == 0)
185  x->xfade->set("position", x->attrMix * 0.01);
186  else
187  x->xfade->set("position", 0.0);
188  return MAX_ERR_NONE;
189 }
190 
191 
192 void gain_perform64(t_gain *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
193 {
194  short i;
195  TTUInt16 vs = x->signalIn->getVectorSizeAsInt();
196 
197  // We sort audioIn so that all channels of signalA comes first, then all channels of signalB
198  for (i=0; i < numouts; i++) {
199  x->signalIn->setVector(i, vs, ins[i]);
200  x->signalIn->setVector(i+numouts, vs, ins[i+numouts]);
201  }
202 
203  x->xfade->process(x->signalIn, x->signalTemp); // perform bypass and/or mix operation on processed input
204  x->gain->process(x->signalTemp, x->signalOut); // perform gain boost/cut on processed/bypassed input
205 
206  for (i=0; i < numouts; i++)
207  x->signalOut->getVectorCopy(i, vs, outs[i]); //getVector doesn't seem to work
208 }
209 
210 
211 
212 void gain_dsp64(t_gain *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags)
213 {
214  short i, k, j;
215  TTUInt16 numChannels = 0;
216 
217  for (i=0; i < x->numChannels; i++) {
218  j = x->numChannels + i;
219  k = x->numChannels*2 + i;
220  if (count[i] && count[j] && count[k]) {
221  numChannels++;
222  }
223  }
224 
225  x->signalIn->setNumChannels(numChannels*2);
226  x->signalOut->setNumChannels(numChannels);
227  x->signalTemp->setNumChannels(numChannels);
228 
229  x->signalIn->setVectorSizeWithInt((TTUInt16)maxvectorsize);
230  x->signalOut->setVectorSizeWithInt((TTUInt16)maxvectorsize);
231  x->signalTemp->setVectorSizeWithInt((TTUInt16)maxvectorsize);
232 
233  //signalIn will be set in the perform method
234  x->signalOut->alloc();
235  x->signalTemp->alloc();
236 
237  x->xfade->set(kTTSym_sampleRate, samplerate);
238  x->gain->set(kTTSym_sampleRate, samplerate);
239  x->gain->set("interpolated", true);
240  object_method(dsp64, gensym("dsp_add64"), x, gain_perform64, 0, NULL);
241 }
242 
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
int C74_EXPORT main(void)
Set up this class as a Max external the first time an object of this kind is instantiated.
Definition: j.gain~.cpp:59
Wrap audio objects for convenience.
Jamoma DSP Library.
void TTDSP_EXPORT TTDSPInit(const char *pathToBinaries=NULL)
Initialise the Jamoma DSP library, as well as Jamoma Foundation foundation if needed.
Definition: TTDSP.cpp:30
Wrap TTAudioSignal instances for convenience.
Definition: TTAudioObject.h:25