r8brain-free-src
High-quality pro audio sample rate converter library
 
Loading...
Searching...
No Matches
r8bbase.h
Go to the documentation of this file.
1//$ nobt
2
60
61#ifndef R8BBASE_INCLUDED
62#define R8BBASE_INCLUDED
63
64#define R8B_VERSION "7.5"
65
71
77
78#include <cstring>
79#include <cmath>
80#include <new>
81
82#if __cplusplus >= 201103L
83
84 #include <cstdint>
85 #include <mutex>
86
87 #define R8B_CONST constexpr
88 #define R8B_NULL nullptr
89
90#else // __cplusplus >= 201103L
91
92 #include <stdint.h> // A C99 fallback, as C++98 has no cstdint header.
93
94 #if defined( _WIN32 )
95 #include <Windows.h>
96 #else // defined( _WIN32 )
97 #include <pthread.h>
98 #endif // defined( _WIN32 )
99
100 #define R8B_CONST static const
101 #define R8B_NULL NULL
102
103#endif // __cplusplus >= 201103L
104
105#include "r8bconf.h"
106
107#if defined( __aarch64__ ) || defined( __arm64__ ) || \
108 defined( _M_ARM64 ) || defined( _M_ARM64EC )
109
110 #if defined( _MSC_VER )
111 #include <arm64_neon.h>
112 #else // defined( _MSC_VER )
113 #include <arm_neon.h>
114 #endif // defined( _MSC_VER )
115
116 #define R8B_NEON
117
118 #if !defined( __APPLE__ )
119 #define R8B_SIMD_ISH // Shuffled interpolation is inefficient on M1.
120 #endif // !defined( __APPLE__ )
121
122#elif defined( __SSE2__ ) || defined( _M_AMD64 ) || \
123 ( defined( _M_IX86_FP ) && _M_IX86_FP == 2 )
124
125 #if defined( _MSC_VER )
126 #include <intrin.h>
127 #else // defined( _MSC_VER )
128 #include <emmintrin.h>
129 #endif // defined( _MSC_VER )
130
131 #define R8B_SSE2
132 #define R8B_SIMD_ISH
133
134#endif // SSE2
135
142
143#if defined( __clang__ )
144
145 #define R8B_EXITDTOR __attribute__((always_destroy))
146
147#else // defined( __clang__ )
148
149 #define R8B_EXITDTOR
150
151#endif // defined( __clang__ )
152
158
159namespace r8b {
160
161using std :: memcpy;
162using std :: memset;
163using std :: floor;
164using std :: ceil;
165using std :: fabs;
166using std :: sqrt;
167using std :: log;
168using std :: exp;
169using std :: pow;
170using std :: sin;
171using std :: cos;
172using std :: tan;
173using std :: atan;
174using std :: atan2;
175using std :: tanh;
176using std :: cosh;
177using std :: size_t;
178
179#if __cplusplus >= 201103L
180
181 using std :: uintptr_t;
182
183#endif // __cplusplus >= 201103L
184
185R8B_CONST double R8B_PI = 3.14159265358979324;
186R8B_CONST double R8B_2PI = 6.28318530717958648;
187R8B_CONST double R8B_3PI = 9.42477796076937972;
188R8B_CONST double R8B_PId2 = 1.57079632679489662;
189
203
204#if __cplusplus >= 201103L
205
206 #define R8BNOCTOR( ClassName ) \
207 public: \
208 ClassName( const ClassName& ) = delete; \
209 ClassName& operator = ( const ClassName& ) = delete;
210
211#else // __cplusplus >= 201103L
212
213 #define R8BNOCTOR( ClassName ) \
214 private: \
215 ClassName( const ClassName& ) { } \
216 ClassName& operator = ( const ClassName& ) { return( *this ); }
217
218#endif // __cplusplus >= 201103L
219
223
225{
226};
227
233
235{
236public:
243
244 static void* allocmem( const size_t Size )
245 {
246 return( new char[ Size ]);
247 }
248
254
255 static void freemem( void* const p )
256 {
257 delete[] (char*) p;
258 }
259};
260
271
272template< typename T >
273inline T* align_ptr( T* const ptr, const uintptr_t align )
274{
275 return( (T*) (( (uintptr_t) ptr + align - 1 ) & ~( align - 1 )));
276}
277
287
288template< typename T >
289inline T* construct_ptr( void* const ptr, const size_t c )
290{
291 return( :: new( ptr ) T[ c ]);
292}
293
311
312template< typename T >
313class CFixedBuffer : protected R8B_MEMALLOCCLASS
314{
315 R8BNOCTOR( CFixedBuffer )
316
317public:
318 CFixedBuffer()
319 : Data0( R8B_NULL )
320 , Data( R8B_NULL )
321 {
322 }
323
330
331 CFixedBuffer( const int Capacity )
332 {
333 R8BASSERT( Capacity >= 0 );
334
335 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
336 Data = construct_ptr< T >( align_ptr( Data0, Alignment ),
337 (size_t) Capacity );
338
339 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
340 }
341
343 {
344 freemem( Data0 );
345 }
346
353
354 void alloc( const int Capacity )
355 {
356 R8BASSERT( Capacity >= 0 );
357
358 freemem( Data0 );
359 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
360 Data = construct_ptr< T >( align_ptr( Data0, Alignment ),
361 (size_t) Capacity );
362
363 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
364 }
365
374
375 void realloc( const int PrevCapacity, const int NewCapacity )
376 {
377 R8BASSERT( PrevCapacity >= 0 );
378 R8BASSERT( NewCapacity >= 0 );
379
380 void* const NewData0 = allocmem( (size_t) NewCapacity * sizeof( T ) +
381 Alignment );
382
383 T* const NewData = construct_ptr< T >( align_ptr( NewData0,
384 Alignment ), (size_t) NewCapacity );
385
386 const size_t CopySize = ( PrevCapacity > NewCapacity ?
387 (size_t) NewCapacity : (size_t) PrevCapacity ) * sizeof( T );
388
389 if( CopySize > 0 )
390 {
391 memcpy( NewData, Data, CopySize );
392 }
393
394 freemem( Data0 );
395 Data0 = NewData0;
396 Data = NewData;
397
398 R8BASSERT( Data0 != R8B_NULL || NewCapacity == 0 );
399 }
400
406
407 void moveFrom( CFixedBuffer& s )
408 {
409 freemem( Data0 );
410 Data0 = s.Data0;
411 Data = s.Data;
412 s.Data0 = R8B_NULL;
413 s.Data = R8B_NULL;
414 }
415
419
420 void free()
421 {
422 freemem( Data0 );
423 Data0 = R8B_NULL;
424 Data = R8B_NULL;
425 }
426
431
432 operator T* () const
433 {
434 return( Data );
435 }
436
437private:
438 static const size_t Alignment = 64;
440 void* Data0;
441 T* Data;
442};
443
454
455template< typename T >
456class CPtrKeeper
457{
458 R8BNOCTOR( CPtrKeeper )
459
460public:
461 CPtrKeeper()
462 : Object( R8B_NULL )
463 {
464 }
465
472
473 template< typename T2 >
474 CPtrKeeper( T2 const aObject )
475 : Object( aObject )
476 {
477 }
478
480 {
481 delete Object;
482 }
483
491
492 template< typename T2 >
493 void operator = ( T2 const aObject )
494 {
495 reset();
496 Object = aObject;
497 }
498
503
504 T* operator -> () const
505 {
506 return( Object );
507 }
508
513
514 operator T* () const
515 {
516 return( Object );
517 }
518
522
523 void reset()
524 {
525 T* const DelObj = Object;
526 Object = R8B_NULL;
527 delete DelObj;
528 }
529
534
536 {
537 T* const ResObject = Object;
538 Object = R8B_NULL;
539 return( ResObject );
540 }
541
542private:
543 T* Object;
544};
545
554
555template< typename T >
556class CRefKeeper
557{
558 R8BNOCTOR( CRefKeeper )
559
560public:
561 CRefKeeper()
562 : Object( R8B_NULL )
563 {
564 }
565
572
573 template< typename T2 >
574 CRefKeeper( T2 const aObject )
575 : Object( aObject )
576 {
577 }
578
580 {
581 if( Object != R8B_NULL )
582 {
583 Object -> unref();
584 }
585 }
586
594
595 template< typename T2 >
596 void operator = ( T2 const aObject )
597 {
598 reset();
599 Object = aObject;
600 }
601
606
607 T* operator -> () const
608 {
609 return( Object );
610 }
611
616
617 operator T* () const
618 {
619 return( Object );
620 }
621
625
626 void reset()
627 {
628 if( Object != R8B_NULL )
629 {
630 T* const RefObj = Object;
631 Object = R8B_NULL;
632 RefObj -> unref();
633 }
634 }
635
636private:
637 T* Object;
638};
639
647
648template< class T >
649class CSinglyLinkedListItem
650{
651public:
652 T* Next;
653
654protected:
655 CSinglyLinkedListItem()
656 : Next( R8B_NULL )
657 {
658 }
659
661 {
662 while( Next != R8B_NULL )
663 {
664 T* const nn = Next -> Next;
665 Next -> Next = R8B_NULL;
666 delete Next;
667 Next = nn;
668 }
669 }
670};
671
672#if __cplusplus >= 201103L
673
674typedef std :: mutex CSyncObject;
675typedef std :: lock_guard< std :: mutex > CSyncKeeper;
676
677#else // __cplusplus >= 201103L
678
689
690class CSyncObject
691{
692 R8BNOCTOR( CSyncObject )
693
694public:
695 CSyncObject()
696 {
697 #if defined( _WIN32 )
698 InitializeCriticalSectionAndSpinCount( &CritSec, 2000 );
699 #else // defined( _WIN32 )
700 pthread_mutexattr_t MutexAttrs;
701 pthread_mutexattr_init( &MutexAttrs );
702 pthread_mutexattr_settype( &MutexAttrs, PTHREAD_MUTEX_RECURSIVE );
703 pthread_mutex_init( &Mutex, &MutexAttrs );
704 pthread_mutexattr_destroy( &MutexAttrs );
705 #endif // defined( _WIN32 )
706 }
707
708 ~CSyncObject()
709 {
710 #if defined( _WIN32 )
711 DeleteCriticalSection( &CritSec );
712 #else // defined( _WIN32 )
713 pthread_mutex_destroy( &Mutex );
714 #endif // defined( _WIN32 )
715 }
716
721
722 void acquire()
723 {
724 #if defined( _WIN32 )
725 EnterCriticalSection( &CritSec );
726 #else // defined( _WIN32 )
727 pthread_mutex_lock( &Mutex );
728 #endif // defined( _WIN32 )
729 }
730
735
736 void release()
737 {
738 #if defined( _WIN32 )
739 LeaveCriticalSection( &CritSec );
740 #else // defined( _WIN32 )
741 pthread_mutex_unlock( &Mutex );
742 #endif // defined( _WIN32 )
743 }
744
745private:
746 #if defined( _WIN32 )
747 CRITICAL_SECTION CritSec;
749 #else // defined( _WIN32 )
750 pthread_mutex_t Mutex;
751 #endif // defined( _WIN32 )
752};
753
763
764class CSyncKeeper
765{
766 R8BNOCTOR( CSyncKeeper )
767
768public:
769 CSyncKeeper()
770 : SyncObj( R8B_NULL )
771 {
772 }
773
780
781 CSyncKeeper( CSyncObject* const aSyncObj )
782 : SyncObj( aSyncObj )
783 {
784 if( SyncObj != R8B_NULL )
785 {
786 SyncObj -> acquire();
787 }
788 }
789
796
798 : SyncObj( &aSyncObj )
799 {
800 SyncObj -> acquire();
801 }
802
804 {
805 if( SyncObj != R8B_NULL )
806 {
807 SyncObj -> release();
808 }
809 }
810
811private:
812 CSyncObject* SyncObj;
813};
814
815#endif // __cplusplus >= 201103L
816
832
833#define R8BSYNC( SyncObject ) R8BSYNC1( SyncObject, __LINE__ )
834#define R8BSYNC1( SyncObject, id ) R8BSYNC2( SyncObject, id )
835#define R8BSYNC2( SyncObject, id ) \
836 const CSyncKeeper SyncKeeper##id( SyncObject )
837
843
844class CSineGen
845{
846public:
847 CSineGen()
848 {
849 }
850
858
859 CSineGen( const double si, const double ph )
860 : svalue1( sin( ph ))
861 , svalue2( sin( ph - si ))
862 , sincr( 2.0 * cos( si ))
863 {
864 }
865
874
875 CSineGen( const double si, const double ph, const double g )
876 : svalue1( sin( ph ) * g )
877 , svalue2( sin( ph - si ) * g )
878 , sincr( 2.0 * cos( si ))
879 {
880 }
881
889
890 void init( const double si, const double ph )
891 {
892 svalue1 = sin( ph );
893 svalue2 = sin( ph - si );
894 sincr = 2.0 * cos( si );
895 }
896
905
906 void init( const double si, const double ph, const double g )
907 {
908 svalue1 = sin( ph ) * g;
909 svalue2 = sin( ph - si ) * g;
910 sincr = 2.0 * cos( si );
911 }
912
918
919 double generate()
920 {
921 const double res = svalue1;
922
923 svalue1 = sincr * res - svalue2;
924 svalue2 = res;
925
926 return( res );
927 }
928
929private:
930 double svalue1;
931 double svalue2;
932 double sincr;
933};
934
943
944inline int getBitOccupancy( const int v )
945{
946 static const unsigned char OccupancyTable[] =
947 {
948 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
949 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
950 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
951 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
952 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
953 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
954 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
955 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
956 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
957 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
958 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
959 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
960 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
961 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
962 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
963 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
964 };
965
966 const int tt = v >> 16;
967
968 if( tt != 0 )
969 {
970 const int t = v >> 24;
971
972 return( t != 0 ? 24 + OccupancyTable[ t & 0xFF ] :
973 16 + OccupancyTable[ tt ]);
974 }
975 else
976 {
977 const int t = v >> 8;
978
979 return( t != 0 ? 8 + OccupancyTable[ t ] : OccupancyTable[ v ]);
980 }
981}
982
996
997inline void calcFIRFilterResponse( const double* flt, int fltlen,
998 const double th, double& re0, double& im0, const int fltlat = 0 )
999{
1000 const double sincr = 2.0 * cos( th );
1001 double cvalue1;
1002 double svalue1;
1003
1004 if( fltlat == 0 )
1005 {
1006 cvalue1 = 1.0;
1007 svalue1 = 0.0;
1008 }
1009 else
1010 {
1011 cvalue1 = cos( -fltlat * th );
1012 svalue1 = sin( -fltlat * th );
1013 }
1014
1015 double cvalue2 = cos( -( fltlat + 1 ) * th );
1016 double svalue2 = sin( -( fltlat + 1 ) * th );
1017
1018 double re = 0.0;
1019 double im = 0.0;
1020
1021 while( fltlen > 0 )
1022 {
1023 re += cvalue1 * flt[ 0 ];
1024 im += svalue1 * flt[ 0 ];
1025 flt++;
1026 fltlen--;
1027
1028 double tmp = cvalue1;
1029 cvalue1 = sincr * cvalue1 - cvalue2;
1030 cvalue2 = tmp;
1031
1032 tmp = svalue1;
1033 svalue1 = sincr * svalue1 - svalue2;
1034 svalue2 = tmp;
1035 }
1036
1037 re0 = re;
1038 im0 = im;
1039}
1040
1053
1054inline double calcFIRFilterGroupDelay( const double* const flt,
1055 const int fltlen, const double th )
1056{
1057 const int Count = 2;
1058 const double thd2 = 1e-9;
1059 double ths[ Count ] = { th - thd2, th + thd2 }; // Side-band frequencies.
1060
1061 if( ths[ 0 ] < 0.0 )
1062 {
1063 ths[ 0 ] = 0.0;
1064 }
1065
1066 if( ths[ 1 ] > R8B_PI )
1067 {
1068 ths[ 1 ] = R8B_PI;
1069 }
1070
1071 double ph1[ Count ];
1072 int i;
1073
1074 for( i = 0; i < Count; i++ )
1075 {
1076 double re1;
1077 double im1;
1078
1079 calcFIRFilterResponse( flt, fltlen, ths[ i ], re1, im1 );
1080 ph1[ i ] = atan2( im1, re1 );
1081 }
1082
1083 if( fabs( ph1[ 1 ] - ph1[ 0 ]) > R8B_PI )
1084 {
1085 if( ph1[ 1 ] > ph1[ 0 ])
1086 {
1087 ph1[ 1 ] -= R8B_2PI;
1088 }
1089 else
1090 {
1091 ph1[ 1 ] += R8B_2PI;
1092 }
1093 }
1094
1095 const double thd = ths[ 1 ] - ths[ 0 ];
1096
1097 return(( ph1[ 1 ] - ph1[ 0 ]) / thd );
1098}
1099
1111
1112inline void normalizeFIRFilter( double* const p, const int l,
1113 const double DCGain, const int pstep = 1 )
1114{
1115 R8BASSERT( l > 0 );
1116 R8BASSERT( pstep != 0 );
1117
1118 double s = 0.0;
1119 double* pp = p;
1120 int i = l;
1121
1122 while( i > 0 )
1123 {
1124 s += *pp;
1125 pp += pstep;
1126 i--;
1127 }
1128
1129 s = DCGain / s;
1130 pp = p;
1131 i = l;
1132
1133 while( i > 0 )
1134 {
1135 *pp *= s;
1136 pp += pstep;
1137 i--;
1138 }
1139}
1140
1157
1158inline void calcSpline3p8Coeffs( double* const c, const double xm3,
1159 const double xm2, const double xm1, const double x0, const double x1,
1160 const double x2, const double x3, const double x4 )
1161{
1162 c[ 0 ] = x0;
1163 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
1164 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
1165
1166 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
1167 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
1168
1169 c[ 3 ] = ( 91.0 * ( x0 - x1 ) + 45.0 * ( x2 - xm1 ) +
1170 13.0 * ( xm2 - x3 ) + 3.0 * ( x4 - xm3 )) * 1.31578947368421052e-2;
1171}
1172
1191
1192inline void calcSpline2p8Coeffs( double* const c, const double xm3,
1193 const double xm2, const double xm1, const double x0, const double x1,
1194 const double x2, const double x3, const double x4 )
1195{
1196 c[ 0 ] = x0;
1197 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
1198 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
1199
1200 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
1201 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
1202}
1203
1214
1215inline void calcSpline3p4Coeffs( double* const c, const double* const y )
1216{
1217 c[ 0 ] = y[ 1 ];
1218 c[ 1 ] = 0.5 * ( y[ 2 ] - y[ 0 ]);
1219 c[ 2 ] = y[ 0 ] - 2.5 * y[ 1 ] + y[ 2 ] + y[ 2 ] - 0.5 * y[ 3 ];
1220 c[ 3 ] = 0.5 * ( y[ 3 ] - y[ 0 ] ) + 1.5 * ( y[ 1 ] - y[ 2 ]);
1221}
1222
1233
1234inline void calcSpline3p6Coeffs( double* const c, const double* const y )
1235{
1236 c[ 0 ] = y[ 2 ];
1237 c[ 1 ] = ( 11.0 * ( y[ 3 ] - y[ 1 ]) + 2.0 * ( y[ 0 ] - y[ 4 ])) / 14.0;
1238 c[ 2 ] = ( 20.0 * ( y[ 1 ] + y[ 3 ]) + 2.0 * y[ 5 ] - 4.0 * y[ 0 ] -
1239 7.0 * y[ 4 ] - 31.0 * y[ 2 ]) / 14.0;
1240
1241 c[ 3 ] = ( 17.0 * ( y[ 2 ] - y[ 3 ]) + 9.0 * ( y[ 4 ] - y[ 1 ]) +
1242 2.0 * ( y[ 0 ] - y[ 5 ])) / 14.0;
1243}
1244
1245#if !defined( min )
1246
1255
1256template< typename T >
1257inline T min( const T& v1, const T& v2 )
1258{
1259 return( v1 < v2 ? v1 : v2 );
1260}
1261
1262#endif // !defined( min )
1263
1264#if !defined( max )
1265
1274
1275template< typename T >
1276inline T max( const T& v1, const T& v2 )
1277{
1278 return( v1 > v2 ? v1 : v2 );
1279}
1280
1281#endif // !defined( max )
1282
1294
1295inline double clampr( const double Value, const double minv,
1296 const double maxv )
1297{
1298 if( Value < minv )
1299 {
1300 return( minv );
1301 }
1302
1303 if( Value > maxv )
1304 {
1305 return( maxv );
1306 }
1307
1308 return( Value );
1309}
1310
1317
1318inline double sqr( const double x )
1319{
1320 return( x * x );
1321}
1322
1331
1332inline double pow_a( const double v, const double p )
1333{
1334 return( exp( p * log( fabs( v ) + 1e-300 )));
1335}
1336
1343
1344inline double gauss( const double v )
1345{
1346 return( exp( -( v * v )));
1347}
1348
1355
1356inline double asinh( const double v )
1357{
1358 return( log( v + sqrt( v * v + 1.0 )));
1359}
1360
1369
1370inline double besselI0( const double x )
1371{
1372 const double ax = fabs( x );
1373 double y;
1374
1375 if( ax < 3.75 )
1376 {
1377 y = x / 3.75;
1378 y *= y;
1379
1380 return( 1.0 + y * ( 3.5156229 + y * ( 3.0899424 + y * ( 1.2067492 +
1381 y * ( 0.2659732 + y * ( 0.360768e-1 + y * 0.45813e-2 ))))));
1382 }
1383
1384 y = 3.75 / ax;
1385
1386 return( exp( ax ) / sqrt( ax ) * ( 0.39894228 + y * ( 0.1328592e-1 +
1387 y * ( 0.225319e-2 + y * ( -0.157565e-2 + y * ( 0.916281e-2 +
1388 y * ( -0.2057706e-1 + y * ( 0.2635537e-1 + y * ( -0.1647633e-1 +
1389 y * 0.392377e-2 )))))))));
1390}
1391
1392} // namespace r8b
1393
1394#endif // R8BBASE_INCLUDED
#define R8B_NULL
The "null pointer" value, portable between C++11 and earlier C++ versions.
Definition r8bbase.h:101
#define R8B_CONST
The prefix for constant definitions, portable between C++11 and earlier C++ versions.
Definition r8bbase.h:100
#define R8BNOCTOR(ClassName)
Macro that defines empty copy-constructor and copy operator.
Definition r8bbase.h:213
The "configuration" inclusion file you can modify.
#define R8BASSERT(e)
Assertion macro used to check for certain run-time conditions. By default, no action is taken if asse...
Definition r8bconf.h:28
#define R8B_MEMALLOCCLASS
Macro defines the name of the class that implements raw memory allocation functions,...
Definition r8bconf.h:65
The "r8brain-free-src" library namespace.
Definition CDSPBlockConvolver.h:22
double calcFIRFilterGroupDelay(const double *const flt, const int fltlen, const double th)
FIR filter's group delay calculation function.
Definition r8bbase.h:1054
void calcSpline3p4Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 4 points.
Definition r8bbase.h:1215
double pow_a(const double v, const double p)
Power of an absolute value.
Definition r8bbase.h:1332
R8B_CONST double R8B_PI
Equals pi.
Definition r8bbase.h:185
void calcFIRFilterResponse(const double *flt, int fltlen, const double th, double &re0, double &im0, const int fltlat=0)
FIR filter's frequency response calculation.
Definition r8bbase.h:997
R8B_CONST double R8B_3PI
Equals 3*pi.
Definition r8bbase.h:187
void calcSpline3p6Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 6 points.
Definition r8bbase.h:1234
R8B_CONST double R8B_2PI
Equals 2*pi.
Definition r8bbase.h:186
R8B_CONST double R8B_PId2
Equals 0.5*pi.
Definition r8bbase.h:188
T min(const T &v1, const T &v2)
Returns minimum of two values.
Definition r8bbase.h:1257
void calcSpline3p8Coeffs(double *const c, const double xm3, const double xm2, const double xm1, const double x0, const double x1, const double x2, const double x3, const double x4)
Calculates 3rd order spline coefficients, using 8 points.
Definition r8bbase.h:1158
int getBitOccupancy(const int v)
Calculate the exact number of bits a value needs for representation.
Definition r8bbase.h:944
double asinh(const double v)
Hyperbolic sine of a value.
Definition r8bbase.h:1356
T * construct_ptr(void *const ptr, const size_t c)
Performs placement new to turn a block of unoccupied memory into a "constructed" array of elements of...
Definition r8bbase.h:289
T max(const T &v1, const T &v2)
Returns maximum of two values.
Definition r8bbase.h:1276
double clampr(const double Value, const double minv, const double maxv)
Clamps a value to be within the specified min-max range.
Definition r8bbase.h:1295
void calcSpline2p8Coeffs(double *const c, const double xm3, const double xm2, const double xm1, const double x0, const double x1, const double x2, const double x3, const double x4)
Calculates 2nd order spline coefficients, using 8 points.
Definition r8bbase.h:1192
T * align_ptr(T *const ptr, const uintptr_t align)
Forces the provided ptr pointer to be aligned to align bytes.
Definition r8bbase.h:273
double gauss(const double v)
Single-argument Gaussian function of a value.
Definition r8bbase.h:1344
double besselI0(const double x)
1st kind, 0th order modified Bessel function of a value.
Definition r8bbase.h:1370
void normalizeFIRFilter(double *const p, const int l, const double DCGain, const int pstep=1)
FIR filter's gain normalization.
Definition r8bbase.h:1112
double sqr(const double x)
Returns square ot a value.
Definition r8bbase.h:1318
The default base class for objects created on heap.
Definition r8bbase.h:225
The default base class for objects that allocate blocks of memory.
Definition r8bbase.h:235
static void * allocmem(const size_t Size)
Allocates a memory block.
Definition r8bbase.h:244
static void freemem(void *const p)
Frees a previously allocated memory block.
Definition r8bbase.h:255
Templated memory buffer class for element buffers of fixed capacity.
Definition r8bbase.h:314
void alloc(const int Capacity)
Allocates memory so that the specified number of elements of type T can be stored in this buffer obje...
Definition r8bbase.h:354
void moveFrom(CFixedBuffer &s)
Moves buffer from another object to this object.
Definition r8bbase.h:407
void free()
Deallocates a previously allocated buffer.
Definition r8bbase.h:420
CFixedBuffer(const int Capacity)
Constructor allocates memory so that the specified number of elements of type T can be stored in this...
Definition r8bbase.h:331
void realloc(const int PrevCapacity, const int NewCapacity)
Reallocates memory so that the specified number of elements of type T can be stored in this buffer ob...
Definition r8bbase.h:375
Pointer-to-object "keeper" class with automatic deletion.
Definition r8bbase.h:457
T * operator->() const
Returns pointer to keeped object, or nullptr, if no object is being kept.
Definition r8bbase.h:504
T * unkeep()
Returns the keeped pointer and resets it in this keeper without object deletion.
Definition r8bbase.h:535
void operator=(T2 const aObject)
Assigns a pointer to object to this keeper. A previously keeped pointer will be reset and object dele...
Definition r8bbase.h:493
CPtrKeeper(T2 const aObject)
Constructor assigns a pointer to object to this keeper.
Definition r8bbase.h:474
void reset()
Resets the keeped pointer and deletes the keeped object.
Definition r8bbase.h:523
Reference "keeper" class with automatic unref() call.
Definition r8bbase.h:557
T * operator->() const
Returns pointer to keeped object, or nullptr, if no object is being kept.
Definition r8bbase.h:607
void operator=(T2 const aObject)
Assigns a pointer to object to this keeper. A previously keeped pointer will be reset and object unre...
Definition r8bbase.h:596
CRefKeeper(T2 const aObject)
Constructor assigns a pointer to object to this keeper.
Definition r8bbase.h:574
void reset()
Resets the keeped pointer and unreferences the keeped object.
Definition r8bbase.h:626
Class for items of a singly-linked list.
Definition r8bbase.h:650
T * Next
Next object of type T in a singly-linked list.
Definition r8bbase.h:652
Multi-threaded synchronization object class.
Definition r8bbase.h:691
void acquire()
Acquires this thread synchronizer object immediately or waits until another thread releases it.
Definition r8bbase.h:722
void release()
Releases this, previously acquired, thread synchronizer object.
Definition r8bbase.h:736
A "keeper" class for CSyncObject-based synchronization.
Definition r8bbase.h:765
CSyncKeeper(CSyncObject &aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:797
CSyncKeeper(CSyncObject *const aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:781
CSineGen(const double si, const double ph)
Constructor initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:859
CSineGen(const double si, const double ph, const double g)
Constructor initializes this sine signal generator.
Definition r8bbase.h:875
void init(const double si, const double ph, const double g)
Function initializes this sine signal generator.
Definition r8bbase.h:906
void init(const double si, const double ph)
Function initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:890
double generate()
Generates the next sample.
Definition r8bbase.h:919