1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2021 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_volume_util.h>
21
22 #include <ags/audio/ags_audio_buffer_util.h>
23
24 /**
25 * SECTION:ags_volume_util
26 * @short_description: Boxed type of volume util
27 * @title: AgsVolumeUtil
28 * @section_id:
29 * @include: ags/audio/ags_volume_util.h
30 *
31 * Boxed type of volume util data type.
32 */
33
34 GType
ags_volume_util_get_type(void)35 ags_volume_util_get_type(void)
36 {
37 static volatile gsize g_define_type_id__volatile = 0;
38
39 if(g_once_init_enter (&g_define_type_id__volatile)){
40 GType ags_type_volume_util = 0;
41
42 ags_type_volume_util =
43 g_boxed_type_register_static("AgsVolumeUtil",
44 (GBoxedCopyFunc) ags_volume_util_copy,
45 (GBoxedFreeFunc) ags_volume_util_free);
46
47 g_once_init_leave(&g_define_type_id__volatile, ags_type_volume_util);
48 }
49
50 return g_define_type_id__volatile;
51 }
52
53 /**
54 * ags_volume_util_alloc:
55 *
56 * Allocate #AgsVolumeUtil-struct
57 *
58 * Returns: a new #AgsVolumeUtil-struct
59 *
60 * Since: 3.9.2
61 */
62 AgsVolumeUtil*
ags_volume_util_alloc()63 ags_volume_util_alloc()
64 {
65 AgsVolumeUtil *ptr;
66
67 ptr = (AgsVolumeUtil *) g_new(AgsVolumeUtil,
68 1);
69
70 ptr->destination = NULL;
71 ptr->destination_stride = 1;
72
73 ptr->source = NULL;
74 ptr->source_stride = 1;
75
76 ptr->buffer_length = 0;
77 ptr->format = AGS_VOLUME_UTIL_DEFAULT_FORMAT;
78
79 ptr->audio_buffer_util_format = AGS_VOLUME_UTIL_DEFAULT_AUDIO_BUFFER_UTIL_FORMAT;
80
81 ptr->volume = 1.0;
82
83 return(ptr);
84 }
85
86 /**
87 * ags_volume_util_copy:
88 * @ptr: the original #AgsVolumeUtil-struct
89 *
90 * Create a copy of @ptr.
91 *
92 * Returns: a pointer of the new #AgsVolumeUtil-struct
93 *
94 * Since: 3.9.2
95 */
96 gpointer
ags_volume_util_copy(AgsVolumeUtil * ptr)97 ags_volume_util_copy(AgsVolumeUtil *ptr)
98 {
99 AgsVolumeUtil *new_ptr;
100
101 new_ptr = (AgsVolumeUtil *) g_new(AgsVolumeUtil,
102 1);
103
104 new_ptr->destination = ptr->destination;
105 new_ptr->destination_stride = ptr->destination_stride;
106
107 new_ptr->source = ptr->source;
108 new_ptr->source_stride = ptr->source_stride;
109
110 new_ptr->buffer_length = ptr->buffer_length;
111 new_ptr->format = ptr->format;
112
113 new_ptr->audio_buffer_util_format = ptr->audio_buffer_util_format;
114
115 new_ptr->volume = ptr->volume;
116
117 return(new_ptr);
118 }
119
120 /**
121 * ags_volume_util_free:
122 * @ptr: the #AgsVolumeUtil-struct
123 *
124 * Free the memory of @ptr.
125 *
126 * Since: 3.9.2
127 */
128 void
ags_volume_util_free(AgsVolumeUtil * ptr)129 ags_volume_util_free(AgsVolumeUtil *ptr)
130 {
131 g_free(ptr->destination);
132
133 if(ptr->destination != ptr->source){
134 g_free(ptr->source);
135 }
136
137 g_free(ptr);
138 }
139
140 /**
141 * ags_volume_util_get_destination:
142 * @volume_util: the #AgsVolumeUtil-struct
143 *
144 * Get destination buffer of @volume_util.
145 *
146 * Returns: the destination buffer
147 *
148 * Since: 3.9.2
149 */
150 gpointer
ags_volume_util_get_destination(AgsVolumeUtil * volume_util)151 ags_volume_util_get_destination(AgsVolumeUtil *volume_util)
152 {
153 if(volume_util == NULL){
154 return(NULL);
155 }
156
157 return(volume_util->destination);
158 }
159
160 /**
161 * ags_volume_util_set_destination:
162 * @volume_util: the #AgsVolumeUtil-struct
163 * @destination: the destination buffer
164 *
165 * Set @destination buffer of @volume_util.
166 *
167 * Since: 3.9.2
168 */
169 void
ags_volume_util_set_destination(AgsVolumeUtil * volume_util,gpointer destination)170 ags_volume_util_set_destination(AgsVolumeUtil *volume_util,
171 gpointer destination)
172 {
173 if(volume_util == NULL){
174 return;
175 }
176
177 volume_util->destination = destination;
178 }
179
180 /**
181 * ags_volume_util_get_destination_stride:
182 * @volume_util: the #AgsVolumeUtil-struct
183 *
184 * Get destination stride of @volume_util.
185 *
186 * Returns: the destination buffer stride
187 *
188 * Since: 3.9.2
189 */
190 guint
ags_volume_util_get_destination_stride(AgsVolumeUtil * volume_util)191 ags_volume_util_get_destination_stride(AgsVolumeUtil *volume_util)
192 {
193 if(volume_util == NULL){
194 return(0);
195 }
196
197 return(volume_util->destination_stride);
198 }
199
200 /**
201 * ags_volume_util_set_destination_stride:
202 * @volume_util: the #AgsVolumeUtil-struct
203 * @destination_stride: the destination buffer stride
204 *
205 * Set @destination stride of @volume_util.
206 *
207 * Since: 3.9.2
208 */
209 void
ags_volume_util_set_destination_stride(AgsVolumeUtil * volume_util,guint destination_stride)210 ags_volume_util_set_destination_stride(AgsVolumeUtil *volume_util,
211 guint destination_stride)
212 {
213 if(volume_util == NULL){
214 return;
215 }
216
217 volume_util->destination_stride = destination_stride;
218 }
219
220 /**
221 * ags_volume_util_get_source:
222 * @volume_util: the #AgsVolumeUtil-struct
223 *
224 * Get source buffer of @volume_util.
225 *
226 * Returns: the source buffer
227 *
228 * Since: 3.9.2
229 */
230 gpointer
ags_volume_util_get_source(AgsVolumeUtil * volume_util)231 ags_volume_util_get_source(AgsVolumeUtil *volume_util)
232 {
233 if(volume_util == NULL){
234 return(NULL);
235 }
236
237 return(volume_util->source);
238 }
239
240 /**
241 * ags_volume_util_set_source:
242 * @volume_util: the #AgsVolumeUtil-struct
243 * @source: the source buffer
244 *
245 * Set @source buffer of @volume_util.
246 *
247 * Since: 3.9.2
248 */
249 void
ags_volume_util_set_source(AgsVolumeUtil * volume_util,gpointer source)250 ags_volume_util_set_source(AgsVolumeUtil *volume_util,
251 gpointer source)
252 {
253 if(volume_util == NULL){
254 return;
255 }
256
257 volume_util->source = source;
258 }
259
260 /**
261 * ags_volume_util_get_source_stride:
262 * @volume_util: the #AgsVolumeUtil-struct
263 *
264 * Get source stride of @volume_util.
265 *
266 * Returns: the source buffer stride
267 *
268 * Since: 3.9.2
269 */
270 guint
ags_volume_util_get_source_stride(AgsVolumeUtil * volume_util)271 ags_volume_util_get_source_stride(AgsVolumeUtil *volume_util)
272 {
273 if(volume_util == NULL){
274 return(0);
275 }
276
277 return(volume_util->source_stride);
278 }
279
280 /**
281 * ags_volume_util_set_source_stride:
282 * @volume_util: the #AgsVolumeUtil-struct
283 * @source_stride: the source buffer stride
284 *
285 * Set @source stride of @volume_util.
286 *
287 * Since: 3.9.2
288 */
289 void
ags_volume_util_set_source_stride(AgsVolumeUtil * volume_util,guint source_stride)290 ags_volume_util_set_source_stride(AgsVolumeUtil *volume_util,
291 guint source_stride)
292 {
293 if(volume_util == NULL){
294 return;
295 }
296
297 volume_util->source_stride = source_stride;
298 }
299
300 /**
301 * ags_volume_util_get_buffer_length:
302 * @volume_util: the #AgsVolumeUtil-struct
303 *
304 * Get buffer length of @volume_util.
305 *
306 * Returns: the buffer length
307 *
308 * Since: 3.9.2
309 */
310 guint
ags_volume_util_get_buffer_length(AgsVolumeUtil * volume_util)311 ags_volume_util_get_buffer_length(AgsVolumeUtil *volume_util)
312 {
313 if(volume_util == NULL){
314 return(0);
315 }
316
317 return(volume_util->buffer_length);
318 }
319
320 /**
321 * ags_volume_util_set_buffer_length:
322 * @volume_util: the #AgsVolumeUtil-struct
323 * @buffer_length: the buffer length
324 *
325 * Set @buffer_length of @volume_util.
326 *
327 * Since: 3.9.2
328 */
329 void
ags_volume_util_set_buffer_length(AgsVolumeUtil * volume_util,guint buffer_length)330 ags_volume_util_set_buffer_length(AgsVolumeUtil *volume_util,
331 guint buffer_length)
332 {
333 if(volume_util == NULL){
334 return;
335 }
336
337 volume_util->buffer_length = buffer_length;
338 }
339
340 /**
341 * ags_volume_util_get_format:
342 * @volume_util: the #AgsVolumeUtil-struct
343 *
344 * Get format of @volume_util.
345 *
346 * Returns: the format
347 *
348 * Since: 3.9.6
349 */
350 guint
ags_volume_util_get_format(AgsVolumeUtil * volume_util)351 ags_volume_util_get_format(AgsVolumeUtil *volume_util)
352 {
353 if(volume_util == NULL){
354 return(0);
355 }
356
357 return(volume_util->format);
358 }
359
360 /**
361 * ags_volume_util_set_format:
362 * @volume_util: the #AgsVolumeUtil-struct
363 * @format: the format
364 *
365 * Set @format of @volume_util.
366 *
367 * Since: 3.9.6
368 */
369 void
ags_volume_util_set_format(AgsVolumeUtil * volume_util,guint format)370 ags_volume_util_set_format(AgsVolumeUtil *volume_util,
371 guint format)
372 {
373 if(volume_util == NULL){
374 return;
375 }
376
377 volume_util->format = format;
378
379 volume_util->audio_buffer_util_format = ags_audio_buffer_util_format_from_soundcard(format);
380 }
381
382 /**
383 * ags_volume_util_get_audio_buffer_util_format:
384 * @volume_util: the #AgsVolumeUtil-struct
385 *
386 * Get audio buffer util format of @volume_util.
387 *
388 * Returns: the audio buffer util format
389 *
390 * Since: 3.9.2
391 */
392 guint
ags_volume_util_get_audio_buffer_util_format(AgsVolumeUtil * volume_util)393 ags_volume_util_get_audio_buffer_util_format(AgsVolumeUtil *volume_util)
394 {
395 if(volume_util == NULL){
396 return(0);
397 }
398
399 return(volume_util->audio_buffer_util_format);
400 }
401
402 /**
403 * ags_volume_util_set_audio_buffer_util_format:
404 * @volume_util: the #AgsVolumeUtil-struct
405 * @audio_buffer_util_format: the audio buffer util format
406 *
407 * Set @audio_buffer_util_format of @volume_util.
408 *
409 * Since: 3.9.2
410 */
411 void
ags_volume_util_set_audio_buffer_util_format(AgsVolumeUtil * volume_util,guint audio_buffer_util_format)412 ags_volume_util_set_audio_buffer_util_format(AgsVolumeUtil *volume_util,
413 guint audio_buffer_util_format)
414 {
415 if(volume_util == NULL){
416 return;
417 }
418
419 volume_util->audio_buffer_util_format = audio_buffer_util_format;
420 }
421
422 /**
423 * ags_volume_util_get_volume:
424 * @volume_util: the #AgsVolumeUtil-struct
425 *
426 * Get volume of @volume_util.
427 *
428 * Returns: the volume
429 *
430 * Since: 3.9.2
431 */
432 gdouble
ags_volume_util_get_volume(AgsVolumeUtil * volume_util)433 ags_volume_util_get_volume(AgsVolumeUtil *volume_util)
434 {
435 if(volume_util == NULL){
436 return(1.0);
437 }
438
439 return(volume_util->volume);
440 }
441
442 /**
443 * ags_volume_util_set_volume:
444 * @volume_util: the #AgsVolumeUtil-struct
445 * @volume: the volume
446 *
447 * Set @volume of @volume_util.
448 *
449 * Since: 3.9.2
450 */
451 void
ags_volume_util_set_volume(AgsVolumeUtil * volume_util,gdouble volume)452 ags_volume_util_set_volume(AgsVolumeUtil *volume_util,
453 gdouble volume)
454 {
455 if(volume_util == NULL){
456 return;
457 }
458
459 volume_util->volume = volume;
460 }
461
462 /**
463 * ags_volume_util_compute_s8:
464 * @volume_util: the #AgsVolumeUtil-struct
465 *
466 * Compute volume of signed 8 bit data.
467 *
468 * Since: 3.9.2
469 */
470 void
ags_volume_util_compute_s8(AgsVolumeUtil * volume_util)471 ags_volume_util_compute_s8(AgsVolumeUtil *volume_util)
472 {
473 gint8 *destination;
474 gint8 *source;
475 guint i, i_stop;
476
477 if(volume_util == NULL ||
478 volume_util->destination == NULL ||
479 volume_util->source == NULL){
480 return;
481 }
482
483 destination = (gint8 *) volume_util->destination;
484 source = (gint8 *) volume_util->source;
485
486 i = 0;
487
488 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
489 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
490
491 for(; i < i_stop;){
492 ags_v8double v_buffer;
493
494 v_buffer = (ags_v8double) {
495 (gdouble) *(source),
496 (gdouble) *(source += volume_util->source_stride),
497 (gdouble) *(source += volume_util->source_stride),
498 (gdouble) *(source += volume_util->source_stride),
499 (gdouble) *(source += volume_util->source_stride),
500 (gdouble) *(source += volume_util->source_stride),
501 (gdouble) *(source += volume_util->source_stride),
502 (gdouble) *(source += volume_util->source_stride)
503 };
504
505 source += volume_util->source_stride;
506
507 v_buffer *= volume_util->volume;
508
509 *(destination) = (gint8) v_buffer[0];
510 *(destination += volume_util->destination_stride) = (gint8) v_buffer[1];
511 *(destination += volume_util->destination_stride) = (gint8) v_buffer[2];
512 *(destination += volume_util->destination_stride) = (gint8) v_buffer[3];
513 *(destination += volume_util->destination_stride) = (gint8) v_buffer[4];
514 *(destination += volume_util->destination_stride) = (gint8) v_buffer[5];
515 *(destination += volume_util->destination_stride) = (gint8) v_buffer[6];
516 *(destination += volume_util->destination_stride) = (gint8) v_buffer[7];
517
518 destination += volume_util->destination_stride;
519 i += 8;
520 }
521 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
522 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
523
524 for(; i < i_stop;){
525 double ret_v_buffer[8];
526
527 double v_buffer[] = {
528 (double) *(source),
529 (double) *(source += volume_util->source_stride),
530 (double) *(source += volume_util->source_stride),
531 (double) *(source += volume_util->source_stride),
532 (double) *(source += volume_util->source_stride),
533 (double) *(source += volume_util->source_stride),
534 (double) *(source += volume_util->source_stride),
535 (double) *(source += volume_util->source_stride)};
536
537 double v_volume[] = {(double) volume_util->volume};
538
539 source += volume_util->source_stride;
540
541 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
542
543 *(destination) = (gint8) ret_v_buffer[0];
544 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[1];
545 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[2];
546 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[3];
547 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[4];
548 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[5];
549 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[6];
550 *(destination += volume_util->destination_stride) = (gint8) ret_v_buffer[7];
551
552 destination += volume_util->destination_stride;
553 i += 8;
554 }
555 #else
556 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
557
558 for(; i < i_stop;){
559 *(destination) = (gint8) ((gint16) ((source)[0] * (volume_util->volume)));
560 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
561 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
562 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
563 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
564 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
565 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
566 *(destination += volume_util->destination_stride) = (gint8) ((gint16) ((source += volume_util->source_stride)[0] * volume_util->volume));
567
568 destination += volume_util->destination_stride;
569 source += volume_util->source_stride;
570 i += 8;
571 }
572 #endif
573
574 /* loop tail */
575 for(; i < volume_util->buffer_length;){
576 destination[0] = (gint8) ((gint16) (source[0] * volume_util->volume));
577
578 destination += volume_util->destination_stride;
579 source += volume_util->source_stride;
580 i++;
581 }
582 }
583
584 /**
585 * ags_volume_util_compute_s16:
586 * @volume_util: the #AgsVolumeUtil-struct
587 *
588 * Compute volume of signed 16 bit data.
589 *
590 * Since: 3.9.2
591 */
592 void
ags_volume_util_compute_s16(AgsVolumeUtil * volume_util)593 ags_volume_util_compute_s16(AgsVolumeUtil *volume_util)
594 {
595 gint16 *destination;
596 gint16 *source;
597 guint i, i_stop;
598
599 if(volume_util == NULL ||
600 volume_util->destination == NULL ||
601 volume_util->source == NULL){
602 return;
603 }
604
605 destination = (gint16 *) volume_util->destination;
606 source = (gint16 *) volume_util->source;
607
608 i = 0;
609
610 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
611 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
612
613 for(; i < i_stop;){
614 ags_v8double v_buffer;
615
616 v_buffer = (ags_v8double) {
617 (gdouble) *(source),
618 (gdouble) *(source += volume_util->source_stride),
619 (gdouble) *(source += volume_util->source_stride),
620 (gdouble) *(source += volume_util->source_stride),
621 (gdouble) *(source += volume_util->source_stride),
622 (gdouble) *(source += volume_util->source_stride),
623 (gdouble) *(source += volume_util->source_stride),
624 (gdouble) *(source += volume_util->source_stride)
625 };
626
627 source += volume_util->source_stride;
628
629 v_buffer *= volume_util->volume;
630
631 *(destination) = (gint16) v_buffer[0];
632 *(destination += volume_util->destination_stride) = (gint16) v_buffer[1];
633 *(destination += volume_util->destination_stride) = (gint16) v_buffer[2];
634 *(destination += volume_util->destination_stride) = (gint16) v_buffer[3];
635 *(destination += volume_util->destination_stride) = (gint16) v_buffer[4];
636 *(destination += volume_util->destination_stride) = (gint16) v_buffer[5];
637 *(destination += volume_util->destination_stride) = (gint16) v_buffer[6];
638 *(destination += volume_util->destination_stride) = (gint16) v_buffer[7];
639
640 destination += volume_util->destination_stride;
641 i += 8;
642 }
643 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
644 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
645
646 for(; i < i_stop;){
647 double ret_v_buffer[8];
648
649 double v_buffer[] = {
650 (double) *(source),
651 (double) *(source += volume_util->source_stride),
652 (double) *(source += volume_util->source_stride),
653 (double) *(source += volume_util->source_stride),
654 (double) *(source += volume_util->source_stride),
655 (double) *(source += volume_util->source_stride),
656 (double) *(source += volume_util->source_stride),
657 (double) *(source += volume_util->source_stride)};
658
659 double v_volume[] = {(double) volume_util->volume};
660
661 source += volume_util->source_stride;
662
663 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
664
665 *(destination) = (gint16) ret_v_buffer[0];
666 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[1];
667 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[2];
668 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[3];
669 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[4];
670 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[5];
671 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[6];
672 *(destination += volume_util->destination_stride) = (gint16) ret_v_buffer[7];
673
674 destination += volume_util->destination_stride;
675 i += 8;
676 }
677 #else
678 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
679
680 for(; i < i_stop;){
681 *(destination) = (gint16) ((gint32) ((source)[0] * (volume_util->volume)));
682 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
683 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
684 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
685 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
686 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
687 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
688 *(destination += volume_util->destination_stride) = (gint16) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
689
690 destination += volume_util->destination_stride;
691 source += volume_util->source_stride;
692 i += 8;
693 }
694 #endif
695
696 /* loop tail */
697 for(; i < volume_util->buffer_length;){
698 destination[0] = (gint16) ((gint32) (source[0] * volume_util->volume));
699
700 destination += volume_util->destination_stride;
701 source += volume_util->source_stride;
702 i++;
703 }
704 }
705
706 /**
707 * ags_volume_util_compute_s24:
708 * @volume_util: the #AgsVolumeUtil-struct
709 *
710 * Compute volume of signed 24 bit data.
711 *
712 * Since: 3.9.2
713 */
714 void
ags_volume_util_compute_s24(AgsVolumeUtil * volume_util)715 ags_volume_util_compute_s24(AgsVolumeUtil *volume_util)
716 {
717 gint32 *destination;
718 gint32 *source;
719 guint i, i_stop;
720
721 if(volume_util == NULL ||
722 volume_util->destination == NULL ||
723 volume_util->source == NULL){
724 return;
725 }
726
727 destination = (gint32 *) volume_util->destination;
728 source = (gint32 *) volume_util->source;
729
730 i = 0;
731
732 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
733 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
734
735 for(; i < i_stop;){
736 ags_v8double v_buffer;
737
738 v_buffer = (ags_v8double) {
739 (gdouble) *(source),
740 (gdouble) *(source += volume_util->source_stride),
741 (gdouble) *(source += volume_util->source_stride),
742 (gdouble) *(source += volume_util->source_stride),
743 (gdouble) *(source += volume_util->source_stride),
744 (gdouble) *(source += volume_util->source_stride),
745 (gdouble) *(source += volume_util->source_stride),
746 (gdouble) *(source += volume_util->source_stride)
747 };
748
749 source += volume_util->source_stride;
750
751 v_buffer *= volume_util->volume;
752
753 *(destination) = (gint32) v_buffer[0];
754 *(destination += volume_util->destination_stride) = (gint32) v_buffer[1];
755 *(destination += volume_util->destination_stride) = (gint32) v_buffer[2];
756 *(destination += volume_util->destination_stride) = (gint32) v_buffer[3];
757 *(destination += volume_util->destination_stride) = (gint32) v_buffer[4];
758 *(destination += volume_util->destination_stride) = (gint32) v_buffer[5];
759 *(destination += volume_util->destination_stride) = (gint32) v_buffer[6];
760 *(destination += volume_util->destination_stride) = (gint32) v_buffer[7];
761
762 destination += volume_util->destination_stride;
763 i += 8;
764 }
765 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
766 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
767
768 for(; i < i_stop;){
769 double ret_v_buffer[8];
770
771 double v_buffer[] = {
772 (double) *(source),
773 (double) *(source += volume_util->source_stride),
774 (double) *(source += volume_util->source_stride),
775 (double) *(source += volume_util->source_stride),
776 (double) *(source += volume_util->source_stride),
777 (double) *(source += volume_util->source_stride),
778 (double) *(source += volume_util->source_stride),
779 (double) *(source += volume_util->source_stride)};
780
781 double v_volume[] = {(double) volume_util->volume};
782
783 source += volume_util->source_stride;
784
785 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
786
787 *(destination) = (gint32) ret_v_buffer[0];
788 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[1];
789 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[2];
790 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[3];
791 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[4];
792 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[5];
793 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[6];
794 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[7];
795
796 destination += volume_util->destination_stride;
797 i += 8;
798 }
799 #else
800 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
801
802 for(; i < i_stop;){
803 *(destination) = (gint32) ((gint32) ((source)[0] * (volume_util->volume)));
804 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
805 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
806 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
807 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
808 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
809 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
810 *(destination += volume_util->destination_stride) = (gint32) ((gint32) ((source += volume_util->source_stride)[0] * volume_util->volume));
811
812 destination += volume_util->destination_stride;
813 source += volume_util->source_stride;
814 i += 8;
815 }
816 #endif
817
818 /* loop tail */
819 for(; i < volume_util->buffer_length;){
820 destination[0] = (gint32) ((gint32) (source[0] * volume_util->volume));
821
822 destination += volume_util->destination_stride;
823 source += volume_util->source_stride;
824 i++;
825 }
826 }
827
828 /**
829 * ags_volume_util_compute_s32:
830 * @volume_util: the #AgsVolumeUtil-struct
831 *
832 * Compute volume of signed 32 bit data.
833 *
834 * Since: 3.9.2
835 */
836 void
ags_volume_util_compute_s32(AgsVolumeUtil * volume_util)837 ags_volume_util_compute_s32(AgsVolumeUtil *volume_util)
838 {
839 gint32 *destination;
840 gint32 *source;
841 guint i, i_stop;
842
843 if(volume_util == NULL ||
844 volume_util->destination == NULL ||
845 volume_util->source == NULL){
846 return;
847 }
848
849 destination = (gint32 *) volume_util->destination;
850 source = (gint32 *) volume_util->source;
851
852 i = 0;
853
854 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
855 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
856
857 for(; i < i_stop;){
858 ags_v8double v_buffer;
859
860 v_buffer = (ags_v8double) {
861 (gdouble) *(source),
862 (gdouble) *(source += volume_util->source_stride),
863 (gdouble) *(source += volume_util->source_stride),
864 (gdouble) *(source += volume_util->source_stride),
865 (gdouble) *(source += volume_util->source_stride),
866 (gdouble) *(source += volume_util->source_stride),
867 (gdouble) *(source += volume_util->source_stride),
868 (gdouble) *(source += volume_util->source_stride)
869 };
870
871 source += volume_util->source_stride;
872
873 v_buffer *= volume_util->volume;
874
875 *(destination) = (gint32) v_buffer[0];
876 *(destination += volume_util->destination_stride) = (gint32) v_buffer[1];
877 *(destination += volume_util->destination_stride) = (gint32) v_buffer[2];
878 *(destination += volume_util->destination_stride) = (gint32) v_buffer[3];
879 *(destination += volume_util->destination_stride) = (gint32) v_buffer[4];
880 *(destination += volume_util->destination_stride) = (gint32) v_buffer[5];
881 *(destination += volume_util->destination_stride) = (gint32) v_buffer[6];
882 *(destination += volume_util->destination_stride) = (gint32) v_buffer[7];
883
884 destination += volume_util->destination_stride;
885 i += 8;
886 }
887 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
888 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
889
890 for(; i < i_stop;){
891 double ret_v_buffer[8];
892
893 double v_buffer[] = {
894 (double) *(source),
895 (double) *(source += volume_util->source_stride),
896 (double) *(source += volume_util->source_stride),
897 (double) *(source += volume_util->source_stride),
898 (double) *(source += volume_util->source_stride),
899 (double) *(source += volume_util->source_stride),
900 (double) *(source += volume_util->source_stride),
901 (double) *(source += volume_util->source_stride)};
902
903 double v_volume[] = {(double) volume_util->volume};
904
905 source += volume_util->source_stride;
906
907 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
908
909 *(destination) = (gint32) ret_v_buffer[0];
910 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[1];
911 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[2];
912 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[3];
913 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[4];
914 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[5];
915 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[6];
916 *(destination += volume_util->destination_stride) = (gint32) ret_v_buffer[7];
917
918 destination += volume_util->destination_stride;
919 i += 8;
920 }
921 #else
922 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
923
924 for(; i < i_stop;){
925 *(destination) = (gint32) ((gint64) ((source)[0] * (volume_util->volume)));
926 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
927 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
928 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
929 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
930 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
931 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
932 *(destination += volume_util->destination_stride) = (gint32) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
933
934 destination += volume_util->destination_stride;
935 source += volume_util->source_stride;
936 i += 8;
937 }
938 #endif
939
940 /* loop tail */
941 for(; i < volume_util->buffer_length;){
942 destination[0] = (gint32) ((gint64) (source[0] * volume_util->volume));
943
944 destination += volume_util->destination_stride;
945 source += volume_util->source_stride;
946 i++;
947 }
948 }
949
950 /**
951 * ags_volume_util_compute_s64:
952 * @volume_util: the #AgsVolumeUtil-struct
953 *
954 * Compute volume of signed 64 bit data.
955 *
956 * Since: 3.9.2
957 */
958 void
ags_volume_util_compute_s64(AgsVolumeUtil * volume_util)959 ags_volume_util_compute_s64(AgsVolumeUtil *volume_util)
960 {
961 gint64 *destination;
962 gint64 *source;
963 guint i, i_stop;
964
965 if(volume_util == NULL ||
966 volume_util->destination == NULL ||
967 volume_util->source == NULL){
968 return;
969 }
970
971 destination = (gint64 *) volume_util->destination;
972 source = (gint64 *) volume_util->source;
973
974 i = 0;
975
976 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
977 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
978
979 for(; i < i_stop;){
980 ags_v8double v_buffer;
981
982 v_buffer = (ags_v8double) {
983 (gdouble) *(source),
984 (gdouble) *(source += volume_util->source_stride),
985 (gdouble) *(source += volume_util->source_stride),
986 (gdouble) *(source += volume_util->source_stride),
987 (gdouble) *(source += volume_util->source_stride),
988 (gdouble) *(source += volume_util->source_stride),
989 (gdouble) *(source += volume_util->source_stride),
990 (gdouble) *(source += volume_util->source_stride)
991 };
992
993 source += volume_util->source_stride;
994
995 v_buffer *= volume_util->volume;
996
997 *(destination) = (gint64) v_buffer[0];
998 *(destination += volume_util->destination_stride) = (gint64) v_buffer[1];
999 *(destination += volume_util->destination_stride) = (gint64) v_buffer[2];
1000 *(destination += volume_util->destination_stride) = (gint64) v_buffer[3];
1001 *(destination += volume_util->destination_stride) = (gint64) v_buffer[4];
1002 *(destination += volume_util->destination_stride) = (gint64) v_buffer[5];
1003 *(destination += volume_util->destination_stride) = (gint64) v_buffer[6];
1004 *(destination += volume_util->destination_stride) = (gint64) v_buffer[7];
1005
1006 destination += volume_util->destination_stride;
1007 i += 8;
1008 }
1009 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
1010 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1011
1012 for(; i < i_stop;){
1013 double ret_v_buffer[8];
1014
1015 double v_buffer[] = {
1016 (double) *(source),
1017 (double) *(source += volume_util->source_stride),
1018 (double) *(source += volume_util->source_stride),
1019 (double) *(source += volume_util->source_stride),
1020 (double) *(source += volume_util->source_stride),
1021 (double) *(source += volume_util->source_stride),
1022 (double) *(source += volume_util->source_stride),
1023 (double) *(source += volume_util->source_stride)};
1024
1025 double v_volume[] = {(double) volume_util->volume};
1026
1027 source += volume_util->source_stride;
1028
1029 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
1030
1031 *(destination) = (gint64) ret_v_buffer[0];
1032 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[1];
1033 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[2];
1034 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[3];
1035 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[4];
1036 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[5];
1037 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[6];
1038 *(destination += volume_util->destination_stride) = (gint64) ret_v_buffer[7];
1039
1040 destination += volume_util->destination_stride;
1041 i += 8;
1042 }
1043 #else
1044 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1045
1046 for(; i < i_stop;){
1047 *(destination) = (gint64) ((gint64) ((source)[0] * (volume_util->volume)));
1048 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1049 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1050 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1051 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1052 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1053 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1054 *(destination += volume_util->destination_stride) = (gint64) ((gint64) ((source += volume_util->source_stride)[0] * volume_util->volume));
1055
1056 destination += volume_util->destination_stride;
1057 source += volume_util->source_stride;
1058 i += 8;
1059 }
1060 #endif
1061
1062 /* loop tail */
1063 for(; i < volume_util->buffer_length;){
1064 destination[0] = (gint64) ((gint64) (source[0] * volume_util->volume));
1065
1066 destination += volume_util->destination_stride;
1067 source += volume_util->source_stride;
1068 i++;
1069 }
1070 }
1071
1072 /**
1073 * ags_volume_util_compute_float:
1074 * @volume_util: the #AgsVolumeUtil-struct
1075 *
1076 * Compute volume of floating point data.
1077 *
1078 * Since: 3.9.2
1079 */
1080 void
ags_volume_util_compute_float(AgsVolumeUtil * volume_util)1081 ags_volume_util_compute_float(AgsVolumeUtil *volume_util)
1082 {
1083 gfloat *destination;
1084 gfloat *source;
1085 guint i, i_stop;
1086
1087 if(volume_util == NULL ||
1088 volume_util->destination == NULL ||
1089 volume_util->source == NULL){
1090 return;
1091 }
1092
1093 destination = (gfloat *) volume_util->destination;
1094 source = (gfloat *) volume_util->source;
1095
1096 i = 0;
1097
1098 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
1099 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1100
1101 for(; i < i_stop;){
1102 ags_v8double v_buffer;
1103
1104 v_buffer = (ags_v8double) {
1105 (gdouble) *(source),
1106 (gdouble) *(source += volume_util->source_stride),
1107 (gdouble) *(source += volume_util->source_stride),
1108 (gdouble) *(source += volume_util->source_stride),
1109 (gdouble) *(source += volume_util->source_stride),
1110 (gdouble) *(source += volume_util->source_stride),
1111 (gdouble) *(source += volume_util->source_stride),
1112 (gdouble) *(source += volume_util->source_stride)
1113 };
1114
1115 source += volume_util->source_stride;
1116
1117 v_buffer *= volume_util->volume;
1118
1119 *(destination) = (gfloat) v_buffer[0];
1120 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[1];
1121 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[2];
1122 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[3];
1123 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[4];
1124 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[5];
1125 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[6];
1126 *(destination += volume_util->destination_stride) = (gfloat) v_buffer[7];
1127
1128 destination += volume_util->destination_stride;
1129 i += 8;
1130 }
1131 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
1132 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1133
1134 for(; i < i_stop;){
1135 double ret_v_buffer[8];
1136
1137 double v_buffer[] = {
1138 (double) *(source),
1139 (double) *(source += volume_util->source_stride),
1140 (double) *(source += volume_util->source_stride),
1141 (double) *(source += volume_util->source_stride),
1142 (double) *(source += volume_util->source_stride),
1143 (double) *(source += volume_util->source_stride),
1144 (double) *(source += volume_util->source_stride),
1145 (double) *(source += volume_util->source_stride)};
1146
1147 double v_volume[] = {(double) volume_util->volume};
1148
1149 source += volume_util->source_stride;
1150
1151 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
1152
1153 *(destination) = (gfloat) ret_v_buffer[0];
1154 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[1];
1155 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[2];
1156 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[3];
1157 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[4];
1158 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[5];
1159 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[6];
1160 *(destination += volume_util->destination_stride) = (gfloat) ret_v_buffer[7];
1161
1162 destination += volume_util->destination_stride;
1163 i += 8;
1164 }
1165 #else
1166 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1167
1168 for(; i < i_stop;){
1169 *(destination) = (gfloat) (((source)[0] * (volume_util->volume)));
1170 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1171 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1172 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1173 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1174 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1175 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1176 *(destination += volume_util->destination_stride) = (gfloat) (((source += volume_util->source_stride)[0] * volume_util->volume));
1177
1178 destination += volume_util->destination_stride;
1179 source += volume_util->source_stride;
1180 i += 8;
1181 }
1182 #endif
1183
1184 /* loop tail */
1185 for(; i < volume_util->buffer_length;){
1186 destination[0] = (gfloat) ((source[0] * volume_util->volume));
1187
1188 destination += volume_util->destination_stride;
1189 source += volume_util->source_stride;
1190 i++;
1191 }
1192 }
1193
1194 /**
1195 * ags_volume_util_compute_double:
1196 * @volume_util: the #AgsVolumeUtil-struct
1197 *
1198 * Compute volume of double floating point data.
1199 *
1200 * Since: 3.9.2
1201 */
1202 void
ags_volume_util_compute_double(AgsVolumeUtil * volume_util)1203 ags_volume_util_compute_double(AgsVolumeUtil *volume_util)
1204 {
1205 gdouble *destination;
1206 gdouble *source;
1207 guint i, i_stop;
1208
1209 if(volume_util == NULL ||
1210 volume_util->destination == NULL ||
1211 volume_util->source == NULL){
1212 return;
1213 }
1214
1215 destination = (gdouble *) volume_util->destination;
1216 source = (gdouble *) volume_util->source;
1217
1218 i = 0;
1219
1220 #if defined(AGS_VECTORIZED_BUILTIN_FUNCTIONS)
1221 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1222
1223 for(; i < i_stop;){
1224 ags_v8double v_buffer;
1225
1226 v_buffer = (ags_v8double) {
1227 (gdouble) *(source),
1228 (gdouble) *(source += volume_util->source_stride),
1229 (gdouble) *(source += volume_util->source_stride),
1230 (gdouble) *(source += volume_util->source_stride),
1231 (gdouble) *(source += volume_util->source_stride),
1232 (gdouble) *(source += volume_util->source_stride),
1233 (gdouble) *(source += volume_util->source_stride),
1234 (gdouble) *(source += volume_util->source_stride)
1235 };
1236
1237 source += volume_util->source_stride;
1238
1239 v_buffer *= volume_util->volume;
1240
1241 *(destination) = (gdouble) v_buffer[0];
1242 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[1];
1243 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[2];
1244 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[3];
1245 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[4];
1246 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[5];
1247 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[6];
1248 *(destination += volume_util->destination_stride) = (gdouble) v_buffer[7];
1249
1250 destination += volume_util->destination_stride;
1251 i += 8;
1252 }
1253 #elif defined(AGS_OSX_ACCELERATE_BUILTIN_FUNCTIONS)
1254 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1255
1256 for(; i < i_stop;){
1257 double ret_v_buffer[8];
1258
1259 double v_buffer[] = {
1260 (double) *(source),
1261 (double) *(source += volume_util->source_stride),
1262 (double) *(source += volume_util->source_stride),
1263 (double) *(source += volume_util->source_stride),
1264 (double) *(source += volume_util->source_stride),
1265 (double) *(source += volume_util->source_stride),
1266 (double) *(source += volume_util->source_stride),
1267 (double) *(source += volume_util->source_stride)};
1268
1269 double v_volume[] = {(double) volume_util->volume};
1270
1271 source += volume_util->source_stride;
1272
1273 vDSP_vmulD(v_buffer, 1, v_volume, 0, ret_v_buffer, 1, 8);
1274
1275 *(destination) = (gdouble) ret_v_buffer[0];
1276 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[1];
1277 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[2];
1278 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[3];
1279 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[4];
1280 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[5];
1281 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[6];
1282 *(destination += volume_util->destination_stride) = (gdouble) ret_v_buffer[7];
1283
1284 destination += volume_util->destination_stride;
1285 i += 8;
1286 }
1287 #else
1288 i_stop = volume_util->buffer_length - (volume_util->buffer_length % 8);
1289
1290 for(; i < i_stop;){
1291 *(destination) = (gdouble) (((source)[0] * (volume_util->volume)));
1292 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1293 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1294 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1295 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1296 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1297 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1298 *(destination += volume_util->destination_stride) = (gdouble) (((source += volume_util->source_stride)[0] * volume_util->volume));
1299
1300 destination += volume_util->destination_stride;
1301 source += volume_util->source_stride;
1302 i += 8;
1303 }
1304 #endif
1305
1306 /* loop tail */
1307 for(; i < volume_util->buffer_length;){
1308 destination[0] = (gdouble) ((source[0] * volume_util->volume));
1309
1310 destination += volume_util->destination_stride;
1311 source += volume_util->source_stride;
1312 i++;
1313 }
1314 }
1315
1316 /**
1317 * ags_volume_util_compute_complex:
1318 * @volume_util: the #AgsVolumeUtil-struct
1319 *
1320 * Compute volume of complex floating point data.
1321 *
1322 * Since: 3.9.2
1323 */
1324 void
ags_volume_util_compute_complex(AgsVolumeUtil * volume_util)1325 ags_volume_util_compute_complex(AgsVolumeUtil *volume_util)
1326 {
1327 AgsComplex *destination;
1328 AgsComplex *source;
1329 guint i;
1330
1331 if(volume_util == NULL ||
1332 volume_util->destination == NULL ||
1333 volume_util->source == NULL){
1334 return;
1335 }
1336
1337 destination = (AgsComplex *) volume_util->destination;
1338 source = (AgsComplex *) volume_util->source;
1339
1340 i = 0;
1341
1342 for(; i < volume_util->buffer_length;){
1343 double _Complex z;
1344
1345 z = ags_complex_get(source);
1346
1347 ags_complex_set(destination,
1348 z * (volume_util->volume));
1349
1350 destination += volume_util->destination_stride;
1351 source += volume_util->source_stride;
1352 i++;
1353 }
1354 }
1355
1356 /**
1357 * ags_volume_util_compute:
1358 * @volume_util: the #AgsVolumeUtil-struct
1359 *
1360 * Compute volume.
1361 *
1362 * Since: 3.9.2
1363 */
1364 void
ags_volume_util_compute(AgsVolumeUtil * volume_util)1365 ags_volume_util_compute(AgsVolumeUtil *volume_util)
1366 {
1367 if(volume_util == NULL ||
1368 volume_util->destination == NULL ||
1369 volume_util->source == NULL){
1370 return;
1371 }
1372
1373 switch(volume_util->audio_buffer_util_format){
1374 case AGS_AUDIO_BUFFER_UTIL_S8:
1375 {
1376 ags_volume_util_compute_s8(volume_util);
1377 }
1378 break;
1379 case AGS_AUDIO_BUFFER_UTIL_S16:
1380 {
1381 ags_volume_util_compute_s16(volume_util);
1382 }
1383 break;
1384 case AGS_AUDIO_BUFFER_UTIL_S24:
1385 {
1386 ags_volume_util_compute_s24(volume_util);
1387 }
1388 break;
1389 case AGS_AUDIO_BUFFER_UTIL_S32:
1390 {
1391 ags_volume_util_compute_s32(volume_util);
1392 }
1393 break;
1394 case AGS_AUDIO_BUFFER_UTIL_S64:
1395 {
1396 ags_volume_util_compute_s64(volume_util);
1397 }
1398 break;
1399 case AGS_AUDIO_BUFFER_UTIL_FLOAT:
1400 {
1401 ags_volume_util_compute_float(volume_util);
1402 }
1403 break;
1404 case AGS_AUDIO_BUFFER_UTIL_DOUBLE:
1405 {
1406 ags_volume_util_compute_double(volume_util);
1407 }
1408 break;
1409 case AGS_AUDIO_BUFFER_UTIL_COMPLEX:
1410 {
1411 ags_volume_util_compute_complex(volume_util);
1412 }
1413 break;
1414 }
1415 }
1416