Jamoma API  0.6.0.a19
j.receive~.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup implementationMaxLibrary
4  *
5  * @brief Jamoma For Max Shared Library
6  *
7  * @details Receive remote audio signals
8  *
9  * @authors Tim Place, Trond Lossius
10  *
11  * @copyright Copyright © 2007, Tim 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 "Jamoma.h"
18 
19 
20 /** Object receiving remote audio signals within a module.
21  */
22 typedef struct _audioreceive{
23  t_pxobject obj;
24  void *dumpout; ///< dumpout outlet
25 
26  t_symbol *attr_target; ///< name of the module we are sending to
27  t_object *obj_target; ///< the hub of the module we are sending to
28  t_object *obj_direct_target; ///< the j.in~ object in the module we are sending to
29 
30  long num_outputs; ///< spec'd as an argument
31  float *audio_out[MAX_NUM_CHANNELS]; ///< pointers to the audio vectors
32  void *outlets[MAX_NUM_CHANNELS];
33  int vs; ///< cached vector-size for audio
35 
36 
37 // Prototypes
38 
39 /** Object instantiation.
40  @param s Pointer to symbol bassed as message argument to the object.
41  @param argc The number of arguments passed to the object.
42  @param argv Pointer to arguments as an array of atoms.
43  @return Pointer to the newly created object.
44  */
45 void *audioreceive_new(t_symbol *s, long argc, t_atom *argv);
46 
47 
48 /** This method is called when the object is free (deleted).
49  @param x Pointer to the object.
50  */
52 
53 
54 /** Method for displaying assist strings for inlets and outlets.
55  @param x Pointer to this object.
56  @param b
57  @param msg
58  @param argc
59  @param argv
60  */
61 void audioreceive_assist(t_audioreceive *x, void *b, long msg, long arg, char *dst);
62 
63 
64 /** When banged, fill a menu with potential targets.
65  @param x Pointer to this class.
66  */
68 
69 
70 /** Audio perform method for the object.
71  */
72 t_int* audioreceive_perform(t_int *w);
73 
74 
75 /** The DSP method for the object, called when compiling the audio chain.
76  @param x
77  @param sp
78  @param count
79  */
80 void audioreceive_dsp(t_audioreceive *x, t_signal **sp, short *count);
81 
82 
83 /** Set the name of the module we are part of as an attribute.
84  */
85 t_max_err audioreceive_attr_settarget(t_audioreceive *x, void *attr, long argc, t_atom *argv);
86 
87 
88 // Globals
89 static t_class *s_audioreceive_class; ///< Required: Global pointer for our class
90 
91 
92 /************************************************************************************/
93 
94 void receive_tilde_initclass(void)
95 {
96  long attrflags = 0;
97  t_class *c;
98  t_object *attr;
99 
100  // Define our class
101  c = class_new("j.receive~", (method)audioreceive_new, (method)audioreceive_free,
102  sizeof(t_audioreceive), (method)NULL, A_GIMME, 0);
103 
104  // Make methods accessible for our class:
105  class_addmethod(c, (method)audioreceive_bang, "bang", 0);
106  class_addmethod(c, (method)audioreceive_dsp, "dsp", A_CANT, 0);
107  class_addmethod(c, (method)audioreceive_assist, "assist", A_CANT, 0);
108  class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT,0);
109 
110  // ATTRIBUTE: name
111  attr = attr_offset_new("target", _sym_symbol, attrflags,
112  (method)0, (method)audioreceive_attr_settarget, calcoffset(t_audioreceive, attr_target));
113  class_addattr(c, attr);
114 
115 
116  // Setup our class to work with MSP
117  class_dspinit(c);
118 
119  // Finalize our class
120  class_register(CLASS_BOX, c);
121  s_audioreceive_class = c;
122 }
123 
124 
125 /************************************************************************************/
126 // Object Life
127 
128 // Create
129 void *audioreceive_new(t_symbol *s, long argc, t_atom *argv)
130 {
131  long attrstart = attr_args_offset(argc, argv); // support normal arguments
132  t_audioreceive *x = (t_audioreceive *)object_alloc(s_audioreceive_class);
133  short i;
134 
135  if (x) {
136  x->dumpout = outlet_new(x, NULL);
137  object_obex_store(x, _sym_dumpout, (t_object *)x->dumpout);
138 
139  x->attr_target = _sym_nothing;
140  x->num_outputs = 2; // TODO: make this dynamic from args
141 
142  for (i=0; i<attrstart; i++) {
143  if (argv[i].a_type == A_LONG)
144  x->num_outputs = atom_getlong(argv+i);
145  else if (argv[i].a_type == A_SYM)
146  x->attr_target = atom_getsym(argv+i);
147  }
148 
149  dsp_setup((t_pxobject *)x, 1);
150  for (i=0; i < x->num_outputs; i++)
151  x->outlets[i] = outlet_new(x, "signal");
152 
153  x->obj.z_misc = Z_NO_INPLACE;
154  attr_args_process(x, argc, argv); // handle attribute args
155  }
156  return x;
157 }
158 
159 
161 {
162  dsp_free((t_pxobject *)x);
163 }
164 
165 
166 /************************************************************************************/
167 // Methods bound to input/inlets
168 
169 // Method for Assistance Messages
170 void audioreceive_assist(t_audioreceive *x, void *b, long msg, long arg, char *dst)
171 {
172  if (msg==1) // Inlets
173  strcpy(dst, "input to send to a named module");
174  else if (msg==2) // Outlets
175  strcpy(dst, "dumpout");
176 }
177 
178 
179 // fill a menu with potential targets
181 {
182  t_atom a[2];
183  t_symbol **moduleNames = NULL;
184  long numModules = 0;
185  long i;
186 
187  jamoma_get_all_module_names(&numModules, &moduleNames);
188 
189  atom_setsym(a+0, SymbolGen("clear"));
190  outlet_anything(x->dumpout, SymbolGen("menu"), 1, a);
191 
192  atom_setsym(a+0, SymbolGen("append"));
193  for (i=0; i<numModules; i++) {
194  atom_setsym(a+1, moduleNames[i]);
195  outlet_anything(x->dumpout, SymbolGen("menu"), 2, a);
196  }
197  if (moduleNames)
198  sysmem_freeptr(moduleNames);
199 }
200 
201 
202 
203 t_int* audioreceive_perform(t_int *w)
204 {
205  t_audioreceive *x = (t_audioreceive*)(w[1]);
206  int channel;
207  int n;
208  float *vector = NULL;
209  float *out;
210 
211  //object_method(x->obj_direct_target, SymbolGen("remoteaudio"), x->audio_out, (long)(w[2]));
212  for (channel = 0; channel < x->num_outputs; channel++) {
213  n = x->vs;
214  object_method(x->obj_direct_target, SymbolGen("getAudioForChannel"), channel, &vector);
215  out = x->audio_out[channel];
216  if (vector) {
217  while (n--)
218  *out++ = *vector++;
219  }
220  }
221 
222  return(w+3);
223 }
224 
225 
226 void audioreceive_dsp(t_audioreceive *x, t_signal **sp, short *count)
227 {
228  long numOutputs = x->num_outputs;
229  short i, j;
230  t_object *hub;
231 
232  if (x->attr_target && x->attr_target != _sym_nothing) {
233  hub = jamoma_get_hub_for_module_named(x->attr_target);
234  if (hub != x->obj_target) {
235  if (hub) {
236  x->obj_target = hub;
237  // we could attach to the hub here to listen for free notifications
238  // but freeing it will restart the dsp anyway, so I don't think there is any need [tap]
239  x->obj_direct_target = (t_object*)object_method(hub, SymbolGen("getobj_audioout"));
240  }
241  }
242  if (x->obj_target) {
243  for (i=0, j=0; i<numOutputs; i++) {
244  if (count[i+1]) // the +1 is to account for the inlet in this object
245  j=i;
246  x->audio_out[i] = (t_float*)sp[i+1]->s_vec;
247  }
248  numOutputs = j+1;
249 
250  x->vs = sp[0]->s_n;
251  dsp_add(audioreceive_perform, 2, x, numOutputs);
252  }
253  }
254 }
255 
256 
257 /************************************************************************************/
258 
259 t_max_err audioreceive_attr_settarget(t_audioreceive *x, void *attr, long argc, t_atom *argv)
260 {
261  t_object *hub;
262 
263  x->attr_target = atom_getsym(argv);
264  hub = jamoma_get_hub_for_module_named(x->attr_target);
265  if (hub) {
266  x->obj_target = hub;
267  x->obj_direct_target = (t_object*)object_method(hub, SymbolGen("getobj_audioout"));
268  }
269  return MAX_ERR_NONE;
270 }
271 
void audioreceive_bang(t_audioreceive *x)
When banged, fill a menu with potential targets.
Definition: j.receive~.cpp:180
void * audioreceive_new(t_symbol *s, long argc, t_atom *argv)
Object instantiation.
Definition: j.receive~.cpp:129
t_object * obj_direct_target
the j.in~ object in the module we are sending to
Definition: j.receive~.cpp:28
void audioreceive_assist(t_audioreceive *x, void *b, long msg, long arg, char *dst)
Method for displaying assist strings for inlets and outlets.
Definition: j.receive~.cpp:170
Object receiving remote audio signals within a module.
Definition: j.receive~.cpp:22
void audioreceive_free(t_audioreceive *x)
This method is called when the object is free (deleted).
Definition: j.receive~.cpp:160
float * audio_out[MAX_NUM_CHANNELS]
pointers to the audio vectors
Definition: j.receive~.cpp:31
long num_outputs
spec'd as an argument
Definition: j.receive~.cpp:30
void * dumpout
dumpout outlet
Definition: j.receive~.cpp:24
int vs
cached vector-size for audio
Definition: j.receive~.cpp:33
t_symbol * attr_target
name of the module we are sending to
Definition: j.receive~.cpp:26
void audioreceive_dsp(t_audioreceive *x, t_signal **sp, short *count)
The DSP method for the object, called when compiling the audio chain.
Definition: j.receive~.cpp:226
t_object * obj_target
the hub of the module we are sending to
Definition: j.receive~.cpp:27
t_max_err audioreceive_attr_settarget(t_audioreceive *x, void *attr, long argc, t_atom *argv)
Set the name of the module we are part of as an attribute.
Definition: j.receive~.cpp:259
t_int * audioreceive_perform(t_int *w)
Audio perform method for the object.
Definition: j.receive~.cpp:203