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.3"
65
71
77
78#if __cplusplus >= 201103L
79
80 #include <cstdint>
81 #include <cstring>
82 #include <cmath>
83 #include <mutex>
84
85 #define R8B_CONST constexpr
86 #define R8B_NULL nullptr
87
88#else // __cplusplus >= 201103L
89
90 #include <stdint.h>
91 #include <string.h>
92 #include <math.h>
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
161#if __cplusplus >= 201103L
162
163 using std :: memcpy;
164 using std :: memset;
165 using std :: floor;
166 using std :: ceil;
167 using std :: exp;
168 using std :: log;
169 using std :: pow;
170 using std :: fabs;
171 using std :: sqrt;
172 using std :: sin;
173 using std :: cos;
174 using std :: atan2;
175 using std :: size_t;
176 using std :: uintptr_t;
177
178#endif // __cplusplus >= 201103L
179
180R8B_CONST double R8B_PI = 3.14159265358979324;
181R8B_CONST double R8B_2PI = 6.28318530717958648;
182R8B_CONST double R8B_3PI = 9.42477796076937972;
183R8B_CONST double R8B_PId2 = 1.57079632679489662;
184
199
200#if __cplusplus >= 201103L
201
202 #define R8BNOCTOR( ClassName ) \
203 public: \
204 ClassName( const ClassName& ) = delete; \
205 ClassName& operator = ( const ClassName& ) = delete;
206
207#else // __cplusplus >= 201103L
208
209 #define R8BNOCTOR( ClassName ) \
210 private: \
211 ClassName( const ClassName& ) { } \
212 ClassName& operator = ( const ClassName& ) { return( *this ); }
213
214#endif // __cplusplus >= 201103L
215
219
221{
222};
223
229
231{
232public:
239
240 static void* allocmem( const size_t Size )
241 {
242 return( new char[ Size ]);
243 }
244
250
251 static void freemem( void* const p )
252 {
253 delete[] (char*) p;
254 }
255};
256
267
268template< typename T >
269inline T* alignptr( T* const ptr, const uintptr_t align )
270{
271 return( (T*) (( (uintptr_t) ptr + align - 1 ) & ~( align - 1 )));
272}
273
291
292template< typename T >
293class CFixedBuffer : public R8B_MEMALLOCCLASS
294{
295 R8BNOCTOR( CFixedBuffer )
296
297public:
298 CFixedBuffer()
299 : Data0( R8B_NULL )
300 , Data( R8B_NULL )
301 {
302 }
303
310
311 CFixedBuffer( const int Capacity )
312 {
313 R8BASSERT( Capacity >= 0 );
314
315 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
316 Data = (T*) alignptr( Data0, Alignment );
317
318 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
319 }
320
322 {
323 freemem( Data0 );
324 }
325
332
333 void alloc( const int Capacity )
334 {
335 R8BASSERT( Capacity >= 0 );
336
337 freemem( Data0 );
338 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
339 Data = (T*) alignptr( Data0, Alignment );
340
341 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
342 }
343
352
353 void realloc( const int PrevCapacity, const int NewCapacity )
354 {
355 R8BASSERT( PrevCapacity >= 0 );
356 R8BASSERT( NewCapacity >= 0 );
357
358 void* const NewData0 = allocmem( (size_t) NewCapacity * sizeof( T ) +
359 Alignment );
360
361 T* const NewData = (T*) alignptr( NewData0, Alignment );
362 const size_t CopySize = ( PrevCapacity > NewCapacity ?
363 (size_t) NewCapacity : (size_t) PrevCapacity ) * sizeof( T );
364
365 if( CopySize > 0 )
366 {
367 memcpy( NewData, Data, CopySize );
368 }
369
370 freemem( Data0 );
371 Data0 = NewData0;
372 Data = NewData;
373
374 R8BASSERT( Data0 != R8B_NULL || NewCapacity == 0 );
375 }
376
380
381 void free()
382 {
383 freemem( Data0 );
384 Data0 = R8B_NULL;
385 Data = R8B_NULL;
386 }
387
392
393 operator T* () const
394 {
395 return( Data );
396 }
397
398private:
399 static const size_t Alignment = 64;
401 void* Data0;
402 T* Data;
403};
404
415
416template< typename T >
417class CPtrKeeper
418{
419 R8BNOCTOR( CPtrKeeper )
420
421public:
422 CPtrKeeper()
423 : Object( R8B_NULL )
424 {
425 }
426
433
434 template< typename T2 >
435 CPtrKeeper( T2 const aObject )
436 : Object( aObject )
437 {
438 }
439
441 {
442 delete Object;
443 }
444
452
453 template< typename T2 >
454 void operator = ( T2 const aObject )
455 {
456 reset();
457 Object = aObject;
458 }
459
464
465 T* operator -> () const
466 {
467 return( Object );
468 }
469
474
475 operator T* () const
476 {
477 return( Object );
478 }
479
483
484 void reset()
485 {
486 T* const DelObj = Object;
487 Object = R8B_NULL;
488 delete DelObj;
489 }
490
495
497 {
498 T* const ResObject = Object;
499 Object = R8B_NULL;
500 return( ResObject );
501 }
502
503private:
504 T* Object;
505};
506
507#if __cplusplus >= 201103L
508
509typedef std :: mutex CSyncObject;
510typedef std :: lock_guard< std :: mutex > CSyncKeeper;
511
512#else // __cplusplus >= 201103L
513
524
525class CSyncObject
526{
527 R8BNOCTOR( CSyncObject )
528
529public:
530 CSyncObject()
531 {
532 #if defined( _WIN32 )
533 InitializeCriticalSectionAndSpinCount( &CritSec, 2000 );
534 #else // defined( _WIN32 )
535 pthread_mutexattr_t MutexAttrs;
536 pthread_mutexattr_init( &MutexAttrs );
537 pthread_mutexattr_settype( &MutexAttrs, PTHREAD_MUTEX_RECURSIVE );
538 pthread_mutex_init( &Mutex, &MutexAttrs );
539 pthread_mutexattr_destroy( &MutexAttrs );
540 #endif // defined( _WIN32 )
541 }
542
543 ~CSyncObject()
544 {
545 #if defined( _WIN32 )
546 DeleteCriticalSection( &CritSec );
547 #else // defined( _WIN32 )
548 pthread_mutex_destroy( &Mutex );
549 #endif // defined( _WIN32 )
550 }
551
556
557 void acquire()
558 {
559 #if defined( _WIN32 )
560 EnterCriticalSection( &CritSec );
561 #else // defined( _WIN32 )
562 pthread_mutex_lock( &Mutex );
563 #endif // defined( _WIN32 )
564 }
565
570
571 void release()
572 {
573 #if defined( _WIN32 )
574 LeaveCriticalSection( &CritSec );
575 #else // defined( _WIN32 )
576 pthread_mutex_unlock( &Mutex );
577 #endif // defined( _WIN32 )
578 }
579
580private:
581 #if defined( _WIN32 )
582 CRITICAL_SECTION CritSec;
584 #else // defined( _WIN32 )
585 pthread_mutex_t Mutex;
586 #endif // defined( _WIN32 )
587};
588
598
599class CSyncKeeper
600{
601 R8BNOCTOR( CSyncKeeper )
602
603public:
604 CSyncKeeper()
605 : SyncObj( R8B_NULL )
606 {
607 }
608
615
616 CSyncKeeper( CSyncObject* const aSyncObj )
617 : SyncObj( aSyncObj )
618 {
619 if( SyncObj != R8B_NULL )
620 {
621 SyncObj -> acquire();
622 }
623 }
624
631
633 : SyncObj( &aSyncObj )
634 {
635 SyncObj -> acquire();
636 }
637
639 {
640 if( SyncObj != R8B_NULL )
641 {
642 SyncObj -> release();
643 }
644 }
645
646private:
647 CSyncObject* SyncObj;
648};
649
650#endif // __cplusplus >= 201103L
651
667
668#define R8BSYNC( SyncObject ) R8BSYNC1( SyncObject, __LINE__ )
669#define R8BSYNC1( SyncObject, id ) R8BSYNC2( SyncObject, id )
670#define R8BSYNC2( SyncObject, id ) \
671 const CSyncKeeper SyncKeeper##id( SyncObject )
672
678
679class CSineGen
680{
681public:
682 CSineGen()
683 {
684 }
685
693
694 CSineGen( const double si, const double ph )
695 : svalue1( sin( ph ))
696 , svalue2( sin( ph - si ))
697 , sincr( 2.0 * cos( si ))
698 {
699 }
700
709
710 CSineGen( const double si, const double ph, const double g )
711 : svalue1( sin( ph ) * g )
712 , svalue2( sin( ph - si ) * g )
713 , sincr( 2.0 * cos( si ))
714 {
715 }
716
724
725 void init( const double si, const double ph )
726 {
727 svalue1 = sin( ph );
728 svalue2 = sin( ph - si );
729 sincr = 2.0 * cos( si );
730 }
731
740
741 void init( const double si, const double ph, const double g )
742 {
743 svalue1 = sin( ph ) * g;
744 svalue2 = sin( ph - si ) * g;
745 sincr = 2.0 * cos( si );
746 }
747
753
754 double generate()
755 {
756 const double res = svalue1;
757
758 svalue1 = sincr * res - svalue2;
759 svalue2 = res;
760
761 return( res );
762 }
763
764private:
765 double svalue1;
766 double svalue2;
767 double sincr;
768};
769
778
779inline int getBitOccupancy( const int v )
780{
781 static const unsigned char OccupancyTable[] =
782 {
783 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
784 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
785 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
786 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
787 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
788 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
789 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
790 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
791 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
792 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
793 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
794 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
795 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
796 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
797 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
798 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
799 };
800
801 const int tt = v >> 16;
802
803 if( tt != 0 )
804 {
805 const int t = v >> 24;
806
807 return( t != 0 ? 24 + OccupancyTable[ t & 0xFF ] :
808 16 + OccupancyTable[ tt ]);
809 }
810 else
811 {
812 const int t = v >> 8;
813
814 return( t != 0 ? 8 + OccupancyTable[ t ] : OccupancyTable[ v ]);
815 }
816}
817
831
832inline void calcFIRFilterResponse( const double* flt, int fltlen,
833 const double th, double& re0, double& im0, const int fltlat = 0 )
834{
835 const double sincr = 2.0 * cos( th );
836 double cvalue1;
837 double svalue1;
838
839 if( fltlat == 0 )
840 {
841 cvalue1 = 1.0;
842 svalue1 = 0.0;
843 }
844 else
845 {
846 cvalue1 = cos( -fltlat * th );
847 svalue1 = sin( -fltlat * th );
848 }
849
850 double cvalue2 = cos( -( fltlat + 1 ) * th );
851 double svalue2 = sin( -( fltlat + 1 ) * th );
852
853 double re = 0.0;
854 double im = 0.0;
855
856 while( fltlen > 0 )
857 {
858 re += cvalue1 * flt[ 0 ];
859 im += svalue1 * flt[ 0 ];
860 flt++;
861 fltlen--;
862
863 double tmp = cvalue1;
864 cvalue1 = sincr * cvalue1 - cvalue2;
865 cvalue2 = tmp;
866
867 tmp = svalue1;
868 svalue1 = sincr * svalue1 - svalue2;
869 svalue2 = tmp;
870 }
871
872 re0 = re;
873 im0 = im;
874}
875
888
889inline double calcFIRFilterGroupDelay( const double* const flt,
890 const int fltlen, const double th )
891{
892 const int Count = 2;
893 const double thd2 = 1e-9;
894 double ths[ Count ] = { th - thd2, th + thd2 }; // Side-band frequencies.
895
896 if( ths[ 0 ] < 0.0 )
897 {
898 ths[ 0 ] = 0.0;
899 }
900
901 if( ths[ 1 ] > R8B_PI )
902 {
903 ths[ 1 ] = R8B_PI;
904 }
905
906 double ph1[ Count ];
907 int i;
908
909 for( i = 0; i < Count; i++ )
910 {
911 double re1;
912 double im1;
913
914 calcFIRFilterResponse( flt, fltlen, ths[ i ], re1, im1 );
915 ph1[ i ] = atan2( im1, re1 );
916 }
917
918 if( fabs( ph1[ 1 ] - ph1[ 0 ]) > R8B_PI )
919 {
920 if( ph1[ 1 ] > ph1[ 0 ])
921 {
922 ph1[ 1 ] -= R8B_2PI;
923 }
924 else
925 {
926 ph1[ 1 ] += R8B_2PI;
927 }
928 }
929
930 const double thd = ths[ 1 ] - ths[ 0 ];
931
932 return(( ph1[ 1 ] - ph1[ 0 ]) / thd );
933}
934
946
947inline void normalizeFIRFilter( double* const p, const int l,
948 const double DCGain, const int pstep = 1 )
949{
950 R8BASSERT( l > 0 );
951 R8BASSERT( pstep != 0 );
952
953 double s = 0.0;
954 double* pp = p;
955 int i = l;
956
957 while( i > 0 )
958 {
959 s += *pp;
960 pp += pstep;
961 i--;
962 }
963
964 s = DCGain / s;
965 pp = p;
966 i = l;
967
968 while( i > 0 )
969 {
970 *pp *= s;
971 pp += pstep;
972 i--;
973 }
974}
975
992
993inline void calcSpline3p8Coeffs( double* const c, const double xm3,
994 const double xm2, const double xm1, const double x0, const double x1,
995 const double x2, const double x3, const double x4 )
996{
997 c[ 0 ] = x0;
998 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
999 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
1000
1001 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
1002 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
1003
1004 c[ 3 ] = ( 91.0 * ( x0 - x1 ) + 45.0 * ( x2 - xm1 ) +
1005 13.0 * ( xm2 - x3 ) + 3.0 * ( x4 - xm3 )) * 1.31578947368421052e-2;
1006}
1007
1026
1027inline void calcSpline2p8Coeffs( double* const c, const double xm3,
1028 const double xm2, const double xm1, const double x0, const double x1,
1029 const double x2, const double x3, const double x4 )
1030{
1031 c[ 0 ] = x0;
1032 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
1033 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
1034
1035 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
1036 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
1037}
1038
1049
1050inline void calcSpline3p4Coeffs( double* const c, const double* const y )
1051{
1052 c[ 0 ] = y[ 1 ];
1053 c[ 1 ] = 0.5 * ( y[ 2 ] - y[ 0 ]);
1054 c[ 2 ] = y[ 0 ] - 2.5 * y[ 1 ] + y[ 2 ] + y[ 2 ] - 0.5 * y[ 3 ];
1055 c[ 3 ] = 0.5 * ( y[ 3 ] - y[ 0 ] ) + 1.5 * ( y[ 1 ] - y[ 2 ]);
1056}
1057
1068
1069inline void calcSpline3p6Coeffs( double* const c, const double* const y )
1070{
1071 c[ 0 ] = y[ 2 ];
1072 c[ 1 ] = ( 11.0 * ( y[ 3 ] - y[ 1 ]) + 2.0 * ( y[ 0 ] - y[ 4 ])) / 14.0;
1073 c[ 2 ] = ( 20.0 * ( y[ 1 ] + y[ 3 ]) + 2.0 * y[ 5 ] - 4.0 * y[ 0 ] -
1074 7.0 * y[ 4 ] - 31.0 * y[ 2 ]) / 14.0;
1075
1076 c[ 3 ] = ( 17.0 * ( y[ 2 ] - y[ 3 ]) + 9.0 * ( y[ 4 ] - y[ 1 ]) +
1077 2.0 * ( y[ 0 ] - y[ 5 ])) / 14.0;
1078}
1079
1080#if !defined( min )
1081
1090
1091template< typename T >
1092inline T min( const T& v1, const T& v2 )
1093{
1094 return( v1 < v2 ? v1 : v2 );
1095}
1096
1097#endif // !defined( min )
1098
1099#if !defined( max )
1100
1109
1110template< typename T >
1111inline T max( const T& v1, const T& v2 )
1112{
1113 return( v1 > v2 ? v1 : v2 );
1114}
1115
1116#endif // !defined( max )
1117
1129
1130inline double clampr( const double Value, const double minv,
1131 const double maxv )
1132{
1133 if( Value < minv )
1134 {
1135 return( minv );
1136 }
1137
1138 if( Value > maxv )
1139 {
1140 return( maxv );
1141 }
1142
1143 return( Value );
1144}
1145
1152
1153inline double sqr( const double x )
1154{
1155 return( x * x );
1156}
1157
1166
1167inline double pow_a( const double v, const double p )
1168{
1169 return( exp( p * log( fabs( v ) + 1e-300 )));
1170}
1171
1178
1179inline double gauss( const double v )
1180{
1181 return( exp( -( v * v )));
1182}
1183
1190
1191inline double asinh( const double v )
1192{
1193 return( log( v + sqrt( v * v + 1.0 )));
1194}
1195
1204
1205inline double besselI0( const double x )
1206{
1207 const double ax = fabs( x );
1208 double y;
1209
1210 if( ax < 3.75 )
1211 {
1212 y = x / 3.75;
1213 y *= y;
1214
1215 return( 1.0 + y * ( 3.5156229 + y * ( 3.0899424 + y * ( 1.2067492 +
1216 y * ( 0.2659732 + y * ( 0.360768e-1 + y * 0.45813e-2 ))))));
1217 }
1218
1219 y = 3.75 / ax;
1220
1221 return( exp( ax ) / sqrt( ax ) * ( 0.39894228 + y * ( 0.1328592e-1 +
1222 y * ( 0.225319e-2 + y * ( -0.157565e-2 + y * ( 0.916281e-2 +
1223 y * ( -0.2057706e-1 + y * ( 0.2635537e-1 + y * ( -0.1647633e-1 +
1224 y * 0.392377e-2 )))))))));
1225}
1226
1227} // namespace r8b
1228
1229#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 with the "private:" prefix.
Definition r8bbase.h:209
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
T * alignptr(T *const ptr, const uintptr_t align)
Forces the provided ptr pointer to be aligned to align bytes.
Definition r8bbase.h:269
double calcFIRFilterGroupDelay(const double *const flt, const int fltlen, const double th)
FIR filter's group delay calculation function.
Definition r8bbase.h:889
void calcSpline3p4Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 4 points.
Definition r8bbase.h:1050
double pow_a(const double v, const double p)
Power of an absolute value.
Definition r8bbase.h:1167
R8B_CONST double R8B_PI
Equals pi.
Definition r8bbase.h:180
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:832
R8B_CONST double R8B_3PI
Equals 3*pi.
Definition r8bbase.h:182
void calcSpline3p6Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 6 points.
Definition r8bbase.h:1069
R8B_CONST double R8B_2PI
Equals 2*pi.
Definition r8bbase.h:181
R8B_CONST double R8B_PId2
Equals 0.5*pi.
Definition r8bbase.h:183
T min(const T &v1, const T &v2)
Returns minimum of two values.
Definition r8bbase.h:1092
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:993
int getBitOccupancy(const int v)
Calculate the exact number of bits a value needs for representation.
Definition r8bbase.h:779
double asinh(const double v)
Hyperbolic sine of a value.
Definition r8bbase.h:1191
T max(const T &v1, const T &v2)
Returns maximum of two values.
Definition r8bbase.h:1111
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:1130
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:1027
double gauss(const double v)
Single-argument Gaussian function of a value.
Definition r8bbase.h:1179
double besselI0(const double x)
1st kind, 0th order modified Bessel function of a value.
Definition r8bbase.h:1205
void normalizeFIRFilter(double *const p, const int l, const double DCGain, const int pstep=1)
FIR filter's gain normalization.
Definition r8bbase.h:947
double sqr(const double x)
Returns square ot a value.
Definition r8bbase.h:1153
The default base class for objects created on heap.
Definition r8bbase.h:221
The default base class for objects that allocate blocks of memory.
Definition r8bbase.h:231
static void * allocmem(const size_t Size)
Allocates a memory block.
Definition r8bbase.h:240
static void freemem(void *const p)
Frees a previously allocated memory block.
Definition r8bbase.h:251
Templated memory buffer class for element buffers of fixed capacity.
Definition r8bbase.h:294
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:333
void free()
Deallocates a previously allocated buffer.
Definition r8bbase.h:381
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:311
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:353
Pointer-to-object "keeper" class with automatic deletion.
Definition r8bbase.h:418
T * operator->() const
Returns pointer to keeped object, or nullptr, if no object is being kept.
Definition r8bbase.h:465
T * unkeep()
Returns the keeped pointer and resets it in this keeper without object deletion.
Definition r8bbase.h:496
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:454
CPtrKeeper(T2 const aObject)
Constructor assigns a pointer to object to this keeper.
Definition r8bbase.h:435
void reset()
Resets the keeped pointer and deletes the keeped object.
Definition r8bbase.h:484
Multi-threaded synchronization object class.
Definition r8bbase.h:526
void acquire()
Acquires this thread synchronizer object immediately or waits until another thread releases it.
Definition r8bbase.h:557
void release()
Releases this, previously acquired, thread synchronizer object.
Definition r8bbase.h:571
A "keeper" class for CSyncObject-based synchronization.
Definition r8bbase.h:600
CSyncKeeper(CSyncObject &aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:632
CSyncKeeper(CSyncObject *const aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:616
CSineGen(const double si, const double ph)
Constructor initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:694
CSineGen(const double si, const double ph, const double g)
Constructor initializes this sine signal generator.
Definition r8bbase.h:710
void init(const double si, const double ph, const double g)
Function initializes this sine signal generator.
Definition r8bbase.h:741
void init(const double si, const double ph)
Function initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:725
double generate()
Generates the next sample.
Definition r8bbase.h:754