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 General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (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 General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSequencer.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <glib.h>
21 #include <glib-object.h>
22 
23 #include <CUnit/CUnit.h>
24 #include <CUnit/Basic.h>
25 
26 #include <ags/libags.h>
27 #include <ags/libags-audio.h>
28 
29 #ifdef __APPLE__
30 #include <mach/clock.h>
31 #include <mach/mach.h>
32 #endif
33 
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <math.h>
38 #include <time.h>
39 
40 gpointer ags_functional_osc_server_test_add_thread(gpointer data);
41 
42 int ags_functional_osc_server_test_init_suite();
43 int ags_functional_osc_server_test_clean_suite();
44 
45 void ags_functional_osc_server_test_action_controller();
46 void ags_functional_osc_server_test_config_controller();
47 void ags_functional_osc_server_test_info_controller();
48 void ags_functional_osc_server_test_meter_controller();
49 void ags_functional_osc_server_test_node_controller();
50 void ags_functional_osc_server_test_renew_controller();
51 void ags_functional_osc_server_test_status_controller();
52 
53 #define AGS_FUNCTIONAL_OSC_SERVER_TEST_CONFIG "[generic]\n"	\
54   "autosave-thread=false\n"					\
55   "simple-file=false\n"						\
56   "disable-feature=experimental\n"				\
57   "segmentation=4/4\n"						\
58   "\n"								\
59   "[thread]\n"							\
60   "model=super-threaded\n"					\
61   "super-threaded-scope=channel\n"				\
62   "lock-global=ags-thread\n"					\
63   "lock-parent=ags-recycling-thread\n"				\
64   "thread-pool-max-unused-threads=8\n"				\
65   "max-precision=125\n"						\
66   "\n"								\
67   "[soundcard-0]\n"						\
68   "backend=alsa\n"						\
69   "device=default\n"						\
70   "samplerate=44100\n"						\
71   "buffer-size=1024\n"						\
72   "pcm-channels=2\n"						\
73   "dsp-channels=2\n"						\
74   "format=16\n"							\
75   "\n"								\
76   "[sequencer-0]\n"						\
77   "backend=alsa\n"						\
78   "device=default\n"						\
79   "\n"								\
80   "[recall]\n"							\
81   "auto-sense=true\n"						\
82   "\n"
83 
84 #define AGS_FUNCTIONAL_OSC_SERVER_TEST_APPLY_CONFIG_ARGUMENT "[generic]\n" \
85   "autosave-thread=false\n"						\
86   "simple-file=false\n"							\
87   "disable-feature=experimental\n"					\
88   "segmentation=4/4\n"							\
89   "\n"									\
90   "[thread]\n"								\
91   "model=super-threaded\n"						\
92   "super-threaded-scope=channel\n"					\
93   "lock-global=ags-thread\n"						\
94   "lock-parent=ags-recycling-thread\n"					\
95   "thread-pool-max-unused-threads=8\n"					\
96   "max-precision=125\n"							\
97   "\n"									\
98   "[soundcard-0]\n"							\
99   "backend=alsa\n"							\
100   "device=default\n"							\
101   "samplerate=44100\n"							\
102   "buffer-size=256\n"							\
103   "pcm-channels=2\n"							\
104   "dsp-channels=2\n"							\
105   "format=16\n"								\
106   "\n"									\
107   "[recall]\n"								\
108   "auto-sense=true\n"							\
109   "\n"
110 
111 #define AGS_FUNCTIONAL_OSC_SERVER_TEST_METER_PACKET_COUNT (16 * 30)
112 
113 GThread *add_thread = NULL;
114 
115 AgsApplicationContext *application_context;
116 
117 AgsAudio *drum;
118 
119 AgsOscServer *osc_server;
120 AgsOscClient *osc_client;
121 
122 GObject *default_soundcard;
123 
124 GMainLoop *main_loop;
125 
126 gpointer
ags_functional_osc_server_test_add_thread(gpointer data)127 ags_functional_osc_server_test_add_thread(gpointer data)
128 {
129   CU_pSuite pSuite = NULL;
130 
131   putenv("LC_ALL=C");
132   putenv("LANG=C");
133 
134   putenv("LADSPA_PATH=\"\"");
135   putenv("DSSI_PATH=\"\"");
136   putenv("LV2_PATH=\"\"");
137 
138   /* initialize the CUnit test registry */
139   if(CUE_SUCCESS != CU_initialize_registry()){
140     g_thread_exit(GINT_TO_POINTER(CU_get_error()));
141   }
142 
143   /* add a suite to the registry */
144   pSuite = CU_add_suite("AgsFunctionalOscServerTest", ags_functional_osc_server_test_init_suite, ags_functional_osc_server_test_clean_suite);
145 
146   if(pSuite == NULL){
147     CU_cleanup_registry();
148 
149     g_thread_exit(GINT_TO_POINTER(CU_get_error()));
150   }
151 
152   /* add the tests to the suite */
153   if((CU_add_test(pSuite, "test of AgsOscServer providing action controller", ags_functional_osc_server_test_action_controller) == NULL) ||
154      (CU_add_test(pSuite, "test of AgsOscServer providing config controller", ags_functional_osc_server_test_config_controller) == NULL) ||
155      (CU_add_test(pSuite, "test of AgsOscServer providing info controller", ags_functional_osc_server_test_info_controller) == NULL) ||
156      (CU_add_test(pSuite, "test of AgsOscServer providing meter controller", ags_functional_osc_server_test_meter_controller) == NULL) ||
157      (CU_add_test(pSuite, "test of AgsOscServer providing node controller", ags_functional_osc_server_test_node_controller) == NULL) ||
158      (CU_add_test(pSuite, "test of AgsOscServer providing renew controller", ags_functional_osc_server_test_renew_controller) == NULL) ||
159      (CU_add_test(pSuite, "test of AgsOscServer providing status controller", ags_functional_osc_server_test_status_controller) == NULL)){
160     CU_cleanup_registry();
161 
162     g_thread_exit(GINT_TO_POINTER(CU_get_error()));
163   }
164 
165   /* Run all tests using the CUnit Basic interface */
166   CU_basic_set_mode(CU_BRM_VERBOSE);
167   CU_basic_run_tests();
168 
169   CU_cleanup_registry();
170 
171   g_thread_exit(GINT_TO_POINTER(CU_get_error()));
172 
173   return(NULL);
174 }
175 
176 /* The suite initialization function.
177  * Opens the temporary file used by the tests.
178  * Returns zero on success, non-zero otherwise.
179  */
180 int
ags_functional_osc_server_test_init_suite()181 ags_functional_osc_server_test_init_suite()
182 {
183   AgsConfig *config;
184 
185   GList *start_audio;
186 
187   ags_priority_load_defaults(ags_priority_get_instance());
188 
189   config = ags_config_get_instance();
190   ags_config_load_from_data(config,
191 			    AGS_FUNCTIONAL_OSC_SERVER_TEST_CONFIG,
192 			    strlen(AGS_FUNCTIONAL_OSC_SERVER_TEST_CONFIG));
193 
194   application_context = ags_audio_application_context_new();
195   g_object_ref(application_context);
196 
197   ags_application_context_prepare(application_context);
198   ags_application_context_setup(application_context);
199 
200   default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
201 
202   /* drum */
203   drum = ags_audio_new(default_soundcard);
204   g_object_ref(drum);
205 
206   g_object_set(drum,
207 	       "audio-name", "test-drum",
208 	       NULL);
209 
210   ags_audio_set_flags(drum,
211 		      (AGS_AUDIO_OUTPUT_HAS_RECYCLING |
212 		       AGS_AUDIO_INPUT_HAS_RECYCLING |
213 		       AGS_AUDIO_SYNC |
214 		       AGS_AUDIO_ASYNC));
215 
216   ags_audio_set_ability_flags(drum, (AGS_SOUND_ABILITY_PLAYBACK |
217 				     AGS_SOUND_ABILITY_SEQUENCER |
218 				     AGS_SOUND_ABILITY_NOTATION));
219 
220   ags_audio_set_audio_channels(drum,
221 			       2, 0);
222 
223   ags_audio_set_pads(drum,
224 		     AGS_TYPE_OUTPUT,
225 		     1, 0);
226   ags_audio_set_pads(drum,
227 		     AGS_TYPE_INPUT,
228 		     8, 0);
229 
230   start_audio = ags_sound_provider_get_audio(AGS_SOUND_PROVIDER(application_context));
231   ags_sound_provider_set_audio(AGS_SOUND_PROVIDER(application_context),
232 			       g_list_prepend(start_audio,
233 					      drum));
234 
235   /* ags-volume */
236   ags_recall_factory_create(drum,
237 			    NULL, NULL,
238 			    "ags-volume",
239 			    0, 2,
240 			    0, 8,
241 			    (AGS_RECALL_FACTORY_INPUT |
242 			     AGS_RECALL_FACTORY_PLAY |
243 			     AGS_RECALL_FACTORY_RECALL |
244 			     AGS_RECALL_FACTORY_ADD),
245 			    0);
246 
247   /* ags-mute */
248   ags_recall_factory_create(drum,
249 			    NULL, NULL,
250 			    "ags-mute",
251 			    0, 2,
252 			    0, 8,
253 			    (AGS_RECALL_FACTORY_INPUT,
254 			     AGS_RECALL_FACTORY_PLAY |
255 			     AGS_RECALL_FACTORY_RECALL |
256 			     AGS_RECALL_FACTORY_ADD),
257 			    0);
258 
259   /* ags-peak */
260   ags_recall_factory_create(drum,
261 			    NULL, NULL,
262 			    "ags-peak",
263 			    0, 2,
264 			    0, 8,
265 			    (AGS_RECALL_FACTORY_INPUT |
266 			     AGS_RECALL_FACTORY_PLAY |
267 			     AGS_RECALL_FACTORY_RECALL |
268 			     AGS_RECALL_FACTORY_ADD),
269 			    0);
270 
271   ags_connectable_connect(AGS_CONNECTABLE(drum));
272 
273   /* OSC server */
274   signal(SIGPIPE, SIG_IGN);
275 
276   osc_server = ags_osc_server_new();
277 
278   osc_server->accept_delay->tv_nsec = AGS_NSEC_PER_SEC / 30;
279   osc_server->dispatch_delay->tv_nsec = AGS_NSEC_PER_SEC / 30;
280 
281   ags_osc_server_set_flags(osc_server,
282 			   (AGS_OSC_SERVER_INET4 |
283 			    AGS_OSC_SERVER_TCP));
284 
285   ags_osc_server_add_default_controller(osc_server);
286 
287   ags_osc_server_start(osc_server);
288 
289   sleep(5);
290 
291   /* OSC client */
292   osc_client = ags_osc_client_new();
293   ags_osc_client_set_flags(osc_client,
294 			   (AGS_OSC_CLIENT_INET4 |
295 			    AGS_OSC_CLIENT_TCP));
296 
297   ags_osc_client_connect(osc_client);
298 
299   /* set work-around for arm */
300   g_object_set(osc_client->ip4_socket,
301 	       "blocking", FALSE,
302 	       NULL);
303 
304 #if 0
305   g_object_set(osc_client->ip6_socket,
306 	       "blocking", FALSE,
307 	       NULL);
308 #endif
309 
310   sleep(5);
311 
312   return(0);
313 }
314 
315 /* The suite cleanup function.
316  * Closes the temporary file used by the tests.
317  * Returns zero on success, non-zero otherwise.
318  */
319 int
ags_functional_osc_server_test_clean_suite()320 ags_functional_osc_server_test_clean_suite()
321 {
322   close(osc_client->ip4_fd);
323 
324   ags_osc_server_stop(osc_server);
325 
326   g_main_loop_quit(main_loop);
327 
328   return(0);
329 }
330 
331 void
ags_functional_osc_server_test_action_controller()332 ags_functional_osc_server_test_action_controller()
333 {
334   guchar *buffer;
335   guchar *packet;
336 
337   guint buffer_length;
338   gboolean retval;
339 
340   static const guchar *start_soundcard_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSoundcard\x00\x00start\x00\x00\x00";
341   static const guchar *start_sequencer_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSequencer\x00\x00start\x00\x00\x00";
342   static const guchar *start_audio_message =     "/action\x00,ss\x00/AgsSoundProvider/AgsAudio[0]\x00\x00\x00start\x00\x00\x00";
343   static const guchar *stop_soundcard_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSoundcard\x00\x00stop\x00\x00\x00\x00";
344   static const guchar *stop_sequencer_message = "/action\x00,ss\x00/AgsSoundProvider/AgsSequencer\x00\x00stop\x00\x00\x00\x00";
345   static const guchar *stop_audio_message =     "/action\x00,ss\x00/AgsSoundProvider/AgsAudio[0]\x00\x00\x00stop\x00\x00\x00\x00";
346 
347   static const guint start_soundcard_message_size = 52;
348   static const guint start_sequencer_message_size = 52;
349   static const guint start_audio_message_size = 52;
350   static const guint stop_soundcard_message_size = 52;
351   static const guint stop_sequencer_message_size = 52;
352   static const guint stop_audio_message_size = 52;
353 
354   CU_ASSERT(osc_server->ip4_fd != -1);
355   CU_ASSERT(osc_client->ip4_fd != -1);
356 
357   /* start soundcard */
358   packet = (guchar *) malloc((4 + start_soundcard_message_size) * sizeof(guchar));
359 
360   ags_osc_buffer_util_put_int32(packet,
361 				start_soundcard_message_size);
362   memcpy(packet + 4, start_soundcard_message, (start_soundcard_message_size) * sizeof(guchar));
363 
364   buffer = ags_osc_util_slip_encode(packet,
365 				    4 + start_soundcard_message_size,
366 				    &buffer_length);
367 
368   CU_ASSERT(buffer_length - 2 >= 4 + start_soundcard_message_size);
369 
370   retval = ags_osc_client_write_bytes(osc_client,
371 				      buffer, buffer_length);
372 
373   CU_ASSERT(retval == TRUE);
374 
375   sleep(5);
376 
377   /* start sequencer */
378   packet = (guchar *) malloc((4 + start_sequencer_message_size) * sizeof(guchar));
379 
380   ags_osc_buffer_util_put_int32(packet,
381 				start_sequencer_message_size);
382   memcpy(packet + 4, start_sequencer_message, (start_sequencer_message_size) * sizeof(guchar));
383 
384   buffer = ags_osc_util_slip_encode(packet,
385 				    4 + start_sequencer_message_size,
386 				    &buffer_length);
387 
388   CU_ASSERT(buffer_length - 2 >= 4 + start_sequencer_message_size);
389 
390   retval = ags_osc_client_write_bytes(osc_client,
391 				      buffer, buffer_length);
392 
393   CU_ASSERT(retval == TRUE);
394 
395   sleep(5);
396 
397   /* start audio */
398   packet = (guchar *) malloc((4 + start_audio_message_size) * sizeof(guchar));
399 
400   ags_osc_buffer_util_put_int32(packet,
401 				start_audio_message_size);
402   memcpy(packet + 4, start_audio_message, (start_audio_message_size) * sizeof(guchar));
403 
404   buffer = ags_osc_util_slip_encode(packet,
405 				    4 + start_audio_message_size,
406 				    &buffer_length);
407 
408   CU_ASSERT(buffer_length - 2 >= 4 + start_audio_message_size);
409 
410   retval = ags_osc_client_write_bytes(osc_client,
411 				      buffer, buffer_length);
412 
413   CU_ASSERT(retval == TRUE);
414 
415   sleep(5);
416 
417   /* stop soundcard */
418   packet = (guchar *) malloc((4 + stop_soundcard_message_size) * sizeof(guchar));
419 
420   ags_osc_buffer_util_put_int32(packet,
421 				stop_soundcard_message_size);
422   memcpy(packet + 4, stop_soundcard_message, (stop_soundcard_message_size) * sizeof(guchar));
423 
424   buffer = ags_osc_util_slip_encode(packet,
425 				    4 + stop_soundcard_message_size,
426 				    &buffer_length);
427 
428   CU_ASSERT(buffer_length - 2 >= 4 + stop_soundcard_message_size);
429 
430   retval = ags_osc_client_write_bytes(osc_client,
431 				      buffer, buffer_length);
432 
433   CU_ASSERT(retval == TRUE);
434 
435   sleep(5);
436 
437   /* stop sequencer */
438   packet = (guchar *) malloc((4 + stop_sequencer_message_size) * sizeof(guchar));
439 
440   ags_osc_buffer_util_put_int32(packet,
441 				stop_sequencer_message_size);
442   memcpy(packet + 4, stop_sequencer_message, (stop_sequencer_message_size) * sizeof(guchar));
443 
444   buffer = ags_osc_util_slip_encode(packet,
445 				    4 + stop_sequencer_message_size,
446 				    &buffer_length);
447 
448   CU_ASSERT(buffer_length - 2 >= 4 + stop_sequencer_message_size);
449 
450   retval = ags_osc_client_write_bytes(osc_client,
451 				      buffer, buffer_length);
452 
453   CU_ASSERT(retval == TRUE);
454 
455   sleep(5);
456 
457   /* stop audio */
458   packet = (guchar *) malloc((4 + stop_audio_message_size) * sizeof(guchar));
459 
460   ags_osc_buffer_util_put_int32(packet,
461 				stop_audio_message_size);
462   memcpy(packet + 4, stop_audio_message, (stop_audio_message_size) * sizeof(guchar));
463 
464   buffer = ags_osc_util_slip_encode(packet,
465 				    4 + stop_audio_message_size,
466 				    &buffer_length);
467 
468   CU_ASSERT(buffer_length - 2 >= 4 + stop_audio_message_size);
469 
470   retval = ags_osc_client_write_bytes(osc_client,
471 				      buffer, buffer_length);
472 
473   CU_ASSERT(retval == TRUE);
474 
475   sleep(5);
476 }
477 
478 void
ags_functional_osc_server_test_config_controller()479 ags_functional_osc_server_test_config_controller()
480 {
481   guchar *message;
482   guchar *buffer;
483   guchar *packet;
484 
485   guint config_length;
486   guint length;
487   guint buffer_length;
488   gboolean retval;
489 
490   static const guchar *config_message = "/config\x00,s\x00\x00";
491 
492   static const guint config_message_size = 12;
493 
494   CU_ASSERT(osc_server->ip4_fd != -1);
495   CU_ASSERT(osc_client->ip4_fd != -1);
496 
497   /* apply config */
498   config_length = strlen(AGS_FUNCTIONAL_OSC_SERVER_TEST_APPLY_CONFIG_ARGUMENT);
499 
500   length = config_message_size + (4 * ceil((double) (config_length + 1) / 4.0));
501 
502   message = (guchar *) malloc(length * sizeof(guchar));
503   memset(message, 0, length * sizeof(guchar));
504 
505   memcpy(message, config_message, config_message_size * sizeof(guchar));
506   memcpy(message + config_message_size, AGS_FUNCTIONAL_OSC_SERVER_TEST_APPLY_CONFIG_ARGUMENT, config_length * sizeof(guchar));
507 
508   packet = (guchar *) malloc((4 + length) * sizeof(guchar));
509 
510   ags_osc_buffer_util_put_int32(packet,
511 				length);
512   memcpy(packet + 4, message, (length) * sizeof(guchar));
513 
514   buffer = ags_osc_util_slip_encode(packet,
515 				    4 + length,
516 				    &buffer_length);
517 
518   CU_ASSERT(buffer_length - 2 >= 4 + length);
519 
520   retval = ags_osc_client_write_bytes(osc_client,
521 				      buffer, buffer_length);
522 
523   CU_ASSERT(retval == TRUE);
524 
525   sleep(5);
526 }
527 
528 void
ags_functional_osc_server_test_info_controller()529 ags_functional_osc_server_test_info_controller()
530 {
531   guchar *buffer;
532   guchar *packet;
533 
534   guint buffer_length;
535   gboolean retval;
536 
537   static const guchar *info_message = "/info\x00\x00\x00";
538 
539   static const guint info_message_size = 8;
540 
541   CU_ASSERT(osc_server->ip4_fd != -1);
542   CU_ASSERT(osc_client->ip4_fd != -1);
543 
544   packet = (guchar *) malloc((4 + info_message_size) * sizeof(guchar));
545 
546   ags_osc_buffer_util_put_int32(packet,
547 				info_message_size);
548   memcpy(packet + 4, info_message, (info_message_size) * sizeof(guchar));
549 
550   buffer = ags_osc_util_slip_encode(packet,
551 				    4 + info_message_size,
552 				    &buffer_length);
553 
554   CU_ASSERT(buffer_length - 2 >= 4 + info_message_size);
555 
556   retval = ags_osc_client_write_bytes(osc_client,
557 				      buffer, buffer_length);
558 
559   CU_ASSERT(retval == TRUE);
560 
561   sleep(5);
562 }
563 
564 void
ags_functional_osc_server_test_meter_controller()565 ags_functional_osc_server_test_meter_controller()
566 {
567   struct timespec start_time;
568   struct timespec timeout_delay;
569   struct timespec idle_delay;
570 
571   guchar *buffer;
572   guchar *packet;
573 
574   guint buffer_length;
575   guint meter_packet_count;
576   guint i;
577   gboolean retval;
578 
579   static const guchar *enable_peak_message = "/meter\x00\x00,sT\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-15]/AgsPeakChannel[0]/AgsPort[\"./peak[0]\"]:value\x00";
580   static const guchar *disable_peak_message = "/meter\x00\x00,sF\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-15]/AgsPeakChannel[0]/AgsPort[\"./peak[0]\"]:value\x00";
581 
582   static const guint enable_peak_message_size = 112;
583   static const guint disable_peak_message_size = 112;
584 
585   CU_ASSERT(osc_server->ip4_fd != -1);
586   CU_ASSERT(osc_client->ip4_fd != -1);
587 
588   /* enable meter */
589   packet = (guchar *) malloc((4 + enable_peak_message_size) * sizeof(guchar));
590 
591   ags_osc_buffer_util_put_int32(packet,
592 				enable_peak_message_size);
593   memcpy(packet + 4, enable_peak_message, (enable_peak_message_size) * sizeof(guchar));
594 
595   buffer = ags_osc_util_slip_encode(packet,
596 				    4 + enable_peak_message_size,
597 				    &buffer_length);
598 
599   CU_ASSERT(buffer_length - 2 >= 4 + enable_peak_message_size);
600 
601   retval = ags_osc_client_write_bytes(osc_client,
602 				      buffer, buffer_length);
603 
604   CU_ASSERT(retval == TRUE);
605 
606   /* read packets */
607 #ifdef __APPLE__
608   host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
609 
610   clock_get_time(cclock, &mts);
611   mach_port_deallocate(mach_task_self(), cclock);
612 
613   start_time.tv_sec = mts.tv_sec;
614   start_time.tv_nsec = mts.tv_nsec;
615 #else
616   clock_gettime(CLOCK_MONOTONIC, &start_time);
617 #endif
618 
619   timeout_delay.tv_sec = 180;
620   timeout_delay.tv_nsec = 0;
621 
622   idle_delay.tv_sec = 0;
623   idle_delay.tv_nsec = AGS_NSEC_PER_SEC / 30;
624 
625   meter_packet_count = 0;
626   i = 0;
627 
628   while(!ags_time_timeout_expired(&start_time,
629 				  &timeout_delay)){
630     guchar *current_data;
631     guchar *current_packet;
632     gchar *address_pattern;
633 
634     guint data_length;
635 
636     current_data = ags_osc_client_read_bytes(osc_client,
637 					     &data_length);
638 
639     if(current_data != NULL){
640       current_packet = ags_osc_util_slip_decode(current_data,
641 						data_length,
642 						NULL);
643 
644       if(data_length >= 8){
645 	ags_osc_buffer_util_get_message(current_packet + 4,
646 					&address_pattern, NULL);
647 
648 	if(!g_strcmp0(address_pattern,
649 		      "/meter")){
650 	  meter_packet_count++;
651 
652 	  i++;
653 	}
654       }
655 
656       free(current_packet);
657     }
658 
659     if(i == 16){
660       i = 0;
661 
662       nanosleep(&idle_delay,
663 		NULL);
664     }
665   }
666 
667   CU_ASSERT(meter_packet_count >= AGS_FUNCTIONAL_OSC_SERVER_TEST_METER_PACKET_COUNT);
668 
669   /* disable meter */
670   packet = (guchar *) malloc((4 + disable_peak_message_size) * sizeof(guchar));
671 
672   ags_osc_buffer_util_put_int32(packet,
673 				disable_peak_message_size);
674   memcpy(packet + 4, disable_peak_message, (disable_peak_message_size) * sizeof(guchar));
675 
676   buffer = ags_osc_util_slip_encode(packet,
677 				    4 + disable_peak_message_size,
678 				    &buffer_length);
679 
680   CU_ASSERT(buffer_length - 2 >= 4 + disable_peak_message_size);
681 
682   retval = ags_osc_client_write_bytes(osc_client,
683 				      buffer, buffer_length);
684 
685   CU_ASSERT(retval == TRUE);
686 }
687 
688 void
ags_functional_osc_server_test_node_controller()689 ags_functional_osc_server_test_node_controller()
690 {
691   struct timespec start_time;
692   struct timespec timeout_delay;
693 
694   guchar *buffer;
695   guchar *packet;
696 
697   guint buffer_length;
698   gboolean retval;
699   gboolean success;
700 
701   static const guchar *volume_message = "/node\x00\x00\x00,s\x00\x00/AgsSoundProvider/AgsAudio[\"test-drum\"]/AgsInput[0-1]/AgsVolumeChannel[0]/AgsPort[\"./volume[0]\"]:value\x00\x00";
702 
703   static const guint volume_message_size = 116;
704 
705   CU_ASSERT(osc_server->ip4_fd != -1);
706   CU_ASSERT(osc_client->ip4_fd != -1);
707 
708   /* volume message */
709   packet = (guchar *) malloc((4 + volume_message_size) * sizeof(guchar));
710 
711   ags_osc_buffer_util_put_int32(packet,
712 				volume_message_size);
713   memcpy(packet + 4, volume_message, (volume_message_size) * sizeof(guchar));
714 
715   buffer = ags_osc_util_slip_encode(packet,
716 				    4 + volume_message_size,
717 				    &buffer_length);
718 
719   CU_ASSERT(buffer_length - 2 >= 4 + volume_message_size);
720 
721   retval = ags_osc_client_write_bytes(osc_client,
722 				      buffer, buffer_length);
723 
724   CU_ASSERT(retval == TRUE);
725 
726   /* read volume */
727 #ifdef __APPLE__
728   host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
729 
730   clock_get_time(cclock, &mts);
731   mach_port_deallocate(mach_task_self(), cclock);
732 
733   start_time.tv_sec = mts.tv_sec;
734   start_time.tv_nsec = mts.tv_nsec;
735 #else
736   clock_gettime(CLOCK_MONOTONIC, &start_time);
737 #endif
738 
739   timeout_delay.tv_sec = 10;
740   timeout_delay.tv_nsec = 0;
741 
742   success = FALSE;
743 
744   while(!ags_time_timeout_expired(&start_time,
745 				  &timeout_delay)){
746     guchar *current_data;
747     guchar *current_packet;
748     gchar *address_pattern;
749 
750     guint data_length;
751 
752     current_data = ags_osc_client_read_bytes(osc_client,
753 					     &data_length);
754 
755     if(current_data != NULL){
756       current_packet = ags_osc_util_slip_decode(current_data,
757 						data_length,
758 						NULL);
759 
760       if(data_length >= 8){
761 	ags_osc_buffer_util_get_message(current_packet + 4,
762 					&address_pattern, NULL);
763 
764 	if(!g_strcmp0(address_pattern,
765 		      "/node")){
766 	  success = TRUE;
767 
768 	  break;
769 	}
770       }
771     }
772   }
773 
774   CU_ASSERT(success == TRUE);
775 }
776 
777 void
ags_functional_osc_server_test_renew_controller()778 ags_functional_osc_server_test_renew_controller()
779 {
780   guchar *buffer;
781   guchar *packet;
782 
783   guint buffer_length;
784   gboolean retval;
785 
786   static const guchar *mute_message = "/renew\x00\x00,sf\x00/AgsSoundProvider/AgsAudio[\"test-panel\"]/AgsInput[0-1]/AgsMuteChannel[0]/AgsPort[\"./muted[0]\"]:value\x00\x00\x00\x00\x00\x00";
787 
788   static const guint mute_message_size = 120;
789 
790   CU_ASSERT(osc_server->ip4_fd != -1);
791   CU_ASSERT(osc_client->ip4_fd != -1);
792 
793   /* mute message */
794   packet = (guchar *) malloc((4 + mute_message_size) * sizeof(guchar));
795 
796   ags_osc_buffer_util_put_int32(packet,
797 				mute_message_size);
798   memcpy(packet + 4, mute_message, (mute_message_size) * sizeof(guchar));
799 
800   buffer = ags_osc_util_slip_encode(packet,
801 				    4 + mute_message_size,
802 				    &buffer_length);
803 
804   CU_ASSERT(buffer_length - 2 >= 4 + mute_message_size);
805 
806   retval = ags_osc_client_write_bytes(osc_client,
807 				      buffer, buffer_length);
808 
809   CU_ASSERT(retval == TRUE);
810 }
811 
812 void
ags_functional_osc_server_test_status_controller()813 ags_functional_osc_server_test_status_controller()
814 {
815   guchar *buffer;
816   guchar *packet;
817 
818   guint buffer_length;
819   gboolean retval;
820 
821   static const guchar *status_message = "/status\x00,\x00\x00\x00";
822 
823   static const guint status_message_size = 12;
824 
825   CU_ASSERT(osc_server->ip4_fd != -1);
826   CU_ASSERT(osc_client->ip4_fd != -1);
827 
828   /* status message */
829   packet = (guchar *) malloc((4 + status_message_size) * sizeof(guchar));
830 
831   ags_osc_buffer_util_put_int32(packet,
832 				status_message_size);
833   memcpy(packet + 4, status_message, (status_message_size) * sizeof(guchar));
834 
835   buffer = ags_osc_util_slip_encode(packet,
836 				    4 + status_message_size,
837 				    &buffer_length);
838 
839   CU_ASSERT(buffer_length - 2 >= 4 + status_message_size);
840 
841   retval = ags_osc_client_write_bytes(osc_client,
842 				      buffer, buffer_length);
843 
844   CU_ASSERT(retval == TRUE);
845 }
846 
847 int
main(int argc,char ** argv)848 main(int argc, char **argv)
849 {
850   int retval;
851 
852   add_thread = g_thread_new("libags_audio.so - functional OSC server test",
853 			    ags_functional_osc_server_test_add_thread,
854 			    NULL);
855 
856   main_loop = g_main_loop_new(g_main_context_default(),
857 			      TRUE);
858   g_main_loop_run(main_loop);
859 
860   retval = GPOINTER_TO_INT(g_thread_join(add_thread));
861 
862   return(retval);
863 }
864