Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Device / addroutines_hifi.c
blob54208f720d672feb0a42ea17577e5eb6788eaeaa
1 /*
2 AHI - Hardware independent audio subsystem
3 Copyright (C) 1996-2005 Martin Blom <martin@blom.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
18 MA 02139, USA.
21 #include <config.h>
23 #include "addroutines.h"
25 /******************************************************************************
26 ** Add-Routines ***************************************************************
27 ******************************************************************************/
30 ** LONG Samples
31 ** LONG ScaleLeft
32 ** LONG ScaleRight
33 ** LONG *StartPointLeft
34 ** LONG *StartPointRight
35 ** void *Src
36 ** void **Dst
37 ** LONG FirstOffsetI
38 ** Fixed64 *Offset
39 ** Fixed64 Add
40 ** BOOL StopAtZero
45 Notes:
47 The fraction offset is divided by two in order to make sure that the
48 calculation of linearsample fits a LONG (0 =< offsetf <= 32767).
50 The routines could be faster, of course. One idea is to split the for loop
51 into two loops in order to eliminate the FirstOffsetI test in the second loop.
53 */
55 /*****************************************************************************/
57 /* Forward mixing code */
59 #define offseti ( (long) ( offset >> 32 ) )
61 #define offsetf ( (long) ( (unsigned long) ( offset & 0xffffffffULL ) >> 17) )
63 LONG
64 AddByteMono( ADDARGS )
66 BYTE *src = Src;
67 LONG *dst = *Dst;
68 Fixed64 offset = *Offset;
69 int i;
70 LONG startpoint, endpoint = 0; // Make compiler happy
71 LONG lastpoint;
73 lastpoint = 0; // 0 doesn't affect the StopAtZero code
75 for( i = 0; i < Samples; i++)
77 if( offseti == FirstOffsetI ) {
78 startpoint = *StartPointLeft;
80 else
82 startpoint = src[ offseti - 1 ] << 8;
85 endpoint = src[ offseti ] << 8;
87 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
89 if( StopAtZero &&
90 ( ( lastpoint < 0 && startpoint >= 0 ) ||
91 ( lastpoint > 0 && startpoint <= 0 ) ) )
93 break;
96 lastpoint = startpoint;
98 *dst++ += ScaleLeft * startpoint;
100 offset += Add;
103 *StartPointLeft = endpoint;
105 *Dst = dst;
106 *Offset = offset;
108 return i;
112 LONG
113 AddByteStereo( ADDARGS )
115 BYTE *src = Src;
116 LONG *dst = *Dst;
117 Fixed64 offset = *Offset;
118 int i;
119 LONG startpoint, endpoint = 0; // Make compiler happy
120 LONG lastpoint;
122 lastpoint = 0; // 0 doesn't affect the StopAtZero code
124 for( i = 0; i < Samples; i++)
126 if( offseti == FirstOffsetI ) {
127 startpoint = *StartPointLeft;
129 else
131 startpoint = src[ offseti - 1 ] << 8;
134 endpoint = src[ offseti ] << 8;
136 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
138 if( StopAtZero &&
139 ( ( lastpoint < 0 && startpoint >= 0 ) ||
140 ( lastpoint > 0 && startpoint <= 0 ) ) )
142 break;
145 lastpoint = startpoint;
147 *dst++ += ScaleLeft * startpoint;
148 *dst++ += ScaleRight * startpoint;
150 offset += Add;
153 *StartPointLeft = endpoint;
155 *Dst = dst;
156 *Offset = offset;
158 return i;
162 LONG
163 AddBytesMono( ADDARGS )
165 BYTE *src = Src;
166 LONG *dst = *Dst;
167 Fixed64 offset = *Offset;
168 int i;
169 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
170 LONG lastpointL, lastpointR;
172 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
174 for( i = 0; i < Samples; i++)
176 if( offseti == FirstOffsetI ) {
177 startpointL = *StartPointLeft;
178 startpointR = *StartPointRight;
180 else
182 startpointL = src[ offseti * 2 + 0 - 2 ] << 8;
183 startpointR = src[ offseti * 2 + 1 - 2 ] << 8;
186 endpointL = src[ offseti * 2 + 0 ] << 8;
187 endpointR = src[ offseti * 2 + 1 ] << 8;
189 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
190 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
192 if( StopAtZero &&
193 ( ( lastpointL < 0 && startpointL >= 0 ) ||
194 ( lastpointR < 0 && startpointR >= 0 ) ||
195 ( lastpointL > 0 && startpointL <= 0 ) ||
196 ( lastpointR > 0 && startpointR <= 0 ) ) )
198 break;
201 lastpointL = startpointL;
202 lastpointR = startpointR;
204 *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
206 offset += Add;
209 *StartPointLeft = endpointL;
210 *StartPointRight = endpointR;
212 *Dst = dst;
213 *Offset = offset;
215 return i;
219 LONG
220 AddBytesStereo( ADDARGS )
222 BYTE *src = Src;
223 LONG *dst = *Dst;
224 Fixed64 offset = *Offset;
225 int i;
226 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
227 LONG lastpointL, lastpointR;
229 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
231 for( i = 0; i < Samples; i++)
233 if( offseti == FirstOffsetI ) {
234 startpointL = *StartPointLeft;
235 startpointR = *StartPointRight;
237 else
239 startpointL = src[ offseti * 2 + 0 - 2 ] << 8;
240 startpointR = src[ offseti * 2 + 1 - 2 ] << 8;
243 endpointL = src[ offseti * 2 + 0 ] << 8;
244 endpointR = src[ offseti * 2 + 1 ] << 8;
246 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
247 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
249 if( StopAtZero &&
250 ( ( lastpointL < 0 && startpointL >= 0 ) ||
251 ( lastpointR < 0 && startpointR >= 0 ) ||
252 ( lastpointL > 0 && startpointL <= 0 ) ||
253 ( lastpointR > 0 && startpointR <= 0 ) ) )
255 break;
258 lastpointL = startpointL;
259 lastpointR = startpointR;
261 *dst++ += ScaleLeft * startpointL;
262 *dst++ += ScaleRight * startpointR;
264 offset += Add;
267 *StartPointLeft = endpointL;
268 *StartPointRight = endpointR;
270 *Dst = dst;
271 *Offset = offset;
273 return i;
277 LONG
278 AddWordMono( ADDARGS )
280 WORD *src = Src;
281 LONG *dst = *Dst;
282 Fixed64 offset = *Offset;
283 int i;
284 LONG startpoint, endpoint = 0; // Make compiler happy
285 LONG lastpoint;
287 lastpoint = 0; // 0 doesn't affect the StopAtZero code
289 for( i = 0; i < Samples; i++)
291 if( offseti == FirstOffsetI ) {
292 startpoint = *StartPointLeft;
294 else
296 startpoint = src[ offseti - 1 ];
299 endpoint = src[ offseti ];
301 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
303 if( StopAtZero &&
304 ( ( lastpoint < 0 && startpoint >= 0 ) ||
305 ( lastpoint > 0 && startpoint <= 0 ) ) )
307 break;
310 lastpoint = startpoint;
312 *dst++ += ScaleLeft * startpoint;
314 offset += Add;
317 *StartPointLeft = endpoint;
319 *Dst = dst;
320 *Offset = offset;
322 return i;
326 LONG
327 AddWordStereo( ADDARGS )
329 WORD *src = Src;
330 LONG *dst = *Dst;
331 Fixed64 offset = *Offset;
332 int i;
333 LONG startpoint, endpoint = 0; // Make compiler happy
334 LONG lastpoint;
336 lastpoint = 0; // 0 doesn't affect the StopAtZero code
338 for( i = 0; i < Samples; i++)
340 if( offseti == FirstOffsetI ) {
341 startpoint = *StartPointLeft;
343 else
345 startpoint = src[ offseti - 1 ];
348 endpoint = src[ offseti ];
350 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
352 if( StopAtZero &&
353 ( ( lastpoint < 0 && startpoint >= 0 ) ||
354 ( lastpoint > 0 && startpoint <= 0 ) ) )
356 break;
359 lastpoint = startpoint;
361 *dst++ += ScaleLeft * startpoint;
362 *dst++ += ScaleRight * startpoint;
364 offset += Add;
367 *StartPointLeft = endpoint;
369 *Dst = dst;
370 *Offset = offset;
372 return i;
375 LONG
376 AddWordsMono( ADDARGS )
378 WORD *src = Src;
379 LONG *dst = *Dst;
380 Fixed64 offset = *Offset;
381 int i;
382 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
383 LONG lastpointL, lastpointR;
385 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
387 for( i = 0; i < Samples; i++)
389 if( offseti == FirstOffsetI ) {
390 startpointL = *StartPointLeft;
391 startpointR = *StartPointRight;
393 else
395 startpointL = src[ offseti * 2 + 0 - 2 ];
396 startpointR = src[ offseti * 2 + 1 - 2 ];
399 endpointL = src[ offseti * 2 + 0 ];
400 endpointR = src[ offseti * 2 + 1 ];
402 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
403 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
405 if( StopAtZero &&
406 ( ( lastpointL < 0 && startpointL >= 0 ) ||
407 ( lastpointR < 0 && startpointR >= 0 ) ||
408 ( lastpointL > 0 && startpointL <= 0 ) ||
409 ( lastpointR > 0 && startpointR <= 0 ) ) )
411 break;
414 lastpointL = startpointL;
415 lastpointR = startpointR;
417 *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
419 offset += Add;
422 *StartPointLeft = endpointL;
423 *StartPointRight = endpointR;
425 *Dst = dst;
426 *Offset = offset;
428 return i;
432 LONG
433 AddWordsStereo( ADDARGS )
435 WORD *src = Src;
436 LONG *dst = *Dst;
437 Fixed64 offset = *Offset;
438 int i;
439 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
440 LONG lastpointL, lastpointR;
442 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
444 for( i = 0; i < Samples; i++)
446 if( offseti == FirstOffsetI ) {
447 startpointL = *StartPointLeft;
448 startpointR = *StartPointRight;
450 else
452 startpointL = src[ offseti * 2 + 0 - 2 ];
453 startpointR = src[ offseti * 2 + 1 - 2 ];
456 endpointL = src[ offseti * 2 + 0 ];
457 endpointR = src[ offseti * 2 + 1 ];
459 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
460 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
462 if( StopAtZero &&
463 ( ( lastpointL < 0 && startpointL >= 0 ) ||
464 ( lastpointR < 0 && startpointR >= 0 ) ||
465 ( lastpointL > 0 && startpointL <= 0 ) ||
466 ( lastpointR > 0 && startpointR <= 0 ) ) )
468 break;
471 lastpointL = startpointL;
472 lastpointR = startpointR;
474 *dst++ += ScaleLeft * startpointL;
475 *dst++ += ScaleRight * startpointR;
477 offset += Add;
480 *StartPointLeft = endpointL;
481 *StartPointRight = endpointR;
483 *Dst = dst;
484 *Offset = offset;
486 return i;
489 #undef offsetf
491 /*****************************************************************************/
493 /* Backward mixing code */
495 #define offsetf ( (long) ( 32768 - ( (unsigned long) ( offset & 0xffffffffULL ) >> 17 ) ) )
497 LONG
498 AddByteMonoB( ADDARGS )
500 BYTE *src = Src;
501 LONG *dst = *Dst;
502 Fixed64 offset = *Offset;
503 int i;
504 LONG startpoint, endpoint = 0; // Make compiler happy
505 LONG lastpoint;
507 lastpoint = 0; // 0 doesn't affect the StopAtZero code
509 for( i = 0; i < Samples; i++)
511 if( offseti == FirstOffsetI ) {
512 startpoint = *StartPointLeft;
514 else
516 startpoint = src[ offseti + 1 ] << 8;
519 endpoint = src[ offseti ] << 8;
521 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
523 if( StopAtZero &&
524 ( ( lastpoint < 0 && startpoint >= 0 ) ||
525 ( lastpoint > 0 && startpoint <= 0 ) ) )
527 break;
530 lastpoint = startpoint;
532 *dst++ += ScaleLeft * startpoint;
534 offset -= Add;
537 *StartPointLeft = endpoint;
539 *Dst = dst;
540 *Offset = offset;
542 return i;
546 LONG
547 AddByteStereoB( ADDARGS )
549 BYTE *src = Src;
550 LONG *dst = *Dst;
551 Fixed64 offset = *Offset;
552 int i;
553 LONG startpoint, endpoint = 0; // Make compiler happy
554 LONG lastpoint;
556 lastpoint = 0; // 0 doesn't affect the StopAtZero code
558 for( i = 0; i < Samples; i++)
560 if( offseti == FirstOffsetI ) {
561 startpoint = *StartPointLeft;
563 else
565 startpoint = src[ offseti + 1 ] << 8;
568 endpoint = src[ offseti ] << 8;
570 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
572 if( StopAtZero &&
573 ( ( lastpoint < 0 && startpoint >= 0 ) ||
574 ( lastpoint > 0 && startpoint <= 0 ) ) )
576 break;
579 lastpoint = startpoint;
581 *dst++ += ScaleLeft * startpoint;
582 *dst++ += ScaleRight * startpoint;
584 offset -= Add;
587 *StartPointLeft = endpoint;
589 *Dst = dst;
590 *Offset = offset;
592 return i;
596 LONG
597 AddBytesMonoB( ADDARGS )
599 BYTE *src = Src;
600 LONG *dst = *Dst;
601 Fixed64 offset = *Offset;
602 int i;
603 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
604 LONG lastpointL, lastpointR;
606 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
608 for( i = 0; i < Samples; i++)
610 if( offseti == FirstOffsetI ) {
611 startpointL = *StartPointLeft;
612 startpointR = *StartPointRight;
614 else
616 startpointL = src[ offseti * 2 + 0 + 2 ] << 8;
617 startpointR = src[ offseti * 2 + 1 + 2 ] << 8;
620 endpointL = src[ offseti * 2 + 0 ] << 8;
621 endpointR = src[ offseti * 2 + 1 ] << 8;
623 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
624 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
626 if( StopAtZero &&
627 ( ( lastpointL < 0 && startpointL >= 0 ) ||
628 ( lastpointR < 0 && startpointR >= 0 ) ||
629 ( lastpointL > 0 && startpointL <= 0 ) ||
630 ( lastpointR > 0 && startpointR <= 0 ) ) )
632 break;
635 lastpointL = startpointL;
636 lastpointR = startpointR;
638 *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
640 offset -= Add;
643 *StartPointLeft = endpointL;
644 *StartPointRight = endpointR;
646 *Dst = dst;
647 *Offset = offset;
649 return i;
653 LONG
654 AddBytesStereoB( ADDARGS )
656 BYTE *src = Src;
657 LONG *dst = *Dst;
658 Fixed64 offset = *Offset;
659 int i;
660 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
661 LONG lastpointL, lastpointR;
663 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
665 for( i = 0; i < Samples; i++)
667 if( offseti == FirstOffsetI ) {
668 startpointL = *StartPointLeft;
669 startpointR = *StartPointRight;
671 else
673 startpointL = src[ offseti * 2 + 0 + 2 ] << 8;
674 startpointR = src[ offseti * 2 + 1 + 2 ] << 8;
677 endpointL = src[ offseti * 2 + 0 ] << 8;
678 endpointR = src[ offseti * 2 + 1 ] << 8;
680 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
681 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
683 if( StopAtZero &&
684 ( ( lastpointL < 0 && startpointL >= 0 ) ||
685 ( lastpointR < 0 && startpointR >= 0 ) ||
686 ( lastpointL > 0 && startpointL <= 0 ) ||
687 ( lastpointR > 0 && startpointR <= 0 ) ) )
689 break;
692 lastpointL = startpointL;
693 lastpointR = startpointR;
695 *dst++ += ScaleLeft * startpointL;
696 *dst++ += ScaleRight * startpointR;
698 offset -= Add;
701 *StartPointLeft = endpointL;
702 *StartPointRight = endpointR;
704 *Dst = dst;
705 *Offset = offset;
707 return i;
711 LONG
712 AddWordMonoB( ADDARGS )
714 WORD *src = Src;
715 LONG *dst = *Dst;
716 Fixed64 offset = *Offset;
717 int i;
718 LONG startpoint, endpoint = 0; // Make compiler happy
719 LONG lastpoint;
721 lastpoint = 0; // 0 doesn't affect the StopAtZero code
723 for( i = 0; i < Samples; i++)
725 if( offseti == FirstOffsetI ) {
726 startpoint = *StartPointLeft;
728 else
730 startpoint = src[ offseti + 1 ];
733 endpoint = src[ offseti ];
735 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
737 if( StopAtZero &&
738 ( ( lastpoint < 0 && startpoint >= 0 ) ||
739 ( lastpoint > 0 && startpoint <= 0 ) ) )
741 break;
744 lastpoint = startpoint;
746 *dst++ += ScaleLeft * startpoint;
748 offset -= Add;
751 *StartPointLeft = endpoint;
753 *Dst = dst;
754 *Offset = offset;
756 return i;
760 LONG
761 AddWordStereoB( ADDARGS )
763 WORD *src = Src;
764 LONG *dst = *Dst;
765 Fixed64 offset = *Offset;
766 int i;
767 LONG startpoint, endpoint = 0; // Make compiler happy
768 LONG lastpoint;
770 lastpoint = 0; // 0 doesn't affect the StopAtZero code
772 for( i = 0; i < Samples; i++)
774 if( offseti == FirstOffsetI ) {
775 startpoint = *StartPointLeft;
777 else
779 startpoint = src[ offseti + 1 ];
782 endpoint = src[ offseti ];
784 startpoint += (((endpoint - startpoint) * offsetf ) >> 15);
786 if( StopAtZero &&
787 ( ( lastpoint < 0 && startpoint >= 0 ) ||
788 ( lastpoint > 0 && startpoint <= 0 ) ) )
790 break;
793 lastpoint = startpoint;
795 *dst++ += ScaleLeft * startpoint;
796 *dst++ += ScaleRight * startpoint;
798 offset -= Add;
801 *StartPointLeft = endpoint;
803 *Dst = dst;
804 *Offset = offset;
806 return i;
810 LONG
811 AddWordsMonoB( ADDARGS )
813 WORD *src = Src;
814 LONG *dst = *Dst;
815 Fixed64 offset = *Offset;
816 int i;
817 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
818 LONG lastpointL, lastpointR;
820 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
822 for( i = 0; i < Samples; i++)
824 if( offseti == FirstOffsetI ) {
825 startpointL = *StartPointLeft;
826 startpointR = *StartPointRight;
828 else
830 startpointL = src[ offseti * 2 + 0 + 2 ];
831 startpointR = src[ offseti * 2 + 1 + 2 ];
834 endpointL = src[ offseti * 2 + 0 ];
835 endpointR = src[ offseti * 2 + 1 ];
837 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
838 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
840 if( StopAtZero &&
841 ( ( lastpointL < 0 && startpointL >= 0 ) ||
842 ( lastpointR < 0 && startpointR >= 0 ) ||
843 ( lastpointL > 0 && startpointL <= 0 ) ||
844 ( lastpointR > 0 && startpointR <= 0 ) ) )
846 break;
849 lastpointL = startpointL;
850 lastpointR = startpointR;
852 *dst++ += ScaleLeft * startpointL + ScaleRight * startpointR;
854 offset -= Add;
857 *StartPointLeft = endpointL;
858 *StartPointRight = endpointR;
860 *Dst = dst;
861 *Offset = offset;
863 return i;
867 LONG
868 AddWordsStereoB( ADDARGS )
870 WORD *src = Src;
871 LONG *dst = *Dst;
872 Fixed64 offset = *Offset;
873 int i;
874 LONG startpointL, startpointR, endpointL = 0, endpointR = 0; // Make compiler happy
875 LONG lastpointL, lastpointR;
877 lastpointL = lastpointR = 0; // 0 doesn't affect the StopAtZero code
879 for( i = 0; i < Samples; i++)
881 if( offseti == FirstOffsetI ) {
882 startpointL = *StartPointLeft;
883 startpointR = *StartPointRight;
885 else
887 startpointL = src[ offseti * 2 + 0 + 2 ];
888 startpointR = src[ offseti * 2 + 1 + 2 ];
891 endpointL = src[ offseti * 2 + 0 ];
892 endpointR = src[ offseti * 2 + 1 ];
894 startpointL += (((endpointL - startpointL) * offsetf ) >> 15);
895 startpointR += (((endpointR - startpointR) * offsetf ) >> 15);
897 if( StopAtZero &&
898 ( ( lastpointL < 0 && startpointL >= 0 ) ||
899 ( lastpointR < 0 && startpointR >= 0 ) ||
900 ( lastpointL > 0 && startpointL <= 0 ) ||
901 ( lastpointR > 0 && startpointR <= 0 ) ) )
903 break;
906 lastpointL = startpointL;
907 lastpointR = startpointR;
909 *dst++ += ScaleLeft * startpointL;
910 *dst++ += ScaleRight * startpointR;
912 offset -= Add;
915 *StartPointLeft = endpointL;
916 *StartPointRight = endpointR;
918 *Dst = dst;
919 *Offset = offset;
921 return i;
925 #undef offseti
926 #undef offsetf
928 /*****************************************************************************/