1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2018 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/Automated.h>
25 #include <CUnit/Basic.h>
26 
27 #include <ags/libags.h>
28 #include <ags/libags-audio.h>
29 
30 int ags_buffer_audio_signal_test_init_suite();
31 int ags_buffer_audio_signal_test_clean_suite();
32 
33 void ags_buffer_audio_signal_test_run_inter();
34 
35 void ags_buffer_audio_signal_test_run_inter_callback(AgsRecall *recall, gpointer data);
36 
37 #define AGS_BUFFER_AUDIO_SIGNAL_TEST_RUN_INTER_AUDIO_SIGNAL_LENGTH (24)
38 
39 AgsDevout *devout;
40 AgsAudio *audio;
41 
42 GList *recall;
43 
44 guint test_run_inter_invoke_count = 0;
45 
46 AgsApplicationContext *application_context;
47 
48 /* The suite initialization function.
49  * Opens the temporary file used by the tests.
50  * Returns zero on success, non-zero otherwise.
51  */
52 int
ags_buffer_audio_signal_test_init_suite()53 ags_buffer_audio_signal_test_init_suite()
54 {
55   ags_priority_load_defaults(ags_priority_get_instance());
56 
57   application_context = ags_audio_application_context_new();
58   g_object_ref(application_context);
59 
60   ags_application_context_prepare(application_context);
61   ags_application_context_setup(application_context);
62 
63   /* create soundcard */
64   devout = g_object_new(AGS_TYPE_DEVOUT,
65 			NULL);
66   g_object_ref(devout);
67 
68   /* create audio */
69   audio = ags_audio_new(devout);
70   g_object_ref(audio);
71 
72   ags_audio_set_flags(audio,
73 		      (AGS_AUDIO_OUTPUT_HAS_RECYCLING |
74 		       AGS_AUDIO_INPUT_HAS_RECYCLING));
75   ags_audio_set_ability_flags(audio,
76 			      AGS_SOUND_ABILITY_PLAYBACK);
77 
78   /* create input/output */
79   ags_audio_set_audio_channels(audio,
80 			       1, 0);
81 
82   ags_audio_set_pads(audio,
83 		     AGS_TYPE_OUTPUT,
84 		     1, 0);
85   ags_audio_set_pads(audio,
86 		     AGS_TYPE_INPUT,
87  		     1, 0);
88 
89   ags_channel_set_ability_flags(audio->output,
90 				AGS_SOUND_ABILITY_PLAYBACK);
91 
92   ags_channel_set_ability_flags(audio->input,
93 				AGS_SOUND_ABILITY_PLAYBACK);
94 
95   ags_connectable_connect(AGS_CONNECTABLE(audio));
96 
97   ags_connectable_connect(AGS_CONNECTABLE(audio->output));
98   ags_connectable_connect(AGS_CONNECTABLE(audio->input));
99 
100   /* create ags-buffer */
101   recall = ags_recall_factory_create(audio,
102 				     NULL, NULL,
103 				     "ags-buffer",
104 				     0, 1,
105 				     0, 1,
106 				     (AGS_RECALL_FACTORY_INPUT |
107 				      AGS_RECALL_FACTORY_ADD |
108 				      AGS_RECALL_FACTORY_PLAY |
109 				      AGS_RECALL_FACTORY_RECALL),
110 				     0);
111 
112   return(0);
113 }
114 
115 /* The suite cleanup function.
116  * Closes the temporary file used by the tests.
117  * Returns zero on success, non-zero otherwise.
118  */
119 int
ags_buffer_audio_signal_test_clean_suite()120 ags_buffer_audio_signal_test_clean_suite()
121 {
122   g_object_run_dispose(devout);
123   g_object_unref(devout);
124 
125   g_object_run_dispose(audio);
126   g_object_unref(audio);
127 
128   return(0);
129 }
130 
131 void
ags_buffer_audio_signal_test_run_inter_callback(AgsRecall * recall,gpointer data)132 ags_buffer_audio_signal_test_run_inter_callback(AgsRecall *recall, gpointer data)
133 {
134   test_run_inter_invoke_count += 1;
135 }
136 
137 void
ags_buffer_audio_signal_test_run_inter()138 ags_buffer_audio_signal_test_run_inter()
139 {
140   AgsChannel *output;
141   AgsChannel *input;
142   AgsRecycling *recycling;
143   AgsAudioSignal *audio_signal;
144   AgsRecallID *output_audio_recall_id;
145   AgsRecallID *input_audio_recall_id;
146   AgsRecallID *output_recall_id;
147   AgsRecallID *input_recall_id;
148   AgsRecyclingContext *output_recycling_context;
149   AgsRecyclingContext *input_recycling_context;
150 
151   GList *start_list, *list;
152   GList *start_recall_recycling, *recall_recycling;
153   GList *start_recall_audio_signal, *recall_audio_signal;
154 
155   guint i;
156 
157   output = audio->output;
158   input = audio->input;
159 
160   recycling = input->first_recycling;
161 
162   /* output - create recall id and recycling context */
163   output_audio_recall_id = ags_recall_id_new();
164   ags_recall_id_set_sound_scope(output_audio_recall_id,
165 				AGS_SOUND_SCOPE_PLAYBACK);
166   ags_audio_add_recall_id(audio,
167 			  output_audio_recall_id);
168 
169   output_recall_id = ags_recall_id_new();
170   ags_recall_id_set_sound_scope(output_recall_id,
171 				AGS_SOUND_SCOPE_PLAYBACK);
172   ags_channel_add_recall_id(output,
173 			    output_recall_id);
174 
175   output_recycling_context = ags_recycling_context_new(1);
176   ags_recycling_context_replace(output_recycling_context,
177 				output->first_recycling,
178 				0);
179   ags_audio_add_recycling_context(audio,
180 				  output_recycling_context);
181 
182   g_object_set(output_audio_recall_id,
183 	       "recycling-context", output_recycling_context,
184 	       NULL);
185   g_object_set(output_recall_id,
186 	       "recycling-context", output_recycling_context,
187 	       NULL);
188 
189   g_object_set(output_recycling_context,
190 	       "recall-id", output_recall_id,
191 	       NULL);
192 
193   /* input - create recall id and recycling context */
194   input_audio_recall_id = ags_recall_id_new();
195   ags_recall_id_set_sound_scope(input_audio_recall_id,
196 				AGS_SOUND_SCOPE_PLAYBACK);
197   ags_audio_add_recall_id(audio,
198 			  input_audio_recall_id);
199 
200   input_recall_id = ags_recall_id_new();
201   ags_recall_id_set_sound_scope(input_recall_id,
202 				AGS_SOUND_SCOPE_PLAYBACK);
203   ags_channel_add_recall_id(input,
204 			    input_recall_id);
205 
206   input_recycling_context = ags_recycling_context_new(1);
207   ags_recycling_context_replace(input_recycling_context,
208 				recycling,
209 				0);
210   ags_audio_add_recycling_context(audio,
211 				  input_recycling_context);
212 
213   g_object_set(input_audio_recall_id,
214 	       "recycling-context", input_recycling_context,
215 	       NULL);
216   g_object_set(input_recall_id,
217 	       "recycling-context", input_recycling_context,
218 	       NULL);
219 
220   g_object_set(output_recycling_context,
221 	       "child", input_recycling_context,
222 	       NULL);
223 
224   g_object_set(input_recycling_context,
225 	       "recall-id", input_recall_id,
226 	       NULL);
227 
228   /* duplicate recall */
229   ags_audio_duplicate_recall(audio,
230 			     input_audio_recall_id,
231 			     0, 0,
232 			     0);
233   ags_channel_duplicate_recall(input,
234 			       input_recall_id);
235 
236   /* resolve recall */
237   ags_audio_resolve_recall(audio,
238 			   input_audio_recall_id);
239   ags_channel_resolve_recall(input,
240 			     input_recall_id);
241 
242   /* init recall */
243   ags_audio_init_recall(audio,
244 			input_audio_recall_id, (AGS_SOUND_STAGING_CHECK_RT_DATA |
245 						AGS_SOUND_STAGING_RUN_INIT_PRE |
246 						AGS_SOUND_STAGING_RUN_INIT_INTER |
247 						AGS_SOUND_STAGING_RUN_INIT_POST));
248 
249   ags_channel_init_recall(input,
250 			  input_recall_id, (AGS_SOUND_STAGING_CHECK_RT_DATA |
251 					    AGS_SOUND_STAGING_RUN_INIT_PRE |
252 					    AGS_SOUND_STAGING_RUN_INIT_INTER |
253 					    AGS_SOUND_STAGING_RUN_INIT_POST));
254 
255   /* create audio signal */
256   audio_signal = ags_audio_signal_new(devout,
257 				      recycling,
258 				      input_recall_id);
259   ags_audio_signal_stream_resize(audio_signal,
260 				 AGS_BUFFER_AUDIO_SIGNAL_TEST_RUN_INTER_AUDIO_SIGNAL_LENGTH);
261 
262   audio_signal->stream_current = audio_signal->stream;
263   ags_recycling_add_audio_signal(recycling,
264 				 audio_signal);
265 
266   /* test */
267   g_object_get(input,
268 	       "recall", &start_list,
269 	       NULL);
270 
271   list = ags_recall_find_type_with_recycling_context(start_list,
272 						     AGS_TYPE_BUFFER_CHANNEL_RUN,
273 						     input_recycling_context);
274 
275   g_object_get(list->data,
276 	       "child", &start_recall_recycling,
277 	       NULL);
278 
279   recall_recycling = ags_recall_find_recycling_context(start_recall_recycling,
280 						       input_recycling_context);
281 
282   g_object_get(start_recall_recycling->data,
283 	       "child", &start_recall_audio_signal,
284 	       NULL);
285 
286   recall_audio_signal = ags_recall_find_provider_with_recycling_context(start_recall_audio_signal,
287 									audio_signal,
288 									input_recycling_context);
289 
290   CU_ASSERT(recall_audio_signal != NULL);
291   CU_ASSERT(AGS_IS_BUFFER_AUDIO_SIGNAL(recall_audio_signal->data));
292   CU_ASSERT(AGS_RECALL_CLASS(AGS_BUFFER_AUDIO_SIGNAL_GET_CLASS(recall_audio_signal->data))->run_inter != NULL);
293 
294   g_signal_connect(recall_audio_signal->data, "run-inter",
295 		   G_CALLBACK(ags_buffer_audio_signal_test_run_inter_callback), NULL);
296 
297   for(i = 0; i < AGS_BUFFER_AUDIO_SIGNAL_TEST_RUN_INTER_AUDIO_SIGNAL_LENGTH; i++){
298     ags_recall_run_inter(recall_audio_signal->data);
299 
300     if(audio_signal->stream_current != NULL){
301       audio_signal->stream_current = audio_signal->stream_current->next;
302     }
303   }
304 
305   CU_ASSERT(test_run_inter_invoke_count == AGS_BUFFER_AUDIO_SIGNAL_TEST_RUN_INTER_AUDIO_SIGNAL_LENGTH);
306 }
307 
308 int
main(int argc,char ** argv)309 main(int argc, char **argv)
310 {
311   CU_pSuite pSuite = NULL;
312 
313   putenv("LC_ALL=C");
314   putenv("LANG=C");
315 
316   putenv("LADSPA_PATH=\"\"");
317   putenv("DSSI_PATH=\"\"");
318   putenv("LV2_PATH=\"\"");
319 
320   /* initialize the CUnit test registry */
321   if(CUE_SUCCESS != CU_initialize_registry()){
322     return CU_get_error();
323   }
324 
325   /* add a suite to the registry */
326   pSuite = CU_add_suite("AgsBufferAudioSignalTest", ags_buffer_audio_signal_test_init_suite, ags_buffer_audio_signal_test_clean_suite);
327 
328   if(pSuite == NULL){
329     CU_cleanup_registry();
330 
331     return CU_get_error();
332   }
333 
334   /* add the tests to the suite */
335   if((CU_add_test(pSuite, "test of AgsBufferAudioSignal run inter", ags_buffer_audio_signal_test_run_inter) == NULL)){
336     CU_cleanup_registry();
337 
338     return CU_get_error();
339   }
340 
341   /* Run all tests using the CUnit Basic interface */
342   CU_basic_set_mode(CU_BRM_VERBOSE);
343   CU_basic_run_tests();
344 
345   CU_cleanup_registry();
346 
347   return(CU_get_error());
348 }
349