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.0"
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 :: fabs;
170 using std :: sqrt;
171 using std :: sin;
172 using std :: cos;
173 using std :: atan2;
174 using std :: size_t;
175 using std :: uintptr_t;
176
177#endif // __cplusplus >= 201103L
178
179R8B_CONST double R8B_PI = 3.14159265358979324;
180R8B_CONST double R8B_2PI = 6.28318530717958648;
181R8B_CONST double R8B_3PI = 9.42477796076937972;
182R8B_CONST double R8B_PId2 = 1.57079632679489662;
183
197
198#define R8BNOCTOR( ClassName ) \
199 private: \
200 ClassName( const ClassName& ) { } \
201 ClassName& operator = ( const ClassName& ) { return( *this ); }
202
206
208{
209};
210
216
218{
219public:
226
227 static void* allocmem( const size_t Size )
228 {
229 return( new char[ Size ]);
230 }
231
237
238 static void freemem( void* const p )
239 {
240 delete[] (char*) p;
241 }
242};
243
254
255template< typename T >
256inline T* alignptr( T* const ptr, const uintptr_t align )
257{
258 return( (T*) (( (uintptr_t) ptr + align - 1 ) & ~( align - 1 )));
259}
260
278
279template< typename T >
280class CFixedBuffer : public R8B_MEMALLOCCLASS
281{
282 R8BNOCTOR( CFixedBuffer )
283
284public:
285 CFixedBuffer()
286 : Data0( R8B_NULL )
287 , Data( R8B_NULL )
288 {
289 }
290
297
298 CFixedBuffer( const int Capacity )
299 {
300 R8BASSERT( Capacity > 0 || Capacity == 0 );
301
302 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
303 Data = (T*) alignptr( Data0, Alignment );
304
305 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
306 }
307
309 {
310 freemem( Data0 );
311 }
312
319
320 void alloc( const int Capacity )
321 {
322 R8BASSERT( Capacity > 0 || Capacity == 0 );
323
324 freemem( Data0 );
325 Data0 = allocmem( (size_t) Capacity * sizeof( T ) + Alignment );
326 Data = (T*) alignptr( Data0, Alignment );
327
328 R8BASSERT( Data0 != R8B_NULL || Capacity == 0 );
329 }
330
339
340 void realloc( const int PrevCapacity, const int NewCapacity )
341 {
342 R8BASSERT( PrevCapacity >= 0 );
343 R8BASSERT( NewCapacity >= 0 );
344
345 void* const NewData0 = allocmem( (size_t) NewCapacity * sizeof( T ) +
346 Alignment );
347
348 T* const NewData = (T*) alignptr( NewData0, Alignment );
349 const size_t CopySize = ( PrevCapacity > NewCapacity ?
350 (size_t) NewCapacity : (size_t) PrevCapacity ) * sizeof( T );
351
352 if( CopySize > 0 )
353 {
354 memcpy( NewData, Data, CopySize );
355 }
356
357 freemem( Data0 );
358 Data0 = NewData0;
359 Data = NewData;
360
361 R8BASSERT( Data0 != R8B_NULL || NewCapacity == 0 );
362 }
363
367
368 void free()
369 {
370 freemem( Data0 );
371 Data0 = R8B_NULL;
372 Data = R8B_NULL;
373 }
374
379
380 operator T* () const
381 {
382 return( Data );
383 }
384
385private:
386 static const size_t Alignment = 64;
388 void* Data0;
389 T* Data;
390};
391
402
403template< typename T >
404class CPtrKeeper
405{
406 R8BNOCTOR( CPtrKeeper )
407
408public:
409 CPtrKeeper()
410 : Object( R8B_NULL )
411 {
412 }
413
420
421 template< typename T2 >
422 CPtrKeeper( T2 const aObject )
423 : Object( aObject )
424 {
425 }
426
428 {
429 delete Object;
430 }
431
439
440 template< typename T2 >
441 void operator = ( T2 const aObject )
442 {
443 reset();
444 Object = aObject;
445 }
446
451
452 T* operator -> () const
453 {
454 return( Object );
455 }
456
461
462 operator T* () const
463 {
464 return( Object );
465 }
466
470
471 void reset()
472 {
473 T* const DelObj = Object;
474 Object = R8B_NULL;
475 delete DelObj;
476 }
477
482
484 {
485 T* const ResObject = Object;
486 Object = R8B_NULL;
487 return( ResObject );
488 }
489
490private:
491 T* Object;
492};
493
494#if __cplusplus >= 201103L
495
496typedef std :: mutex CSyncObject;
497typedef std :: lock_guard< std :: mutex > CSyncKeeper;
498
499#else // __cplusplus >= 201103L
500
511
512class CSyncObject
513{
514 R8BNOCTOR( CSyncObject )
515
516public:
517 CSyncObject()
518 {
519 #if defined( _WIN32 )
520 InitializeCriticalSectionAndSpinCount( &CritSec, 2000 );
521 #else // defined( _WIN32 )
522 pthread_mutexattr_t MutexAttrs;
523 pthread_mutexattr_init( &MutexAttrs );
524 pthread_mutexattr_settype( &MutexAttrs, PTHREAD_MUTEX_RECURSIVE );
525 pthread_mutex_init( &Mutex, &MutexAttrs );
526 pthread_mutexattr_destroy( &MutexAttrs );
527 #endif // defined( _WIN32 )
528 }
529
530 ~CSyncObject()
531 {
532 #if defined( _WIN32 )
533 DeleteCriticalSection( &CritSec );
534 #else // defined( _WIN32 )
535 pthread_mutex_destroy( &Mutex );
536 #endif // defined( _WIN32 )
537 }
538
543
544 void acquire()
545 {
546 #if defined( _WIN32 )
547 EnterCriticalSection( &CritSec );
548 #else // defined( _WIN32 )
549 pthread_mutex_lock( &Mutex );
550 #endif // defined( _WIN32 )
551 }
552
557
558 void release()
559 {
560 #if defined( _WIN32 )
561 LeaveCriticalSection( &CritSec );
562 #else // defined( _WIN32 )
563 pthread_mutex_unlock( &Mutex );
564 #endif // defined( _WIN32 )
565 }
566
567private:
568 #if defined( _WIN32 )
569 CRITICAL_SECTION CritSec;
571 #else // defined( _WIN32 )
572 pthread_mutex_t Mutex;
573 #endif // defined( _WIN32 )
574};
575
585
586class CSyncKeeper
587{
588 R8BNOCTOR( CSyncKeeper )
589
590public:
591 CSyncKeeper()
592 : SyncObj( R8B_NULL )
593 {
594 }
595
602
603 CSyncKeeper( CSyncObject* const aSyncObj )
604 : SyncObj( aSyncObj )
605 {
606 if( SyncObj != R8B_NULL )
607 {
608 SyncObj -> acquire();
609 }
610 }
611
618
620 : SyncObj( &aSyncObj )
621 {
622 SyncObj -> acquire();
623 }
624
626 {
627 if( SyncObj != R8B_NULL )
628 {
629 SyncObj -> release();
630 }
631 }
632
633private:
634 CSyncObject* SyncObj;
635};
636
637#endif // __cplusplus >= 201103L
638
654
655#define R8BSYNC( SyncObject ) R8BSYNC1( SyncObject, __LINE__ )
656#define R8BSYNC1( SyncObject, id ) R8BSYNC2( SyncObject, id )
657#define R8BSYNC2( SyncObject, id ) \
658 const CSyncKeeper SyncKeeper##id( SyncObject )
659
665
666class CSineGen
667{
668public:
669 CSineGen()
670 {
671 }
672
680
681 CSineGen( const double si, const double ph )
682 : svalue1( sin( ph ))
683 , svalue2( sin( ph - si ))
684 , sincr( 2.0 * cos( si ))
685 {
686 }
687
696
697 CSineGen( const double si, const double ph, const double g )
698 : svalue1( sin( ph ) * g )
699 , svalue2( sin( ph - si ) * g )
700 , sincr( 2.0 * cos( si ))
701 {
702 }
703
711
712 void init( const double si, const double ph )
713 {
714 svalue1 = sin( ph );
715 svalue2 = sin( ph - si );
716 sincr = 2.0 * cos( si );
717 }
718
727
728 void init( const double si, const double ph, const double g )
729 {
730 svalue1 = sin( ph ) * g;
731 svalue2 = sin( ph - si ) * g;
732 sincr = 2.0 * cos( si );
733 }
734
740
741 double generate()
742 {
743 const double res = svalue1;
744
745 svalue1 = sincr * res - svalue2;
746 svalue2 = res;
747
748 return( res );
749 }
750
751private:
752 double svalue1;
753 double svalue2;
754 double sincr;
755};
756
765
766inline int getBitOccupancy( const int v )
767{
768 static const unsigned char OccupancyTable[] =
769 {
770 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
771 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
772 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
773 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
774 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
775 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
776 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
777 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
778 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
779 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
780 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
781 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
782 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
783 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
784 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
785 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
786 };
787
788 const int tt = v >> 16;
789
790 if( tt != 0 )
791 {
792 const int t = v >> 24;
793
794 return( t != 0 ? 24 + OccupancyTable[ t & 0xFF ] :
795 16 + OccupancyTable[ tt ]);
796 }
797 else
798 {
799 const int t = v >> 8;
800
801 return( t != 0 ? 8 + OccupancyTable[ t ] : OccupancyTable[ v ]);
802 }
803}
804
818
819inline void calcFIRFilterResponse( const double* flt, int fltlen,
820 const double th, double& re0, double& im0, const int fltlat = 0 )
821{
822 const double sincr = 2.0 * cos( th );
823 double cvalue1;
824 double svalue1;
825
826 if( fltlat == 0 )
827 {
828 cvalue1 = 1.0;
829 svalue1 = 0.0;
830 }
831 else
832 {
833 cvalue1 = cos( -fltlat * th );
834 svalue1 = sin( -fltlat * th );
835 }
836
837 double cvalue2 = cos( -( fltlat + 1 ) * th );
838 double svalue2 = sin( -( fltlat + 1 ) * th );
839
840 double re = 0.0;
841 double im = 0.0;
842
843 while( fltlen > 0 )
844 {
845 re += cvalue1 * flt[ 0 ];
846 im += svalue1 * flt[ 0 ];
847 flt++;
848 fltlen--;
849
850 double tmp = cvalue1;
851 cvalue1 = sincr * cvalue1 - cvalue2;
852 cvalue2 = tmp;
853
854 tmp = svalue1;
855 svalue1 = sincr * svalue1 - svalue2;
856 svalue2 = tmp;
857 }
858
859 re0 = re;
860 im0 = im;
861}
862
875
876inline double calcFIRFilterGroupDelay( const double* const flt,
877 const int fltlen, const double th )
878{
879 const int Count = 2;
880 const double thd2 = 1e-9;
881 double ths[ Count ] = { th - thd2, th + thd2 }; // Side-band frequencies.
882
883 if( ths[ 0 ] < 0.0 )
884 {
885 ths[ 0 ] = 0.0;
886 }
887
888 if( ths[ 1 ] > R8B_PI )
889 {
890 ths[ 1 ] = R8B_PI;
891 }
892
893 double ph1[ Count ];
894 int i;
895
896 for( i = 0; i < Count; i++ )
897 {
898 double re1;
899 double im1;
900
901 calcFIRFilterResponse( flt, fltlen, ths[ i ], re1, im1 );
902 ph1[ i ] = atan2( im1, re1 );
903 }
904
905 if( fabs( ph1[ 1 ] - ph1[ 0 ]) > R8B_PI )
906 {
907 if( ph1[ 1 ] > ph1[ 0 ])
908 {
909 ph1[ 1 ] -= R8B_2PI;
910 }
911 else
912 {
913 ph1[ 1 ] += R8B_2PI;
914 }
915 }
916
917 const double thd = ths[ 1 ] - ths[ 0 ];
918
919 return(( ph1[ 1 ] - ph1[ 0 ]) / thd );
920}
921
933
934inline void normalizeFIRFilter( double* const p, const int l,
935 const double DCGain, const int pstep = 1 )
936{
937 R8BASSERT( l > 0 );
938 R8BASSERT( pstep != 0 );
939
940 double s = 0.0;
941 double* pp = p;
942 int i = l;
943
944 while( i > 0 )
945 {
946 s += *pp;
947 pp += pstep;
948 i--;
949 }
950
951 s = DCGain / s;
952 pp = p;
953 i = l;
954
955 while( i > 0 )
956 {
957 *pp *= s;
958 pp += pstep;
959 i--;
960 }
961}
962
979
980inline void calcSpline3p8Coeffs( double* const c, const double xm3,
981 const double xm2, const double xm1, const double x0, const double x1,
982 const double x2, const double x3, const double x4 )
983{
984 c[ 0 ] = x0;
985 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
986 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
987
988 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
989 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
990
991 c[ 3 ] = ( 91.0 * ( x0 - x1 ) + 45.0 * ( x2 - xm1 ) +
992 13.0 * ( xm2 - x3 ) + 3.0 * ( x4 - xm3 )) * 1.31578947368421052e-2;
993}
994
1013
1014inline void calcSpline2p8Coeffs( double* const c, const double xm3,
1015 const double xm2, const double xm1, const double x0, const double x1,
1016 const double x2, const double x3, const double x4 )
1017{
1018 c[ 0 ] = x0;
1019 c[ 1 ] = ( 61.0 * ( x1 - xm1 ) + 16.0 * ( xm2 - x2 ) +
1020 3.0 * ( x3 - xm3 )) * 1.31578947368421052e-2;
1021
1022 c[ 2 ] = ( 106.0 * ( xm1 + x1 ) + 10.0 * x3 + 6.0 * xm3 - 3.0 * x4 -
1023 29.0 * ( xm2 + x2 ) - 167.0 * x0 ) * 1.31578947368421052e-2;
1024}
1025
1036
1037inline void calcSpline3p4Coeffs( double* const c, const double* const y )
1038{
1039 c[ 0 ] = y[ 1 ];
1040 c[ 1 ] = 0.5 * ( y[ 2 ] - y[ 0 ]);
1041 c[ 2 ] = y[ 0 ] - 2.5 * y[ 1 ] + y[ 2 ] + y[ 2 ] - 0.5 * y[ 3 ];
1042 c[ 3 ] = 0.5 * ( y[ 3 ] - y[ 0 ] ) + 1.5 * ( y[ 1 ] - y[ 2 ]);
1043}
1044
1055
1056inline void calcSpline3p6Coeffs( double* const c, const double* const y )
1057{
1058 c[ 0 ] = y[ 2 ];
1059 c[ 1 ] = ( 11.0 * ( y[ 3 ] - y[ 1 ]) + 2.0 * ( y[ 0 ] - y[ 4 ])) / 14.0;
1060 c[ 2 ] = ( 20.0 * ( y[ 1 ] + y[ 3 ]) + 2.0 * y[ 5 ] - 4.0 * y[ 0 ] -
1061 7.0 * y[ 4 ] - 31.0 * y[ 2 ]) / 14.0;
1062
1063 c[ 3 ] = ( 17.0 * ( y[ 2 ] - y[ 3 ]) + 9.0 * ( y[ 4 ] - y[ 1 ]) +
1064 2.0 * ( y[ 0 ] - y[ 5 ])) / 14.0;
1065}
1066
1067#if !defined( min )
1068
1077
1078template< typename T >
1079inline T min( const T& v1, const T& v2 )
1080{
1081 return( v1 < v2 ? v1 : v2 );
1082}
1083
1084#endif // !defined( min )
1085
1086#if !defined( max )
1087
1096
1097template< typename T >
1098inline T max( const T& v1, const T& v2 )
1099{
1100 return( v1 > v2 ? v1 : v2 );
1101}
1102
1103#endif // !defined( max )
1104
1116
1117inline double clampr( const double Value, const double minv,
1118 const double maxv )
1119{
1120 if( Value < minv )
1121 {
1122 return( minv );
1123 }
1124
1125 if( Value > maxv )
1126 {
1127 return( maxv );
1128 }
1129
1130 return( Value );
1131}
1132
1139
1140inline double sqr( const double x )
1141{
1142 return( x * x );
1143}
1144
1153
1154inline double pow_a( const double v, const double p )
1155{
1156 return( exp( p * log( fabs( v ) + 1e-300 )));
1157}
1158
1165
1166inline double gauss( const double v )
1167{
1168 return( exp( -( v * v )));
1169}
1170
1177
1178inline double asinh( const double v )
1179{
1180 return( log( v + sqrt( v * v + 1.0 )));
1181}
1182
1191
1192inline double besselI0( const double x )
1193{
1194 const double ax = fabs( x );
1195 double y;
1196
1197 if( ax < 3.75 )
1198 {
1199 y = x / 3.75;
1200 y *= y;
1201
1202 return( 1.0 + y * ( 3.5156229 + y * ( 3.0899424 + y * ( 1.2067492 +
1203 y * ( 0.2659732 + y * ( 0.360768e-1 + y * 0.45813e-2 ))))));
1204 }
1205
1206 y = 3.75 / ax;
1207
1208 return( exp( ax ) / sqrt( ax ) * ( 0.39894228 + y * ( 0.1328592e-1 +
1209 y * ( 0.225319e-2 + y * ( -0.157565e-2 + y * ( 0.916281e-2 +
1210 y * ( -0.2057706e-1 + y * ( 0.2635537e-1 + y * ( -0.1647633e-1 +
1211 y * 0.392377e-2 )))))))));
1212}
1213
1214} // namespace r8b
1215
1216#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:198
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:256
double calcFIRFilterGroupDelay(const double *const flt, const int fltlen, const double th)
FIR filter's group delay calculation function.
Definition r8bbase.h:876
void calcSpline3p4Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 4 points.
Definition r8bbase.h:1037
double pow_a(const double v, const double p)
Power of an absolute value.
Definition r8bbase.h:1154
R8B_CONST double R8B_PI
Equals pi.
Definition r8bbase.h:179
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:819
R8B_CONST double R8B_3PI
Equals 3*pi.
Definition r8bbase.h:181
void calcSpline3p6Coeffs(double *const c, const double *const y)
Calculates 3rd order spline coefficients, using 6 points.
Definition r8bbase.h:1056
R8B_CONST double R8B_2PI
Equals 2*pi.
Definition r8bbase.h:180
R8B_CONST double R8B_PId2
Equals 0.5*pi.
Definition r8bbase.h:182
T min(const T &v1, const T &v2)
Returns minimum of two values.
Definition r8bbase.h:1079
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:980
int getBitOccupancy(const int v)
Calculate the exact number of bits a value needs for representation.
Definition r8bbase.h:766
double asinh(const double v)
Hyperbolic sine of a value.
Definition r8bbase.h:1178
T max(const T &v1, const T &v2)
Returns maximum of two values.
Definition r8bbase.h:1098
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:1117
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:1014
double gauss(const double v)
Single-argument Gaussian function of a value.
Definition r8bbase.h:1166
double besselI0(const double x)
1st kind, 0th order modified Bessel function of a value.
Definition r8bbase.h:1192
void normalizeFIRFilter(double *const p, const int l, const double DCGain, const int pstep=1)
FIR filter's gain normalization.
Definition r8bbase.h:934
double sqr(const double x)
Returns square ot a value.
Definition r8bbase.h:1140
The default base class for objects created on heap.
Definition r8bbase.h:208
The default base class for objects that allocate blocks of memory.
Definition r8bbase.h:218
static void * allocmem(const size_t Size)
Allocates a memory block.
Definition r8bbase.h:227
static void freemem(void *const p)
Frees a previously allocated memory block.
Definition r8bbase.h:238
Templated memory buffer class for element buffers of fixed capacity.
Definition r8bbase.h:281
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:320
void free()
Deallocates a previously allocated buffer.
Definition r8bbase.h:368
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:298
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:340
Pointer-to-object "keeper" class with automatic deletion.
Definition r8bbase.h:405
T * operator->() const
Returns pointer to keeped object, or nullptr, if no object is being kept.
Definition r8bbase.h:452
T * unkeep()
Returns the keeped pointer and resets it in this keeper without object deletion.
Definition r8bbase.h:483
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:441
CPtrKeeper(T2 const aObject)
Constructor assigns a pointer to object to this keeper.
Definition r8bbase.h:422
void reset()
Resets the keeped pointer and deletes the keeped object.
Definition r8bbase.h:471
Multi-threaded synchronization object class.
Definition r8bbase.h:513
void acquire()
Acquires this thread synchronizer object immediately or waits until another thread releases it.
Definition r8bbase.h:544
void release()
Releases this, previously acquired, thread synchronizer object.
Definition r8bbase.h:558
A "keeper" class for CSyncObject-based synchronization.
Definition r8bbase.h:587
CSyncKeeper(CSyncObject &aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:619
CSyncKeeper(CSyncObject *const aSyncObj)
Constructor acquires a specified synchronization object.
Definition r8bbase.h:603
CSineGen(const double si, const double ph)
Constructor initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:681
CSineGen(const double si, const double ph, const double g)
Constructor initializes this sine signal generator.
Definition r8bbase.h:697
void init(const double si, const double ph, const double g)
Function initializes this sine signal generator.
Definition r8bbase.h:728
void init(const double si, const double ph)
Function initializes this sine signal generator, with unity gain output.
Definition r8bbase.h:712
double generate()
Generates the next sample.
Definition r8bbase.h:741