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