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_front_controller.h>
21
22 #include <ags/audio/osc/ags_osc_server.h>
23 #include <ags/audio/osc/ags_osc_message.h>
24 #include <ags/audio/osc/ags_osc_response.h>
25 #include <ags/audio/osc/ags_osc_util.h>
26 #include <ags/audio/osc/ags_osc_buffer_util.h>
27
28 #include <ags/audio/osc/controller/ags_osc_action_controller.h>
29 #include <ags/audio/osc/controller/ags_osc_config_controller.h>
30 #include <ags/audio/osc/controller/ags_osc_controller.h>
31 #include <ags/audio/osc/controller/ags_osc_info_controller.h>
32 #include <ags/audio/osc/controller/ags_osc_meter_controller.h>
33 #include <ags/audio/osc/controller/ags_osc_node_controller.h>
34 #include <ags/audio/osc/controller/ags_osc_plugin_controller.h>
35 #include <ags/audio/osc/controller/ags_osc_renew_controller.h>
36 #include <ags/audio/osc/controller/ags_osc_status_controller.h>
37
38 #include <stdlib.h>
39 #include <math.h>
40
41 #ifdef __APPLE__
42 #include <mach/clock.h>
43 #include <mach/mach.h>
44 #endif
45
46 #include <ags/i18n.h>
47
48 void ags_osc_front_controller_class_init(AgsOscFrontControllerClass *osc_front_controller);
49 void ags_osc_front_controller_init(AgsOscFrontController *osc_front_controller);
50 void ags_osc_front_controller_set_property(GObject *gobject,
51 guint prop_id,
52 const GValue *value,
53 GParamSpec *param_spec);
54 void ags_osc_front_controller_get_property(GObject *gobject,
55 guint prop_id,
56 GValue *value,
57 GParamSpec *param_spec);
58 void ags_osc_front_controller_dispose(GObject *gobject);
59 void ags_osc_front_controller_finalize(GObject *gobject);
60
61 void* ags_osc_front_controller_delegate_thread(void *ptr);
62
63 void ags_osc_front_controller_real_start_delegate(AgsOscFrontController *osc_front_controller);
64 void ags_osc_front_controller_real_stop_delegate(AgsOscFrontController *osc_front_controller);
65
66 gsize ags_osc_front_controller_read_bundle(AgsOscFrontController *osc_front_controller,
67 AgsOscConnection *osc_connection,
68 guchar *packet, gsize packet_size,
69 gsize offset);
70 gsize ags_osc_front_controller_read_message(AgsOscFrontController *osc_front_controller,
71 AgsOscConnection *osc_connection,
72 guchar *packet, gsize packet_size,
73 gsize offset,
74 gint32 tv_sec, gint32 tv_fraction, gboolean immediately);
75
76 gpointer ags_osc_front_controller_real_do_request(AgsOscFrontController *osc_front_controller,
77 AgsOscConnection *osc_connection,
78 guchar *packet, gsize packet_size);
79
80 /**
81 * SECTION:ags_osc_front_controller
82 * @short_description: OSC front controller
83 * @title: AgsOscFrontController
84 * @section_id:
85 * @include: ags/audio/osc/controller/ags_osc_front_controller.h
86 *
87 * The #AgsOscFrontController implements the OSC front controller.
88 */
89
90 enum{
91 PROP_0,
92 };
93
94 enum{
95 START_DELEGATE,
96 STOP_DELEGATE,
97 DO_REQUEST,
98 LAST_SIGNAL,
99 };
100
101 static gpointer ags_osc_front_controller_parent_class = NULL;
102 static guint osc_front_controller_signals[LAST_SIGNAL];
103
104 GType
ags_osc_front_controller_get_type()105 ags_osc_front_controller_get_type()
106 {
107 static volatile gsize g_define_type_id__volatile = 0;
108
109 if(g_once_init_enter (&g_define_type_id__volatile)){
110 GType ags_type_osc_front_controller = 0;
111
112 static const GTypeInfo ags_osc_front_controller_info = {
113 sizeof (AgsOscFrontControllerClass),
114 NULL, /* base_init */
115 NULL, /* base_finalize */
116 (GClassInitFunc) ags_osc_front_controller_class_init,
117 NULL, /* class_finalize */
118 NULL, /* class_data */
119 sizeof (AgsOscFrontController),
120 0, /* n_preallocs */
121 (GInstanceInitFunc) ags_osc_front_controller_init,
122 };
123
124 ags_type_osc_front_controller = g_type_register_static(AGS_TYPE_OSC_CONTROLLER,
125 "AgsOscFrontController",
126 &ags_osc_front_controller_info,
127 0);
128
129 g_once_init_leave(&g_define_type_id__volatile, ags_type_osc_front_controller);
130 }
131
132 return g_define_type_id__volatile;
133 }
134
135 void
ags_osc_front_controller_class_init(AgsOscFrontControllerClass * osc_front_controller)136 ags_osc_front_controller_class_init(AgsOscFrontControllerClass *osc_front_controller)
137 {
138 GObjectClass *gobject;
139 GParamSpec *param_spec;
140
141 ags_osc_front_controller_parent_class = g_type_class_peek_parent(osc_front_controller);
142
143 /* GObjectClass */
144 gobject = (GObjectClass *) osc_front_controller;
145
146 // gobject->set_property = ags_osc_front_controller_set_property;
147 // gobject->get_property = ags_osc_front_controller_get_property;
148
149 gobject->dispose = ags_osc_front_controller_dispose;
150 gobject->finalize = ags_osc_front_controller_finalize;
151
152 /* properties */
153
154 /* AgsOscFrontControllerClass */
155 osc_front_controller->start_delegate = ags_osc_front_controller_real_start_delegate;
156 osc_front_controller->stop_delegate = ags_osc_front_controller_real_stop_delegate;
157
158 osc_front_controller->do_request = ags_osc_front_controller_real_do_request;
159
160 /* signals */
161 /**
162 * AgsOscFrontController::start-delegate:
163 * @osc_front_controller: the #AgsOscFrontController
164 *
165 * The ::start-delegate signal is emited during start of delegating messages.
166 *
167 * Since: 3.0.0
168 */
169 osc_front_controller_signals[START_DELEGATE] =
170 g_signal_new("start-delegate",
171 G_TYPE_FROM_CLASS(osc_front_controller),
172 G_SIGNAL_RUN_LAST,
173 G_STRUCT_OFFSET(AgsOscFrontControllerClass, start_delegate),
174 NULL, NULL,
175 g_cclosure_marshal_VOID__VOID,
176 G_TYPE_NONE, 0);
177
178 /**
179 * AgsOscFrontController::stop-delegate:
180 * @osc_front_controller: the #AgsOscFrontController
181 *
182 * The ::stop-delegate signal is emited during stop of delegating messages.
183 *
184 * Since: 3.0.0
185 */
186 osc_front_controller_signals[STOP_DELEGATE] =
187 g_signal_new("stop-delegate",
188 G_TYPE_FROM_CLASS(osc_front_controller),
189 G_SIGNAL_RUN_LAST,
190 G_STRUCT_OFFSET(AgsOscFrontControllerClass, stop_delegate),
191 NULL, NULL,
192 g_cclosure_marshal_VOID__VOID,
193 G_TYPE_NONE, 0);
194
195 /**
196 * AgsOscFrontController::do-request:
197 * @osc_front_controller: the #AgsOscFrontController
198 * @osc_connection: the #AgsOscConnection
199 * @packet: the packet received
200 * @packet_size: the packet size
201 *
202 * The ::do-request signal is emited during do request of front controller.
203 *
204 * Since: 3.0.0
205 */
206 osc_front_controller_signals[DO_REQUEST] =
207 g_signal_new("do-request",
208 G_TYPE_FROM_CLASS(osc_front_controller),
209 G_SIGNAL_RUN_LAST,
210 G_STRUCT_OFFSET(AgsOscFrontControllerClass, do_request),
211 NULL, NULL,
212 ags_cclosure_marshal_POINTER__OBJECT_POINTER_INT64,
213 G_TYPE_POINTER, 3,
214 G_TYPE_OBJECT,
215 G_TYPE_POINTER,
216 G_TYPE_INT64);
217 }
218
219 void
ags_osc_front_controller_init(AgsOscFrontController * osc_front_controller)220 ags_osc_front_controller_init(AgsOscFrontController *osc_front_controller)
221 {
222 g_object_set(osc_front_controller,
223 "context-path", "/",
224 NULL);
225
226 osc_front_controller->flags = 0;
227
228 osc_front_controller->delegate_timeout = (struct timespec *) malloc(sizeof(struct timespec));
229
230 osc_front_controller->delegate_timeout = 0;
231
232 g_atomic_int_set(&(osc_front_controller->do_reset),
233 FALSE);
234
235 g_mutex_init(&(osc_front_controller->delegate_mutex));
236
237 g_cond_init(&(osc_front_controller->delegate_cond));
238
239 osc_front_controller->delegate_thread = NULL;
240
241 osc_front_controller->message = NULL;
242 }
243
244 void
ags_osc_front_controller_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)245 ags_osc_front_controller_set_property(GObject *gobject,
246 guint prop_id,
247 const GValue *value,
248 GParamSpec *param_spec)
249 {
250 AgsOscFrontController *osc_front_controller;
251
252 GRecMutex *osc_controller_mutex;
253
254 osc_front_controller = AGS_OSC_FRONT_CONTROLLER(gobject);
255
256 /* get osc controller mutex */
257 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
258
259 switch(prop_id){
260 default:
261 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
262 break;
263 }
264 }
265
266 void
ags_osc_front_controller_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)267 ags_osc_front_controller_get_property(GObject *gobject,
268 guint prop_id,
269 GValue *value,
270 GParamSpec *param_spec)
271 {
272 AgsOscFrontController *osc_front_controller;
273
274 GRecMutex *osc_controller_mutex;
275
276 osc_front_controller = AGS_OSC_FRONT_CONTROLLER(gobject);
277
278 /* get osc controller mutex */
279 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
280
281 switch(prop_id){
282 default:
283 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
284 break;
285 }
286 }
287
288 void
ags_osc_front_controller_dispose(GObject * gobject)289 ags_osc_front_controller_dispose(GObject *gobject)
290 {
291 AgsOscFrontController *osc_front_controller;
292
293 osc_front_controller = AGS_OSC_FRONT_CONTROLLER(gobject);
294
295 if(osc_front_controller->message != NULL){
296 g_list_free_full(osc_front_controller->message,
297 (GDestroyNotify) g_object_unref);
298
299 osc_front_controller->message = NULL;
300 }
301
302 /* call parent */
303 G_OBJECT_CLASS(ags_osc_front_controller_parent_class)->dispose(gobject);
304 }
305
306 void
ags_osc_front_controller_finalize(GObject * gobject)307 ags_osc_front_controller_finalize(GObject *gobject)
308 {
309 AgsOscFrontController *osc_front_controller;
310
311 osc_front_controller = AGS_OSC_FRONT_CONTROLLER(gobject);
312
313 if(osc_front_controller->message != NULL){
314 g_list_free_full(osc_front_controller->message,
315 (GDestroyNotify) g_object_unref);
316 }
317
318 /* call parent */
319 G_OBJECT_CLASS(ags_osc_front_controller_parent_class)->finalize(gobject);
320 }
321
322 void*
ags_osc_front_controller_delegate_thread(void * ptr)323 ags_osc_front_controller_delegate_thread(void *ptr)
324 {
325 AgsOscServer *osc_server;
326 AgsOscFrontController *osc_front_controller;
327
328 GList *start_controller, *controller;
329
330 gint64 time_now, time_next;
331 gint64 current_time;
332
333 GRecMutex *osc_controller_mutex;
334
335 osc_front_controller = AGS_OSC_FRONT_CONTROLLER(ptr);
336
337 g_object_get(osc_front_controller,
338 "osc-server", &osc_server,
339 NULL);
340
341 g_object_get(osc_server,
342 "controller", &start_controller,
343 NULL);
344
345 /* get OSC front controller mutex */
346 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
347
348 time_next = 0;
349
350 ags_osc_front_controller_set_flags(osc_front_controller,
351 AGS_OSC_FRONT_CONTROLLER_DELEGATE_RUNNING);
352
353 while(ags_osc_front_controller_test_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_RUNNING)){
354 GList *start_message, *message;
355 GList *start_list, *list;
356
357 g_mutex_lock(&(osc_front_controller->delegate_mutex));
358
359 time_now = g_get_monotonic_time();
360 osc_front_controller->delegate_timeout = time_now + (G_TIME_SPAN_SECOND / 30);
361
362 while(!g_atomic_int_get(&(osc_front_controller->do_reset)) &&
363 ((time_now < time_next) &&
364 (time_now < osc_front_controller->delegate_timeout)) &&
365 ags_osc_front_controller_test_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_RUNNING) &&
366 time_now > 0){
367 g_cond_wait_until(&(osc_front_controller->delegate_cond),
368 &(osc_front_controller->delegate_mutex),
369 osc_front_controller->delegate_timeout);
370
371 time_now = g_get_monotonic_time();
372 }
373
374 g_atomic_int_set(&(osc_front_controller->do_reset),
375 FALSE);
376
377 g_mutex_unlock(&(osc_front_controller->delegate_mutex));
378
379 /* check delegate */
380 g_rec_mutex_lock(osc_controller_mutex);
381
382 start_message = NULL;
383 list =
384 start_list = g_list_copy(osc_front_controller->message);
385
386 while(list != NULL){
387 if(AGS_OSC_MESSAGE(list->data)->immediately){
388 start_message = g_list_prepend(start_message,
389 list->data);
390 g_object_ref(list->data);
391
392 ags_osc_front_controller_remove_message(osc_front_controller,
393 list->data);
394 }else{
395 current_time = AGS_OSC_MESSAGE(list->data)->tv_sec + AGS_OSC_MESSAGE(list->data)->tv_fraction / 4.294967296 * 1000.0;
396
397 if(current_time < time_now){
398 start_message = g_list_prepend(start_message,
399 list->data);
400 g_object_ref(list->data);
401
402 ags_osc_front_controller_remove_message(osc_front_controller,
403 list->data);
404 }else{
405 break;
406 }
407 }
408
409 list = list->next;
410 }
411
412 g_rec_mutex_unlock(osc_controller_mutex);
413
414 g_list_free(start_list);
415
416 message =
417 start_message = g_list_reverse(start_message);
418
419 while(message != NULL){
420 GList *start_osc_response, *osc_response;
421
422 AgsOscMessage *current;
423
424 gchar *path;
425
426 ags_osc_buffer_util_get_string(AGS_OSC_MESSAGE(message->data)->message,
427 &path, NULL);
428
429 controller = start_controller;
430 start_osc_response = NULL;
431
432 while(controller != NULL){
433 gboolean success;
434
435 GRecMutex *mutex;
436
437 /* get OSC controller mutex */
438 mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(controller->data);
439
440 /* match path */
441 g_rec_mutex_lock(mutex);
442
443 success = !g_strcmp0(AGS_OSC_CONTROLLER(controller->data)->context_path,
444 path);
445
446 g_rec_mutex_unlock(mutex);
447
448 if(success){
449 current = AGS_OSC_MESSAGE(message->data);
450
451 /* delegate */
452 if(AGS_IS_OSC_ACTION_CONTROLLER(controller->data)){
453 start_osc_response = ags_osc_action_controller_run_action(controller->data,
454 current->osc_connection,
455 current->message, current->message_size);
456 }else if(AGS_IS_OSC_CONFIG_CONTROLLER(controller->data)){
457 start_osc_response = ags_osc_config_controller_apply_config(controller->data,
458 current->osc_connection,
459 current->message, current->message_size);
460 }else if(AGS_IS_OSC_INFO_CONTROLLER(controller->data)){
461 start_osc_response = ags_osc_info_controller_get_info(controller->data,
462 current->osc_connection,
463 current->message, current->message_size);
464 }else if(AGS_IS_OSC_METER_CONTROLLER(controller->data)){
465 start_osc_response = ags_osc_meter_controller_monitor_meter(controller->data,
466 current->osc_connection,
467 current->message, current->message_size);
468 }else if(AGS_IS_OSC_NODE_CONTROLLER(controller->data)){
469 start_osc_response = ags_osc_node_controller_get_data(controller->data,
470 current->osc_connection,
471 current->message, current->message_size);
472 }else if(AGS_IS_OSC_RENEW_CONTROLLER(controller->data)){
473 start_osc_response = ags_osc_renew_controller_set_data(controller->data,
474 current->osc_connection,
475 current->message, current->message_size);
476 }else if(AGS_IS_OSC_STATUS_CONTROLLER(controller->data)){
477 start_osc_response = ags_osc_status_controller_get_status(controller->data,
478 current->osc_connection,
479 current->message, current->message_size);
480 }else if(AGS_IS_OSC_PLUGIN_CONTROLLER(controller->data)){
481 start_osc_response = ags_osc_plugin_controller_do_request(AGS_OSC_PLUGIN_CONTROLLER(controller->data),
482 current->osc_connection,
483 current->message, current->message_size);
484 }
485
486 break;
487 }
488
489 controller = controller->next;
490 }
491
492 /* write response */
493 osc_response = start_osc_response;
494
495 while(osc_response != NULL){
496 ags_osc_connection_write_response(current->osc_connection,
497 osc_response->data);
498
499 osc_response = osc_response->next;
500 }
501
502 g_list_free_full(start_osc_response,
503 g_object_unref);
504
505 message = message->next;
506 }
507
508 /* free messages */
509 g_list_free_full(start_message,
510 (GDestroyNotify) g_object_unref);
511
512 /* next */
513 g_mutex_lock(&(osc_front_controller->delegate_mutex));
514
515 if(osc_front_controller->message != NULL){
516 time_now = g_get_monotonic_time();
517
518 time_next = AGS_OSC_MESSAGE(osc_front_controller->message)->tv_sec + AGS_OSC_MESSAGE(osc_front_controller->message)->tv_fraction / 4.294967296 * 1000.0;
519
520 if(time_next == -1){
521 time_next = time_now + 1;
522 }else if(time_next > time_now + G_TIME_SPAN_SECOND / 30){
523 time_next = time_now + G_TIME_SPAN_SECOND / 30;
524 }
525 }else{
526 time_now = g_get_monotonic_time();
527
528 time_next = time_now + G_TIME_SPAN_SECOND / 30;
529 }
530
531 g_mutex_unlock(&(osc_front_controller->delegate_mutex));
532 }
533
534 g_object_unref(osc_server);
535
536 g_list_free_full(start_controller,
537 g_object_unref);
538
539 g_thread_exit(NULL);
540
541 return(NULL);
542 }
543
544 /**
545 * ags_osc_front_controller_test_flags:
546 * @osc_front_controller: the #AgsOscFrontController
547 * @flags: the flags
548 *
549 * Test @flags to be set on @osc_front_controller.
550 *
551 * Returns: %TRUE if flags are set, else %FALSE
552 *
553 * Since: 3.0.0
554 */
555 gboolean
ags_osc_front_controller_test_flags(AgsOscFrontController * osc_front_controller,guint flags)556 ags_osc_front_controller_test_flags(AgsOscFrontController *osc_front_controller, guint flags)
557 {
558 gboolean retval;
559
560 GRecMutex *osc_controller_mutex;
561
562 if(!AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller)){
563 return(FALSE);
564 }
565
566 /* get OSC front controller mutex */
567 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
568
569 /* test */
570 g_rec_mutex_lock(osc_controller_mutex);
571
572 retval = (flags & (osc_front_controller->flags)) ? TRUE: FALSE;
573
574 g_rec_mutex_unlock(osc_controller_mutex);
575
576 return(retval);
577 }
578
579 /**
580 * ags_osc_front_controller_set_flags:
581 * @osc_front_controller: the #AgsOscFrontController
582 * @flags: the flags
583 *
584 * Set flags.
585 *
586 * Since: 3.0.0
587 */
588 void
ags_osc_front_controller_set_flags(AgsOscFrontController * osc_front_controller,guint flags)589 ags_osc_front_controller_set_flags(AgsOscFrontController *osc_front_controller, guint flags)
590 {
591 GRecMutex *osc_controller_mutex;
592
593 if(!AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller)){
594 return;
595 }
596
597 /* get OSC front controller mutex */
598 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
599
600 /* set flags */
601 g_rec_mutex_lock(osc_controller_mutex);
602
603 osc_front_controller->flags |= flags;
604
605 g_rec_mutex_unlock(osc_controller_mutex);
606 }
607
608 /**
609 * ags_osc_front_controller_unset_flags:
610 * @osc_front_controller: the #AgsOscFrontController
611 * @flags: the flags
612 *
613 * Unset flags.
614 *
615 * Since: 3.0.0
616 */
617 void
ags_osc_front_controller_unset_flags(AgsOscFrontController * osc_front_controller,guint flags)618 ags_osc_front_controller_unset_flags(AgsOscFrontController *osc_front_controller, guint flags)
619 {
620 GRecMutex *osc_controller_mutex;
621
622 if(!AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller)){
623 return;
624 }
625
626 /* get OSC front controller mutex */
627 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
628
629 /* set flags */
630 g_rec_mutex_lock(osc_controller_mutex);
631
632 osc_front_controller->flags &= (~flags);
633
634 g_rec_mutex_unlock(osc_controller_mutex);
635 }
636
637 /**
638 * ags_osc_front_controller_add_message:
639 * @osc_front_controller: the #AgsOscFrontController
640 * @message: the #AgsOscMessage
641 *
642 * Add @message to @osc_front_controller.
643 *
644 * Since: 3.0.0
645 */
646 void
ags_osc_front_controller_add_message(AgsOscFrontController * osc_front_controller,GObject * message)647 ags_osc_front_controller_add_message(AgsOscFrontController *osc_front_controller,
648 GObject *message)
649 {
650 GRecMutex *osc_controller_mutex;
651
652 if(!AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller) ||
653 message == NULL){
654 return;
655 }
656
657 /* get OSC front controller mutex */
658 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
659
660 /* add */
661 g_rec_mutex_lock(osc_controller_mutex);
662
663 if(g_list_find(osc_front_controller->message, message) == NULL){
664 osc_front_controller->message = g_list_insert_sorted(osc_front_controller->message,
665 message,
666 ags_osc_message_sort_func);
667 g_object_ref(message);
668 }
669
670 g_rec_mutex_unlock(osc_controller_mutex);
671 }
672
673 /**
674 * ags_osc_front_controller_remove_message:
675 * @osc_front_controller: the #AgsOscFrontController
676 * @message: the #AgsOscMessage
677 *
678 * Remove @message from @osc_front_controller.
679 *
680 * Since: 3.0.0
681 */
682 void
ags_osc_front_controller_remove_message(AgsOscFrontController * osc_front_controller,GObject * message)683 ags_osc_front_controller_remove_message(AgsOscFrontController *osc_front_controller,
684 GObject *message)
685 {
686 GRecMutex *osc_controller_mutex;
687
688 if(!AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller) ||
689 message == NULL){
690 return;
691 }
692
693 /* get OSC front controller mutex */
694 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
695
696 /* remove */
697 g_rec_mutex_lock(osc_controller_mutex);
698
699 if(g_list_find(osc_front_controller->message, message) != NULL){
700 osc_front_controller->message = g_list_remove(osc_front_controller->message,
701 message);
702 g_object_unref(message);
703 }
704
705 g_rec_mutex_unlock(osc_controller_mutex);
706 }
707
708 void
ags_osc_front_controller_real_start_delegate(AgsOscFrontController * osc_front_controller)709 ags_osc_front_controller_real_start_delegate(AgsOscFrontController *osc_front_controller)
710 {
711 GRecMutex *osc_controller_mutex;
712
713 /* get OSC front controller mutex */
714 osc_controller_mutex = AGS_OSC_CONTROLLER_GET_OBJ_MUTEX(osc_front_controller);
715
716 /* test if already started */
717 g_rec_mutex_lock(osc_controller_mutex);
718
719 if(ags_osc_front_controller_test_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_STARTED)){
720 g_rec_mutex_unlock(osc_controller_mutex);
721
722 return;
723 }
724
725 ags_osc_front_controller_set_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_STARTED);
726
727 g_rec_mutex_unlock(osc_controller_mutex);
728
729 /* create delegate thread */
730 osc_front_controller->delegate_thread = g_thread_new("Advanced Gtk+ Sequencer OSC Server - delegate thread",
731 ags_osc_front_controller_delegate_thread,
732 osc_front_controller);
733 }
734
735 /**
736 * ags_osc_front_controller_start_delegate:
737 * @osc_front_controller: the #AgsOscFrontController
738 *
739 * Start delegating.
740 *
741 * Since: 3.0.0
742 */
743 void
ags_osc_front_controller_start_delegate(AgsOscFrontController * osc_front_controller)744 ags_osc_front_controller_start_delegate(AgsOscFrontController *osc_front_controller)
745 {
746 g_return_if_fail(AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller));
747
748 g_object_ref((GObject *) osc_front_controller);
749 g_signal_emit(G_OBJECT(osc_front_controller),
750 osc_front_controller_signals[START_DELEGATE], 0);
751 g_object_unref((GObject *) osc_front_controller);
752 }
753
754 void
ags_osc_front_controller_real_stop_delegate(AgsOscFrontController * osc_front_controller)755 ags_osc_front_controller_real_stop_delegate(AgsOscFrontController *osc_front_controller)
756 {
757 if(!ags_osc_front_controller_test_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_RUNNING)){
758 return;
759 }
760
761 ags_osc_front_controller_set_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_TERMINATING);
762 ags_osc_front_controller_unset_flags(osc_front_controller, AGS_OSC_FRONT_CONTROLLER_DELEGATE_RUNNING);
763
764 /* join thread */
765 //TODO:JK: this was disabled as a work-around
766 #if 1
767 g_thread_join(osc_front_controller->delegate_thread);
768 #endif
769
770 ags_osc_front_controller_unset_flags(osc_front_controller, (AGS_OSC_FRONT_CONTROLLER_DELEGATE_TERMINATING |
771 AGS_OSC_FRONT_CONTROLLER_DELEGATE_STARTED));
772 }
773
774 /**
775 * ags_osc_front_controller_stop_delegate:
776 * @osc_front_controller: the #AgsOscFrontController
777 *
778 * Stop delegating.
779 *
780 * Since: 3.0.0
781 */
782 void
ags_osc_front_controller_stop_delegate(AgsOscFrontController * osc_front_controller)783 ags_osc_front_controller_stop_delegate(AgsOscFrontController *osc_front_controller)
784 {
785 g_return_if_fail(AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller));
786
787 g_object_ref((GObject *) osc_front_controller);
788 g_signal_emit(G_OBJECT(osc_front_controller),
789 osc_front_controller_signals[STOP_DELEGATE], 0);
790 g_object_unref((GObject *) osc_front_controller);
791 }
792
793 gsize
ags_osc_front_controller_read_bundle(AgsOscFrontController * osc_front_controller,AgsOscConnection * osc_connection,guchar * packet,gsize packet_size,gsize offset)794 ags_osc_front_controller_read_bundle(AgsOscFrontController *osc_front_controller,
795 AgsOscConnection *osc_connection,
796 guchar *packet, gsize packet_size,
797 gsize offset)
798 {
799 gint32 tv_sec;
800 gint32 tv_fraction;
801 gboolean immediately;
802 gsize read_count;
803 gint32 length;
804
805 read_count = 8;
806
807 ags_osc_buffer_util_get_timetag(packet + offset + read_count,
808 &(tv_sec), &(tv_fraction), &(immediately));
809 read_count += 8;
810
811 for(; offset < packet_size;){
812 ags_osc_buffer_util_get_int32(packet + offset + read_count,
813 &length);
814 read_count += 4;
815
816 if(!g_strcmp0(packet + offset + read_count, "#bundle")){
817 ags_osc_front_controller_read_bundle(osc_front_controller,
818 osc_connection,
819 packet, packet_size,
820 offset + read_count);
821
822 read_count += ((gsize) 4 * ceil((double) length / 4.0));
823 }else if(packet[offset + read_count] == '/'){
824 ags_osc_front_controller_read_message(osc_front_controller,
825 osc_connection,
826 packet, packet_size,
827 offset + read_count,
828 tv_sec, tv_fraction, immediately);
829
830 read_count += ((gsize) 4 * ceil((double) length / 4.0));
831 }else{
832 read_count += 1;
833
834 g_warning("malformed data");
835 }
836 }
837
838 return(read_count);
839 }
840
841 gsize
ags_osc_front_controller_read_message(AgsOscFrontController * osc_front_controller,AgsOscConnection * osc_connection,guchar * packet,gsize packet_size,gsize offset,gint32 tv_sec,gint32 tv_fraction,gboolean immediately)842 ags_osc_front_controller_read_message(AgsOscFrontController *osc_front_controller,
843 AgsOscConnection *osc_connection,
844 guchar *packet, gsize packet_size,
845 gsize offset,
846 gint32 tv_sec, gint32 tv_fraction, gboolean immediately)
847 {
848 AgsOscMessage *osc_message;
849
850 guchar *message;
851 gchar *address_pattern;
852 gchar *type_tag;
853
854 gsize address_pattern_length;
855 gsize type_tag_length;
856 gsize data_length;
857 gsize read_count;
858 guint i;
859
860 read_count = 0;
861
862 ags_osc_buffer_util_get_string(packet + offset,
863 &address_pattern, &address_pattern_length);
864
865 if(address_pattern == NULL){
866 return(0);
867 }
868
869 read_count += (4 * (gsize) ceil((double) (address_pattern_length + 1) / 4.0));
870 free(address_pattern);
871
872 type_tag = NULL;
873
874 if(packet_size > offset + read_count){
875 if(packet[offset + read_count] == ','){
876 ags_osc_buffer_util_get_string(packet + offset + read_count,
877 &type_tag, &type_tag_length);
878
879 read_count += (4 * (gsize) ceil((double) (type_tag_length + 1) / 4.0));
880 }
881 }
882
883 data_length = 0;
884
885 if(type_tag != NULL){
886 for(i = 1; i < type_tag_length; i++){
887 switch(type_tag[i]){
888 case AGS_OSC_UTIL_TYPE_TAG_STRING_TRUE:
889 case AGS_OSC_UTIL_TYPE_TAG_STRING_FALSE:
890 case AGS_OSC_UTIL_TYPE_TAG_STRING_NIL:
891 case AGS_OSC_UTIL_TYPE_TAG_STRING_INFINITE:
892 case AGS_OSC_UTIL_TYPE_TAG_STRING_ARRAY_START:
893 case AGS_OSC_UTIL_TYPE_TAG_STRING_ARRAY_END:
894 {
895 //empty
896 }
897 break;
898 case AGS_OSC_UTIL_TYPE_TAG_STRING_CHAR:
899 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT32:
900 case AGS_OSC_UTIL_TYPE_TAG_STRING_FLOAT:
901 case AGS_OSC_UTIL_TYPE_TAG_STRING_RGBA:
902 case AGS_OSC_UTIL_TYPE_TAG_STRING_MIDI:
903 {
904 data_length += 4;
905 }
906 break;
907 case AGS_OSC_UTIL_TYPE_TAG_STRING_INT64:
908 case AGS_OSC_UTIL_TYPE_TAG_STRING_DOUBLE:
909 case AGS_OSC_UTIL_TYPE_TAG_STRING_TIMETAG:
910 {
911 data_length += 8;
912 }
913 break;
914 case AGS_OSC_UTIL_TYPE_TAG_STRING_SYMBOL:
915 case AGS_OSC_UTIL_TYPE_TAG_STRING_STRING:
916 {
917 gsize length;
918
919 length = strlen(packet + offset + read_count + data_length);
920
921 data_length += (4 * (gsize) ceil((double) (length + 1) / 4.0));
922 }
923 break;
924 case AGS_OSC_UTIL_TYPE_TAG_STRING_BLOB:
925 {
926 gint32 data_size;
927
928 ags_osc_buffer_util_get_int32(packet + offset + read_count + data_length,
929 &data_size);
930
931 data_length += data_size;
932 }
933 break;
934 }
935 }
936
937 free(type_tag);
938 }
939
940 read_count += (4 * (gsize) ceil((double) data_length / 4.0));
941
942 osc_message = ags_osc_message_new();
943
944 message = (guchar *) malloc(read_count * sizeof(guchar));
945 memcpy(message,
946 packet + offset,
947 read_count * sizeof(guchar));
948
949 g_object_set(osc_message,
950 "osc-connection", osc_connection,
951 "tv-sec", tv_sec,
952 "tv-fraction", tv_fraction,
953 "immediately", immediately,
954 "message-size", read_count,
955 "message", message,
956 NULL);
957
958 ags_osc_front_controller_add_message(osc_front_controller,
959 osc_message);
960
961 return(read_count);
962 }
963
964 gpointer
ags_osc_front_controller_real_do_request(AgsOscFrontController * osc_front_controller,AgsOscConnection * osc_connection,guchar * packet,gsize packet_size)965 ags_osc_front_controller_real_do_request(AgsOscFrontController *osc_front_controller,
966 AgsOscConnection *osc_connection,
967 guchar *packet, gsize packet_size)
968 {
969 gint32 tv_sec;
970 gint32 tv_fraction;
971 gboolean immediately;
972 gsize offset;
973
974 if(packet == NULL ||
975 packet_size < 0){
976 return(NULL);
977 }
978
979 tv_sec = 0;
980 tv_fraction = 0;
981 immediately = TRUE;
982
983 for(offset = 4; offset < packet_size;){
984 gsize read_count;
985
986 #ifdef AGS_DEBUG
987 g_message("%d %d", offset, packet_size);
988 g_message("%x[%c]", packet[offset], packet[offset]);
989 #endif
990
991 read_count = 0;
992
993 if(!g_strcmp0(packet + offset, "#bundle")){
994 read_count = ags_osc_front_controller_read_bundle(osc_front_controller,
995 osc_connection,
996 packet, packet_size,
997 offset);
998 }else if(packet[offset] == '/'){
999 read_count = ags_osc_front_controller_read_message(osc_front_controller,
1000 osc_connection,
1001 packet, packet_size,
1002 offset,
1003 0, 0, TRUE);
1004 }
1005
1006 if(read_count > 0){
1007 offset += ((gsize) 4 * ceil((double) read_count / 4.0));
1008 }else{
1009 offset += 1;
1010
1011 g_warning("malformed data");
1012 }
1013 }
1014
1015 return(NULL);
1016 }
1017
1018 /**
1019 * ags_osc_front_controller_write_response:
1020 * @osc_front_controller: the #AgsOscFrontController
1021 * @osc_connection: the #AgsOscConnection
1022 * @packet: the packet received
1023 * @packet_size: the packet size
1024 *
1025 * Do request.
1026 *
1027 * Returns: %NULL
1028 *
1029 * Since: 3.0.0
1030 */
1031 gpointer
ags_osc_front_controller_do_request(AgsOscFrontController * osc_front_controller,AgsOscConnection * osc_connection,guchar * packet,gsize packet_size)1032 ags_osc_front_controller_do_request(AgsOscFrontController *osc_front_controller,
1033 AgsOscConnection *osc_connection,
1034 guchar *packet, gsize packet_size)
1035 {
1036 gpointer osc_response;
1037
1038 g_return_val_if_fail(AGS_IS_OSC_FRONT_CONTROLLER(osc_front_controller), NULL);
1039
1040 g_object_ref((GObject *) osc_front_controller);
1041 g_object_ref((GObject *) osc_connection);
1042 g_signal_emit(G_OBJECT(osc_front_controller),
1043 osc_front_controller_signals[DO_REQUEST], 0,
1044 osc_connection,
1045 packet, (gint64) packet_size,
1046 &osc_response);
1047 g_object_unref((GObject *) osc_connection);
1048 g_object_unref((GObject *) osc_front_controller);
1049
1050 return(osc_response);
1051 }
1052
1053 /**
1054 * ags_osc_front_controller_new:
1055 *
1056 * Instantiate new #AgsOscFrontController
1057 *
1058 * Returns: the #AgsOscFrontController
1059 *
1060 * Since: 3.0.0
1061 */
1062 AgsOscFrontController*
ags_osc_front_controller_new()1063 ags_osc_front_controller_new()
1064 {
1065 AgsOscFrontController *osc_front_controller;
1066
1067 osc_front_controller = (AgsOscFrontController *) g_object_new(AGS_TYPE_OSC_FRONT_CONTROLLER,
1068 NULL);
1069
1070 return(osc_front_controller);
1071 }
1072