CDSPResampler.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. //$ nobt
  2. //$ nocpp
  3. /**
  4. * @file CDSPResampler.h
  5. *
  6. * @brief The master sample rate converter (resampler) class.
  7. *
  8. * This file includes the master sample rate converter (resampler) class that
  9. * combines all elements of this library into a single front-end class.
  10. *
  11. * r8brain-free-src Copyright (c) 2013-2022 Aleksey Vaneev
  12. * See the "LICENSE" file for license.
  13. */
  14. #ifndef R8B_CDSPRESAMPLER_INCLUDED
  15. #define R8B_CDSPRESAMPLER_INCLUDED
  16. #include "CDSPHBDownsampler.h"
  17. #include "CDSPHBUpsampler.h"
  18. #include "CDSPBlockConvolver.h"
  19. #include "CDSPFracInterpolator.h"
  20. namespace r8b {
  21. /**
  22. * @brief The master sample rate converter (resampler) class.
  23. *
  24. * This class can be considered the "master" sample rate converter (resampler)
  25. * class since it combines all functionality of this library into a single
  26. * front-end class to perform sample rate conversion to/from any sample rate,
  27. * including non-integer sample rates.
  28. *
  29. * Note that objects of this class can be constructed on the stack as it has a
  30. * small member data size. The default template parameters of this class are
  31. * suited for 27-bit fixed point resampling.
  32. *
  33. * Use the CDSPResampler16 class for 16-bit resampling.
  34. *
  35. * Use the CDSPResampler16IR class for 16-bit impulse response resampling.
  36. *
  37. * Use the CDSPResampler24 class for 24-bit resampling (including 32-bit
  38. * floating point resampling).
  39. */
  40. class CDSPResampler : public CDSPProcessor
  41. {
  42. public:
  43. /**
  44. * Constructor initalizes the resampler object.
  45. *
  46. * Note that increasing the transition band and decreasing attenuation
  47. * reduces the filter length, this in turn reduces the "input before
  48. * output" delay. However, the filter length has only a minor influence on
  49. * the overall resampling speed.
  50. *
  51. * It should be noted that the ReqAtten specifies the minimal difference
  52. * between the loudest input signal component and the produced aliasing
  53. * artifacts during resampling. For example, if ReqAtten=100 was specified
  54. * when performing 2x upsampling, the analysis of the resulting signal may
  55. * display high-frequency components which are quieter than the loudest
  56. * part of the input signal by only 100 decibel meaning the high-frequency
  57. * part did not become "magically" completely silent after resampling. You
  58. * have to specify a higher ReqAtten value if you need a totally clean
  59. * high-frequency content. On the other hand, it may not be reasonable to
  60. * have a high-frequency content cleaner than the input signal itself: if
  61. * the input signal is 16-bit, setting ReqAtten to 180 will make its
  62. * high-frequency content 24-bit, but the original part of the signal will
  63. * remain 16-bit.
  64. *
  65. * @param SrcSampleRate Source signal sample rate. Both sample rates can
  66. * be specified as a ratio, e.g. SrcSampleRate = 1.0, DstSampleRate = 2.0.
  67. * @param DstSampleRate Destination signal sample rate. The "power of 2"
  68. * ratios between the source and destination sample rates force resampler
  69. * to use several fast "power of 2" resampling steps, without using
  70. * fractional interpolation at all.
  71. * @param aMaxInLen The maximal planned length of the input buffer (in
  72. * samples) that will be passed to the resampler. The resampler relies on
  73. * this value as it allocates intermediate buffers. Input buffers longer
  74. * than this value should never be supplied to the resampler. Note that
  75. * upsampling produces more samples than was provided on input, so at
  76. * higher upsampling ratios it is advisable to use smaller MaxInLen
  77. * values to reduce memory footprint. When downsampling, a larger MaxInLen
  78. * is suggested in order to increase downsampling performance.
  79. * @param ReqTransBand Required transition band, in percent of the
  80. * spectral space of the input signal (or the output signal if
  81. * downsampling is performed) between filter's -3 dB point and the Nyquist
  82. * frequency. The range is from CDSPFIRFilter::getLPMinTransBand() to
  83. * CDSPFIRFilter::getLPMaxTransBand(), inclusive. When upsampling 88200 or
  84. * 96000 audio to a higher sample rates the ReqTransBand can be
  85. * considerably increased, up to 30. The selection of ReqTransBand depends
  86. * on the level of desire to preserve the high-frequency content. While
  87. * values 0.5 to 2 are extremely "greedy" settings, not necessary in most
  88. * cases, values 2 to 3 can be used in most cases. Values 3 to 4 are
  89. * relaxed settings, but they still offer a flat frequency response up to
  90. * 21kHz with 44.1k source or destination sample rate.
  91. * @param ReqAtten Required stop-band attenuation in decibel, in the
  92. * range CDSPFIRFilter::getLPMinAtten() to CDSPFIRFilter::getLPMaxAtten(),
  93. * inclusive. The actual attenuation may be 0.40-4.46 dB higher. The
  94. * general formula for selecting the ReqAtten is 6.02 * Bits + 40, where
  95. * "Bits" is the bit resolution (e.g. 16, 24), "40" is an added resolution
  96. * for dynamic signals; this value can be decreased to 20 to 10 if the
  97. * signal being resampled is non-dynamic (e.g., an impulse response or
  98. * filter, with a non-steep frequency response).
  99. * @param ReqPhase Required filter's phase response. Note that this
  100. * setting does not affect interpolator's phase response which is always
  101. * linear-phase. Also note that if the "power of 2" resampling was engaged
  102. * by the resampler together with the minimum-phase response, the audio
  103. * stream may become fractionally delayed, depending on the minimum-phase
  104. * filter's actual fractional delay. Linear-phase filters do not have
  105. * fractional delay.
  106. * @see CDSPFIRFilterCache::getLPFilter()
  107. */
  108. CDSPResampler( const double SrcSampleRate, const double DstSampleRate,
  109. const int aMaxInLen, const double ReqTransBand = 2.0,
  110. const double ReqAtten = 206.91,
  111. const EDSPFilterPhaseResponse ReqPhase = fprLinearPhase )
  112. : StepCapacity( 0 )
  113. , StepCount( 0 )
  114. , MaxInLen( aMaxInLen )
  115. , CurMaxOutLen( aMaxInLen )
  116. , LatencyFrac( 0.0 )
  117. {
  118. R8BASSERT( SrcSampleRate > 0.0 );
  119. R8BASSERT( DstSampleRate > 0.0 );
  120. R8BASSERT( MaxInLen > 0 );
  121. R8BCONSOLE( "* CDSPResampler: src=%.1f dst=%.1f len=%i tb=%.1f "
  122. "att=%.2f ph=%i\n", SrcSampleRate, DstSampleRate, aMaxInLen,
  123. ReqTransBand, ReqAtten, (int) ReqPhase );
  124. if( SrcSampleRate == DstSampleRate )
  125. {
  126. return;
  127. }
  128. TmpBufCapacities[ 0 ] = 0;
  129. TmpBufCapacities[ 1 ] = 0;
  130. CurTmpBuf = 0;
  131. // Try some common efficient ratios requiring only a single step.
  132. const int CommonRatioCount = 5;
  133. const int CommonRatios[ CommonRatioCount ][ 2 ] = {
  134. { 1, 2 },
  135. { 1, 3 },
  136. { 2, 3 },
  137. { 3, 2 },
  138. { 3, 4 }
  139. };
  140. int i;
  141. for( i = 0; i < CommonRatioCount; i++ )
  142. {
  143. const int num = CommonRatios[ i ][ 0 ];
  144. const int den = CommonRatios[ i ][ 1 ];
  145. if( SrcSampleRate * num == DstSampleRate * den )
  146. {
  147. addProcessor( new CDSPBlockConvolver(
  148. CDSPFIRFilterCache :: getLPFilter(
  149. 1.0 / ( num > den ? num : den ), ReqTransBand,
  150. ReqAtten, ReqPhase, num ), num, den, LatencyFrac ));
  151. createTmpBuffers();
  152. return;
  153. }
  154. }
  155. // Try whole-number power-of-2 or 3*power-of-2 upsampling.
  156. for( i = 2; i <= 3; i++ )
  157. {
  158. bool WasFound = false;
  159. int c = 0;
  160. while( true )
  161. {
  162. const double NewSR = SrcSampleRate * ( i << c );
  163. if( NewSR == DstSampleRate )
  164. {
  165. WasFound = true;
  166. break;
  167. }
  168. if( NewSR > DstSampleRate )
  169. {
  170. break;
  171. }
  172. c++;
  173. }
  174. if( WasFound )
  175. {
  176. addProcessor( new CDSPBlockConvolver(
  177. CDSPFIRFilterCache :: getLPFilter( 1.0 / i, ReqTransBand,
  178. ReqAtten, ReqPhase, i ), i, 1, LatencyFrac ));
  179. const bool IsThird = ( i == 3 );
  180. for( i = 0; i < c; i++ )
  181. {
  182. addProcessor( new CDSPHBUpsampler( ReqAtten, i, IsThird,
  183. LatencyFrac ));
  184. }
  185. createTmpBuffers();
  186. return;
  187. }
  188. }
  189. if( DstSampleRate * 2.0 > SrcSampleRate )
  190. {
  191. // Upsampling or fractional downsampling down to 2X.
  192. const double NormFreq = ( DstSampleRate > SrcSampleRate ? 0.5 :
  193. 0.5 * DstSampleRate / SrcSampleRate );
  194. addProcessor( new CDSPBlockConvolver(
  195. CDSPFIRFilterCache :: getLPFilter( NormFreq, ReqTransBand,
  196. ReqAtten, ReqPhase, 2.0 ), 2, 1, LatencyFrac ));
  197. // Try intermediate interpolated resampling with subsequent 2X
  198. // or 3X upsampling.
  199. const double tbw = 0.0175; // Intermediate filter's transition
  200. // band extension coefficient.
  201. const double ThreshSampleRate = SrcSampleRate /
  202. ( 1.0 - tbw * ReqTransBand ); // Make sure intermediate
  203. // filter's transition band is not steeper than ReqTransBand
  204. // (this keeps the latency under control).
  205. int c = 0;
  206. int div = 1;
  207. while( true )
  208. {
  209. const int ndiv = div * 2;
  210. if( DstSampleRate < ThreshSampleRate * ndiv )
  211. {
  212. break;
  213. }
  214. div = ndiv;
  215. c++;
  216. }
  217. int c2 = 0;
  218. int div2 = 1;
  219. while( true )
  220. {
  221. const int ndiv = div * ( c2 == 0 ? 3 : 2 );
  222. if( DstSampleRate < ThreshSampleRate * ndiv )
  223. {
  224. break;
  225. }
  226. div2 = ndiv;
  227. c2++;
  228. }
  229. const double SrcSampleRate2 = SrcSampleRate * 2.0;
  230. int tmp1;
  231. int tmp2;
  232. if( c == 1 && getWholeStepping( SrcSampleRate2, DstSampleRate,
  233. tmp1, tmp2 ))
  234. {
  235. // Do not use intermediate interpolation if whole stepping is
  236. // available as it performs very fast.
  237. c = 0;
  238. }
  239. if( c > 0 )
  240. {
  241. // Add steps using intermediate interpolation.
  242. int num;
  243. if( c2 > 0 && div2 > div )
  244. {
  245. div = div2;
  246. c = c2;
  247. num = 3;
  248. }
  249. else
  250. {
  251. num = 2;
  252. }
  253. addProcessor( new CDSPFracInterpolator( SrcSampleRate2 * div,
  254. DstSampleRate, ReqAtten, false, LatencyFrac ));
  255. double tb = ( 1.0 - SrcSampleRate * div / DstSampleRate ) /
  256. tbw; // Divide TransBand by a constant that assures a
  257. // linear response in the pass-band.
  258. if( tb > CDSPFIRFilter :: getLPMaxTransBand() )
  259. {
  260. tb = CDSPFIRFilter :: getLPMaxTransBand();
  261. }
  262. addProcessor( new CDSPBlockConvolver(
  263. CDSPFIRFilterCache :: getLPFilter( 1.0 / num, tb,
  264. ReqAtten, ReqPhase, num ), num, 1, LatencyFrac ));
  265. const bool IsThird = ( num == 3 );
  266. for( i = 1; i < c; i++ )
  267. {
  268. addProcessor( new CDSPHBUpsampler( ReqAtten, i - 1,
  269. IsThird, LatencyFrac ));
  270. }
  271. }
  272. else
  273. {
  274. addProcessor( new CDSPFracInterpolator( SrcSampleRate2,
  275. DstSampleRate, ReqAtten, false, LatencyFrac ));
  276. }
  277. createTmpBuffers();
  278. return;
  279. }
  280. // Use downsampling steps, including power-of-2 downsampling.
  281. double CheckSR = DstSampleRate * 4.0;
  282. int c = 0;
  283. double FinGain = 1.0;
  284. while( CheckSR <= SrcSampleRate )
  285. {
  286. c++;
  287. CheckSR *= 2.0;
  288. FinGain *= 0.5;
  289. }
  290. const int SrcSRDiv = ( 1 << c );
  291. int downf;
  292. double NormFreq = 0.5;
  293. bool UseInterp = true;
  294. bool IsThird = false;
  295. for( downf = 2; downf <= 3; downf++ )
  296. {
  297. if( DstSampleRate * SrcSRDiv * downf == SrcSampleRate )
  298. {
  299. NormFreq = 1.0 / downf;
  300. UseInterp = false;
  301. IsThird = ( downf == 3 );
  302. break;
  303. }
  304. }
  305. if( UseInterp )
  306. {
  307. downf = 1;
  308. NormFreq = DstSampleRate * SrcSRDiv / SrcSampleRate;
  309. IsThird = ( NormFreq * 3.0 <= 1.0 );
  310. }
  311. for( i = 0; i < c; i++ )
  312. {
  313. // Use a fixed very relaxed 2X downsampling filters, that at
  314. // the final stage only guarantees stop-band between 0.75 and
  315. // pi. 0.5-0.75 range will be aliased to 0.25-0.5 range which
  316. // will then be filtered out by the final filter.
  317. addProcessor( new CDSPHBDownsampler( ReqAtten, c - 1 - i, IsThird,
  318. LatencyFrac ));
  319. }
  320. addProcessor( new CDSPBlockConvolver(
  321. CDSPFIRFilterCache :: getLPFilter( NormFreq, ReqTransBand,
  322. ReqAtten, ReqPhase, FinGain ), 1, downf, LatencyFrac ));
  323. if( UseInterp )
  324. {
  325. addProcessor( new CDSPFracInterpolator( SrcSampleRate,
  326. DstSampleRate * SrcSRDiv, ReqAtten, IsThird, LatencyFrac ));
  327. }
  328. createTmpBuffers();
  329. }
  330. virtual ~CDSPResampler()
  331. {
  332. int i;
  333. for( i = 0; i < StepCount; i++ )
  334. {
  335. delete Steps[ i ];
  336. }
  337. }
  338. virtual int getLatency() const
  339. {
  340. return( 0 );
  341. }
  342. virtual double getLatencyFrac() const
  343. {
  344. return( LatencyFrac );
  345. }
  346. /**
  347. * This function ignores the supplied parameter and returns the maximal
  348. * output buffer length that depends on the MaxInLen supplied to the
  349. * constructor.
  350. */
  351. virtual int getMaxOutLen( const int/* MaxInLen */ ) const
  352. {
  353. return( CurMaxOutLen );
  354. }
  355. /**
  356. * Function clears (resets) the state of *this object and returns it to
  357. * the state after construction. All input data accumulated in the
  358. * internal buffer so far will be discarded.
  359. *
  360. * This function makes it possible to use *this object for converting
  361. * separate streams from the same source sample rate to the same
  362. * destination sample rate without reconstructing the object. It is more
  363. * efficient to clear the state of the resampler object than to destroy it
  364. * and create a new object.
  365. */
  366. virtual void clear()
  367. {
  368. int i;
  369. for( i = 0; i < StepCount; i++ )
  370. {
  371. Steps[ i ] -> clear();
  372. }
  373. }
  374. /**
  375. * Function performs sample rate conversion.
  376. *
  377. * If the source and destination sample rates are equal, the resampler
  378. * will do nothing and will simply return the input buffer unchanged.
  379. *
  380. * You do not need to allocate an intermediate output buffer for use with
  381. * this function. If required, the resampler will allocate a suitable
  382. * intermediate output buffer itself.
  383. *
  384. * @param ip0 Input buffer. This buffer is never used as output buffer by
  385. * this function. This pointer may be returned in "op0" if no resampling
  386. * is happening (source sample rate equals destination sample rate).
  387. * @param l The number of samples available in the input buffer. Should
  388. * not exceed the MaxInLen supplied in the constructor.
  389. * @param[out] op0 This variable receives the pointer to the resampled
  390. * data. On function's return, this pointer points to *this object's
  391. * internal buffer. In real-time applications it is suggested to pass this
  392. * pointer to the next output audio block and consume any data left from
  393. * the previous output audio block first before calling the process()
  394. * function again. The buffer pointed to by the "op0" on return is owned
  395. * by the resampler, so it should not be freed by the caller.
  396. * @return The number of samples available in the "op0" output buffer. If
  397. * the data from the output buffer "op0" is going to be written to a
  398. * bigger output buffer, it is suggested to check the returned number of
  399. * samples so that no overflow of the bigger output buffer happens.
  400. */
  401. virtual int process( double* ip0, int l, double*& op0 )
  402. {
  403. R8BASSERT( l >= 0 );
  404. double* ip = ip0;
  405. int i;
  406. for( i = 0; i < StepCount; i++ )
  407. {
  408. double* op = TmpBufs[ i & 1 ];
  409. l = Steps[ i ] -> process( ip, l, op );
  410. ip = op;
  411. }
  412. op0 = ip;
  413. return( l );
  414. }
  415. /**
  416. * Function performs resampling of an input sample buffer of the specified
  417. * length in the "one-shot" mode. This function can be useful when impulse
  418. * response resampling is required.
  419. *
  420. * @param ip Input buffer pointer.
  421. * @param iplen Length of the input buffer in samples.
  422. * @param[out] op Output buffer pointer.
  423. * @param oplen Length of the output buffer in samples.
  424. * @tparam Tin Input buffer's element type.
  425. * @tparam Tout Output buffer's element type.
  426. */
  427. template< typename Tin, typename Tout >
  428. void oneshot( const Tin* ip, int iplen, Tout* op, int oplen )
  429. {
  430. CFixedBuffer< double > Buf( MaxInLen );
  431. bool IsZero = false;
  432. while( oplen > 0 )
  433. {
  434. int rc;
  435. double* p;
  436. int i;
  437. if( iplen == 0 )
  438. {
  439. rc = MaxInLen;
  440. p = &Buf[ 0 ];
  441. if( !IsZero )
  442. {
  443. IsZero = true;
  444. memset( p, 0, MaxInLen * sizeof( p[ 0 ]));
  445. }
  446. }
  447. else
  448. {
  449. rc = min( iplen, MaxInLen );
  450. if( sizeof( Tin ) == sizeof( double ))
  451. {
  452. p = (double*) ip;
  453. }
  454. else
  455. {
  456. p = &Buf[ 0 ];
  457. for( i = 0; i < rc; i++ )
  458. {
  459. p[ i ] = ip[ i ];
  460. }
  461. }
  462. ip += rc;
  463. iplen -= rc;
  464. }
  465. double* op0;
  466. int wc = process( p, rc, op0 );
  467. wc = min( oplen, wc );
  468. for( i = 0; i < wc; i++ )
  469. {
  470. op[ i ] = (Tout) op0[ i ];
  471. }
  472. op += wc;
  473. oplen -= wc;
  474. }
  475. clear();
  476. }
  477. /**
  478. * Function obtains overall input sample count required to produce first
  479. * output sample. Function works by iteratively passing 1 sample at a time
  480. * until output begins. This is a relatively CPU-consuming operation. This
  481. * function should be called after the clear() function call or after
  482. * object's construction. The function itself calls the clear() function
  483. * before return.
  484. *
  485. * Note that it is advisable to cache the value returned by this function,
  486. * for each SrcSampleRate/DstSampleRate pair, if it is called frequently.
  487. */
  488. int getInLenBeforeOutStart()
  489. {
  490. int inc = 0;
  491. while( true )
  492. {
  493. double ins = 0.0;
  494. double* op;
  495. if( process( &ins, 1, op ) > 0 )
  496. {
  497. clear();
  498. return( inc );
  499. }
  500. inc++;
  501. }
  502. }
  503. private:
  504. CFixedBuffer< CDSPProcessor* > Steps; ///< Array of processing steps.
  505. ///<
  506. int StepCapacity; ///< The capacity of the Steps array.
  507. ///<
  508. int StepCount; ///< The number of created processing steps.
  509. ///<
  510. int MaxInLen; ///< Maximal input length.
  511. ///<
  512. CFixedBuffer< double > TmpBufAll; ///< Buffer containing both temporary
  513. ///< buffers.
  514. ///<
  515. double* TmpBufs[ 2 ]; ///< Temporary output buffers.
  516. ///<
  517. int TmpBufCapacities[ 2 ]; ///< Capacities of temporary buffers, updated
  518. ///< during processing steps building.
  519. ///<
  520. int CurTmpBuf; ///< Current temporary buffer.
  521. ///<
  522. int CurMaxOutLen; ///< Current maximal output length.
  523. ///<
  524. double LatencyFrac; ///< Current fractional latency. After object's
  525. ///< construction, equals to the remaining fractional latency in the
  526. ///< output.
  527. ///<
  528. /**
  529. * Function adds processor, updates MaxOutLen variable and adjusts length
  530. * of temporary internal buffers.
  531. *
  532. * @param Proc Processor to add. This pointer is inherited and will be
  533. * destroyed on *this object's destruction.
  534. */
  535. void addProcessor( CDSPProcessor* const Proc )
  536. {
  537. if( StepCount == StepCapacity )
  538. {
  539. // Reallocate and increase Steps array's capacity.
  540. const int NewCapacity = StepCapacity + 8;
  541. Steps.realloc( StepCapacity, NewCapacity );
  542. StepCapacity = NewCapacity;
  543. }
  544. LatencyFrac = Proc -> getLatencyFrac();
  545. CurMaxOutLen = Proc -> getMaxOutLen( CurMaxOutLen );
  546. if( CurMaxOutLen > TmpBufCapacities[ CurTmpBuf ])
  547. {
  548. TmpBufCapacities[ CurTmpBuf ] = CurMaxOutLen;
  549. }
  550. CurTmpBuf ^= 1;
  551. Steps[ StepCount ] = Proc;
  552. StepCount++;
  553. }
  554. /**
  555. * Function creates temporary buffers.
  556. */
  557. void createTmpBuffers()
  558. {
  559. const int ol = TmpBufCapacities[ 0 ] + TmpBufCapacities[ 1 ];
  560. if( ol > 0 )
  561. {
  562. TmpBufAll.alloc( ol );
  563. TmpBufs[ 0 ] = &TmpBufAll[ 0 ];
  564. TmpBufs[ 1 ] = &TmpBufAll[ TmpBufCapacities[ 0 ]];
  565. }
  566. R8BCONSOLE( "* CDSPResampler: init done\n" );
  567. }
  568. };
  569. /**
  570. * @brief The resampler class for 16-bit resampling.
  571. *
  572. * This class defines resampling parameters suitable for 16-bit resampling,
  573. * using linear-phase low-pass filter. See the r8b::CDSPResampler class for
  574. * details.
  575. */
  576. class CDSPResampler16 : public CDSPResampler
  577. {
  578. public:
  579. /**
  580. * Constructor initializes the 16-bit resampler. See the
  581. * r8b::CDSPResampler class for details.
  582. *
  583. * @param SrcSampleRate Source signal sample rate.
  584. * @param DstSampleRate Destination signal sample rate.
  585. * @param aMaxInLen The maximal planned length of the input buffer (in
  586. * samples) that will be passed to the resampler.
  587. * @param ReqTransBand Required transition band, in percent.
  588. */
  589. CDSPResampler16( const double SrcSampleRate, const double DstSampleRate,
  590. const int aMaxInLen, const double ReqTransBand = 2.0 )
  591. : CDSPResampler( SrcSampleRate, DstSampleRate, aMaxInLen, ReqTransBand,
  592. 136.45, fprLinearPhase )
  593. {
  594. }
  595. };
  596. /**
  597. * @brief The resampler class for 16-bit impulse response resampling.
  598. *
  599. * This class defines resampling parameters suitable for 16-bit impulse
  600. * response resampling, using linear-phase low-pass filter. Impulse responses
  601. * are non-dynamic signals, and thus need resampler with a lesser SNR. See the
  602. * r8b::CDSPResampler class for details.
  603. */
  604. class CDSPResampler16IR : public CDSPResampler
  605. {
  606. public:
  607. /**
  608. * Constructor initializes the 16-bit impulse response resampler. See the
  609. * r8b::CDSPResampler class for details.
  610. *
  611. * @param SrcSampleRate Source signal sample rate.
  612. * @param DstSampleRate Destination signal sample rate.
  613. * @param aMaxInLen The maximal planned length of the input buffer (in
  614. * samples) that will be passed to the resampler.
  615. * @param ReqTransBand Required transition band, in percent.
  616. */
  617. CDSPResampler16IR( const double SrcSampleRate, const double DstSampleRate,
  618. const int aMaxInLen, const double ReqTransBand = 2.0 )
  619. : CDSPResampler( SrcSampleRate, DstSampleRate, aMaxInLen, ReqTransBand,
  620. 109.56, fprLinearPhase )
  621. {
  622. }
  623. };
  624. /**
  625. * @brief The resampler class for 24-bit resampling.
  626. *
  627. * This class defines resampling parameters suitable for 24-bit resampling
  628. * (including 32-bit floating point resampling), using linear-phase low-pass
  629. * filter. See the r8b::CDSPResampler class for details.
  630. */
  631. class CDSPResampler24 : public CDSPResampler
  632. {
  633. public:
  634. /**
  635. * Constructor initializes the 24-bit resampler (including 32-bit floating
  636. * point). See the r8b::CDSPResampler class for details.
  637. *
  638. * @param SrcSampleRate Source signal sample rate.
  639. * @param DstSampleRate Destination signal sample rate.
  640. * @param aMaxInLen The maximal planned length of the input buffer (in
  641. * samples) that will be passed to the resampler.
  642. * @param ReqTransBand Required transition band, in percent.
  643. */
  644. CDSPResampler24( const double SrcSampleRate, const double DstSampleRate,
  645. const int aMaxInLen, const double ReqTransBand = 2.0 )
  646. : CDSPResampler( SrcSampleRate, DstSampleRate, aMaxInLen, ReqTransBand,
  647. 180.15, fprLinearPhase )
  648. {
  649. }
  650. };
  651. } // namespace r8b
  652. #endif // R8B_CDSPRESAMPLER_INCLUDED