1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2020 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 <ags/audio/ags_acceleration.h>
21
22 #include <stdlib.h>
23
24 #include <ags/i18n.h>
25
26 void ags_acceleration_class_init(AgsAccelerationClass *acceleration);
27 void ags_acceleration_init(AgsAcceleration *acceleration);
28 void ags_acceleration_set_property(GObject *gobject,
29 guint prop_id,
30 const GValue *value,
31 GParamSpec *param_spec);
32 void ags_acceleration_get_property(GObject *gobject,
33 guint prop_id,
34 GValue *value,
35 GParamSpec *param_spec);
36 void ags_acceleration_finalize(GObject *gobject);
37
38 /**
39 * SECTION:ags_acceleration
40 * @short_description: Acceleration class
41 * @title: AgsAcceleration
42 * @section_id:
43 * @include: ags/audio/ags_acceleration.h
44 *
45 * #AgsAcceleration represents a downhill-grade.
46 */
47
48 enum{
49 PROP_0,
50 PROP_X,
51 PROP_Y,
52 PROP_ACCELERATION_NAME,
53 };
54
55 static gpointer ags_acceleration_parent_class = NULL;
56
57 GType
ags_acceleration_get_type()58 ags_acceleration_get_type()
59 {
60 static volatile gsize g_define_type_id__volatile = 0;
61
62 if(g_once_init_enter (&g_define_type_id__volatile)){
63 GType ags_type_acceleration = 0;
64
65 static const GTypeInfo ags_acceleration_info = {
66 sizeof(AgsAccelerationClass),
67 NULL,
68 NULL,
69 (GClassInitFunc) ags_acceleration_class_init,
70 NULL,
71 NULL,
72 sizeof(AgsAcceleration),
73 0,
74 (GInstanceInitFunc) ags_acceleration_init,
75 };
76
77 ags_type_acceleration = g_type_register_static(G_TYPE_OBJECT,
78 "AgsAcceleration",
79 &ags_acceleration_info,
80 0);
81
82 g_once_init_leave(&g_define_type_id__volatile, ags_type_acceleration);
83 }
84
85 return g_define_type_id__volatile;
86 }
87
88 GType
ags_acceleration_flags_get_type()89 ags_acceleration_flags_get_type()
90 {
91 static volatile gsize g_flags_type_id__volatile;
92
93 if(g_once_init_enter (&g_flags_type_id__volatile)){
94 static const GFlagsValue values[] = {
95 { AGS_ACCELERATION_DEFAULT_START, "AGS_ACCELERATION_DEFAULT_START", "acceleration-default-start" },
96 { AGS_ACCELERATION_DEFAULT_END, "AGS_ACCELERATION_DEFAULT_END", "acceleration-default-end" },
97 { AGS_ACCELERATION_GUI, "AGS_ACCELERATION_GUI", "acceleration-gui" },
98 { AGS_ACCELERATION_RUNTIME, "AGS_ACCELERATION_RUNTIME", "acceleration-runtime" },
99 { AGS_ACCELERATION_HUMAN_READABLE, "AGS_ACCELERATION_HUMAN_READABLE", "acceleration-human-readable" },
100 { AGS_ACCELERATION_DEFAULT_LENGTH, "AGS_ACCELERATION_DEFAULT_LENGTH", "acceleration-default-length" },
101 { AGS_ACCELERATION_IS_SELECTED, "AGS_ACCELERATION_IS_SELECTED", "acceleration-is-selected" },
102 { 0, NULL, NULL }
103 };
104
105 GType g_flags_type_id = g_flags_register_static(g_intern_static_string("AgsAccelerationFlags"), values);
106
107 g_once_init_leave (&g_flags_type_id__volatile, g_flags_type_id);
108 }
109
110 return g_flags_type_id__volatile;
111 }
112
113 void
ags_acceleration_class_init(AgsAccelerationClass * acceleration)114 ags_acceleration_class_init(AgsAccelerationClass *acceleration)
115 {
116 GObjectClass *gobject;
117
118 GParamSpec *param_spec;
119
120 ags_acceleration_parent_class = g_type_class_peek_parent(acceleration);
121
122 gobject = (GObjectClass *) acceleration;
123
124 gobject->set_property = ags_acceleration_set_property;
125 gobject->get_property = ags_acceleration_get_property;
126
127 gobject->finalize = ags_acceleration_finalize;
128
129 /* properties */
130 /**
131 * AgsAcceleration:x:
132 *
133 * Acceleration offset x.
134 *
135 * Since: 3.0.0
136 */
137 param_spec = g_param_spec_uint("x",
138 i18n_pspec("offset x"),
139 i18n_pspec("The x offset"),
140 0,
141 G_MAXUINT32,
142 0,
143 G_PARAM_READABLE | G_PARAM_WRITABLE);
144 g_object_class_install_property(gobject,
145 PROP_X,
146 param_spec);
147
148 /**
149 * AgsAcceleration:y:
150 *
151 * Acceleration value y.
152 *
153 * Since: 3.0.0
154 */
155 param_spec = g_param_spec_double("y",
156 i18n_pspec("offset y"),
157 i18n_pspec("The y offset"),
158 -1.0 * G_MAXDOUBLE,
159 G_MAXDOUBLE,
160 0.0,
161 G_PARAM_READABLE | G_PARAM_WRITABLE);
162 g_object_class_install_property(gobject,
163 PROP_Y,
164 param_spec);
165
166 /**
167 * AgsAcceleration:acceleration-name:
168 *
169 * The acceleration's name.
170 *
171 * Since: 3.0.0
172 */
173 param_spec = g_param_spec_string("acceleration-name",
174 i18n_pspec("acceleration name"),
175 i18n_pspec("The acceleration's name"),
176 NULL,
177 G_PARAM_READABLE | G_PARAM_WRITABLE);
178 g_object_class_install_property(gobject,
179 PROP_ACCELERATION_NAME,
180 param_spec);
181 }
182
183 void
ags_acceleration_init(AgsAcceleration * acceleration)184 ags_acceleration_init(AgsAcceleration *acceleration)
185 {
186 acceleration->flags = 0;
187
188 /* acceleration mutex */
189 g_rec_mutex_init(&(acceleration->obj_mutex));
190
191 /* fields */
192 acceleration->x = 0;
193 acceleration->y = 0.0;
194
195 acceleration->acceleration_name = NULL;
196 }
197
198
199 void
ags_acceleration_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)200 ags_acceleration_set_property(GObject *gobject,
201 guint prop_id,
202 const GValue *value,
203 GParamSpec *param_spec)
204 {
205 AgsAcceleration *acceleration;
206
207 GRecMutex *acceleration_mutex;
208
209 acceleration = AGS_ACCELERATION(gobject);
210
211 /* get acceleration mutex */
212 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
213
214 switch(prop_id){
215 case PROP_X:
216 {
217 g_rec_mutex_lock(acceleration_mutex);
218
219 acceleration->x = g_value_get_uint(value);
220
221 g_rec_mutex_unlock(acceleration_mutex);
222 }
223 break;
224 case PROP_Y:
225 {
226 g_rec_mutex_lock(acceleration_mutex);
227
228 acceleration->y = g_value_get_double(value);
229
230 g_rec_mutex_unlock(acceleration_mutex);
231 }
232 break;
233 case PROP_ACCELERATION_NAME:
234 {
235 gchar *acceleration_name;
236
237 acceleration_name = g_value_get_string(value);
238
239 g_rec_mutex_lock(acceleration_mutex);
240
241 if(acceleration_name == acceleration->acceleration_name){
242 g_rec_mutex_unlock(acceleration_mutex);
243
244 return;
245 }
246
247 if(acceleration->acceleration_name != NULL){
248 g_free(acceleration->acceleration_name);
249 }
250
251 acceleration->acceleration_name = g_strdup(acceleration_name);
252
253 g_rec_mutex_unlock(acceleration_mutex);
254 }
255 break;
256 default:
257 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
258 break;
259 }
260 }
261
262 void
ags_acceleration_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)263 ags_acceleration_get_property(GObject *gobject,
264 guint prop_id,
265 GValue *value,
266 GParamSpec *param_spec)
267 {
268 AgsAcceleration *acceleration;
269
270 GRecMutex *acceleration_mutex;
271
272 acceleration = AGS_ACCELERATION(gobject);
273
274 /* get acceleration mutex */
275 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
276
277 switch(prop_id){
278 case PROP_X:
279 {
280 g_rec_mutex_lock(acceleration_mutex);
281
282 g_value_set_uint(value, acceleration->x);
283
284 g_rec_mutex_unlock(acceleration_mutex);
285 }
286 break;
287 case PROP_Y:
288 {
289 g_rec_mutex_lock(acceleration_mutex);
290
291 g_value_set_double(value, acceleration->y);
292
293 g_rec_mutex_unlock(acceleration_mutex);
294 }
295 break;
296 case PROP_ACCELERATION_NAME:
297 {
298 g_rec_mutex_lock(acceleration_mutex);
299
300 g_value_set_string(value, acceleration->acceleration_name);
301
302 g_rec_mutex_unlock(acceleration_mutex);
303 }
304 break;
305 default:
306 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
307 break;
308 }
309 }
310
311 void
ags_acceleration_finalize(GObject * gobject)312 ags_acceleration_finalize(GObject *gobject)
313 {
314 AgsAcceleration *acceleration;
315
316 acceleration = AGS_ACCELERATION(gobject);
317
318 if(acceleration->acceleration_name != NULL){
319 free(acceleration->acceleration_name);
320 }
321
322 /* call parent */
323 G_OBJECT_CLASS(ags_acceleration_parent_class)->finalize(gobject);
324 }
325
326 /**
327 * ags_acceleration_get_obj_mutex:
328 * @acceleration: the #AgsAcceleration
329 *
330 * Get object mutex.
331 *
332 * Returns: the #GRecMutex to lock @acceleration
333 *
334 * Since: 3.1.0
335 */
336 GRecMutex*
ags_acceleration_get_obj_mutex(AgsAcceleration * acceleration)337 ags_acceleration_get_obj_mutex(AgsAcceleration *acceleration)
338 {
339 if(!AGS_IS_ACCELERATION(acceleration)){
340 return(NULL);
341 }
342
343 return(AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration));
344 }
345
346 /**
347 * ags_acceleration_test_flags:
348 * @acceleration: the #AgsAcceleration
349 * @flags: the flags
350 *
351 * Test @flags to be set on @acceleration.
352 *
353 * Returns: %TRUE if flags are set, else %FALSE
354 *
355 * Since: 3.0.0
356 */
357 gboolean
ags_acceleration_test_flags(AgsAcceleration * acceleration,guint flags)358 ags_acceleration_test_flags(AgsAcceleration *acceleration, guint flags)
359 {
360 gboolean retval;
361
362 GRecMutex *acceleration_mutex;
363
364 if(!AGS_IS_ACCELERATION(acceleration)){
365 return(FALSE);
366 }
367
368 /* get acceleration mutex */
369 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
370
371 /* test */
372 g_rec_mutex_lock(acceleration_mutex);
373
374 retval = (flags & (acceleration->flags)) ? TRUE: FALSE;
375
376 g_rec_mutex_unlock(acceleration_mutex);
377
378 return(retval);
379 }
380
381 /**
382 * ags_acceleration_set_flags:
383 * @acceleration: the #AgsAcceleration
384 * @flags: the flags
385 *
386 * Set @flags on @acceleration.
387 *
388 * Since: 3.0.0
389 */
390 void
ags_acceleration_set_flags(AgsAcceleration * acceleration,guint flags)391 ags_acceleration_set_flags(AgsAcceleration *acceleration, guint flags)
392 {
393 GRecMutex *acceleration_mutex;
394
395 if(!AGS_IS_ACCELERATION(acceleration)){
396 return;
397 }
398
399 /* get acceleration mutex */
400 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
401
402 /* set */
403 g_rec_mutex_lock(acceleration_mutex);
404
405 acceleration->flags |= flags;
406
407 g_rec_mutex_unlock(acceleration_mutex);
408 }
409
410 /**
411 * ags_acceleration_unset_flags:
412 * @acceleration: the #AgsAcceleration
413 * @flags: the flags
414 *
415 * Unset @flags on @acceleration.
416 *
417 * Since: 3.0.0
418 */
419 void
ags_acceleration_unset_flags(AgsAcceleration * acceleration,guint flags)420 ags_acceleration_unset_flags(AgsAcceleration *acceleration, guint flags)
421 {
422 GRecMutex *acceleration_mutex;
423
424 if(!AGS_IS_ACCELERATION(acceleration)){
425 return;
426 }
427
428 /* get acceleration mutex */
429 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
430
431 /* unset */
432 g_rec_mutex_lock(acceleration_mutex);
433
434 acceleration->flags &= (~flags);
435
436 g_rec_mutex_unlock(acceleration_mutex);
437 }
438
439 /**
440 * ags_acceleration_sort_func:
441 * @a: an #AgsAcceleration
442 * @b: an other #AgsAcceleration
443 *
444 * Sort accelerations.
445 *
446 * Returns: 0 if equal, -1 if smaller and 1 if bigger offset
447 *
448 * Since: 3.0.0
449 */
450 gint
ags_acceleration_sort_func(gconstpointer a,gconstpointer b)451 ags_acceleration_sort_func(gconstpointer a, gconstpointer b)
452 {
453 guint a_x, b_x;
454
455 if(a == NULL || b == NULL){
456 return(0);
457 }
458
459 g_object_get(a,
460 "x", &a_x,
461 NULL);
462
463 g_object_get(b,
464 "x", &b_x,
465 NULL);
466
467 if(a_x == b_x){
468 return(0);
469 }
470
471 if(a_x < b_x){
472 return(-1);
473 }else{
474 return(1);
475 }
476 }
477
478 /**
479 * ags_acceleration_get_x:
480 * @acceleration: the #AgsAcceleration
481 *
482 * Gets x.
483 *
484 * Returns: the x
485 *
486 * Since: 3.1.0
487 */
488 guint
ags_acceleration_get_x(AgsAcceleration * acceleration)489 ags_acceleration_get_x(AgsAcceleration *acceleration)
490 {
491 guint x;
492
493 if(!AGS_IS_ACCELERATION(acceleration)){
494 return(0);
495 }
496
497 g_object_get(acceleration,
498 "x", &x,
499 NULL);
500
501 return(x);
502 }
503
504 /**
505 * ags_acceleration_set_x:
506 * @acceleration: the #AgsAcceleration
507 * @x: the x
508 *
509 * Sets x.
510 *
511 * Since: 3.1.0
512 */
513 void
ags_acceleration_set_x(AgsAcceleration * acceleration,guint x)514 ags_acceleration_set_x(AgsAcceleration *acceleration, guint x)
515 {
516 if(!AGS_IS_ACCELERATION(acceleration)){
517 return;
518 }
519
520 g_object_set(acceleration,
521 "x", x,
522 NULL);
523 }
524
525 /**
526 * ags_acceleration_get_y:
527 * @acceleration: the #AgsAcceleration
528 *
529 * Gets y.
530 *
531 * Returns: the y
532 *
533 * Since: 3.1.0
534 */
535 gdouble
ags_acceleration_get_y(AgsAcceleration * acceleration)536 ags_acceleration_get_y(AgsAcceleration *acceleration)
537 {
538 gdouble y;
539
540 if(!AGS_IS_ACCELERATION(acceleration)){
541 return(0);
542 }
543
544 g_object_get(acceleration,
545 "y", &y,
546 NULL);
547
548 return(y);
549 }
550
551 /**
552 * ags_acceleration_set_y:
553 * @acceleration: the #AgsAcceleration
554 * @y: the y
555 *
556 * Sets y.
557 *
558 * Since: 3.1.0
559 */
560 void
ags_acceleration_set_y(AgsAcceleration * acceleration,gdouble y)561 ags_acceleration_set_y(AgsAcceleration *acceleration, gdouble y)
562 {
563 if(!AGS_IS_ACCELERATION(acceleration)){
564 return;
565 }
566
567 g_object_set(acceleration,
568 "y", y,
569 NULL);
570 }
571
572 /**
573 * ags_acceleration_duplicate:
574 * @acceleration: an #AgsAcceleration
575 *
576 * Duplicate a acceleration.
577 *
578 * Returns: (transfer full): the duplicated #AgsAcceleration.
579 *
580 * Since: 3.0.0
581 */
582 AgsAcceleration*
ags_acceleration_duplicate(AgsAcceleration * acceleration)583 ags_acceleration_duplicate(AgsAcceleration *acceleration)
584 {
585 AgsAcceleration *acceleration_copy;
586
587 GRecMutex *acceleration_mutex;
588
589 if(!AGS_IS_ACCELERATION(acceleration)){
590 return(NULL);
591 }
592
593 /* get acceleration mutex */
594 acceleration_mutex = AGS_ACCELERATION_GET_OBJ_MUTEX(acceleration);
595
596 /* instantiate acceleration */
597 acceleration_copy = ags_acceleration_new();
598
599 acceleration_copy->flags = 0;
600
601 g_rec_mutex_lock(acceleration_mutex);
602
603 acceleration_copy->x = acceleration->x;
604 acceleration_copy->y = acceleration->y;
605
606 acceleration_copy->acceleration_name = g_strdup(acceleration->acceleration_name);
607
608 g_rec_mutex_unlock(acceleration_mutex);
609
610 return(acceleration_copy);
611 }
612
613 /**
614 * ags_acceleration_new:
615 *
616 * Creates a new instance of #AgsAcceleration
617 *
618 * Returns: the new #AgsAcceleration
619 *
620 * Since: 3.0.0
621 */
622 AgsAcceleration*
ags_acceleration_new()623 ags_acceleration_new()
624 {
625 AgsAcceleration *acceleration;
626
627 acceleration = (AgsAcceleration *) g_object_new(AGS_TYPE_ACCELERATION,
628 NULL);
629
630 return(acceleration);
631 }
632