1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2019 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/audio/osc/controller/ags_osc_node_controller.h>
21
22 #include <ags/audio/ags_sound_provider.h>
23 #include <ags/audio/ags_audio.h>
24 #include <ags/audio/ags_channel.h>
25 #include <ags/audio/ags_output.h>
26 #include <ags/audio/ags_input.h>
27 #include <ags/audio/ags_recall.h>
28 #include <ags/audio/ags_recall_audio.h>
29 #include <ags/audio/ags_recall_channel.h>
30 #include <ags/audio/ags_port.h>
31
32 #include <ags/audio/osc/ags_osc_response.h>
33 #include <ags/audio/osc/ags_osc_buffer_util.h>
34
35 #include <ags/i18n.h>
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40
41 #include <sys/types.h>
42 #include <regex.h>
43
44 void ags_osc_node_controller_class_init(AgsOscNodeControllerClass *osc_node_controller);
45 void ags_osc_node_controller_init(AgsOscNodeController *osc_node_controller);
46 void ags_osc_node_controller_set_property(GObject *gobject,
47 guint prop_id,
48 const GValue *value,
49 GParamSpec *param_spec);
50 void ags_osc_node_controller_get_property(GObject *gobject,
51 guint prop_id,
52 GValue *value,
53 GParamSpec *param_spec);
54 void ags_osc_node_controller_dispose(GObject *gobject);
55 void ags_osc_node_controller_finalize(GObject *gobject);
56
57 gpointer ags_osc_node_controller_get_data_soundcard(AgsOscNodeController *osc_node_controller,
58 AgsOscConnection *osc_connection,
59 GObject *soundcard,
60 unsigned char *message, guint message_size,
61 gchar *type_tag,
62 gchar *path, guint path_offset);
63 gpointer ags_osc_node_controller_get_data_sequencer(AgsOscNodeController *osc_node_controller,
64 AgsOscConnection *osc_connection,
65 GObject *sequencer,
66 unsigned char *message, guint message_size,
67 gchar *type_tag,
68 gchar *path, guint path_offset);
69
70 gpointer ags_osc_node_controller_get_data_audio(AgsOscNodeController *osc_node_controller,
71 AgsOscConnection *osc_connection,
72 AgsAudio *audio,
73 unsigned char *message, guint message_size,
74 gchar *type_tag,
75 gchar *path, guint path_offset);
76 gpointer ags_osc_node_controller_get_data_channel(AgsOscNodeController *osc_node_controller,
77 AgsOscConnection *osc_connection,
78 AgsChannel *channel,
79 unsigned char *message, guint message_size,
80 gchar *type_tag,
81 gchar *path, guint path_offset);
82
83 gpointer ags_osc_node_controller_get_data_recall(AgsOscNodeController *osc_node_controller,
84 AgsOscConnection *osc_connection,
85 AgsRecall *recall,
86 unsigned char *message, guint message_size,
87 gchar *type_tag,
88 gchar *path, guint path_offset);
89
90 gpointer ags_osc_node_controller_get_data_port(AgsOscNodeController *osc_node_controller,
91 AgsOscConnection *osc_connection,
92 AgsRecall *parent,
93 AgsPort *port,
94 unsigned char *message, guint message_size,
95 gchar *type_tag,
96 gchar *path, guint path_offset);
97
98 gpointer ags_osc_node_controller_real_get_data(AgsOscNodeController *osc_node_controller,
99 AgsOscConnection *osc_connection,
100 unsigned char *message, guint message_size);
101
102 /**
103 * SECTION:ags_osc_node_controller
104 * @short_description: OSC node controller
105 * @title: AgsOscNodeController
106 * @section_id:
107 * @include: ags/audio/osc/controller/ags_osc_node_controller.h
108 *
109 * The #AgsOscNodeController implements the OSC node controller.
110 */
111
112 enum{
113 PROP_0,
114 };
115
116 enum{
117 GET_DATA,
118 LAST_SIGNAL,
119 };
120
121 static gpointer ags_osc_node_controller_parent_class = NULL;
122 static guint osc_node_controller_signals[LAST_SIGNAL];
123
124 static GMutex regex_mutex;
125
126 GType
ags_osc_node_controller_get_type()127 ags_osc_node_controller_get_type()
128 {
129 static volatile gsize g_define_type_id__volatile = 0;
130
131 if(g_once_init_enter (&g_define_type_id__volatile)){
132 GType ags_type_osc_node_controller = 0;
133
134 static const GTypeInfo ags_osc_node_controller_info = {
135 sizeof (AgsOscNodeControllerClass),
136 NULL, /* base_init */
137 NULL, /* base_finalize */
138 (GClassInitFunc) ags_osc_node_controller_class_init,
139 NULL, /* class_finalize */
140 NULL, /* class_data */
141 sizeof (AgsOscNodeController),
142 0, /* n_preallocs */
143 (GInstanceInitFunc) ags_osc_node_controller_init,
144 };
145
146 ags_type_osc_node_controller = g_type_register_static(AGS_TYPE_OSC_CONTROLLER,
147 "AgsOscNodeController",
148 &ags_osc_node_controller_info,
149 0);
150
151 g_once_init_leave(&g_define_type_id__volatile, ags_type_osc_node_controller);
152 }
153
154 return g_define_type_id__volatile;
155 }
156
157 void
ags_osc_node_controller_class_init(AgsOscNodeControllerClass * osc_node_controller)158 ags_osc_node_controller_class_init(AgsOscNodeControllerClass *osc_node_controller)
159 {
160 GObjectClass *gobject;
161 GParamSpec *param_spec;
162
163 ags_osc_node_controller_parent_class = g_type_class_peek_parent(osc_node_controller);
164
165 /* GObjectClass */
166 gobject = (GObjectClass *) osc_node_controller;
167
168 gobject->set_property = ags_osc_node_controller_set_property;
169 gobject->get_property = ags_osc_node_controller_get_property;
170
171 gobject->dispose = ags_osc_node_controller_dispose;
172 gobject->finalize = ags_osc_node_controller_finalize;
173
174 /* properties */
175
176 /* AgsOscNodeControllerClass */
177 osc_node_controller->get_data = ags_osc_node_controller_real_get_data;
178
179 /* signals */
180 /**
181 * AgsOscNodeController::get-data:
182 * @osc_node_controller: the #AgsOscNodeController
183 * @osc_connection: the #AgsOscConnection
184 * @message: the message received
185 * @message_size: the message size
186 *
187 * The ::get-data signal is emited during get data of node controller.
188 *
189 * Returns: the #AgsOscResponse
190 *
191 * Since: 3.0.0
192 */
193 osc_node_controller_signals[GET_DATA] =
194 g_signal_new("get-data",
195 G_TYPE_FROM_CLASS(osc_node_controller),
196 G_SIGNAL_RUN_LAST,
197 G_STRUCT_OFFSET(AgsOscNodeControllerClass, get_data),
198 NULL, NULL,
199 ags_cclosure_marshal_POINTER__OBJECT_POINTER_UINT,
200 G_TYPE_POINTER, 3,
201 G_TYPE_OBJECT,
202 G_TYPE_POINTER,
203 G_TYPE_UINT);
204 }
205
206 void
ags_osc_node_controller_init(AgsOscNodeController * osc_node_controller)207 ags_osc_node_controller_init(AgsOscNodeController *osc_node_controller)
208 {
209 g_object_set(osc_node_controller,
210 "context-path", "/node",
211 NULL);
212 }
213
214 void
ags_osc_node_controller_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)215 ags_osc_node_controller_set_property(GObject *gobject,
216 guint prop_id,
217 const GValue *value,
218 GParamSpec *param_spec)
219 {
220 AgsOscNodeController *osc_node_controller;
221
222 GRecMutex *osc_controller_mutex;
223
224 osc_node_controller = AGS_OSC_NODE_CONTROLLER(gobject);
225
226 /* get osc controller mutex */
227 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_node_controller);
228
229 switch(prop_id){
230 default:
231 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
232 break;
233 }
234 }
235
236 void
ags_osc_node_controller_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)237 ags_osc_node_controller_get_property(GObject *gobject,
238 guint prop_id,
239 GValue *value,
240 GParamSpec *param_spec)
241 {
242 AgsOscNodeController *osc_node_controller;
243
244 GRecMutex *osc_controller_mutex;
245
246 osc_node_controller = AGS_OSC_NODE_CONTROLLER(gobject);
247
248 /* get osc controller mutex */
249 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_node_controller);
250
251 switch(prop_id){
252 default:
253 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
254 break;
255 }
256 }
257
258 void
ags_osc_node_controller_dispose(GObject * gobject)259 ags_osc_node_controller_dispose(GObject *gobject)
260 {
261 AgsOscNodeController *osc_node_controller;
262
263 osc_node_controller = AGS_OSC_NODE_CONTROLLER(gobject);
264
265 /* call parent */
266 G_OBJECT_CLASS(ags_osc_node_controller_parent_class)->dispose(gobject);
267 }
268
269 void
ags_osc_node_controller_finalize(GObject * gobject)270 ags_osc_node_controller_finalize(GObject *gobject)
271 {
272 AgsOscNodeController *osc_node_controller;
273
274 osc_node_controller = AGS_OSC_NODE_CONTROLLER(gobject);
275
276 /* call parent */
277 G_OBJECT_CLASS(ags_osc_node_controller_parent_class)->finalize(gobject);
278 }
279
280 gpointer
ags_osc_node_controller_get_data_soundcard(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,GObject * soundcard,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)281 ags_osc_node_controller_get_data_soundcard(AgsOscNodeController *osc_node_controller,
282 AgsOscConnection *osc_connection,
283 GObject *soundcard,
284 unsigned char *message, guint message_size,
285 gchar *type_tag,
286 gchar *path, guint path_offset)
287 {
288 AgsOscResponse *osc_response;
289
290 AgsApplicationContext *application_context;
291
292 GList *start_response;
293 GList *start_list;
294
295 unsigned char *packet;
296 gchar *current_path;
297
298 guint real_packet_size;
299 guint packet_size;
300 gint nth_soundcard;
301
302 if(!AGS_IS_SOUNDCARD(soundcard)){
303 return(NULL);
304 }
305
306 start_response = NULL;
307
308 application_context = ags_application_context_get_instance();
309
310 real_packet_size = 0;
311 packet_size = 0;
312
313 if(!strncmp(path + path_offset,
314 ":",
315 1)){
316 /* get nth soundcard */
317 start_list = ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(application_context));
318
319 nth_soundcard = g_list_index(start_list,
320 soundcard);
321
322 g_list_free_full(start_list,
323 g_object_unref);
324
325 osc_response = ags_osc_response_new();
326 start_response = g_list_prepend(start_response,
327 osc_response);
328
329 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
330 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
331
332 g_object_set(osc_response,
333 "packet", packet,
334 "packet-size", packet_size,
335 NULL);
336
337 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
338
339 path_offset += 1;
340
341 if(!strncmp(path + path_offset,
342 "device",
343 7)){
344 gchar *device;
345
346 guint length;
347
348 /* create current path */
349 current_path = g_strdup_printf("/AgsSoundProvider/AgsSoundcard[%d]:device", nth_soundcard);
350
351 /* message path */
352 packet_size = 4;
353
354 ags_osc_buffer_util_put_string(packet + packet_size,
355 "/node", -1);
356
357 /* message type tag */
358 packet_size += 8;
359
360 ags_osc_buffer_util_put_string(packet + packet_size,
361 ",ss", -1);
362
363 /* node path */
364 packet_size += 4;
365
366 length = strlen(current_path);
367
368 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
369 ags_osc_response_set_flags(osc_response,
370 AGS_OSC_RESPONSE_ERROR);
371
372 g_object_set(osc_response,
373 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
374 NULL);
375
376 return(start_response);
377 }
378
379 ags_osc_buffer_util_put_string(packet + packet_size,
380 current_path, -1);
381
382 /* node argument */
383 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
384
385 device = ags_soundcard_get_device(AGS_SOUNDCARD(soundcard));
386 length = strlen(device);
387
388 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
389 ags_osc_response_set_flags(osc_response,
390 AGS_OSC_RESPONSE_ERROR);
391
392 g_object_set(osc_response,
393 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
394 NULL);
395
396 return(start_response);
397 }
398
399 ags_osc_buffer_util_put_string(packet + packet_size,
400 device, -1);
401
402 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
403
404 /* packet size */
405 ags_osc_buffer_util_put_int32(packet,
406 packet_size);
407 }else if(!strncmp(path + path_offset,
408 "pcm-channels",
409 13)){
410 guint pcm_channels;
411 guint length;
412
413 /* create current path */
414 current_path = g_strdup_printf("/AgsSoundProvider/AgsSoundcard[%d]:pcm-channels", nth_soundcard);
415
416 /* message path */
417 packet_size = 4;
418
419 ags_osc_buffer_util_put_string(packet + packet_size,
420 "/node", -1);
421
422 /* message type tag */
423 packet_size += 8;
424
425 ags_osc_buffer_util_put_string(packet + packet_size,
426 ",si", -1);
427
428 /* node path */
429 packet_size += 4;
430
431 length = strlen(current_path);
432
433 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
434 ags_osc_response_set_flags(osc_response,
435 AGS_OSC_RESPONSE_ERROR);
436
437 g_object_set(osc_response,
438 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
439 NULL);
440
441 return(start_response);
442 }
443
444 ags_osc_buffer_util_put_string(packet + packet_size,
445 current_path, -1);
446
447 /* node argument */
448 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
449
450 ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard),
451 &pcm_channels,
452 NULL,
453 NULL,
454 NULL);
455 ags_osc_buffer_util_put_int32(packet + packet_size,
456 pcm_channels);
457
458 packet_size += 4;
459
460 /* packet size */
461 ags_osc_buffer_util_put_int32(packet,
462 packet_size);
463 }else if(!strncmp(path + path_offset,
464 "samplerate",
465 11)){
466 guint samplerate;
467 guint length;
468
469 /* create current path */
470 current_path = g_strdup_printf("/AgsSoundProvider/AgsSoundcard[%d]:samplerate", nth_soundcard);
471
472 /* message path */
473 packet_size = 4;
474
475 ags_osc_buffer_util_put_string(packet + packet_size,
476 "/node", -1);
477
478 /* message type tag */
479 packet_size += 8;
480
481 ags_osc_buffer_util_put_string(packet + packet_size,
482 ",si", -1);
483
484 /* node path */
485 packet_size += 4;
486
487 length = strlen(current_path);
488
489 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
490 ags_osc_response_set_flags(osc_response,
491 AGS_OSC_RESPONSE_ERROR);
492
493 g_object_set(osc_response,
494 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
495 NULL);
496
497 return(start_response);
498 }
499
500 ags_osc_buffer_util_put_string(packet + packet_size,
501 current_path, -1);
502
503 /* node argument */
504 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
505
506 packet_size = 16 + length;
507
508 ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard),
509 NULL,
510 &samplerate,
511 NULL,
512 NULL);
513 ags_osc_buffer_util_put_int32(packet + packet_size,
514 samplerate);
515
516 packet_size += 4;
517
518 /* packet size */
519 ags_osc_buffer_util_put_int32(packet,
520 packet_size);
521 }else if(!strncmp(path + path_offset,
522 "buffer-size",
523 12)){
524 guint buffer_size;
525 guint length;
526
527 /* create current path */
528 current_path = g_strdup_printf("/AgsSoundProvider/AgsSoundcard[%d]:buffer-size", nth_soundcard);
529
530 /* message path */
531 packet_size = 4;
532
533 ags_osc_buffer_util_put_string(packet + packet_size,
534 "/node", -1);
535
536 /* message type tag */
537 packet_size += 8;
538
539 ags_osc_buffer_util_put_string(packet + packet_size,
540 ",si", -1);
541
542 /* node path */
543 packet_size += 4;
544
545 length = strlen(current_path);
546
547 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
548 ags_osc_response_set_flags(osc_response,
549 AGS_OSC_RESPONSE_ERROR);
550
551 g_object_set(osc_response,
552 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
553 NULL);
554
555 return(start_response);
556 }
557
558 ags_osc_buffer_util_put_string(packet + packet_size,
559 current_path, -1);
560
561 /* node argument */
562 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
563
564 ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard),
565 NULL,
566 NULL,
567 &buffer_size,
568 NULL);
569 ags_osc_buffer_util_put_int32(packet + packet_size,
570 buffer_size);
571
572 packet_size += 4;
573
574 /* packet size */
575 ags_osc_buffer_util_put_int32(packet,
576 packet_size);
577 }else if(!strncmp(path + path_offset,
578 "format",
579 7)){
580 guint format;
581 guint length;
582
583 /* create current path */
584 current_path = g_strdup_printf("/AgsSoundProvider/AgsSoundcard[%d]:format", nth_soundcard);
585
586 /* message path */
587 packet_size = 4;
588
589 ags_osc_buffer_util_put_string(packet + packet_size,
590 "/node", -1);
591
592 /* message type tag */
593 packet_size += 8;
594
595 length = strlen(current_path);
596
597 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
598 ags_osc_response_set_flags(osc_response,
599 AGS_OSC_RESPONSE_ERROR);
600
601 g_object_set(osc_response,
602 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
603 NULL);
604
605 return(start_response);
606 }
607
608 ags_osc_buffer_util_put_string(packet + packet_size,
609 ",si", -1);
610
611 /* node path */
612 packet_size += 4;
613
614 ags_osc_buffer_util_put_string(packet + packet_size,
615 current_path, -1);
616
617 /* node argument */
618 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
619
620 ags_soundcard_get_presets(AGS_SOUNDCARD(soundcard),
621 NULL,
622 NULL,
623 NULL,
624 &format);
625
626 ags_osc_buffer_util_put_int32(packet + packet_size,
627 format);
628
629 packet_size += 4;
630
631 /* packet size */
632 ags_osc_buffer_util_put_int32(packet,
633 packet_size);
634 }else{
635 ags_osc_response_set_flags(osc_response,
636 AGS_OSC_RESPONSE_ERROR);
637
638 g_object_set(osc_response,
639 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
640 NULL);
641
642 return(start_response);
643 }
644
645 g_object_set(osc_response,
646 "packet-size", packet_size,
647 NULL);
648 }else{
649 osc_response = ags_osc_response_new();
650 start_response = g_list_prepend(start_response,
651 osc_response);
652
653 ags_osc_response_set_flags(osc_response,
654 AGS_OSC_RESPONSE_ERROR);
655
656 g_object_set(osc_response,
657 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_PATH,
658 NULL);
659
660 return(start_response);
661 }
662
663 return(start_response);
664 }
665
666 gpointer
ags_osc_node_controller_get_data_sequencer(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,GObject * sequencer,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)667 ags_osc_node_controller_get_data_sequencer(AgsOscNodeController *osc_node_controller,
668 AgsOscConnection *osc_connection,
669 GObject *sequencer,
670 unsigned char *message, guint message_size,
671 gchar *type_tag,
672 gchar *path, guint path_offset)
673 {
674 AgsOscResponse *osc_response;
675
676 AgsApplicationContext *application_context;
677
678 GList *start_response;
679 GList *start_list;
680
681 unsigned char *packet;
682 gchar *current_path;
683
684 guint real_packet_size;
685 guint packet_size;
686 gint nth_sequencer;
687
688 if(!AGS_IS_SEQUENCER(sequencer)){
689 return(NULL);
690 }
691
692 start_response = NULL;
693
694 application_context = ags_application_context_get_instance();
695
696 real_packet_size = 0;
697 packet_size = 0;
698
699 if(!strncmp(path + path_offset,
700 ":",
701 1)){
702 /* get nth sequencer */
703 start_list = ags_sound_provider_get_sequencer(AGS_SOUND_PROVIDER(application_context));
704
705 nth_sequencer = g_list_index(start_list,
706 sequencer);
707
708 g_list_free_full(start_list,
709 g_object_unref);
710
711 osc_response = ags_osc_response_new();
712 start_response = g_list_prepend(start_response,
713 osc_response);
714
715 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
716 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
717
718 g_object_set(osc_response,
719 "packet", packet,
720 "packet-size", packet_size,
721 NULL);
722
723 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
724
725 path_offset += 1;
726
727 if(!strncmp(path + path_offset,
728 "device",
729 7)){
730 gchar *device;
731
732 guint length;
733
734 /* create current path */
735 current_path = g_strdup_printf("/AgsSoundProvider/AgsSequencer[%d]:device", nth_sequencer);
736
737 /* message path */
738 packet_size = 4;
739
740 ags_osc_buffer_util_put_string(packet + packet_size,
741 "/node", -1);
742
743 /* message type tag */
744 packet_size += 8;
745
746 ags_osc_buffer_util_put_string(packet + packet_size,
747 ",ss", -1);
748
749 /* node path */
750 packet_size += 4;
751
752 length = strlen(current_path);
753
754 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
755 ags_osc_response_set_flags(osc_response,
756 AGS_OSC_RESPONSE_ERROR);
757
758 g_object_set(osc_response,
759 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
760 NULL);
761
762 return(start_response);
763 }
764
765 ags_osc_buffer_util_put_string(packet + packet_size,
766 current_path, -1);
767
768 /* node argument */
769 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
770
771 device = ags_sequencer_get_device(AGS_SEQUENCER(sequencer));
772 length = strlen(device);
773
774 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
775 ags_osc_response_set_flags(osc_response,
776 AGS_OSC_RESPONSE_ERROR);
777
778 g_object_set(osc_response,
779 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
780 NULL);
781
782 return(start_response);
783 }
784
785 ags_osc_buffer_util_put_string(packet + packet_size,
786 device, -1);
787
788 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
789
790 /* packet size */
791 ags_osc_buffer_util_put_int32(packet,
792 packet_size);
793 }else{
794 ags_osc_response_set_flags(osc_response,
795 AGS_OSC_RESPONSE_ERROR);
796
797 g_object_set(osc_response,
798 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
799 NULL);
800
801 return(start_response);
802 }
803
804 g_object_set(osc_response,
805 "packet-size", packet_size,
806 NULL);
807 }else{
808 osc_response = ags_osc_response_new();
809 start_response = g_list_prepend(start_response,
810 osc_response);
811
812 ags_osc_response_set_flags(osc_response,
813 AGS_OSC_RESPONSE_ERROR);
814
815 g_object_set(osc_response,
816 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_PATH,
817 NULL);
818
819 return(start_response);
820 }
821
822 return(start_response);
823 }
824
825 gpointer
ags_osc_node_controller_get_data_audio(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,AgsAudio * audio,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)826 ags_osc_node_controller_get_data_audio(AgsOscNodeController *osc_node_controller,
827 AgsOscConnection *osc_connection,
828 AgsAudio *audio,
829 unsigned char *message, guint message_size,
830 gchar *type_tag,
831 gchar *path, guint path_offset)
832 {
833 AgsOscResponse *osc_response;
834
835 AgsApplicationContext *application_context;
836
837 GList *start_response;
838 GList *start_list;
839
840 unsigned char *packet;
841 gchar *current_path;
842
843 guint real_packet_size;
844 guint packet_size;
845 gint nth_audio;
846
847 if(!AGS_IS_AUDIO(audio)){
848 return(NULL);
849 }
850
851 start_response = NULL;
852
853 application_context = ags_application_context_get_instance();
854
855 real_packet_size = 0;
856 packet_size = 0;
857
858 if(!strncmp(path + path_offset,
859 ":",
860 1)){
861 guint length;
862
863 /* get nth audio */
864 start_list = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
865
866 nth_audio = g_list_index(start_list,
867 audio);
868
869 g_list_free_full(start_list,
870 g_object_unref);
871
872 osc_response = ags_osc_response_new();
873 start_response = g_list_prepend(start_response,
874 osc_response);
875
876 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
877 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
878
879 g_object_set(osc_response,
880 "packet", packet,
881 "packet-size", packet_size,
882 NULL);
883
884 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
885
886 path_offset += 1;
887
888 /* properties */
889 if(!strncmp(path + path_offset,
890 "audio-channels",
891 15)){
892 guint audio_channels;
893
894 /* create current path */
895 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:audio-channels", nth_audio);
896
897 /* message path */
898 packet_size = 4;
899
900 ags_osc_buffer_util_put_string(packet + packet_size,
901 "/node", -1);
902
903 /* message type tag */
904 packet_size += 8;
905
906 ags_osc_buffer_util_put_string(packet + packet_size,
907 ",si", -1);
908
909 /* node path */
910 packet_size += 4;
911
912 length = strlen(current_path);
913
914 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
915 ags_osc_response_set_flags(osc_response,
916 AGS_OSC_RESPONSE_ERROR);
917
918 g_object_set(osc_response,
919 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
920 NULL);
921
922 return(start_response);
923 }
924
925 ags_osc_buffer_util_put_string(packet + packet_size,
926 current_path, -1);
927
928 /* node argument */
929 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
930
931 g_object_get(audio,
932 "audio-channels", &audio_channels,
933 NULL);
934 ags_osc_buffer_util_put_int32(packet + packet_size,
935 audio_channels);
936
937 packet_size += 4;
938
939 /* packet size */
940 ags_osc_buffer_util_put_int32(packet,
941 packet_size);
942 }else if(!strncmp(path + path_offset,
943 "output-pads",
944 12)){
945 guint output_pads;
946
947 /* create current path */
948 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:output-pads", nth_audio);
949
950 /* message path */
951 packet_size = 4;
952
953 ags_osc_buffer_util_put_string(packet + packet_size,
954 "/node", -1);
955
956 /* message type tag */
957 packet_size += 8;
958
959 ags_osc_buffer_util_put_string(packet + packet_size,
960 ",si", -1);
961
962 /* node path */
963 packet_size += 4;
964
965 length = strlen(current_path);
966
967 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
968 ags_osc_response_set_flags(osc_response,
969 AGS_OSC_RESPONSE_ERROR);
970
971 g_object_set(osc_response,
972 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
973 NULL);
974
975 return(start_response);
976 }
977
978 ags_osc_buffer_util_put_string(packet + packet_size,
979 current_path, -1);
980
981 /* node argument */
982 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
983
984 g_object_get(audio,
985 "output-pads", &output_pads,
986 NULL);
987 ags_osc_buffer_util_put_int32(packet + packet_size,
988 output_pads);
989
990 packet_size += 4;
991
992 /* packet size */
993 ags_osc_buffer_util_put_int32(packet,
994 packet_size);
995 }else if(!strncmp(path + path_offset,
996 "input-pads",
997 11)){
998 guint input_pads;
999
1000 /* create current path */
1001 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:input-pads", nth_audio);
1002
1003 /* message path */
1004 packet_size = 4;
1005
1006 ags_osc_buffer_util_put_string(packet + packet_size,
1007 "/node", -1);
1008
1009 /* message type tag */
1010 packet_size += 8;
1011
1012 ags_osc_buffer_util_put_string(packet + packet_size,
1013 ",si", -1);
1014
1015 /* node path */
1016 packet_size += 4;
1017
1018 length = strlen(current_path);
1019
1020 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
1021 ags_osc_response_set_flags(osc_response,
1022 AGS_OSC_RESPONSE_ERROR);
1023
1024 g_object_set(osc_response,
1025 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
1026 NULL);
1027
1028 return(start_response);
1029 }
1030
1031 ags_osc_buffer_util_put_string(packet + packet_size,
1032 current_path, -1);
1033
1034 /* node argument */
1035 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
1036
1037 g_object_get(audio,
1038 "input-pads", &input_pads,
1039 NULL);
1040 ags_osc_buffer_util_put_int32(packet + packet_size,
1041 input_pads);
1042
1043 packet_size += 4;
1044
1045 /* packet size */
1046 ags_osc_buffer_util_put_int32(packet,
1047 packet_size);
1048 }else if(!strncmp(path + path_offset,
1049 "buffer-size",
1050 12)){
1051 guint buffer_size;
1052
1053 /* create current path */
1054 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:buffer-size", nth_audio);
1055
1056 /* message path */
1057 packet_size = 4;
1058
1059 ags_osc_buffer_util_put_string(packet + packet_size,
1060 "/node", -1);
1061
1062 /* message type tag */
1063 packet_size += 8;
1064
1065 ags_osc_buffer_util_put_string(packet + packet_size,
1066 ",si", -1);
1067
1068 /* node path */
1069 packet_size += 4;
1070
1071 length = strlen(current_path);
1072
1073 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
1074 ags_osc_response_set_flags(osc_response,
1075 AGS_OSC_RESPONSE_ERROR);
1076
1077 g_object_set(osc_response,
1078 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
1079 NULL);
1080
1081 return(start_response);
1082 }
1083
1084 ags_osc_buffer_util_put_string(packet + packet_size,
1085 current_path, -1);
1086
1087 /* node argument */
1088 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
1089
1090 g_object_get(audio,
1091 "buffer-size", &buffer_size,
1092 NULL);
1093 ags_osc_buffer_util_put_int32(packet + packet_size,
1094 buffer_size);
1095
1096 packet_size += 4;
1097
1098 /* packet size */
1099 ags_osc_buffer_util_put_int32(packet,
1100 packet_size);
1101 }else if(!strncmp(path + path_offset,
1102 "samplerate",
1103 11)){
1104 guint samplerate;
1105
1106 /* create current path */
1107 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:samplerate", nth_audio);
1108
1109 /* message path */
1110 packet_size = 4;
1111
1112 ags_osc_buffer_util_put_string(packet + packet_size,
1113 "/node", -1);
1114
1115 /* message type tag */
1116 packet_size += 8;
1117
1118 ags_osc_buffer_util_put_string(packet + packet_size,
1119 ",si", -1);
1120
1121 /* node path */
1122 packet_size += 4;
1123
1124 length = strlen(current_path);
1125
1126 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
1127 ags_osc_response_set_flags(osc_response,
1128 AGS_OSC_RESPONSE_ERROR);
1129
1130 g_object_set(osc_response,
1131 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
1132 NULL);
1133
1134 return(start_response);
1135 }
1136
1137 ags_osc_buffer_util_put_string(packet + packet_size,
1138 current_path, -1);
1139
1140 /* node argument */
1141 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
1142
1143 g_object_get(audio,
1144 "samplerate", &samplerate,
1145 NULL);
1146 ags_osc_buffer_util_put_int32(packet + packet_size,
1147 samplerate);
1148
1149 packet_size += 4;
1150
1151 /* packet size */
1152 ags_osc_buffer_util_put_int32(packet,
1153 packet_size);
1154 }else if(!strncmp(path + path_offset,
1155 "format",
1156 7)){
1157 guint format;
1158
1159 /* create current path */
1160 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]:format", nth_audio);
1161
1162 /* message path */
1163 packet_size = 4;
1164
1165 ags_osc_buffer_util_put_string(packet + packet_size,
1166 "/node", -1);
1167
1168 /* message type tag */
1169 packet_size += 8;
1170
1171 ags_osc_buffer_util_put_string(packet + packet_size,
1172 ",si", -1);
1173
1174 /* node path */
1175 packet_size += 4;
1176
1177 length = strlen(current_path);
1178
1179 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
1180 ags_osc_response_set_flags(osc_response,
1181 AGS_OSC_RESPONSE_ERROR);
1182
1183 g_object_set(osc_response,
1184 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
1185 NULL);
1186
1187 return(start_response);
1188 }
1189
1190 ags_osc_buffer_util_put_string(packet + packet_size,
1191 current_path, -1);
1192
1193 /* node argument */
1194 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
1195
1196 g_object_get(audio,
1197 "format", &format,
1198 NULL);
1199 ags_osc_buffer_util_put_int32(packet + packet_size,
1200 format);
1201
1202 packet_size += 4;
1203
1204 /* packet size */
1205 ags_osc_buffer_util_put_int32(packet,
1206 packet_size);
1207 }else{
1208 ags_osc_response_set_flags(osc_response,
1209 AGS_OSC_RESPONSE_ERROR);
1210
1211 g_object_set(osc_response,
1212 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
1213 NULL);
1214
1215 return(start_response);
1216 }
1217
1218 g_object_set(osc_response,
1219 "packet-size", packet_size,
1220 NULL);
1221 }else if(!strncmp(path + path_offset,
1222 "/AgsOutput",
1223 10) ||
1224 !strncmp(path + path_offset,
1225 "/AgsInput",
1226 9)){
1227 AgsChannel *start_channel;
1228 AgsChannel *channel, *next_channel;
1229
1230 regmatch_t match_arr[2];
1231
1232 static regex_t single_access_regex;
1233 static regex_t range_access_regex;
1234 static regex_t voluntary_access_regex;
1235 static regex_t more_access_regex;
1236 static regex_t wildcard_access_regex;
1237
1238 static gboolean regex_compiled = FALSE;
1239
1240 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
1241 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
1242 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
1243 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
1244 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
1245
1246 static const size_t max_matches = 2;
1247 static const size_t index_max_matches = 1;
1248
1249 start_channel = NULL;
1250
1251 if(!strncmp(path + path_offset,
1252 "/AgsOutput",
1253 10)){
1254 path_offset += 10;
1255
1256 g_object_get(audio,
1257 "output", &start_channel,
1258 NULL);
1259 }else{
1260 path_offset += 9;
1261
1262 g_object_get(audio,
1263 "input", &start_channel,
1264 NULL);
1265 }
1266
1267 /* compile regex */
1268 g_mutex_lock(®ex_mutex);
1269
1270 if(!regex_compiled){
1271 regex_compiled = TRUE;
1272
1273 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
1274 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
1275 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
1276 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
1277 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
1278 }
1279
1280 g_mutex_unlock(®ex_mutex);
1281
1282 if(ags_regexec(&single_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
1283 gchar *endptr;
1284
1285 guint i_stop;
1286
1287 endptr = NULL;
1288 i_stop = g_ascii_strtoull(path + path_offset + 1,
1289 &endptr,
1290 10);
1291
1292 channel = ags_channel_nth(start_channel,
1293 i_stop);
1294
1295 path_offset += ((endptr + 1) - (path + path_offset));
1296
1297 start_response = ags_osc_node_controller_get_data_channel(osc_node_controller,
1298 osc_connection,
1299 channel,
1300 message, message_size,
1301 type_tag,
1302 path, path_offset);
1303
1304 if(start_channel != NULL){
1305 g_object_unref(start_channel);
1306 }
1307
1308 if(channel != NULL){
1309 g_object_unref(channel);
1310 }
1311 }else if(ags_regexec(&range_access_regex, path + path_offset, max_matches, match_arr, 0) == 0){
1312 gchar *endptr;
1313
1314 guint i;
1315 guint i_start, i_stop;
1316
1317 endptr = NULL;
1318 i_start = g_ascii_strtoull(path + path_offset + 1,
1319 &endptr,
1320 10);
1321
1322 i_stop = g_ascii_strtoull(endptr + 1,
1323 &endptr,
1324 10);
1325
1326 path_offset += ((endptr + 1) - (path + path_offset));
1327
1328 channel = ags_channel_nth(start_channel,
1329 i_start);
1330
1331 next_channel = NULL;
1332
1333 for(i = i_start; i <= i_stop && channel != NULL; i++){
1334 GList *retval;
1335
1336 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
1337 osc_connection,
1338 channel,
1339 message, message_size,
1340 type_tag,
1341 path, path_offset);
1342
1343 if(start_response != NULL){
1344 start_response = g_list_concat(start_response,
1345 retval);
1346 }else{
1347 start_response = retval;
1348 }
1349
1350 /* iterate */
1351 next_channel = ags_channel_next(channel);
1352
1353 g_object_unref(channel);
1354
1355 channel = next_channel;
1356 }
1357
1358 if(start_channel != NULL){
1359 g_object_unref(start_channel);
1360 }
1361
1362 if(next_channel != NULL){
1363 g_object_unref(next_channel);
1364 }
1365 }else if(ags_regexec(&voluntary_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
1366 path_offset += 3;
1367
1368 if(start_channel != NULL){
1369 GList *retval;
1370
1371 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
1372 osc_connection,
1373 start_channel,
1374 message, message_size,
1375 type_tag,
1376 path, path_offset);
1377 }else{
1378 osc_response = ags_osc_response_new();
1379 start_response = g_list_prepend(start_response,
1380 osc_response);
1381
1382 ags_osc_response_set_flags(osc_response,
1383 AGS_OSC_RESPONSE_OK);
1384
1385 return(start_response);
1386 }
1387 }else if(ags_regexec(&more_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
1388 path_offset += 3;
1389
1390 if(start_channel == NULL){
1391 osc_response = ags_osc_response_new();
1392 start_response = g_list_prepend(start_response,
1393 osc_response);
1394
1395 ags_osc_response_set_flags(osc_response,
1396 AGS_OSC_RESPONSE_ERROR);
1397
1398 g_object_set(osc_response,
1399 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
1400 NULL);
1401
1402 return(start_response);
1403 }
1404
1405 /* prepare */
1406 channel = start_channel;
1407 g_object_ref(channel);
1408
1409 next_channel = NULL;
1410
1411 while(channel != NULL){
1412 GList *retval;
1413
1414 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
1415 osc_connection,
1416 channel,
1417 message, message_size,
1418 type_tag,
1419 path, path_offset);
1420
1421 if(start_response != NULL){
1422 start_response = g_list_concat(start_response,
1423 retval);
1424 }else{
1425 start_response = retval;
1426 }
1427
1428 /* iterate */
1429 next_channel = ags_channel_next(channel);
1430
1431 g_object_unref(channel);
1432
1433 channel = next_channel;
1434 }
1435
1436 /* unref */
1437 if(start_channel != NULL){
1438 g_object_unref(start_channel);
1439 }
1440
1441 if(next_channel != NULL){
1442 g_object_unref(next_channel);
1443 }
1444 }else if(ags_regexec(&wildcard_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
1445 path_offset += 3;
1446
1447 if(start_channel == NULL){
1448 osc_response = ags_osc_response_new();
1449 start_response = g_list_prepend(start_response,
1450 osc_response);
1451
1452 ags_osc_response_set_flags(osc_response,
1453 AGS_OSC_RESPONSE_OK);
1454
1455 return(start_response);
1456 }
1457
1458 /* prepare */
1459 channel = start_channel;
1460 g_object_ref(channel);
1461
1462 next_channel = NULL;
1463
1464 while(channel != NULL){
1465 GList *retval;
1466
1467 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
1468 osc_connection,
1469 channel,
1470 message, message_size,
1471 type_tag,
1472 path, path_offset);
1473
1474 if(start_response != NULL){
1475 start_response = g_list_concat(start_response,
1476 retval);
1477 }else{
1478 start_response = retval;
1479 }
1480
1481 /* iterate */
1482 next_channel = ags_channel_next(channel);
1483
1484 g_object_unref(channel);
1485
1486 channel = next_channel;
1487 }
1488
1489 /* unref */
1490 if(start_channel != NULL){
1491 g_object_unref(start_channel);
1492 }
1493
1494 if(next_channel != NULL){
1495 g_object_unref(next_channel);
1496 }
1497 }else{
1498 osc_response = ags_osc_response_new();
1499 start_response = g_list_prepend(start_response,
1500 osc_response);
1501
1502 ags_osc_response_set_flags(osc_response,
1503 AGS_OSC_RESPONSE_ERROR);
1504
1505 g_object_set(osc_response,
1506 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
1507 NULL);
1508
1509 /* unref */
1510 if(start_channel != NULL){
1511 g_object_unref(start_channel);
1512 }
1513
1514 return(start_response);
1515 }
1516 }else{
1517 GType recall_type;
1518
1519 GList *start_play, *play;
1520 GList *start_recall, *recall;
1521
1522 regmatch_t match_arr[3];
1523
1524 gchar *type_name;
1525 gchar *str;
1526
1527 guint type_name_length;
1528 guint str_length;
1529
1530 static regex_t recall_regex;
1531 static regex_t single_access_regex;
1532 static regex_t range_access_regex;
1533 static regex_t voluntary_access_regex;
1534 static regex_t more_access_regex;
1535 static regex_t wildcard_access_regex;
1536
1537 static gboolean regex_compiled = FALSE;
1538
1539 static const gchar *recall_pattern = "^\\/([a-zA-Z]+)(\\/|\\[[0-9]+\\]|\\[[0-9]+\\-[0-9]+\\]|\\[\\?\\]|\\[\\+\\]|\\[\\*\\]|:)";
1540 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
1541 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
1542 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
1543 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
1544 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
1545
1546 static const size_t max_matches = 3;
1547 static const size_t index_max_matches = 2;
1548
1549 /* compile regex */
1550 g_mutex_lock(®ex_mutex);
1551
1552 if(!regex_compiled){
1553 regex_compiled = TRUE;
1554
1555 ags_regcomp(&recall_regex, recall_pattern, REG_EXTENDED);
1556
1557 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
1558 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
1559 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
1560 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
1561 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
1562 }
1563
1564 g_mutex_unlock(®ex_mutex);
1565
1566 if(ags_regexec(&recall_regex, path + path_offset, max_matches, match_arr, 0) == 0){
1567 type_name_length = match_arr[1].rm_eo - match_arr[1].rm_so;
1568 type_name = g_strndup(path + path_offset + 1,
1569 type_name_length);
1570
1571 str_length = match_arr[2].rm_eo - match_arr[2].rm_so;
1572 str = g_strndup(path + path_offset + 1 + type_name_length,
1573 str_length);
1574 }else{
1575 osc_response = ags_osc_response_new();
1576 start_response = g_list_prepend(start_response,
1577 osc_response);
1578
1579 ags_osc_response_set_flags(osc_response,
1580 AGS_OSC_RESPONSE_ERROR);
1581
1582 g_object_set(osc_response,
1583 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_PATH,
1584 NULL);
1585
1586 return(start_response);
1587 }
1588
1589 recall_type = g_type_from_name(type_name);
1590
1591 g_object_get(audio,
1592 "play", &start_play,
1593 "recall", &start_recall,
1594 NULL);
1595
1596 if(ags_regexec(&single_access_regex, str, index_max_matches, match_arr, 0) == 0){
1597 guint i;
1598 guint i_stop;
1599
1600 path_offset += (type_name_length + 1) + str_length;
1601
1602 i_stop = g_ascii_strtoull(str + 1,
1603 NULL,
1604 10);
1605
1606 play = start_play;
1607 recall = start_recall;
1608
1609 for(i = 0; i <= i_stop; i++){
1610 play = ags_recall_template_find_type(play, recall_type);
1611 recall = ags_recall_template_find_type(recall, recall_type);
1612
1613 if(i + 1 < i_stop){
1614 if(play != NULL){
1615 play = play->next;
1616 }
1617
1618 if(recall != NULL){
1619 recall = recall->next;
1620 }
1621 }
1622 }
1623
1624 if(play != NULL){
1625 AgsRecall *current;
1626
1627 GList *retval;
1628
1629 current = play->data;
1630 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1631 osc_connection,
1632 current,
1633 message, message_size,
1634 type_tag,
1635 path, path_offset);
1636
1637 if(start_response != NULL){
1638 start_response = g_list_concat(start_response,
1639 retval);
1640 }else{
1641 start_response = retval;
1642 }
1643 }
1644
1645 if(recall != NULL){
1646 AgsRecall *current;
1647
1648 GList *retval;
1649
1650 current = recall->data;
1651 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1652 osc_connection,
1653 current,
1654 message, message_size,
1655 type_tag,
1656 path, path_offset);
1657
1658 if(start_response != NULL){
1659 start_response = g_list_concat(start_response,
1660 retval);
1661 }else{
1662 start_response = retval;
1663 }
1664 }
1665 }else if(ags_regexec(&range_access_regex, str, max_matches, match_arr, 0) == 0){
1666 gchar *endptr;
1667
1668 guint i;
1669 guint i_start, i_stop;
1670
1671 path_offset += (type_name_length + 1) + str_length;
1672
1673 endptr = NULL;
1674 i_start = g_ascii_strtoull(str + 1,
1675 &endptr,
1676 10);
1677
1678 i_stop = g_ascii_strtoull(endptr + 1,
1679 NULL,
1680 10);
1681
1682 play = start_play;
1683 recall = start_recall;
1684
1685 for(i = 0; i <= i_stop; i++){
1686 play = ags_recall_template_find_type(play, recall_type);
1687 recall = ags_recall_template_find_type(recall, recall_type);
1688
1689 if(i >= i_start){
1690 if(play != NULL){
1691 AgsRecall *current;
1692
1693 GList *retval;
1694
1695 current = play->data;
1696 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1697 osc_connection,
1698 current,
1699 message, message_size,
1700 type_tag,
1701 path, path_offset);
1702
1703 if(start_response != NULL){
1704 start_response = g_list_concat(start_response,
1705 retval);
1706 }else{
1707 start_response = retval;
1708 }
1709 }
1710
1711 if(recall != NULL){
1712 AgsRecall *current;
1713
1714 GList *retval;
1715
1716 current = recall->data;
1717 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1718 osc_connection,
1719 current,
1720 message, message_size,
1721 type_tag,
1722 path, path_offset);
1723
1724 if(start_response != NULL){
1725 start_response = g_list_concat(start_response,
1726 retval);
1727 }else{
1728 start_response = retval;
1729 }
1730 }
1731 }
1732
1733 if(i + 1 < i_stop){
1734 if(play != NULL){
1735 play = play->next;
1736 }
1737
1738 if(recall != NULL){
1739 recall = recall->next;
1740 }
1741 }
1742 }
1743 }else if(ags_regexec(&voluntary_access_regex, str, index_max_matches, match_arr, 0) == 0){
1744 path_offset += (type_name_length + 1) + str_length;
1745
1746 play = start_play;
1747 recall = start_recall;
1748
1749 play = ags_recall_template_find_type(play, recall_type);
1750 recall = ags_recall_template_find_type(recall, recall_type);
1751
1752 if(play != NULL){
1753 AgsRecall *current;
1754
1755 current = play->data;
1756 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
1757 osc_connection,
1758 current,
1759 message, message_size,
1760 type_tag,
1761 path, path_offset);
1762 }
1763
1764 if(recall != NULL){
1765 AgsRecall *current;
1766
1767 current = recall->data;
1768 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
1769 osc_connection,
1770 current,
1771 message, message_size,
1772 type_tag,
1773 path, path_offset);
1774 }
1775
1776 if(play == NULL && recall == NULL){
1777 osc_response = ags_osc_response_new();
1778 start_response = g_list_prepend(start_response,
1779 osc_response);
1780
1781 ags_osc_response_set_flags(osc_response,
1782 AGS_OSC_RESPONSE_OK);
1783
1784 g_list_free_full(start_play,
1785 g_object_unref);
1786 g_list_free_full(start_recall,
1787 g_object_unref);
1788
1789 return(start_response);
1790 }
1791 }else if(ags_regexec(&more_access_regex, str, index_max_matches, match_arr, 0) == 0){
1792 path_offset += (type_name_length + 1) + str_length;
1793
1794 play = start_play;
1795 recall = start_recall;
1796
1797 play = ags_recall_template_find_type(play, recall_type);
1798 recall = ags_recall_template_find_type(recall, recall_type);
1799
1800 if(play == NULL && recall == NULL){
1801 osc_response = ags_osc_response_new();
1802 start_response = g_list_prepend(start_response,
1803 osc_response);
1804
1805 ags_osc_response_set_flags(osc_response,
1806 AGS_OSC_RESPONSE_ERROR);
1807
1808 g_object_set(osc_response,
1809 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
1810 NULL);
1811
1812 g_list_free_full(start_play,
1813 g_object_unref);
1814 g_list_free_full(start_recall,
1815 g_object_unref);
1816
1817 return(start_response);
1818 }
1819
1820 if(play != NULL){
1821 AgsRecall *current;
1822
1823 current = play->data;
1824 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
1825 osc_connection,
1826 current,
1827 message, message_size,
1828 type_tag,
1829 path, path_offset);
1830 }
1831
1832 if(recall != NULL){
1833 AgsRecall *current;
1834
1835 GList *retval;
1836
1837 current = recall->data;
1838 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1839 osc_connection,
1840 current,
1841 message, message_size,
1842 type_tag,
1843 path, path_offset);
1844
1845 if(start_response != NULL){
1846 start_response = g_list_concat(start_response,
1847 retval);
1848 }else{
1849 start_response = retval;
1850 }
1851 }
1852
1853 while(play != NULL || recall != NULL){
1854 play = ags_recall_template_find_type(play, recall_type);
1855 recall = ags_recall_template_find_type(recall, recall_type);
1856
1857 if(play != NULL){
1858 AgsRecall *current;
1859
1860 GList *retval;
1861
1862 current = play->data;
1863 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1864 osc_connection,
1865 current,
1866 message, message_size,
1867 type_tag,
1868 path, path_offset);
1869
1870 start_response = g_list_concat(start_response,
1871 retval);
1872 }
1873
1874 if(recall != NULL){
1875 AgsRecall *current;
1876
1877 GList *retval;
1878
1879 current = recall->data;
1880 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1881 osc_connection,
1882 current,
1883 message, message_size,
1884 type_tag,
1885 path, path_offset);
1886
1887 start_response = g_list_concat(start_response,
1888 retval);
1889 }
1890
1891 if(play != NULL){
1892 play = play->next;
1893 }
1894
1895 if(recall != NULL){
1896 recall = recall->next;
1897 }
1898 }
1899 }else if(ags_regexec(&wildcard_access_regex, str, index_max_matches, match_arr, 0) == 0){
1900 path_offset += (type_name_length + 1) + str_length;
1901
1902 play = start_play;
1903 recall = start_recall;
1904
1905 while(play != NULL || recall != NULL){
1906 play = ags_recall_template_find_type(play, recall_type);
1907 recall = ags_recall_template_find_type(recall, recall_type);
1908
1909 if(play != NULL){
1910 AgsRecall *current;
1911
1912 GList *retval;
1913
1914 current = play->data;
1915 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1916 osc_connection,
1917 current,
1918 message, message_size,
1919 type_tag,
1920 path, path_offset);
1921
1922 if(start_response != NULL){
1923 start_response = g_list_concat(start_response,
1924 retval);
1925 }else{
1926 start_response = retval;
1927 }
1928 }
1929
1930 if(recall != NULL){
1931 AgsRecall *current;
1932
1933 GList *retval;
1934
1935 current = recall->data;
1936 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
1937 osc_connection,
1938 current,
1939 message, message_size,
1940 type_tag,
1941 path, path_offset);
1942
1943 if(start_response != NULL){
1944 start_response = g_list_concat(start_response,
1945 retval);
1946 }else{
1947 start_response = retval;
1948 }
1949 }
1950
1951 if(play != NULL){
1952 play = play->next;
1953 }
1954
1955 if(recall != NULL){
1956 recall = recall->next;
1957 }
1958 }
1959 }else{
1960 osc_response = ags_osc_response_new();
1961 start_response = g_list_prepend(start_response,
1962 osc_response);
1963
1964 ags_osc_response_set_flags(osc_response,
1965 AGS_OSC_RESPONSE_ERROR);
1966
1967 g_object_set(osc_response,
1968 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_MALFORMED_REQUEST,
1969 NULL);
1970
1971 g_list_free_full(start_play,
1972 g_object_unref);
1973 g_list_free_full(start_recall,
1974 g_object_unref);
1975
1976 return(start_response);
1977 }
1978
1979 g_list_free_full(start_play,
1980 g_object_unref);
1981 g_list_free_full(start_recall,
1982 g_object_unref);
1983 }
1984
1985 return(start_response);
1986 }
1987
1988 gpointer
ags_osc_node_controller_get_data_channel(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,AgsChannel * channel,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)1989 ags_osc_node_controller_get_data_channel(AgsOscNodeController *osc_node_controller,
1990 AgsOscConnection *osc_connection,
1991 AgsChannel *channel,
1992 unsigned char *message, guint message_size,
1993 gchar *type_tag,
1994 gchar *path, guint path_offset)
1995 {
1996 AgsAudio *audio;
1997
1998 AgsOscResponse *osc_response;
1999
2000 AgsApplicationContext *application_context;
2001
2002 GList *start_response;
2003 GList *start_list;
2004
2005 unsigned char *packet;
2006 gchar *current_path;
2007
2008 guint real_packet_size;
2009 guint packet_size;
2010 gint nth_audio;
2011 gint nth_channel;
2012
2013 if(!AGS_IS_CHANNEL(channel)){
2014 return(NULL);
2015 }
2016
2017 start_response = NULL;
2018
2019 application_context = ags_application_context_get_instance();
2020
2021 real_packet_size = 0;
2022 packet_size = 0;
2023
2024 if(!strncmp(path + path_offset,
2025 ":",
2026 1)){
2027 guint length;
2028
2029 g_object_get(channel,
2030 "audio", &audio,
2031 "line", &nth_channel,
2032 NULL);
2033
2034 g_object_unref(audio);
2035
2036 /* get nth audio */
2037 start_list = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
2038
2039 nth_audio = g_list_index(start_list,
2040 audio);
2041
2042 g_list_free_full(start_list,
2043 g_object_unref);
2044
2045 osc_response = ags_osc_response_new();
2046 start_response = g_list_prepend(start_response,
2047 osc_response);
2048
2049 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
2050 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
2051
2052 g_object_set(osc_response,
2053 "packet", packet,
2054 "packet-size", packet_size,
2055 NULL);
2056
2057 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
2058
2059 path_offset += 1;
2060
2061 if(!strncmp(path + path_offset,
2062 "buffer-size",
2063 12)){
2064 guint buffer_size;
2065
2066 /* create current path */
2067 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]/%s[%d]:buffer-size",
2068 nth_audio,
2069 ((AGS_IS_OUTPUT(channel)) ? "AgsOutput": "AgsInput"),
2070 nth_channel);
2071
2072 /* message path */
2073 packet_size = 4;
2074
2075 ags_osc_buffer_util_put_string(packet + packet_size,
2076 "/node", -1);
2077
2078 /* message type tag */
2079 packet_size += 8;
2080
2081 ags_osc_buffer_util_put_string(packet + packet_size,
2082 ",si", -1);
2083
2084 /* node path */
2085 packet_size += 4;
2086
2087 length = strlen(current_path);
2088
2089 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
2090 ags_osc_response_set_flags(osc_response,
2091 AGS_OSC_RESPONSE_ERROR);
2092
2093 g_object_set(osc_response,
2094 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
2095 NULL);
2096
2097 return(start_response);
2098 }
2099
2100 ags_osc_buffer_util_put_string(packet + packet_size,
2101 current_path, -1);
2102
2103 /* node argument */
2104 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
2105
2106 g_object_get(channel,
2107 "buffer-size", &buffer_size,
2108 NULL);
2109 ags_osc_buffer_util_put_int32(packet + packet_size,
2110 buffer_size);
2111
2112 packet_size += 4;
2113
2114 /* packet size */
2115 ags_osc_buffer_util_put_int32(packet,
2116 packet_size);
2117 }else if(!strncmp(path + path_offset,
2118 "samplerate",
2119 11)){
2120 guint samplerate;
2121
2122 /* create current path */
2123 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]/%s[%d]:samplerate",
2124 nth_audio,
2125 ((AGS_IS_OUTPUT(channel)) ? "AgsOutput": "AgsInput"),
2126 nth_channel);
2127
2128 /* message path */
2129 packet_size = 4;
2130
2131 ags_osc_buffer_util_put_string(packet + packet_size,
2132 "/node", -1);
2133
2134 /* message type tag */
2135 packet_size += 8;
2136
2137 ags_osc_buffer_util_put_string(packet + packet_size,
2138 ",si", -1);
2139
2140 /* node path */
2141 packet_size += 4;
2142
2143 length = strlen(current_path);
2144
2145 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
2146 ags_osc_response_set_flags(osc_response,
2147 AGS_OSC_RESPONSE_ERROR);
2148
2149 g_object_set(osc_response,
2150 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
2151 NULL);
2152
2153 return(start_response);
2154 }
2155
2156 ags_osc_buffer_util_put_string(packet + packet_size,
2157 current_path, -1);
2158
2159 /* node argument */
2160 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
2161
2162 g_object_get(channel,
2163 "samplerate", &samplerate,
2164 NULL);
2165 ags_osc_buffer_util_put_int32(packet + packet_size,
2166 samplerate);
2167
2168 packet_size += 4;
2169
2170 /* packet size */
2171 ags_osc_buffer_util_put_int32(packet,
2172 packet_size);
2173 }else if(!strncmp(path + path_offset,
2174 "format",
2175 7)){
2176 guint format;
2177
2178 /* create current path */
2179 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]/%s[%d]:format",
2180 nth_audio,
2181 ((AGS_IS_OUTPUT(channel)) ? "AgsOutput": "AgsInput"),
2182 nth_channel);
2183
2184 /* message path */
2185 packet_size = 4;
2186
2187 ags_osc_buffer_util_put_string(packet + packet_size,
2188 "/node", -1);
2189
2190 /* message type tag */
2191 packet_size += 8;
2192
2193 ags_osc_buffer_util_put_string(packet + packet_size,
2194 ",si", -1);
2195
2196 /* node path */
2197 packet_size += 4;
2198
2199 length = strlen(current_path);
2200
2201 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 4 > real_packet_size){
2202 ags_osc_response_set_flags(osc_response,
2203 AGS_OSC_RESPONSE_ERROR);
2204
2205 g_object_set(osc_response,
2206 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
2207 NULL);
2208
2209 return(start_response);
2210 }
2211
2212 ags_osc_buffer_util_put_string(packet + packet_size,
2213 current_path, -1);
2214
2215 /* node argument */
2216 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
2217
2218 g_object_get(channel,
2219 "format", &format,
2220 NULL);
2221 ags_osc_buffer_util_put_int32(packet + packet_size,
2222 format);
2223
2224 packet_size += 4;
2225
2226 /* packet size */
2227 ags_osc_buffer_util_put_int32(packet,
2228 packet_size);
2229 }else{
2230 ags_osc_response_set_flags(osc_response,
2231 AGS_OSC_RESPONSE_ERROR);
2232
2233 g_object_set(osc_response,
2234 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
2235 NULL);
2236
2237 return(start_response);
2238 }
2239
2240 g_object_set(osc_response,
2241 "packet-size", packet_size,
2242 NULL);
2243 }else{
2244 GType recall_type;
2245
2246 GList *start_play, *play;
2247 GList *start_recall, *recall;
2248
2249 regmatch_t match_arr[3];
2250
2251 gchar *type_name;
2252 gchar *str;
2253
2254 guint type_name_length;
2255 guint str_length;
2256
2257 static regex_t recall_regex;
2258 static regex_t single_access_regex;
2259 static regex_t range_access_regex;
2260 static regex_t voluntary_access_regex;
2261 static regex_t more_access_regex;
2262 static regex_t wildcard_access_regex;
2263
2264 static gboolean regex_compiled = FALSE;
2265
2266 static const gchar *recall_pattern = "^\\/([a-zA-Z]+)(\\/|\\[[0-9]+\\]|\\[[0-9]+\\-[0-9]+\\]|\\[\\?\\]|\\[\\+\\]|\\[\\*\\]|:)";
2267 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
2268 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
2269 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
2270 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
2271 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
2272
2273 static const size_t max_matches = 3;
2274 static const size_t index_max_matches = 2;
2275
2276 /* compile regex */
2277 g_mutex_lock(®ex_mutex);
2278
2279 if(!regex_compiled){
2280 regex_compiled = TRUE;
2281
2282 ags_regcomp(&recall_regex, recall_pattern, REG_EXTENDED);
2283
2284 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
2285 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
2286 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
2287 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
2288 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
2289 }
2290
2291 g_mutex_unlock(®ex_mutex);
2292
2293 if(ags_regexec(&recall_regex, path + path_offset, max_matches, match_arr, 0) == 0){
2294 type_name_length = match_arr[1].rm_eo - match_arr[1].rm_so;
2295 type_name = g_strndup(path + path_offset + 1,
2296 type_name_length);
2297
2298 str_length = match_arr[2].rm_eo - match_arr[2].rm_so;
2299 str = g_strndup(path + path_offset + 1 + type_name_length,
2300 str_length);
2301 }else{
2302 osc_response = ags_osc_response_new();
2303 start_response = g_list_prepend(start_response,
2304 osc_response);
2305
2306 ags_osc_response_set_flags(osc_response,
2307 AGS_OSC_RESPONSE_ERROR);
2308
2309 g_object_set(osc_response,
2310 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_PATH,
2311 NULL);
2312
2313 return(start_response);
2314 }
2315
2316 recall_type = g_type_from_name(type_name);
2317
2318 g_object_get(channel,
2319 "play", &start_play,
2320 "recall", &start_recall,
2321 NULL);
2322
2323 if(ags_regexec(&single_access_regex, str, index_max_matches, match_arr, 0) == 0){
2324 guint i;
2325 guint i_stop;
2326
2327 path_offset += (type_name_length + 1) + str_length;
2328
2329 i_stop = g_ascii_strtoull(str + 1,
2330 NULL,
2331 10);
2332
2333 play = start_play;
2334 recall = start_recall;
2335
2336 for(i = 0; i <= i_stop; i++){
2337 play = ags_recall_template_find_type(play, recall_type);
2338 recall = ags_recall_template_find_type(recall, recall_type);
2339
2340 if(i + 1 < i_stop){
2341 if(play != NULL){
2342 play = play->next;
2343 }
2344
2345 if(recall != NULL){
2346 recall = recall->next;
2347 }
2348 }
2349 }
2350
2351 if(play != NULL){
2352 AgsRecall *current;
2353
2354 GList *retval;
2355
2356 current = play->data;
2357 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2358 osc_connection,
2359 current,
2360 message, message_size,
2361 type_tag,
2362 path, path_offset);
2363
2364 if(start_response != NULL){
2365 start_response = g_list_concat(start_response,
2366 retval);
2367 }else{
2368 start_response = retval;
2369 }
2370 }
2371
2372 if(recall != NULL){
2373 AgsRecall *current;
2374
2375 GList *retval;
2376
2377 current = recall->data;
2378 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2379 osc_connection,
2380 current,
2381 message, message_size,
2382 type_tag,
2383 path, path_offset);
2384
2385 if(start_response != NULL){
2386 start_response = g_list_concat(start_response,
2387 retval);
2388 }else{
2389 start_response = retval;
2390 }
2391 }
2392 }else if(ags_regexec(&range_access_regex, str, max_matches, match_arr, 0) == 0){
2393 gchar *endptr;
2394
2395 guint i;
2396 guint i_start, i_stop;
2397
2398 path_offset += (type_name_length + 1) + str_length;
2399
2400 endptr = NULL;
2401 i_start = g_ascii_strtoull(str + 1,
2402 &endptr,
2403 10);
2404
2405 i_stop = g_ascii_strtoull(endptr + 1,
2406 NULL,
2407 10);
2408
2409 play = start_play;
2410 recall = start_recall;
2411
2412 for(i = 0; i <= i_stop; i++){
2413 play = ags_recall_template_find_type(play, recall_type);
2414 recall = ags_recall_template_find_type(recall, recall_type);
2415
2416 if(i >= i_start){
2417 if(play != NULL){
2418 AgsRecall *current;
2419
2420 GList *retval;
2421
2422 current = play->data;
2423 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2424 osc_connection,
2425 current,
2426 message, message_size,
2427 type_tag,
2428 path, path_offset);
2429
2430 if(start_response != NULL){
2431 start_response = g_list_concat(start_response,
2432 retval);
2433 }else{
2434 start_response = retval;
2435 }
2436 }
2437
2438 if(recall != NULL){
2439 AgsRecall *current;
2440
2441 GList *retval;
2442
2443 current = recall->data;
2444 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2445 osc_connection,
2446 current,
2447 message, message_size,
2448 type_tag,
2449 path, path_offset);
2450
2451 if(start_response != NULL){
2452 start_response = g_list_concat(start_response,
2453 retval);
2454 }else{
2455 start_response = retval;
2456 }
2457 }
2458 }
2459
2460 if(i + 1 < i_stop){
2461 if(play != NULL){
2462 play = play->next;
2463 }
2464
2465 if(recall != NULL){
2466 recall = recall->next;
2467 }
2468 }
2469 }
2470 }else if(ags_regexec(&voluntary_access_regex, str, index_max_matches, match_arr, 0) == 0){
2471 path_offset += (type_name_length + 1) + str_length;
2472
2473 play = start_play;
2474 recall = start_recall;
2475
2476 play = ags_recall_template_find_type(play, recall_type);
2477 recall = ags_recall_template_find_type(recall, recall_type);
2478
2479 if(play != NULL){
2480 AgsRecall *current;
2481
2482 current = play->data;
2483 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
2484 osc_connection,
2485 current,
2486 message, message_size,
2487 type_tag,
2488 path, path_offset);
2489 }
2490
2491 if(recall != NULL){
2492 AgsRecall *current;
2493
2494 current = recall->data;
2495 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
2496 osc_connection,
2497 current,
2498 message, message_size,
2499 type_tag,
2500 path, path_offset);
2501 }
2502
2503 if(play == NULL && recall == NULL){
2504 osc_response = ags_osc_response_new();
2505 start_response = g_list_prepend(start_response,
2506 osc_response);
2507
2508 ags_osc_response_set_flags(osc_response,
2509 AGS_OSC_RESPONSE_OK);
2510
2511 g_list_free_full(start_play,
2512 g_object_unref);
2513 g_list_free_full(start_recall,
2514 g_object_unref);
2515
2516 return(start_response);
2517 }
2518 }else if(ags_regexec(&more_access_regex, str, index_max_matches, match_arr, 0) == 0){
2519 path_offset += (type_name_length + 1) + str_length;
2520
2521 play = start_play;
2522 recall = start_recall;
2523
2524 play = ags_recall_template_find_type(play, recall_type);
2525 recall = ags_recall_template_find_type(recall, recall_type);
2526
2527 if(play == NULL && recall == NULL){
2528 osc_response = ags_osc_response_new();
2529 start_response = g_list_prepend(start_response,
2530 osc_response);
2531
2532 ags_osc_response_set_flags(osc_response,
2533 AGS_OSC_RESPONSE_ERROR);
2534
2535 g_object_set(osc_response,
2536 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
2537 NULL);
2538
2539 g_list_free_full(start_play,
2540 g_object_unref);
2541 g_list_free_full(start_recall,
2542 g_object_unref);
2543
2544 return(start_response);
2545 }
2546
2547 if(play != NULL){
2548 AgsRecall *current;
2549
2550 current = play->data;
2551 start_response = ags_osc_node_controller_get_data_recall(osc_node_controller,
2552 osc_connection,
2553 current,
2554 message, message_size,
2555 type_tag,
2556 path, path_offset);
2557 }
2558
2559 if(recall != NULL){
2560 AgsRecall *current;
2561
2562 GList *retval;
2563
2564 current = recall->data;
2565 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2566 osc_connection,
2567 current,
2568 message, message_size,
2569 type_tag,
2570 path, path_offset);
2571
2572 if(start_response != NULL){
2573 start_response = g_list_concat(start_response,
2574 retval);
2575 }else{
2576 start_response = retval;
2577 }
2578 }
2579
2580 while(play != NULL || recall != NULL){
2581 play = ags_recall_template_find_type(play, recall_type);
2582 recall = ags_recall_template_find_type(recall, recall_type);
2583
2584 if(play != NULL){
2585 AgsRecall *current;
2586
2587 GList *retval;
2588
2589 current = play->data;
2590 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2591 osc_connection,
2592 current,
2593 message, message_size,
2594 type_tag,
2595 path, path_offset);
2596
2597 start_response = g_list_concat(start_response,
2598 retval);
2599 }
2600
2601 if(recall != NULL){
2602 AgsRecall *current;
2603
2604 GList *retval;
2605
2606 current = recall->data;
2607 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2608 osc_connection,
2609 current,
2610 message, message_size,
2611 type_tag,
2612 path, path_offset);
2613
2614 start_response = g_list_concat(start_response,
2615 retval);
2616 }
2617
2618 if(play != NULL){
2619 play = play->next;
2620 }
2621
2622 if(recall != NULL){
2623 recall = recall->next;
2624 }
2625 }
2626 }else if(ags_regexec(&wildcard_access_regex, str, index_max_matches, match_arr, 0) == 0){
2627 path_offset += (type_name_length + 1) + str_length;
2628
2629 play = start_play;
2630 recall = start_recall;
2631
2632 while(play != NULL || recall != NULL){
2633 play = ags_recall_template_find_type(play, recall_type);
2634 recall = ags_recall_template_find_type(recall, recall_type);
2635
2636 if(play != NULL){
2637 AgsRecall *current;
2638
2639 GList *retval;
2640
2641 current = play->data;
2642 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2643 osc_connection,
2644 current,
2645 message, message_size,
2646 type_tag,
2647 path, path_offset);
2648
2649 if(start_response != NULL){
2650 start_response = g_list_concat(start_response,
2651 retval);
2652 }else{
2653 start_response = retval;
2654 }
2655 }
2656
2657 if(recall != NULL){
2658 AgsRecall *current;
2659
2660 GList *retval;
2661
2662 current = recall->data;
2663 retval = ags_osc_node_controller_get_data_recall(osc_node_controller,
2664 osc_connection,
2665 current,
2666 message, message_size,
2667 type_tag,
2668 path, path_offset);
2669
2670 if(start_response != NULL){
2671 start_response = g_list_concat(start_response,
2672 retval);
2673 }else{
2674 start_response = retval;
2675 }
2676 }
2677
2678 if(play != NULL){
2679 play = play->next;
2680 }
2681
2682 if(recall != NULL){
2683 recall = recall->next;
2684 }
2685 }
2686 }else{
2687 osc_response = ags_osc_response_new();
2688 start_response = g_list_prepend(start_response,
2689 osc_response);
2690
2691 ags_osc_response_set_flags(osc_response,
2692 AGS_OSC_RESPONSE_ERROR);
2693
2694 g_object_set(osc_response,
2695 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_MALFORMED_REQUEST,
2696 NULL);
2697
2698 g_list_free_full(start_play,
2699 g_object_unref);
2700 g_list_free_full(start_recall,
2701 g_object_unref);
2702
2703 return(start_response);
2704 }
2705
2706 g_list_free_full(start_play,
2707 g_object_unref);
2708 g_list_free_full(start_recall,
2709 g_object_unref);
2710 }
2711
2712 return(start_response);
2713 }
2714
2715 gpointer
ags_osc_node_controller_get_data_recall(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,AgsRecall * recall,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)2716 ags_osc_node_controller_get_data_recall(AgsOscNodeController *osc_node_controller,
2717 AgsOscConnection *osc_connection,
2718 AgsRecall *recall,
2719 unsigned char *message, guint message_size,
2720 gchar *type_tag,
2721 gchar *path, guint path_offset)
2722 {
2723 AgsOscResponse *osc_response;
2724
2725 AgsTaskLauncher *task_launcher;
2726
2727 AgsApplicationContext *application_context;
2728
2729 GList *start_response;
2730
2731 unsigned char *packet;
2732
2733 guint path_length;
2734 guint real_packet_size;
2735 guint packet_size;
2736
2737 if(!AGS_IS_RECALL(recall)){
2738 return(NULL);
2739 }
2740
2741 start_response = NULL;
2742
2743 application_context = ags_application_context_get_instance();
2744
2745 task_launcher = ags_concurrency_provider_get_task_launcher(AGS_CONCURRENCY_PROVIDER(application_context));
2746
2747 real_packet_size = 0;
2748 packet_size = 0;
2749
2750 if(!strncmp(path + path_offset,
2751 ":",
2752 1)){
2753 guint length;
2754
2755 osc_response = ags_osc_response_new();
2756 start_response = g_list_prepend(start_response,
2757 osc_response);
2758
2759 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
2760 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
2761
2762 g_object_set(osc_response,
2763 "packet", packet,
2764 "packet-size", packet_size,
2765 NULL);
2766
2767 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
2768
2769 path_length = 4 * (guint) ceil((double) (strlen(path) + 1) / 4.0);
2770 path_offset += 1;
2771
2772 ags_osc_response_set_flags(osc_response,
2773 AGS_OSC_RESPONSE_ERROR);
2774
2775 g_object_set(osc_response,
2776 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
2777 NULL);
2778
2779 g_object_unref(task_launcher);
2780
2781 return(start_response);
2782 }else if(!strncmp(path + path_offset,
2783 "/AgsPort",
2784 8)){
2785 GList *start_port, *port;
2786
2787 regmatch_t match_arr[3];
2788
2789 static regex_t single_access_regex;
2790 static regex_t range_access_regex;
2791 static regex_t voluntary_access_regex;
2792 static regex_t more_access_regex;
2793 static regex_t wildcard_access_regex;
2794
2795 static gboolean regex_compiled = FALSE;
2796
2797 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
2798 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
2799 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
2800 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
2801 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
2802
2803 static const size_t max_matches = 3;
2804 static const size_t index_max_matches = 2;
2805
2806 path_offset += 8;
2807
2808 /* compile regex */
2809 g_mutex_lock(®ex_mutex);
2810
2811 if(!regex_compiled){
2812 regex_compiled = TRUE;
2813
2814 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
2815 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
2816 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
2817 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
2818 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
2819 }
2820
2821 g_mutex_unlock(®ex_mutex);
2822
2823 g_object_get(recall,
2824 "port", &start_port,
2825 NULL);
2826
2827 port = start_port;
2828
2829 if(ags_regexec(&single_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
2830 AgsPort *current;
2831
2832 gchar *endptr;
2833
2834 guint i_stop;
2835
2836 endptr = NULL;
2837 i_stop = g_ascii_strtoull(path + path_offset + 1,
2838 &endptr,
2839 10);
2840
2841 current = g_list_nth_data(start_port,
2842 i_stop);
2843
2844 path_offset += ((endptr + 1) - (path + path_offset));
2845
2846 start_response = ags_osc_node_controller_get_data_port(osc_node_controller,
2847 osc_connection,
2848 recall,
2849 current,
2850 message, message_size,
2851 type_tag,
2852 path, path_offset);
2853 }else if(ags_regexec(&range_access_regex, path + path_offset, max_matches, match_arr, 0) == 0){
2854 gchar *endptr;
2855
2856 guint i;
2857 guint i_start, i_stop;
2858
2859 endptr = NULL;
2860 i_start = g_ascii_strtoull(path + path_offset + 1,
2861 &endptr,
2862 10);
2863
2864 i_stop = g_ascii_strtoull(endptr + 1,
2865 &endptr,
2866 10);
2867
2868 path_offset += ((endptr + 1) - (path + path_offset));
2869
2870 port = g_list_nth(start_port,
2871 i_start);
2872
2873 for(i = i_start; i <= i_stop; i++){
2874 GList *retval;
2875
2876 retval = ags_osc_node_controller_get_data_port(osc_node_controller,
2877 osc_connection,
2878 recall,
2879 port->data,
2880 message, message_size,
2881 type_tag,
2882 path, path_offset);
2883
2884 if(start_response != NULL){
2885 start_response = g_list_concat(start_response,
2886 retval);
2887 }else{
2888 start_response = retval;
2889 }
2890
2891 port = port->next;
2892 }
2893 }else if(ags_regexec(&voluntary_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
2894 path_offset += 3;
2895
2896 if(start_port != NULL){
2897 GList *retval;
2898
2899 retval = ags_osc_node_controller_get_data_port(osc_node_controller,
2900 osc_connection,
2901 recall,
2902 start_port->data,
2903 message, message_size,
2904 type_tag,
2905 path, path_offset);
2906 }else{
2907 osc_response = ags_osc_response_new();
2908 start_response = g_list_prepend(start_response,
2909 osc_response);
2910
2911 ags_osc_response_set_flags(osc_response,
2912 AGS_OSC_RESPONSE_OK);
2913
2914 g_object_unref(task_launcher);
2915
2916 return(start_response);
2917 }
2918 }else if(ags_regexec(&more_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
2919 path_offset += 3;
2920
2921 if(start_port == NULL){
2922 osc_response = ags_osc_response_new();
2923 start_response = g_list_prepend(start_response,
2924 osc_response);
2925
2926 ags_osc_response_set_flags(osc_response,
2927 AGS_OSC_RESPONSE_ERROR);
2928
2929 g_object_set(osc_response,
2930 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
2931 NULL);
2932
2933 g_object_unref(task_launcher);
2934
2935 return(start_response);
2936 }
2937
2938 port = start_port;
2939
2940 while(port != NULL){
2941 GList *retval;
2942
2943 retval = ags_osc_node_controller_get_data_port(osc_node_controller,
2944 osc_connection,
2945 recall,
2946 port->data,
2947 message, message_size,
2948 type_tag,
2949 path, path_offset);
2950
2951 if(start_response != NULL){
2952 start_response = g_list_concat(start_response,
2953 retval);
2954 }else{
2955 start_response = retval;
2956 }
2957
2958 port = port->next;
2959 }
2960 }else if(ags_regexec(&wildcard_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
2961 path_offset += 3;
2962
2963 if(start_port == NULL){
2964 osc_response = ags_osc_response_new();
2965 start_response = g_list_prepend(start_response,
2966 osc_response);
2967
2968 ags_osc_response_set_flags(osc_response,
2969 AGS_OSC_RESPONSE_OK);
2970
2971 g_object_unref(task_launcher);
2972
2973 return(start_response);
2974 }
2975
2976 while(port != NULL){
2977 GList *retval;
2978
2979 retval = ags_osc_node_controller_get_data_port(osc_node_controller,
2980 osc_connection,
2981 recall,
2982 port->data,
2983 message, message_size,
2984 type_tag,
2985 path, path_offset);
2986
2987 if(start_response != NULL){
2988 start_response = g_list_concat(start_response,
2989 retval);
2990 }else{
2991 start_response = retval;
2992 }
2993
2994 port = port->next;
2995 }
2996 }else if(path[path_offset] == '[' &&
2997 path[path_offset + 1] == '"'){
2998 AgsPort *current;
2999
3000 gchar *port_specifier;
3001 gchar *offset;
3002
3003 guint length;
3004
3005 if((offset = strchr(path + path_offset + 2, '"')) == NULL){
3006 osc_response = ags_osc_response_new();
3007 start_response = g_list_prepend(start_response,
3008 osc_response);
3009
3010 ags_osc_response_set_flags(osc_response,
3011 AGS_OSC_RESPONSE_ERROR);
3012
3013 g_object_set(osc_response,
3014 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3015 NULL);
3016
3017 g_list_free_full(start_port,
3018 g_object_unref);
3019
3020 g_object_unref(task_launcher);
3021
3022 return(start_response);
3023 }
3024
3025 length = offset - (path + path_offset + 2);
3026
3027 port_specifier = (gchar *) malloc((length + 1) * sizeof(gchar));
3028 memcpy(port_specifier, path + path_offset + 2, (length) * sizeof(gchar));
3029 port_specifier[length] = '\0';
3030
3031 current = NULL;
3032 port = ags_port_find_specifier(start_port,
3033 port_specifier);
3034
3035 if(port != NULL){
3036 current = port->data;
3037 }
3038
3039 path_offset += (length + 4);
3040 start_response = ags_osc_node_controller_get_data_port(osc_node_controller,
3041 osc_connection,
3042 recall,
3043 current,
3044 message, message_size,
3045 type_tag,
3046 path, path_offset);
3047 }else{
3048 osc_response = ags_osc_response_new();
3049 start_response = g_list_prepend(start_response,
3050 osc_response);
3051
3052 ags_osc_response_set_flags(osc_response,
3053 AGS_OSC_RESPONSE_ERROR);
3054
3055 g_object_set(osc_response,
3056 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
3057 NULL);
3058
3059 g_list_free_full(start_port,
3060 g_object_unref);
3061
3062 g_object_unref(task_launcher);
3063
3064 return(start_response);
3065 }
3066
3067 g_list_free_full(start_port,
3068 g_object_unref);
3069 }else{
3070 osc_response = ags_osc_response_new();
3071 start_response = g_list_prepend(start_response,
3072 osc_response);
3073
3074 ags_osc_response_set_flags(osc_response,
3075 AGS_OSC_RESPONSE_ERROR);
3076
3077 g_object_set(osc_response,
3078 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
3079 NULL);
3080
3081 g_object_unref(task_launcher);
3082
3083 return(start_response);
3084 }
3085
3086 g_object_unref(task_launcher);
3087
3088 return(start_response);
3089 }
3090
3091 gpointer
ags_osc_node_controller_get_data_port(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,AgsRecall * parent,AgsPort * port,unsigned char * message,guint message_size,gchar * type_tag,gchar * path,guint path_offset)3092 ags_osc_node_controller_get_data_port(AgsOscNodeController *osc_node_controller,
3093 AgsOscConnection *osc_connection,
3094 AgsRecall *parent,
3095 AgsPort *port,
3096 unsigned char *message, guint message_size,
3097 gchar *type_tag,
3098 gchar *path, guint path_offset)
3099 {
3100 AgsAudio *audio;
3101 AgsChannel *channel;
3102
3103 AgsOscResponse *osc_response;
3104
3105 AgsApplicationContext *application_context;
3106
3107 GList *start_response;
3108 GList *start_list;
3109
3110 unsigned char *packet;
3111 gchar *current_path;
3112 gchar *specifier;
3113
3114 guint real_packet_size;
3115 guint packet_size;
3116 gint nth_audio;
3117 gint nth_channel;
3118
3119 if(!AGS_IS_PORT(port)){
3120 return(NULL);
3121 }
3122
3123 start_response = NULL;
3124
3125 application_context = ags_application_context_get_instance();
3126
3127 real_packet_size = 0;
3128 packet_size = 0;
3129
3130 if(!strncmp(path + path_offset,
3131 ":",
3132 1)){
3133 guint length;
3134
3135 audio = NULL;
3136 channel = NULL;
3137
3138 if(AGS_IS_RECALL_CHANNEL(parent)){
3139 g_object_get(parent,
3140 "source", &channel,
3141 NULL);
3142
3143 g_object_get(channel,
3144 "audio", &audio,
3145 "line", &nth_channel,
3146 NULL);
3147
3148 g_object_unref(channel);
3149
3150 g_object_unref(audio);
3151 }else if(AGS_IS_RECALL_AUDIO(parent)){
3152 g_object_get(parent,
3153 "audio", &audio,
3154 NULL);
3155
3156 g_object_unref(audio);
3157 }
3158
3159 /* get nth audio */
3160 start_list = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
3161
3162 nth_audio = g_list_index(start_list,
3163 audio);
3164
3165 g_list_free_full(start_list,
3166 g_object_unref);
3167
3168 osc_response = ags_osc_response_new();
3169 start_response = g_list_prepend(start_response,
3170 osc_response);
3171
3172 packet = (unsigned char *) malloc(AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
3173 memset(packet, 0, AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE * sizeof(unsigned char));
3174
3175 g_object_set(osc_response,
3176 "packet", packet,
3177 "packet-size", packet_size,
3178 NULL);
3179
3180 real_packet_size = AGS_OSC_RESPONSE_DEFAULT_CHUNK_SIZE;
3181
3182 path_offset += 1;
3183
3184 if(!strncmp(path + path_offset,
3185 "value",
3186 6)){
3187 GType port_value_type;
3188
3189 guint port_value_length;
3190 gboolean port_value_is_pointer;
3191
3192 GRecMutex *port_mutex;
3193
3194 /* get port mutex */
3195 port_mutex = AGS_PORT_GET_OBJ_MUTEX(port);
3196
3197 /* create current path */
3198 g_rec_mutex_lock(port_mutex);
3199
3200 specifier = g_strdup(port->specifier);
3201
3202 g_rec_mutex_unlock(port_mutex);
3203
3204 if(channel != NULL){
3205 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]/%s[%d]/%s/AgsPort[%s]:value",
3206 nth_audio,
3207 ((AGS_IS_OUTPUT(channel)) ? "AgsOutput": "AgsInput"),
3208 nth_channel,
3209 G_OBJECT_TYPE_NAME(parent),
3210 specifier);
3211 }else{
3212 current_path = g_strdup_printf("/AgsSoundProvider/AgsAudio[%d]/%s/AgsPort[%s]:value",
3213 nth_audio,
3214 G_OBJECT_TYPE_NAME(parent),
3215 specifier);
3216 }
3217
3218 g_free(specifier);
3219
3220 /* message path */
3221 packet_size = 4;
3222
3223 ags_osc_buffer_util_put_string(packet + packet_size,
3224 "/node", -1);
3225
3226 packet_size += 8;
3227
3228 /* check array type */
3229 g_object_get(port,
3230 "port-value-is-pointer", &port_value_is_pointer,
3231 "port-value-type", &port_value_type,
3232 "port-value-length", &port_value_length,
3233 NULL);
3234
3235 if(port_value_is_pointer){
3236 gchar *type_tag;
3237
3238 guint i;
3239
3240 /* message type tag */
3241 if(packet_size + (4 * (guint) ceil((double) (port_value_length + 5) / 4.0)) > real_packet_size){
3242 ags_osc_response_set_flags(osc_response,
3243 AGS_OSC_RESPONSE_ERROR);
3244
3245 g_object_set(osc_response,
3246 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3247 NULL);
3248
3249 return(start_response);
3250 }
3251
3252 type_tag = packet + packet_size; // (gchar *) malloc((port_value_length + 5) * sizeof(gchar));
3253
3254 type_tag[0] = ',';
3255 type_tag[1] = 's';
3256 type_tag[2] = '[';
3257 type_tag[port_value_length + 4] = ']';
3258
3259 if(port_value_type == G_TYPE_BOOLEAN){
3260 g_rec_mutex_lock(port_mutex);
3261
3262 for(i = 0; i < port_value_length; i++){
3263 gboolean is_active;
3264
3265 is_active = port->port_value.ags_port_boolean_ptr[i];
3266
3267 if(is_active){
3268 packet[packet_size + 3 + i] = 'T';
3269 }else{
3270 packet[packet_size + 3 + i] = 'F';
3271 }
3272 }
3273
3274 g_rec_mutex_unlock(port_mutex);
3275
3276 /* node path */
3277 packet_size += (4 * (guint) ceil((double) (port_value_length + 5) / 4.0));
3278
3279 length = strlen(current_path);
3280
3281 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3282 ags_osc_response_set_flags(osc_response,
3283 AGS_OSC_RESPONSE_ERROR);
3284
3285 g_object_set(osc_response,
3286 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3287 NULL);
3288
3289 return(start_response);
3290 }
3291
3292 ags_osc_buffer_util_put_string(packet + packet_size,
3293 current_path, -1);
3294
3295 /* node argument */
3296 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3297
3298 /* packet size */
3299 ags_osc_buffer_util_put_int32(packet,
3300 packet_size);
3301 }else if(port_value_type == G_TYPE_INT64){
3302 for(i = 0; i < port_value_length; i++){
3303 packet[packet_size + 3 + i] = 'h';
3304 }
3305
3306 /* node path */
3307 packet_size += (4 * (guint) ceil((double) (port_value_length + 5) / 4.0));
3308
3309 length = strlen(current_path);
3310
3311 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3312 ags_osc_response_set_flags(osc_response,
3313 AGS_OSC_RESPONSE_ERROR);
3314
3315 g_object_set(osc_response,
3316 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3317 NULL);
3318
3319 return(start_response);
3320 }
3321
3322 ags_osc_buffer_util_put_string(packet + packet_size,
3323 current_path, -1);
3324
3325 /* node argument */
3326 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3327
3328 if(packet_size + (4 * (guint) ceil((double) (port_value_length * 8) / 4.0)) > real_packet_size){
3329 ags_osc_response_set_flags(osc_response,
3330 AGS_OSC_RESPONSE_ERROR);
3331
3332 g_object_set(osc_response,
3333 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3334 NULL);
3335
3336 return(start_response);
3337 }
3338
3339 g_rec_mutex_lock(port_mutex);
3340
3341 for(i = 0; i < port_value_length; i++){
3342 gint64 value;
3343
3344 value = port->port_value.ags_port_int_ptr[i];
3345
3346 ags_osc_buffer_util_put_int64(packet + packet_size + 3 + (i * 8),
3347 value);
3348 }
3349
3350 g_rec_mutex_unlock(port_mutex);
3351
3352 /* packet size */
3353 ags_osc_buffer_util_put_int32(packet,
3354 packet_size);
3355 }else if(port_value_type == G_TYPE_UINT64){
3356 for(i = 0; i < port_value_length; i++){
3357 packet[packet_size + 3 + i] = 'h';
3358 }
3359
3360 /* node path */
3361 packet_size += (4 * (guint) ceil((double) (port_value_length + 5) / 4.0));
3362
3363 length = strlen(current_path);
3364
3365 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3366 ags_osc_response_set_flags(osc_response,
3367 AGS_OSC_RESPONSE_ERROR);
3368
3369 g_object_set(osc_response,
3370 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3371 NULL);
3372
3373 return(start_response);
3374 }
3375
3376 ags_osc_buffer_util_put_string(packet + packet_size,
3377 current_path, -1);
3378
3379 /* node argument */
3380 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3381
3382 if(packet_size + (4 * (guint) ceil((double) (port_value_length * 8) / 4.0)) > real_packet_size){
3383 ags_osc_response_set_flags(osc_response,
3384 AGS_OSC_RESPONSE_ERROR);
3385
3386 g_object_set(osc_response,
3387 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3388 NULL);
3389
3390 return(start_response);
3391 }
3392
3393 g_rec_mutex_lock(port_mutex);
3394
3395 for(i = 0; i < port_value_length; i++){
3396 guint64 value;
3397
3398 value = port->port_value.ags_port_uint_ptr[i];
3399
3400 //FIXME:JK: unsafe sign
3401 ags_osc_buffer_util_put_int64(packet + packet_size + 3 + (i * 8),
3402 value);
3403 }
3404
3405 g_rec_mutex_unlock(port_mutex);
3406
3407 /* packet size */
3408 ags_osc_buffer_util_put_int32(packet,
3409 packet_size);
3410 }else if(port_value_type == G_TYPE_FLOAT){
3411 for(i = 0; i < port_value_length; i++){
3412 packet[packet_size + 3 + i] = 'f';
3413 }
3414
3415 /* node path */
3416 packet_size += (4 * (guint) ceil((double) (port_value_length + 5) / 4.0));
3417
3418 length = strlen(current_path);
3419
3420 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3421 ags_osc_response_set_flags(osc_response,
3422 AGS_OSC_RESPONSE_ERROR);
3423
3424 g_object_set(osc_response,
3425 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3426 NULL);
3427
3428 return(start_response);
3429 }
3430
3431 ags_osc_buffer_util_put_string(packet + packet_size,
3432 current_path, -1);
3433
3434 /* node argument */
3435 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3436
3437 if(packet_size + (4 * (guint) ceil((double) (port_value_length * 4) / 4.0)) > real_packet_size){
3438 ags_osc_response_set_flags(osc_response,
3439 AGS_OSC_RESPONSE_ERROR);
3440
3441 g_object_set(osc_response,
3442 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3443 NULL);
3444
3445 return(start_response);
3446 }
3447
3448 g_rec_mutex_lock(port_mutex);
3449
3450 for(i = 0; i < port_value_length; i++){
3451 gfloat value;
3452
3453 value = port->port_value.ags_port_float_ptr[i];
3454
3455 ags_osc_buffer_util_put_float(packet + packet_size + 3 + (i * 4),
3456 value);
3457 }
3458
3459 g_rec_mutex_unlock(port_mutex);
3460
3461 /* packet size */
3462 ags_osc_buffer_util_put_int32(packet,
3463 packet_size);
3464 }else if(port_value_type == G_TYPE_DOUBLE){
3465 for(i = 0; i < port_value_length; i++){
3466 packet[packet_size + 3 + i] = 'd';
3467 }
3468
3469 /* node path */
3470 packet_size += (4 * (guint) ceil((double) (port_value_length + 5) / 4.0));
3471
3472 length = strlen(current_path);
3473
3474 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3475 ags_osc_response_set_flags(osc_response,
3476 AGS_OSC_RESPONSE_ERROR);
3477
3478 g_object_set(osc_response,
3479 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3480 NULL);
3481
3482 return(start_response);
3483 }
3484
3485 ags_osc_buffer_util_put_string(packet + packet_size,
3486 current_path, -1);
3487
3488 /* node argument */
3489 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3490
3491 if(packet_size + (4 * (guint) ceil((double) (port_value_length * 8) / 4.0)) > real_packet_size){
3492 ags_osc_response_set_flags(osc_response,
3493 AGS_OSC_RESPONSE_ERROR);
3494
3495 g_object_set(osc_response,
3496 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3497 NULL);
3498
3499 return(start_response);
3500 }
3501
3502 g_rec_mutex_lock(port_mutex);
3503
3504 for(i = 0; i < port_value_length; i++){
3505 gdouble value;
3506
3507 value = port->port_value.ags_port_double_ptr[i];
3508
3509 ags_osc_buffer_util_put_double(packet + packet_size + 3 + (i * 8),
3510 value);
3511 }
3512
3513 g_rec_mutex_unlock(port_mutex);
3514
3515 /* packet size */
3516 ags_osc_buffer_util_put_int32(packet,
3517 packet_size);
3518 }
3519 }else{
3520 if(port_value_type == G_TYPE_BOOLEAN){
3521 gboolean is_active;
3522
3523 /* message type tag */
3524 g_rec_mutex_lock(port_mutex);
3525
3526 is_active = port->port_value.ags_port_boolean;
3527
3528 g_rec_mutex_unlock(port_mutex);
3529
3530 if(is_active){
3531 ags_osc_buffer_util_put_string(packet + packet_size,
3532 ",sT", -1);
3533 }else{
3534 ags_osc_buffer_util_put_string(packet + packet_size,
3535 ",sF", -1);
3536 }
3537
3538 /* node path */
3539 packet_size += 4;
3540
3541 length = strlen(current_path);
3542
3543 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) > real_packet_size){
3544 ags_osc_response_set_flags(osc_response,
3545 AGS_OSC_RESPONSE_ERROR);
3546
3547 g_object_set(osc_response,
3548 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3549 NULL);
3550
3551 return(start_response);
3552 }
3553
3554 ags_osc_buffer_util_put_string(packet + packet_size,
3555 current_path, -1);
3556
3557 /* node argument */
3558 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3559
3560 /* packet size */
3561 ags_osc_buffer_util_put_int32(packet,
3562 packet_size);
3563 }else if(port_value_type == G_TYPE_INT64){
3564 gint64 value;
3565
3566 /* message type tag */
3567 g_rec_mutex_lock(port_mutex);
3568
3569 value = port->port_value.ags_port_int;
3570
3571 g_rec_mutex_unlock(port_mutex);
3572
3573 ags_osc_buffer_util_put_string(packet + packet_size,
3574 ",sh", -1);
3575
3576 /* node path */
3577 packet_size += 4;
3578
3579 length = strlen(current_path);
3580
3581 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 8 > real_packet_size){
3582 ags_osc_response_set_flags(osc_response,
3583 AGS_OSC_RESPONSE_ERROR);
3584
3585 g_object_set(osc_response,
3586 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3587 NULL);
3588
3589 return(start_response);
3590 }
3591
3592 ags_osc_buffer_util_put_string(packet + packet_size,
3593 current_path, -1);
3594
3595 /* node argument */
3596 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3597
3598 ags_osc_buffer_util_put_int64(packet + packet_size,
3599 value);
3600
3601 packet_size += 8;
3602
3603 /* packet size */
3604 ags_osc_buffer_util_put_int32(packet,
3605 packet_size);
3606 }else if(port_value_type == G_TYPE_UINT64){
3607 guint64 value;
3608
3609 /* message type tag */
3610 g_rec_mutex_lock(port_mutex);
3611
3612 value = port->port_value.ags_port_uint;
3613
3614 g_rec_mutex_unlock(port_mutex);
3615
3616 ags_osc_buffer_util_put_string(packet + packet_size,
3617 ",sh", -1);
3618
3619 /* node path */
3620 packet_size += 4;
3621
3622 length = strlen(current_path);
3623
3624 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 8 > real_packet_size){
3625 ags_osc_response_set_flags(osc_response,
3626 AGS_OSC_RESPONSE_ERROR);
3627
3628 g_object_set(osc_response,
3629 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3630 NULL);
3631
3632 return(start_response);
3633 }
3634
3635 ags_osc_buffer_util_put_string(packet + packet_size,
3636 current_path, -1);
3637
3638 /* node argument */
3639 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3640
3641 //FIXME:JK: unsafe sign
3642 ags_osc_buffer_util_put_int64(packet + packet_size,
3643 value);
3644
3645 packet_size += 8;
3646
3647 /* packet size */
3648 ags_osc_buffer_util_put_int32(packet,
3649 packet_size);
3650 }else if(port_value_type == G_TYPE_FLOAT){
3651 gfloat value;
3652
3653 /* message type tag */
3654 g_rec_mutex_lock(port_mutex);
3655
3656 value = port->port_value.ags_port_float;
3657
3658 g_rec_mutex_unlock(port_mutex);
3659
3660 ags_osc_buffer_util_put_string(packet + packet_size,
3661 ",sf", -1);
3662
3663 /* node path */
3664 packet_size += 4;
3665
3666 length = strlen(current_path);
3667
3668 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 8 > real_packet_size){
3669 ags_osc_response_set_flags(osc_response,
3670 AGS_OSC_RESPONSE_ERROR);
3671
3672 g_object_set(osc_response,
3673 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3674 NULL);
3675
3676 return(start_response);
3677 }
3678
3679 ags_osc_buffer_util_put_string(packet + packet_size,
3680 current_path, -1);
3681
3682 /* node argument */
3683 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3684
3685 ags_osc_buffer_util_put_float(packet + packet_size,
3686 value);
3687
3688 packet_size += 4;
3689
3690 /* packet size */
3691 ags_osc_buffer_util_put_int32(packet,
3692 packet_size);
3693 }else if(port_value_type == G_TYPE_DOUBLE){
3694 gdouble value;
3695
3696 /* message type tag */
3697 g_rec_mutex_lock(port_mutex);
3698
3699 value = port->port_value.ags_port_double;
3700
3701 g_rec_mutex_unlock(port_mutex);
3702
3703 ags_osc_buffer_util_put_string(packet + packet_size,
3704 ",sd", -1);
3705
3706 /* node path */
3707 packet_size += 4;
3708
3709 length = strlen(current_path);
3710
3711 if(packet_size + (4 * (guint) ceil((double) (length + 1) / 4.0)) + 8 > real_packet_size){
3712 ags_osc_response_set_flags(osc_response,
3713 AGS_OSC_RESPONSE_ERROR);
3714
3715 g_object_set(osc_response,
3716 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
3717 NULL);
3718
3719 return(start_response);
3720 }
3721
3722 ags_osc_buffer_util_put_string(packet + packet_size,
3723 current_path, -1);
3724
3725 /* node argument */
3726 packet_size += (4 * (guint) ceil((double) (length + 1) / 4.0));
3727
3728 ags_osc_buffer_util_put_double(packet + packet_size,
3729 value);
3730
3731 packet_size += 8;
3732
3733 /* packet size */
3734 ags_osc_buffer_util_put_int32(packet,
3735 packet_size);
3736 }
3737 }
3738
3739 g_object_set(osc_response,
3740 "packet-size", packet_size,
3741 NULL);
3742 }
3743 }
3744
3745 return(start_response);
3746 }
3747
3748 gpointer
ags_osc_node_controller_real_get_data(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,unsigned char * message,guint message_size)3749 ags_osc_node_controller_real_get_data(AgsOscNodeController *osc_node_controller,
3750 AgsOscConnection *osc_connection,
3751 unsigned char *message, guint message_size)
3752 {
3753 AgsOscResponse *osc_response;
3754
3755 AgsApplicationContext *application_context;
3756
3757 GList *start_response;
3758
3759 gchar *type_tag;
3760 gchar *path;
3761
3762 guint path_offset;
3763 gboolean success;
3764
3765 start_response = NULL;
3766
3767 /* read type tag */
3768 ags_osc_buffer_util_get_string(message + 8,
3769 &type_tag, NULL);
3770
3771 success = (type_tag != NULL &&
3772 !strncmp(type_tag, ",s", 2)) ? TRUE: FALSE;
3773
3774 if(!success){
3775 osc_response = ags_osc_response_new();
3776 start_response = g_list_prepend(start_response,
3777 osc_response);
3778
3779 ags_osc_response_set_flags(osc_response,
3780 AGS_OSC_RESPONSE_ERROR);
3781
3782 g_object_set(osc_response,
3783 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_MALFORMED_REQUEST,
3784 NULL);
3785
3786 if(type_tag != NULL){
3787 free(type_tag);
3788 }
3789
3790 return(start_response);
3791 }
3792
3793 /* read argument */
3794 ags_osc_buffer_util_get_string(message + 8 + (4 * (guint) ceil((gdouble) (strlen(type_tag) + 1) / 4.0)),
3795 &path, NULL);
3796
3797 if(path == NULL){
3798 osc_response = ags_osc_response_new();
3799 start_response = g_list_prepend(start_response,
3800 osc_response);
3801
3802 ags_osc_response_set_flags(osc_response,
3803 AGS_OSC_RESPONSE_ERROR);
3804
3805 g_object_set(osc_response,
3806 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_MALFORMED_REQUEST,
3807 NULL);
3808
3809 free(type_tag);
3810
3811 return(start_response);
3812 }
3813
3814 /* create packet */
3815 application_context = ags_application_context_get_instance();
3816
3817 path_offset = 0;
3818
3819 if(!strncmp(path,
3820 "/AgsSoundProvider",
3821 17)){
3822 path_offset = 17;
3823
3824 if(!strncmp(path + path_offset,
3825 "/AgsSoundcard",
3826 13)){
3827 GList *start_soundcard, *soundcard;
3828
3829 regmatch_t match_arr[2];
3830
3831 static regex_t single_access_regex;
3832 static regex_t range_access_regex;
3833 static regex_t voluntary_access_regex;
3834 static regex_t more_access_regex;
3835 static regex_t wildcard_access_regex;
3836
3837 static gboolean regex_compiled = FALSE;
3838
3839 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
3840 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
3841 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
3842 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
3843 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
3844
3845 static const size_t max_matches = 2;
3846 static const size_t index_max_matches = 1;
3847
3848 path_offset += 13;
3849
3850 /* compile regex */
3851 g_mutex_lock(®ex_mutex);
3852
3853 if(!regex_compiled){
3854 regex_compiled = TRUE;
3855
3856 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
3857 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
3858 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
3859 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
3860 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
3861 }
3862
3863 g_mutex_unlock(®ex_mutex);
3864
3865 soundcard =
3866 start_soundcard = ags_sound_provider_get_soundcard(AGS_SOUND_PROVIDER(application_context));
3867
3868 if(ags_regexec(&single_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
3869 GObject *current;
3870
3871 gchar *endptr;
3872
3873 guint i_stop;
3874
3875 endptr = NULL;
3876 i_stop = g_ascii_strtoull(path + path_offset + 1,
3877 &endptr,
3878 10);
3879
3880 current = g_list_nth_data(start_soundcard,
3881 i_stop);
3882
3883 path_offset += ((endptr + 1) - (path + path_offset));
3884
3885 start_response = ags_osc_node_controller_get_data_soundcard(osc_node_controller,
3886 osc_connection,
3887 current,
3888 message, message_size,
3889 type_tag,
3890 path, path_offset);
3891 }else if(ags_regexec(&range_access_regex, path + path_offset, max_matches, match_arr, 0) == 0){
3892 gchar *endptr;
3893
3894 guint i;
3895 guint i_start, i_stop;
3896
3897 endptr = NULL;
3898 i_start = g_ascii_strtoull(path + path_offset + 1,
3899 &endptr,
3900 10);
3901
3902 i_stop = g_ascii_strtoull(endptr + 1,
3903 &endptr,
3904 10);
3905
3906 path_offset += ((endptr + 1) - (path + path_offset));
3907
3908 soundcard = g_list_nth(start_soundcard,
3909 i_start);
3910
3911 for(i = i_start; i <= i_stop; i++){
3912 GList *retval;
3913
3914 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
3915 osc_connection,
3916 soundcard->data,
3917 message, message_size,
3918 type_tag,
3919 path, path_offset);
3920
3921 if(start_response != NULL){
3922 start_response = g_list_concat(start_response,
3923 retval);
3924 }else{
3925 start_response = retval;
3926 }
3927
3928 soundcard = soundcard->next;
3929 }
3930 }else if(ags_regexec(&voluntary_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
3931 path_offset += 3;
3932
3933 if(start_soundcard != NULL){
3934 GList *retval;
3935
3936 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
3937 osc_connection,
3938 start_soundcard->data,
3939 message, message_size,
3940 type_tag,
3941 path, path_offset);
3942 }else{
3943 osc_response = ags_osc_response_new();
3944 start_response = g_list_prepend(start_response,
3945 osc_response);
3946
3947 ags_osc_response_set_flags(osc_response,
3948 AGS_OSC_RESPONSE_OK);
3949
3950 free(type_tag);
3951 free(path);
3952
3953 return(start_response);
3954 }
3955 }else if(ags_regexec(&more_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
3956 path_offset += 3;
3957
3958 if(start_soundcard == NULL){
3959 osc_response = ags_osc_response_new();
3960 start_response = g_list_prepend(start_response,
3961 osc_response);
3962
3963 ags_osc_response_set_flags(osc_response,
3964 AGS_OSC_RESPONSE_ERROR);
3965
3966 g_object_set(osc_response,
3967 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
3968 NULL);
3969
3970 g_list_free_full(start_soundcard,
3971 g_object_unref);
3972
3973 free(type_tag);
3974 free(path);
3975
3976 return(start_response);
3977 }
3978
3979 soundcard = start_soundcard;
3980
3981 while(soundcard != NULL){
3982 GList *retval;
3983
3984 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
3985 osc_connection,
3986 soundcard->data,
3987 message, message_size,
3988 type_tag,
3989 path, path_offset);
3990
3991 if(start_response != NULL){
3992 start_response = g_list_concat(start_response,
3993 retval);
3994 }else{
3995 start_response = retval;
3996 }
3997
3998 soundcard = soundcard->next;
3999 }
4000 }else if(ags_regexec(&wildcard_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4001 path_offset += 3;
4002
4003 if(start_soundcard == NULL){
4004 osc_response = ags_osc_response_new();
4005 start_response = g_list_prepend(start_response,
4006 osc_response);
4007
4008 ags_osc_response_set_flags(osc_response,
4009 AGS_OSC_RESPONSE_OK);
4010
4011 free(type_tag);
4012 free(path);
4013
4014 return(start_response);
4015 }
4016
4017 while(soundcard != NULL){
4018 GList *retval;
4019
4020 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
4021 osc_connection,
4022 soundcard->data,
4023 message, message_size,
4024 type_tag,
4025 path, path_offset);
4026
4027 if(start_response != NULL){
4028 start_response = g_list_concat(start_response,
4029 retval);
4030 }else{
4031 start_response = retval;
4032 }
4033
4034 soundcard = soundcard->next;
4035 }
4036 }else{
4037 osc_response = ags_osc_response_new();
4038 start_response = g_list_prepend(start_response,
4039 osc_response);
4040
4041 ags_osc_response_set_flags(osc_response,
4042 AGS_OSC_RESPONSE_ERROR);
4043
4044 g_object_set(osc_response,
4045 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4046 NULL);
4047
4048 g_list_free_full(start_soundcard,
4049 g_object_unref);
4050
4051 free(type_tag);
4052 free(path);
4053
4054 return(start_response);
4055 }
4056
4057 g_list_free_full(start_soundcard,
4058 g_object_unref);
4059 }else if(!strncmp(path + path_offset,
4060 "/AgsSequencer",
4061 13)){
4062 GList *start_sequencer, *sequencer;
4063
4064 regmatch_t match_arr[2];
4065
4066 static regex_t single_access_regex;
4067 static regex_t range_access_regex;
4068 static regex_t voluntary_access_regex;
4069 static regex_t more_access_regex;
4070 static regex_t wildcard_access_regex;
4071
4072 static gboolean regex_compiled = FALSE;
4073
4074 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
4075 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
4076 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
4077 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
4078 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
4079
4080 static const size_t max_matches = 2;
4081 static const size_t index_max_matches = 1;
4082
4083 path_offset += 13;
4084
4085 /* compile regex */
4086 g_mutex_lock(®ex_mutex);
4087
4088 if(!regex_compiled){
4089 regex_compiled = TRUE;
4090
4091 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
4092 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
4093 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
4094 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
4095 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
4096 }
4097
4098 g_mutex_unlock(®ex_mutex);
4099
4100 sequencer =
4101 start_sequencer = ags_sound_provider_get_sequencer(AGS_SOUND_PROVIDER(application_context));
4102
4103 if(ags_regexec(&single_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4104 GObject *current;
4105
4106 gchar *endptr;
4107
4108 guint i_stop;
4109
4110 endptr = NULL;
4111 i_stop = g_ascii_strtoull(path + path_offset + 1,
4112 &endptr,
4113 10);
4114
4115 current = g_list_nth_data(start_sequencer,
4116 i_stop);
4117
4118 path_offset += ((endptr + 1) - (path + path_offset));
4119
4120 start_response = ags_osc_node_controller_get_data_sequencer(osc_node_controller,
4121 osc_connection,
4122 current,
4123 message, message_size,
4124 type_tag,
4125 path, path_offset);
4126 }else if(ags_regexec(&range_access_regex, path + path_offset, max_matches, match_arr, 0) == 0){
4127 gchar *endptr;
4128
4129 guint i;
4130 guint i_start, i_stop;
4131
4132 endptr = NULL;
4133 i_start = g_ascii_strtoull(path + path_offset + 1,
4134 &endptr,
4135 10);
4136
4137 i_stop = g_ascii_strtoull(endptr + 1,
4138 &endptr,
4139 10);
4140
4141 path_offset += ((endptr + 1) - (path + path_offset));
4142
4143 sequencer = g_list_nth(start_sequencer,
4144 i_start);
4145
4146 for(i = i_start; i <= i_stop; i++){
4147 GList *retval;
4148
4149 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
4150 osc_connection,
4151 sequencer->data,
4152 message, message_size,
4153 type_tag,
4154 path, path_offset);
4155
4156 if(start_response != NULL){
4157 start_response = g_list_concat(start_response,
4158 retval);
4159 }else{
4160 start_response = retval;
4161 }
4162
4163 sequencer = sequencer->next;
4164 }
4165 }else if(ags_regexec(&voluntary_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4166 path_offset += 3;
4167
4168 if(start_sequencer != NULL){
4169 GList *retval;
4170
4171 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
4172 osc_connection,
4173 start_sequencer->data,
4174 message, message_size,
4175 type_tag,
4176 path, path_offset);
4177 }else{
4178 osc_response = ags_osc_response_new();
4179 start_response = g_list_prepend(start_response,
4180 osc_response);
4181
4182 ags_osc_response_set_flags(osc_response,
4183 AGS_OSC_RESPONSE_OK);
4184
4185 free(type_tag);
4186 free(path);
4187
4188 return(start_response);
4189 }
4190 }else if(ags_regexec(&more_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4191 path_offset += 3;
4192
4193 if(start_sequencer == NULL){
4194 osc_response = ags_osc_response_new();
4195 start_response = g_list_prepend(start_response,
4196 osc_response);
4197
4198 ags_osc_response_set_flags(osc_response,
4199 AGS_OSC_RESPONSE_ERROR);
4200
4201 g_object_set(osc_response,
4202 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4203 NULL);
4204
4205 free(type_tag);
4206 free(path);
4207
4208 return(start_response);
4209 }
4210
4211 sequencer = start_sequencer;
4212
4213 while(sequencer != NULL){
4214 GList *retval;
4215
4216 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
4217 osc_connection,
4218 sequencer->data,
4219 message, message_size,
4220 type_tag,
4221 path, path_offset);
4222
4223 if(start_response != NULL){
4224 start_response = g_list_concat(start_response,
4225 retval);
4226 }else{
4227 start_response = retval;
4228 }
4229
4230 sequencer = sequencer->next;
4231 }
4232 }else if(ags_regexec(&wildcard_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4233 path_offset += 3;
4234
4235 if(start_sequencer == NULL){
4236 osc_response = ags_osc_response_new();
4237 start_response = g_list_prepend(start_response,
4238 osc_response);
4239
4240 ags_osc_response_set_flags(osc_response,
4241 AGS_OSC_RESPONSE_OK);
4242
4243 free(type_tag);
4244 free(path);
4245
4246 return(start_response);
4247 }
4248
4249 while(sequencer != NULL){
4250 GList *retval;
4251
4252 retval = ags_osc_node_controller_get_data_channel(osc_node_controller,
4253 osc_connection,
4254 sequencer->data,
4255 message, message_size,
4256 type_tag,
4257 path, path_offset);
4258
4259 if(start_response != NULL){
4260 start_response = g_list_concat(start_response,
4261 retval);
4262 }else{
4263 start_response = retval;
4264 }
4265
4266 sequencer = sequencer->next;
4267 }
4268 }else{
4269 osc_response = ags_osc_response_new();
4270 start_response = g_list_prepend(start_response,
4271 osc_response);
4272
4273 ags_osc_response_set_flags(osc_response,
4274 AGS_OSC_RESPONSE_ERROR);
4275
4276 g_object_set(osc_response,
4277 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4278 NULL);
4279
4280 g_list_free_full(start_sequencer,
4281 g_object_unref);
4282
4283 free(type_tag);
4284 free(path);
4285
4286 return(start_response);
4287 }
4288
4289 g_list_free_full(start_sequencer,
4290 g_object_unref);
4291 }else if(!strncmp(path + path_offset,
4292 "/AgsAudio",
4293 9)){
4294 GList *start_audio, *audio;
4295
4296 regmatch_t match_arr[2];
4297
4298 static regex_t single_access_regex;
4299 static regex_t range_access_regex;
4300 static regex_t voluntary_access_regex;
4301 static regex_t more_access_regex;
4302 static regex_t wildcard_access_regex;
4303
4304 static gboolean regex_compiled = FALSE;
4305
4306 static const gchar *single_access_pattern = "^\\[([0-9]+)\\]";
4307 static const gchar *range_access_pattern = "^\\[([0-9]+)\\-([0-9]+)\\]";
4308 static const gchar *voluntary_access_pattern = "^\\[(\\?)\\]";
4309 static const gchar *more_access_pattern = "^\\[(\\+)\\]";
4310 static const gchar *wildcard_access_pattern = "^\\[(\\*)\\]";
4311
4312 static const size_t max_matches = 2;
4313 static const size_t index_max_matches = 1;
4314
4315 path_offset += 9;
4316
4317 /* compile regex */
4318 g_mutex_lock(®ex_mutex);
4319
4320 if(!regex_compiled){
4321 regex_compiled = TRUE;
4322
4323 ags_regcomp(&single_access_regex, single_access_pattern, REG_EXTENDED);
4324 ags_regcomp(&range_access_regex, range_access_pattern, REG_EXTENDED);
4325 ags_regcomp(&voluntary_access_regex, voluntary_access_pattern, REG_EXTENDED);
4326 ags_regcomp(&more_access_regex, more_access_pattern, REG_EXTENDED);
4327 ags_regcomp(&wildcard_access_regex, wildcard_access_pattern, REG_EXTENDED);
4328 }
4329
4330 g_mutex_unlock(®ex_mutex);
4331
4332 audio =
4333 start_audio = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
4334
4335 if(ags_regexec(&single_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4336 AgsAudio *current;
4337
4338 gchar *endptr;
4339
4340 guint i_stop;
4341
4342 endptr = NULL;
4343 i_stop = g_ascii_strtoull(path + path_offset + 1,
4344 &endptr,
4345 10);
4346
4347 current = g_list_nth_data(start_audio,
4348 i_stop);
4349
4350 path_offset += ((endptr + 1) - (path + path_offset));
4351
4352 start_response = ags_osc_node_controller_get_data_audio(osc_node_controller,
4353 osc_connection,
4354 current,
4355 message, message_size,
4356 type_tag,
4357 path, path_offset);
4358 }else if(ags_regexec(&range_access_regex, path + path_offset, max_matches, match_arr, 0) == 0){
4359 gchar *endptr;
4360
4361 guint i;
4362 guint i_start, i_stop;
4363
4364 endptr = NULL;
4365 i_start = g_ascii_strtoull(path + path_offset + 1,
4366 &endptr,
4367 10);
4368
4369 i_stop = g_ascii_strtoull(endptr + 1,
4370 &endptr,
4371 10);
4372
4373 path_offset += ((endptr + 1) - (path + path_offset));
4374
4375 audio = g_list_nth(start_audio,
4376 i_start);
4377
4378 for(i = i_start; i <= i_stop; i++){
4379 GList *retval;
4380
4381 retval = ags_osc_node_controller_get_data_audio(osc_node_controller,
4382 osc_connection,
4383 audio->data,
4384 message, message_size,
4385 type_tag,
4386 path, path_offset);
4387
4388 if(start_response != NULL){
4389 start_response = g_list_concat(start_response,
4390 retval);
4391 }else{
4392 start_response = retval;
4393 }
4394
4395 audio = audio->next;
4396 }
4397 }else if(ags_regexec(&voluntary_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4398 path_offset += 3;
4399
4400 if(start_audio != NULL){
4401 GList *retval;
4402
4403 retval = ags_osc_node_controller_get_data_audio(osc_node_controller,
4404 osc_connection,
4405 start_audio->data,
4406 message, message_size,
4407 type_tag,
4408 path, path_offset);
4409 }else{
4410 osc_response = ags_osc_response_new();
4411 start_response = g_list_prepend(start_response,
4412 osc_response);
4413
4414 ags_osc_response_set_flags(osc_response,
4415 AGS_OSC_RESPONSE_OK);
4416
4417 free(type_tag);
4418 free(path);
4419
4420 return(start_response);
4421 }
4422 }else if(ags_regexec(&more_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4423 path_offset += 3;
4424
4425 if(start_audio == NULL){
4426 osc_response = ags_osc_response_new();
4427 start_response = g_list_prepend(start_response,
4428 osc_response);
4429
4430 ags_osc_response_set_flags(osc_response,
4431 AGS_OSC_RESPONSE_ERROR);
4432
4433 g_object_set(osc_response,
4434 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4435 NULL);
4436
4437 free(type_tag);
4438 free(path);
4439
4440 return(start_response);
4441 }
4442
4443 audio = start_audio;
4444
4445 while(audio != NULL){
4446 GList *retval;
4447
4448 retval = ags_osc_node_controller_get_data_audio(osc_node_controller,
4449 osc_connection,
4450 audio->data,
4451 message, message_size,
4452 type_tag,
4453 path, path_offset);
4454
4455 if(start_response != NULL){
4456 start_response = g_list_concat(start_response,
4457 retval);
4458 }else{
4459 start_response = retval;
4460 }
4461
4462 audio = audio->next;
4463 }
4464 }else if(ags_regexec(&wildcard_access_regex, path + path_offset, index_max_matches, match_arr, 0) == 0){
4465 path_offset += 3;
4466
4467 if(start_audio == NULL){
4468 osc_response = ags_osc_response_new();
4469 start_response = g_list_prepend(start_response,
4470 osc_response);
4471
4472 ags_osc_response_set_flags(osc_response,
4473 AGS_OSC_RESPONSE_OK);
4474
4475 free(type_tag);
4476 free(path);
4477
4478 return(start_response);
4479 }
4480
4481 while(audio != NULL){
4482 GList *retval;
4483
4484 retval = ags_osc_node_controller_get_data_audio(osc_node_controller,
4485 osc_connection,
4486 audio->data,
4487 message, message_size,
4488 type_tag,
4489 path, path_offset);
4490
4491 if(start_response != NULL){
4492 start_response = g_list_concat(start_response,
4493 retval);
4494 }else{
4495 start_response = retval;
4496 }
4497
4498 audio = audio->next;
4499 }
4500 }else if(path[path_offset] == '[' &&
4501 path[path_offset + 1] == '"'){
4502 AgsAudio *current;
4503
4504 gchar *audio_name;
4505 gchar *offset;
4506
4507 guint length;
4508
4509 if((offset = strchr(path + path_offset + 2, '"')) == NULL){
4510 osc_response = ags_osc_response_new();
4511 start_response = g_list_prepend(start_response,
4512 osc_response);
4513
4514 ags_osc_response_set_flags(osc_response,
4515 AGS_OSC_RESPONSE_ERROR);
4516
4517 g_object_set(osc_response,
4518 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_CHUNK_SIZE_EXCEEDED,
4519 NULL);
4520
4521 g_list_free_full(start_audio,
4522 g_object_unref);
4523
4524 free(type_tag);
4525 free(path);
4526
4527 return(start_response);
4528 }
4529
4530 length = offset - (path + path_offset + 2);
4531
4532 audio_name = (gchar *) malloc((length + 1) * sizeof(gchar));
4533 memcpy(audio_name, path + path_offset + 2, (length) * sizeof(gchar));
4534 audio_name[length] = '\0';
4535
4536 current = NULL;
4537 audio = ags_audio_find_name(start_audio,
4538 audio_name);
4539
4540 if(audio != NULL){
4541 current = audio->data;
4542 }
4543
4544 path_offset += (length + 4);
4545 start_response = ags_osc_node_controller_get_data_audio(osc_node_controller,
4546 osc_connection,
4547 current,
4548 message, message_size,
4549 type_tag,
4550 path, path_offset);
4551 }else{
4552 osc_response = ags_osc_response_new();
4553 start_response = g_list_prepend(start_response,
4554 osc_response);
4555
4556 ags_osc_response_set_flags(osc_response,
4557 AGS_OSC_RESPONSE_ERROR);
4558
4559 g_object_set(osc_response,
4560 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4561 NULL);
4562
4563 g_list_free_full(start_audio,
4564 g_object_unref);
4565
4566 free(type_tag);
4567 free(path);
4568
4569 return(start_response);
4570 }
4571
4572 g_list_free_full(start_audio,
4573 g_object_unref);
4574 }else{
4575 osc_response = ags_osc_response_new();
4576 start_response = g_list_prepend(start_response,
4577 osc_response);
4578
4579 ags_osc_response_set_flags(osc_response,
4580 AGS_OSC_RESPONSE_ERROR);
4581
4582 g_object_set(osc_response,
4583 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_UNKNOWN_ARGUMENT,
4584 NULL);
4585
4586 free(type_tag);
4587 free(path);
4588
4589 return(start_response);
4590 }
4591 }
4592
4593 if(start_response == NULL){
4594 osc_response = ags_osc_response_new();
4595 start_response = g_list_prepend(start_response,
4596 osc_response);
4597
4598 ags_osc_response_set_flags(osc_response,
4599 AGS_OSC_RESPONSE_ERROR);
4600
4601 g_object_set(osc_response,
4602 "error-message", AGS_OSC_RESPONSE_ERROR_MESSAGE_SERVER_FAILURE,
4603 NULL);
4604
4605 free(type_tag);
4606 free(path);
4607
4608 return(start_response);
4609 }
4610
4611 free(type_tag);
4612 free(path);
4613
4614 return(start_response);
4615 }
4616
4617 /**
4618 * ags_osc_node_controller_get_data:
4619 * @osc_node_controller: the #AgsOscNodeController
4620 * @osc_connection: the #AgsOscConnection
4621 * @message: the message received
4622 * @message_size: the message size
4623 *
4624 * Get node.
4625 *
4626 * Returns: the #GList-struct containing #AgsOscResponse
4627 *
4628 * Since: 3.0.0
4629 */
4630 gpointer
ags_osc_node_controller_get_data(AgsOscNodeController * osc_node_controller,AgsOscConnection * osc_connection,unsigned char * message,guint message_size)4631 ags_osc_node_controller_get_data(AgsOscNodeController *osc_node_controller,
4632 AgsOscConnection *osc_connection,
4633 unsigned char *message, guint message_size)
4634 {
4635 gpointer osc_response;
4636
4637 g_return_val_if_fail(AGS_IS_OSC_NODE_CONTROLLER(osc_node_controller), NULL);
4638
4639 g_object_ref((GObject *) osc_node_controller);
4640 g_signal_emit(G_OBJECT(osc_node_controller),
4641 osc_node_controller_signals[GET_DATA], 0,
4642 osc_connection,
4643 message, message_size,
4644 &osc_response);
4645 g_object_unref((GObject *) osc_node_controller);
4646
4647 return(osc_response);
4648 }
4649
4650 /**
4651 * ags_osc_node_controller_new:
4652 *
4653 * Instantiate new #AgsOscNodeController
4654 *
4655 * Returns: the #AgsOscNodeController
4656 *
4657 * Since: 3.0.0
4658 */
4659 AgsOscNodeController*
ags_osc_node_controller_new()4660 ags_osc_node_controller_new()
4661 {
4662 AgsOscNodeController *osc_node_controller;
4663
4664 osc_node_controller = (AgsOscNodeController *) g_object_new(AGS_TYPE_OSC_NODE_CONTROLLER,
4665 NULL);
4666
4667 return(osc_node_controller);
4668 }
4669