You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1192 lines
38KB

  1. /*
  2. ** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
  3. ** All rights reserved.
  4. **
  5. ** This code is released under 2-clause BSD license. Please see the
  6. ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "config.h"
  12. #include "float_cast.h"
  13. #include "common.h"
  14. #define SINC_MAGIC_MARKER MAKE_MAGIC (' ', 's', 'i', 'n', 'c', ' ')
  15. /*========================================================================================
  16. */
  17. #define MAKE_INCREMENT_T(x) ((increment_t) (x))
  18. #define SHIFT_BITS 12
  19. #define FP_ONE ((double) (((increment_t) 1) << SHIFT_BITS))
  20. #define INV_FP_ONE (1.0 / FP_ONE)
  21. /*========================================================================================
  22. */
  23. typedef int32_t increment_t ;
  24. typedef float coeff_t ;
  25. #include "fastest_coeffs.h"
  26. #include "mid_qual_coeffs.h"
  27. #include "high_qual_coeffs.h"
  28. typedef struct
  29. { int sinc_magic_marker ;
  30. int channels ;
  31. long in_count, in_used ;
  32. long out_count, out_gen ;
  33. int coeff_half_len, index_inc ;
  34. double src_ratio, input_index ;
  35. coeff_t const *coeffs ;
  36. int b_current, b_end, b_real_end, b_len ;
  37. /* Sure hope noone does more than 128 channels at once. */
  38. double left_calc [128], right_calc [128] ;
  39. /* C99 struct flexible array. */
  40. float buffer [] ;
  41. } SINC_FILTER ;
  42. static int sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
  43. static int sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
  44. static int sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
  45. static int sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
  46. static int sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data) ;
  47. static int prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len) WARN_UNUSED ;
  48. static void sinc_reset (SRC_PRIVATE *psrc) ;
  49. static inline increment_t
  50. double_to_fp (double x)
  51. { return (lrint ((x) * FP_ONE)) ;
  52. } /* double_to_fp */
  53. static inline increment_t
  54. int_to_fp (int x)
  55. { return (((increment_t) (x)) << SHIFT_BITS) ;
  56. } /* int_to_fp */
  57. static inline int
  58. fp_to_int (increment_t x)
  59. { return (((x) >> SHIFT_BITS)) ;
  60. } /* fp_to_int */
  61. static inline increment_t
  62. fp_fraction_part (increment_t x)
  63. { return ((x) & ((((increment_t) 1) << SHIFT_BITS) - 1)) ;
  64. } /* fp_fraction_part */
  65. static inline double
  66. fp_to_double (increment_t x)
  67. { return fp_fraction_part (x) * INV_FP_ONE ;
  68. } /* fp_to_double */
  69. /*----------------------------------------------------------------------------------------
  70. */
  71. const char*
  72. sinc_get_name (int src_enum)
  73. {
  74. switch (src_enum)
  75. { case SRC_SINC_BEST_QUALITY :
  76. return "Best Sinc Interpolator" ;
  77. case SRC_SINC_MEDIUM_QUALITY :
  78. return "Medium Sinc Interpolator" ;
  79. case SRC_SINC_FASTEST :
  80. return "Fastest Sinc Interpolator" ;
  81. default: break ;
  82. } ;
  83. return NULL ;
  84. } /* sinc_get_descrition */
  85. const char*
  86. sinc_get_description (int src_enum)
  87. {
  88. switch (src_enum)
  89. { case SRC_SINC_FASTEST :
  90. return "Band limited sinc interpolation, fastest, 97dB SNR, 80% BW." ;
  91. case SRC_SINC_MEDIUM_QUALITY :
  92. return "Band limited sinc interpolation, medium quality, 121dB SNR, 90% BW." ;
  93. case SRC_SINC_BEST_QUALITY :
  94. return "Band limited sinc interpolation, best quality, 144dB SNR, 96% BW." ;
  95. default :
  96. break ;
  97. } ;
  98. return NULL ;
  99. } /* sinc_get_descrition */
  100. int
  101. sinc_set_converter (SRC_PRIVATE *psrc, int src_enum)
  102. { SINC_FILTER *filter, temp_filter ;
  103. increment_t count ;
  104. int bits ;
  105. /* Quick sanity check. */
  106. if (SHIFT_BITS >= sizeof (increment_t) * 8 - 1)
  107. return SRC_ERR_SHIFT_BITS ;
  108. if (psrc->private_data != NULL)
  109. { free (psrc->private_data) ;
  110. psrc->private_data = NULL ;
  111. } ;
  112. memset (&temp_filter, 0, sizeof (temp_filter)) ;
  113. temp_filter.sinc_magic_marker = SINC_MAGIC_MARKER ;
  114. temp_filter.channels = psrc->channels ;
  115. if (psrc->channels > ARRAY_LEN (temp_filter.left_calc))
  116. return SRC_ERR_BAD_CHANNEL_COUNT ;
  117. else if (psrc->channels == 1)
  118. { psrc->const_process = sinc_mono_vari_process ;
  119. psrc->vari_process = sinc_mono_vari_process ;
  120. }
  121. else
  122. if (psrc->channels == 2)
  123. { psrc->const_process = sinc_stereo_vari_process ;
  124. psrc->vari_process = sinc_stereo_vari_process ;
  125. }
  126. else
  127. if (psrc->channels == 4)
  128. { psrc->const_process = sinc_quad_vari_process ;
  129. psrc->vari_process = sinc_quad_vari_process ;
  130. }
  131. else
  132. if (psrc->channels == 6)
  133. { psrc->const_process = sinc_hex_vari_process ;
  134. psrc->vari_process = sinc_hex_vari_process ;
  135. }
  136. else
  137. { psrc->const_process = sinc_multichan_vari_process ;
  138. psrc->vari_process = sinc_multichan_vari_process ;
  139. } ;
  140. psrc->reset = sinc_reset ;
  141. switch (src_enum)
  142. { case SRC_SINC_FASTEST :
  143. temp_filter.coeffs = fastest_coeffs.coeffs ;
  144. temp_filter.coeff_half_len = ARRAY_LEN (fastest_coeffs.coeffs) - 2 ;
  145. temp_filter.index_inc = fastest_coeffs.increment ;
  146. break ;
  147. case SRC_SINC_MEDIUM_QUALITY :
  148. temp_filter.coeffs = slow_mid_qual_coeffs.coeffs ;
  149. temp_filter.coeff_half_len = ARRAY_LEN (slow_mid_qual_coeffs.coeffs) - 2 ;
  150. temp_filter.index_inc = slow_mid_qual_coeffs.increment ;
  151. break ;
  152. case SRC_SINC_BEST_QUALITY :
  153. temp_filter.coeffs = slow_high_qual_coeffs.coeffs ;
  154. temp_filter.coeff_half_len = ARRAY_LEN (slow_high_qual_coeffs.coeffs) - 2 ;
  155. temp_filter.index_inc = slow_high_qual_coeffs.increment ;
  156. break ;
  157. default :
  158. return SRC_ERR_BAD_CONVERTER ;
  159. } ;
  160. /*
  161. ** FIXME : This needs to be looked at more closely to see if there is
  162. ** a better way. Need to look at prepare_data () at the same time.
  163. */
  164. temp_filter.b_len = lrint (2.5 * temp_filter.coeff_half_len / (temp_filter.index_inc * 1.0) * SRC_MAX_RATIO) ;
  165. temp_filter.b_len = MAX (temp_filter.b_len, 4096) ;
  166. temp_filter.b_len *= temp_filter.channels ;
  167. if ((filter = calloc (1, sizeof (SINC_FILTER) + sizeof (filter->buffer [0]) * (temp_filter.b_len + temp_filter.channels))) == NULL)
  168. return SRC_ERR_MALLOC_FAILED ;
  169. *filter = temp_filter ;
  170. memset (&temp_filter, 0xEE, sizeof (temp_filter)) ;
  171. psrc->private_data = filter ;
  172. sinc_reset (psrc) ;
  173. count = filter->coeff_half_len ;
  174. for (bits = 0 ; (MAKE_INCREMENT_T (1) << bits) < count ; bits++)
  175. count |= (MAKE_INCREMENT_T (1) << bits) ;
  176. if (bits + SHIFT_BITS - 1 >= (int) (sizeof (increment_t) * 8))
  177. return SRC_ERR_FILTER_LEN ;
  178. return SRC_ERR_NO_ERROR ;
  179. } /* sinc_set_converter */
  180. static void
  181. sinc_reset (SRC_PRIVATE *psrc)
  182. { SINC_FILTER *filter ;
  183. filter = (SINC_FILTER*) psrc->private_data ;
  184. if (filter == NULL)
  185. return ;
  186. filter->b_current = filter->b_end = 0 ;
  187. filter->b_real_end = -1 ;
  188. filter->src_ratio = filter->input_index = 0.0 ;
  189. memset (filter->buffer, 0, filter->b_len * sizeof (filter->buffer [0])) ;
  190. /* Set this for a sanity check */
  191. memset (filter->buffer + filter->b_len, 0xAA, filter->channels * sizeof (filter->buffer [0])) ;
  192. } /* sinc_reset */
  193. /*========================================================================================
  194. ** Beware all ye who dare pass this point. There be dragons here.
  195. */
  196. static inline double
  197. calc_output_single (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index)
  198. { double fraction, left, right, icoeff ;
  199. increment_t filter_index, max_filter_index ;
  200. int data_index, coeff_count, indx ;
  201. /* Convert input parameters into fixed point. */
  202. max_filter_index = int_to_fp (filter->coeff_half_len) ;
  203. /* First apply the left half of the filter. */
  204. filter_index = start_filter_index ;
  205. coeff_count = (max_filter_index - filter_index) / increment ;
  206. filter_index = filter_index + coeff_count * increment ;
  207. data_index = filter->b_current - coeff_count ;
  208. left = 0.0 ;
  209. do
  210. { fraction = fp_to_double (filter_index) ;
  211. indx = fp_to_int (filter_index) ;
  212. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  213. left += icoeff * filter->buffer [data_index] ;
  214. filter_index -= increment ;
  215. data_index = data_index + 1 ;
  216. }
  217. while (filter_index >= MAKE_INCREMENT_T (0)) ;
  218. /* Now apply the right half of the filter. */
  219. filter_index = increment - start_filter_index ;
  220. coeff_count = (max_filter_index - filter_index) / increment ;
  221. filter_index = filter_index + coeff_count * increment ;
  222. data_index = filter->b_current + 1 + coeff_count ;
  223. right = 0.0 ;
  224. do
  225. { fraction = fp_to_double (filter_index) ;
  226. indx = fp_to_int (filter_index) ;
  227. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  228. right += icoeff * filter->buffer [data_index] ;
  229. filter_index -= increment ;
  230. data_index = data_index - 1 ;
  231. }
  232. while (filter_index > MAKE_INCREMENT_T (0)) ;
  233. return (left + right) ;
  234. } /* calc_output_single */
  235. static int
  236. sinc_mono_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
  237. { SINC_FILTER *filter ;
  238. double input_index, src_ratio, count, float_increment, terminate, rem ;
  239. increment_t increment, start_filter_index ;
  240. int half_filter_chan_len, samples_in_hand ;
  241. if (psrc->private_data == NULL)
  242. return SRC_ERR_NO_PRIVATE ;
  243. filter = (SINC_FILTER*) psrc->private_data ;
  244. /* If there is not a problem, this will be optimised out. */
  245. if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
  246. return SRC_ERR_SIZE_INCOMPATIBILITY ;
  247. filter->in_count = data->input_frames * filter->channels ;
  248. filter->out_count = data->output_frames * filter->channels ;
  249. filter->in_used = filter->out_gen = 0 ;
  250. src_ratio = psrc->last_ratio ;
  251. if (is_bad_src_ratio (src_ratio))
  252. return SRC_ERR_BAD_INTERNAL_STATE ;
  253. /* Check the sample rate ratio wrt the buffer len. */
  254. count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
  255. if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
  256. count /= MIN (psrc->last_ratio, data->src_ratio) ;
  257. /* Maximum coefficientson either side of center point. */
  258. half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
  259. input_index = psrc->last_position ;
  260. float_increment = filter->index_inc ;
  261. rem = fmod_one (input_index) ;
  262. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  263. input_index = rem ;
  264. terminate = 1.0 / src_ratio + 1e-20 ;
  265. /* Main processing loop. */
  266. while (filter->out_gen < filter->out_count)
  267. {
  268. /* Need to reload buffer? */
  269. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  270. if (samples_in_hand <= half_filter_chan_len)
  271. { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0)
  272. return psrc->error ;
  273. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  274. if (samples_in_hand <= half_filter_chan_len)
  275. break ;
  276. } ;
  277. /* This is the termination condition. */
  278. if (filter->b_real_end >= 0)
  279. { if (filter->b_current + input_index + terminate > filter->b_real_end)
  280. break ;
  281. } ;
  282. if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
  283. src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
  284. float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ;
  285. increment = double_to_fp (float_increment) ;
  286. start_filter_index = double_to_fp (input_index * float_increment) ;
  287. data->data_out [filter->out_gen] = (float) ((float_increment / filter->index_inc) *
  288. calc_output_single (filter, increment, start_filter_index)) ;
  289. filter->out_gen ++ ;
  290. /* Figure out the next index. */
  291. input_index += 1.0 / src_ratio ;
  292. rem = fmod_one (input_index) ;
  293. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  294. input_index = rem ;
  295. } ;
  296. psrc->last_position = input_index ;
  297. /* Save current ratio rather then target ratio. */
  298. psrc->last_ratio = src_ratio ;
  299. data->input_frames_used = filter->in_used / filter->channels ;
  300. data->output_frames_gen = filter->out_gen / filter->channels ;
  301. return SRC_ERR_NO_ERROR ;
  302. } /* sinc_mono_vari_process */
  303. static inline void
  304. calc_output_stereo (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
  305. { double fraction, left [2], right [2], icoeff ;
  306. increment_t filter_index, max_filter_index ;
  307. int data_index, coeff_count, indx ;
  308. /* Convert input parameters into fixed point. */
  309. max_filter_index = int_to_fp (filter->coeff_half_len) ;
  310. /* First apply the left half of the filter. */
  311. filter_index = start_filter_index ;
  312. coeff_count = (max_filter_index - filter_index) / increment ;
  313. filter_index = filter_index + coeff_count * increment ;
  314. data_index = filter->b_current - filter->channels * coeff_count ;
  315. left [0] = left [1] = 0.0 ;
  316. do
  317. { fraction = fp_to_double (filter_index) ;
  318. indx = fp_to_int (filter_index) ;
  319. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  320. left [0] += icoeff * filter->buffer [data_index] ;
  321. left [1] += icoeff * filter->buffer [data_index + 1] ;
  322. filter_index -= increment ;
  323. data_index = data_index + 2 ;
  324. }
  325. while (filter_index >= MAKE_INCREMENT_T (0)) ;
  326. /* Now apply the right half of the filter. */
  327. filter_index = increment - start_filter_index ;
  328. coeff_count = (max_filter_index - filter_index) / increment ;
  329. filter_index = filter_index + coeff_count * increment ;
  330. data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
  331. right [0] = right [1] = 0.0 ;
  332. do
  333. { fraction = fp_to_double (filter_index) ;
  334. indx = fp_to_int (filter_index) ;
  335. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  336. right [0] += icoeff * filter->buffer [data_index] ;
  337. right [1] += icoeff * filter->buffer [data_index + 1] ;
  338. filter_index -= increment ;
  339. data_index = data_index - 2 ;
  340. }
  341. while (filter_index > MAKE_INCREMENT_T (0)) ;
  342. output [0] = scale * (left [0] + right [0]) ;
  343. output [1] = scale * (left [1] + right [1]) ;
  344. } /* calc_output_stereo */
  345. static int
  346. sinc_stereo_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
  347. { SINC_FILTER *filter ;
  348. double input_index, src_ratio, count, float_increment, terminate, rem ;
  349. increment_t increment, start_filter_index ;
  350. int half_filter_chan_len, samples_in_hand ;
  351. if (psrc->private_data == NULL)
  352. return SRC_ERR_NO_PRIVATE ;
  353. filter = (SINC_FILTER*) psrc->private_data ;
  354. /* If there is not a problem, this will be optimised out. */
  355. if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
  356. return SRC_ERR_SIZE_INCOMPATIBILITY ;
  357. filter->in_count = data->input_frames * filter->channels ;
  358. filter->out_count = data->output_frames * filter->channels ;
  359. filter->in_used = filter->out_gen = 0 ;
  360. src_ratio = psrc->last_ratio ;
  361. if (is_bad_src_ratio (src_ratio))
  362. return SRC_ERR_BAD_INTERNAL_STATE ;
  363. /* Check the sample rate ratio wrt the buffer len. */
  364. count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
  365. if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
  366. count /= MIN (psrc->last_ratio, data->src_ratio) ;
  367. /* Maximum coefficientson either side of center point. */
  368. half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
  369. input_index = psrc->last_position ;
  370. float_increment = filter->index_inc ;
  371. rem = fmod_one (input_index) ;
  372. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  373. input_index = rem ;
  374. terminate = 1.0 / src_ratio + 1e-20 ;
  375. /* Main processing loop. */
  376. while (filter->out_gen < filter->out_count)
  377. {
  378. /* Need to reload buffer? */
  379. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  380. if (samples_in_hand <= half_filter_chan_len)
  381. { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0)
  382. return psrc->error ;
  383. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  384. if (samples_in_hand <= half_filter_chan_len)
  385. break ;
  386. } ;
  387. /* This is the termination condition. */
  388. if (filter->b_real_end >= 0)
  389. { if (filter->b_current + input_index + terminate >= filter->b_real_end)
  390. break ;
  391. } ;
  392. if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
  393. src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
  394. float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ;
  395. increment = double_to_fp (float_increment) ;
  396. start_filter_index = double_to_fp (input_index * float_increment) ;
  397. calc_output_stereo (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
  398. filter->out_gen += 2 ;
  399. /* Figure out the next index. */
  400. input_index += 1.0 / src_ratio ;
  401. rem = fmod_one (input_index) ;
  402. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  403. input_index = rem ;
  404. } ;
  405. psrc->last_position = input_index ;
  406. /* Save current ratio rather then target ratio. */
  407. psrc->last_ratio = src_ratio ;
  408. data->input_frames_used = filter->in_used / filter->channels ;
  409. data->output_frames_gen = filter->out_gen / filter->channels ;
  410. return SRC_ERR_NO_ERROR ;
  411. } /* sinc_stereo_vari_process */
  412. static inline void
  413. calc_output_quad (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
  414. { double fraction, left [4], right [4], icoeff ;
  415. increment_t filter_index, max_filter_index ;
  416. int data_index, coeff_count, indx ;
  417. /* Convert input parameters into fixed point. */
  418. max_filter_index = int_to_fp (filter->coeff_half_len) ;
  419. /* First apply the left half of the filter. */
  420. filter_index = start_filter_index ;
  421. coeff_count = (max_filter_index - filter_index) / increment ;
  422. filter_index = filter_index + coeff_count * increment ;
  423. data_index = filter->b_current - filter->channels * coeff_count ;
  424. left [0] = left [1] = left [2] = left [3] = 0.0 ;
  425. do
  426. { fraction = fp_to_double (filter_index) ;
  427. indx = fp_to_int (filter_index) ;
  428. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  429. left [0] += icoeff * filter->buffer [data_index] ;
  430. left [1] += icoeff * filter->buffer [data_index + 1] ;
  431. left [2] += icoeff * filter->buffer [data_index + 2] ;
  432. left [3] += icoeff * filter->buffer [data_index + 3] ;
  433. filter_index -= increment ;
  434. data_index = data_index + 4 ;
  435. }
  436. while (filter_index >= MAKE_INCREMENT_T (0)) ;
  437. /* Now apply the right half of the filter. */
  438. filter_index = increment - start_filter_index ;
  439. coeff_count = (max_filter_index - filter_index) / increment ;
  440. filter_index = filter_index + coeff_count * increment ;
  441. data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
  442. right [0] = right [1] = right [2] = right [3] = 0.0 ;
  443. do
  444. { fraction = fp_to_double (filter_index) ;
  445. indx = fp_to_int (filter_index) ;
  446. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  447. right [0] += icoeff * filter->buffer [data_index] ;
  448. right [1] += icoeff * filter->buffer [data_index + 1] ;
  449. right [2] += icoeff * filter->buffer [data_index + 2] ;
  450. right [3] += icoeff * filter->buffer [data_index + 3] ;
  451. filter_index -= increment ;
  452. data_index = data_index - 4 ;
  453. }
  454. while (filter_index > MAKE_INCREMENT_T (0)) ;
  455. output [0] = scale * (left [0] + right [0]) ;
  456. output [1] = scale * (left [1] + right [1]) ;
  457. output [2] = scale * (left [2] + right [2]) ;
  458. output [3] = scale * (left [3] + right [3]) ;
  459. } /* calc_output_quad */
  460. static int
  461. sinc_quad_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
  462. { SINC_FILTER *filter ;
  463. double input_index, src_ratio, count, float_increment, terminate, rem ;
  464. increment_t increment, start_filter_index ;
  465. int half_filter_chan_len, samples_in_hand ;
  466. if (psrc->private_data == NULL)
  467. return SRC_ERR_NO_PRIVATE ;
  468. filter = (SINC_FILTER*) psrc->private_data ;
  469. /* If there is not a problem, this will be optimised out. */
  470. if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
  471. return SRC_ERR_SIZE_INCOMPATIBILITY ;
  472. filter->in_count = data->input_frames * filter->channels ;
  473. filter->out_count = data->output_frames * filter->channels ;
  474. filter->in_used = filter->out_gen = 0 ;
  475. src_ratio = psrc->last_ratio ;
  476. if (is_bad_src_ratio (src_ratio))
  477. return SRC_ERR_BAD_INTERNAL_STATE ;
  478. /* Check the sample rate ratio wrt the buffer len. */
  479. count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
  480. if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
  481. count /= MIN (psrc->last_ratio, data->src_ratio) ;
  482. /* Maximum coefficientson either side of center point. */
  483. half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
  484. input_index = psrc->last_position ;
  485. float_increment = filter->index_inc ;
  486. rem = fmod_one (input_index) ;
  487. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  488. input_index = rem ;
  489. terminate = 1.0 / src_ratio + 1e-20 ;
  490. /* Main processing loop. */
  491. while (filter->out_gen < filter->out_count)
  492. {
  493. /* Need to reload buffer? */
  494. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  495. if (samples_in_hand <= half_filter_chan_len)
  496. { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0)
  497. return psrc->error ;
  498. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  499. if (samples_in_hand <= half_filter_chan_len)
  500. break ;
  501. } ;
  502. /* This is the termination condition. */
  503. if (filter->b_real_end >= 0)
  504. { if (filter->b_current + input_index + terminate >= filter->b_real_end)
  505. break ;
  506. } ;
  507. if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
  508. src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
  509. float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ;
  510. increment = double_to_fp (float_increment) ;
  511. start_filter_index = double_to_fp (input_index * float_increment) ;
  512. calc_output_quad (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
  513. filter->out_gen += 4 ;
  514. /* Figure out the next index. */
  515. input_index += 1.0 / src_ratio ;
  516. rem = fmod_one (input_index) ;
  517. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  518. input_index = rem ;
  519. } ;
  520. psrc->last_position = input_index ;
  521. /* Save current ratio rather then target ratio. */
  522. psrc->last_ratio = src_ratio ;
  523. data->input_frames_used = filter->in_used / filter->channels ;
  524. data->output_frames_gen = filter->out_gen / filter->channels ;
  525. return SRC_ERR_NO_ERROR ;
  526. } /* sinc_quad_vari_process */
  527. static inline void
  528. calc_output_hex (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, double scale, float * output)
  529. { double fraction, left [6], right [6], icoeff ;
  530. increment_t filter_index, max_filter_index ;
  531. int data_index, coeff_count, indx ;
  532. /* Convert input parameters into fixed point. */
  533. max_filter_index = int_to_fp (filter->coeff_half_len) ;
  534. /* First apply the left half of the filter. */
  535. filter_index = start_filter_index ;
  536. coeff_count = (max_filter_index - filter_index) / increment ;
  537. filter_index = filter_index + coeff_count * increment ;
  538. data_index = filter->b_current - filter->channels * coeff_count ;
  539. left [0] = left [1] = left [2] = left [3] = left [4] = left [5] = 0.0 ;
  540. do
  541. { fraction = fp_to_double (filter_index) ;
  542. indx = fp_to_int (filter_index) ;
  543. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  544. left [0] += icoeff * filter->buffer [data_index] ;
  545. left [1] += icoeff * filter->buffer [data_index + 1] ;
  546. left [2] += icoeff * filter->buffer [data_index + 2] ;
  547. left [3] += icoeff * filter->buffer [data_index + 3] ;
  548. left [4] += icoeff * filter->buffer [data_index + 4] ;
  549. left [5] += icoeff * filter->buffer [data_index + 5] ;
  550. filter_index -= increment ;
  551. data_index = data_index + 6 ;
  552. }
  553. while (filter_index >= MAKE_INCREMENT_T (0)) ;
  554. /* Now apply the right half of the filter. */
  555. filter_index = increment - start_filter_index ;
  556. coeff_count = (max_filter_index - filter_index) / increment ;
  557. filter_index = filter_index + coeff_count * increment ;
  558. data_index = filter->b_current + filter->channels * (1 + coeff_count) ;
  559. right [0] = right [1] = right [2] = right [3] = right [4] = right [5] = 0.0 ;
  560. do
  561. { fraction = fp_to_double (filter_index) ;
  562. indx = fp_to_int (filter_index) ;
  563. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  564. right [0] += icoeff * filter->buffer [data_index] ;
  565. right [1] += icoeff * filter->buffer [data_index + 1] ;
  566. right [2] += icoeff * filter->buffer [data_index + 2] ;
  567. right [3] += icoeff * filter->buffer [data_index + 3] ;
  568. right [4] += icoeff * filter->buffer [data_index + 4] ;
  569. right [5] += icoeff * filter->buffer [data_index + 5] ;
  570. filter_index -= increment ;
  571. data_index = data_index - 6 ;
  572. }
  573. while (filter_index > MAKE_INCREMENT_T (0)) ;
  574. output [0] = scale * (left [0] + right [0]) ;
  575. output [1] = scale * (left [1] + right [1]) ;
  576. output [2] = scale * (left [2] + right [2]) ;
  577. output [3] = scale * (left [3] + right [3]) ;
  578. output [4] = scale * (left [4] + right [4]) ;
  579. output [5] = scale * (left [5] + right [5]) ;
  580. } /* calc_output_hex */
  581. static int
  582. sinc_hex_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
  583. { SINC_FILTER *filter ;
  584. double input_index, src_ratio, count, float_increment, terminate, rem ;
  585. increment_t increment, start_filter_index ;
  586. int half_filter_chan_len, samples_in_hand ;
  587. if (psrc->private_data == NULL)
  588. return SRC_ERR_NO_PRIVATE ;
  589. filter = (SINC_FILTER*) psrc->private_data ;
  590. /* If there is not a problem, this will be optimised out. */
  591. if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
  592. return SRC_ERR_SIZE_INCOMPATIBILITY ;
  593. filter->in_count = data->input_frames * filter->channels ;
  594. filter->out_count = data->output_frames * filter->channels ;
  595. filter->in_used = filter->out_gen = 0 ;
  596. src_ratio = psrc->last_ratio ;
  597. if (is_bad_src_ratio (src_ratio))
  598. return SRC_ERR_BAD_INTERNAL_STATE ;
  599. /* Check the sample rate ratio wrt the buffer len. */
  600. count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
  601. if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
  602. count /= MIN (psrc->last_ratio, data->src_ratio) ;
  603. /* Maximum coefficientson either side of center point. */
  604. half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
  605. input_index = psrc->last_position ;
  606. float_increment = filter->index_inc ;
  607. rem = fmod_one (input_index) ;
  608. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  609. input_index = rem ;
  610. terminate = 1.0 / src_ratio + 1e-20 ;
  611. /* Main processing loop. */
  612. while (filter->out_gen < filter->out_count)
  613. {
  614. /* Need to reload buffer? */
  615. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  616. if (samples_in_hand <= half_filter_chan_len)
  617. { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0)
  618. return psrc->error ;
  619. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  620. if (samples_in_hand <= half_filter_chan_len)
  621. break ;
  622. } ;
  623. /* This is the termination condition. */
  624. if (filter->b_real_end >= 0)
  625. { if (filter->b_current + input_index + terminate >= filter->b_real_end)
  626. break ;
  627. } ;
  628. if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
  629. src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
  630. float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ;
  631. increment = double_to_fp (float_increment) ;
  632. start_filter_index = double_to_fp (input_index * float_increment) ;
  633. calc_output_hex (filter, increment, start_filter_index, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
  634. filter->out_gen += 6 ;
  635. /* Figure out the next index. */
  636. input_index += 1.0 / src_ratio ;
  637. rem = fmod_one (input_index) ;
  638. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  639. input_index = rem ;
  640. } ;
  641. psrc->last_position = input_index ;
  642. /* Save current ratio rather then target ratio. */
  643. psrc->last_ratio = src_ratio ;
  644. data->input_frames_used = filter->in_used / filter->channels ;
  645. data->output_frames_gen = filter->out_gen / filter->channels ;
  646. return SRC_ERR_NO_ERROR ;
  647. } /* sinc_hex_vari_process */
  648. static inline void
  649. calc_output_multi (SINC_FILTER *filter, increment_t increment, increment_t start_filter_index, int channels, double scale, float * output)
  650. { double fraction, icoeff ;
  651. /* The following line is 1999 ISO Standard C. If your compiler complains, get a better compiler. */
  652. double *left, *right ;
  653. increment_t filter_index, max_filter_index ;
  654. int data_index, coeff_count, indx, ch ;
  655. left = filter->left_calc ;
  656. right = filter->right_calc ;
  657. /* Convert input parameters into fixed point. */
  658. max_filter_index = int_to_fp (filter->coeff_half_len) ;
  659. /* First apply the left half of the filter. */
  660. filter_index = start_filter_index ;
  661. coeff_count = (max_filter_index - filter_index) / increment ;
  662. filter_index = filter_index + coeff_count * increment ;
  663. data_index = filter->b_current - channels * coeff_count ;
  664. memset (left, 0, sizeof (left [0]) * channels) ;
  665. do
  666. { fraction = fp_to_double (filter_index) ;
  667. indx = fp_to_int (filter_index) ;
  668. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  669. /*
  670. ** Duff's Device.
  671. ** See : http://en.wikipedia.org/wiki/Duff's_device
  672. */
  673. ch = channels ;
  674. do
  675. {
  676. switch (ch % 8)
  677. { default :
  678. ch -- ;
  679. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  680. case 7 :
  681. ch -- ;
  682. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  683. case 6 :
  684. ch -- ;
  685. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  686. case 5 :
  687. ch -- ;
  688. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  689. case 4 :
  690. ch -- ;
  691. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  692. case 3 :
  693. ch -- ;
  694. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  695. case 2 :
  696. ch -- ;
  697. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  698. case 1 :
  699. ch -- ;
  700. left [ch] += icoeff * filter->buffer [data_index + ch] ;
  701. } ;
  702. }
  703. while (ch > 0) ;
  704. filter_index -= increment ;
  705. data_index = data_index + channels ;
  706. }
  707. while (filter_index >= MAKE_INCREMENT_T (0)) ;
  708. /* Now apply the right half of the filter. */
  709. filter_index = increment - start_filter_index ;
  710. coeff_count = (max_filter_index - filter_index) / increment ;
  711. filter_index = filter_index + coeff_count * increment ;
  712. data_index = filter->b_current + channels * (1 + coeff_count) ;
  713. memset (right, 0, sizeof (right [0]) * channels) ;
  714. do
  715. { fraction = fp_to_double (filter_index) ;
  716. indx = fp_to_int (filter_index) ;
  717. icoeff = filter->coeffs [indx] + fraction * (filter->coeffs [indx + 1] - filter->coeffs [indx]) ;
  718. ch = channels ;
  719. do
  720. {
  721. switch (ch % 8)
  722. { default :
  723. ch -- ;
  724. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  725. case 7 :
  726. ch -- ;
  727. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  728. case 6 :
  729. ch -- ;
  730. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  731. case 5 :
  732. ch -- ;
  733. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  734. case 4 :
  735. ch -- ;
  736. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  737. case 3 :
  738. ch -- ;
  739. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  740. case 2 :
  741. ch -- ;
  742. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  743. case 1 :
  744. ch -- ;
  745. right [ch] += icoeff * filter->buffer [data_index + ch] ;
  746. } ;
  747. }
  748. while (ch > 0) ;
  749. filter_index -= increment ;
  750. data_index = data_index - channels ;
  751. }
  752. while (filter_index > MAKE_INCREMENT_T (0)) ;
  753. ch = channels ;
  754. do
  755. {
  756. switch (ch % 8)
  757. { default :
  758. ch -- ;
  759. output [ch] = scale * (left [ch] + right [ch]) ;
  760. case 7 :
  761. ch -- ;
  762. output [ch] = scale * (left [ch] + right [ch]) ;
  763. case 6 :
  764. ch -- ;
  765. output [ch] = scale * (left [ch] + right [ch]) ;
  766. case 5 :
  767. ch -- ;
  768. output [ch] = scale * (left [ch] + right [ch]) ;
  769. case 4 :
  770. ch -- ;
  771. output [ch] = scale * (left [ch] + right [ch]) ;
  772. case 3 :
  773. ch -- ;
  774. output [ch] = scale * (left [ch] + right [ch]) ;
  775. case 2 :
  776. ch -- ;
  777. output [ch] = scale * (left [ch] + right [ch]) ;
  778. case 1 :
  779. ch -- ;
  780. output [ch] = scale * (left [ch] + right [ch]) ;
  781. } ;
  782. }
  783. while (ch > 0) ;
  784. return ;
  785. } /* calc_output_multi */
  786. static int
  787. sinc_multichan_vari_process (SRC_PRIVATE *psrc, SRC_DATA *data)
  788. { SINC_FILTER *filter ;
  789. double input_index, src_ratio, count, float_increment, terminate, rem ;
  790. increment_t increment, start_filter_index ;
  791. int half_filter_chan_len, samples_in_hand ;
  792. if (psrc->private_data == NULL)
  793. return SRC_ERR_NO_PRIVATE ;
  794. filter = (SINC_FILTER*) psrc->private_data ;
  795. /* If there is not a problem, this will be optimised out. */
  796. if (sizeof (filter->buffer [0]) != sizeof (data->data_in [0]))
  797. return SRC_ERR_SIZE_INCOMPATIBILITY ;
  798. filter->in_count = data->input_frames * filter->channels ;
  799. filter->out_count = data->output_frames * filter->channels ;
  800. filter->in_used = filter->out_gen = 0 ;
  801. src_ratio = psrc->last_ratio ;
  802. if (is_bad_src_ratio (src_ratio))
  803. return SRC_ERR_BAD_INTERNAL_STATE ;
  804. /* Check the sample rate ratio wrt the buffer len. */
  805. count = (filter->coeff_half_len + 2.0) / filter->index_inc ;
  806. if (MIN (psrc->last_ratio, data->src_ratio) < 1.0)
  807. count /= MIN (psrc->last_ratio, data->src_ratio) ;
  808. /* Maximum coefficientson either side of center point. */
  809. half_filter_chan_len = filter->channels * (lrint (count) + 1) ;
  810. input_index = psrc->last_position ;
  811. float_increment = filter->index_inc ;
  812. rem = fmod_one (input_index) ;
  813. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  814. input_index = rem ;
  815. terminate = 1.0 / src_ratio + 1e-20 ;
  816. /* Main processing loop. */
  817. while (filter->out_gen < filter->out_count)
  818. {
  819. /* Need to reload buffer? */
  820. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  821. if (samples_in_hand <= half_filter_chan_len)
  822. { if ((psrc->error = prepare_data (filter, data, half_filter_chan_len)) != 0)
  823. return psrc->error ;
  824. samples_in_hand = (filter->b_end - filter->b_current + filter->b_len) % filter->b_len ;
  825. if (samples_in_hand <= half_filter_chan_len)
  826. break ;
  827. } ;
  828. /* This is the termination condition. */
  829. if (filter->b_real_end >= 0)
  830. { if (filter->b_current + input_index + terminate >= filter->b_real_end)
  831. break ;
  832. } ;
  833. if (filter->out_count > 0 && fabs (psrc->last_ratio - data->src_ratio) > 1e-10)
  834. src_ratio = psrc->last_ratio + filter->out_gen * (data->src_ratio - psrc->last_ratio) / filter->out_count ;
  835. float_increment = filter->index_inc * (src_ratio < 1.0 ? src_ratio : 1.0) ;
  836. increment = double_to_fp (float_increment) ;
  837. start_filter_index = double_to_fp (input_index * float_increment) ;
  838. calc_output_multi (filter, increment, start_filter_index, filter->channels, float_increment / filter->index_inc, data->data_out + filter->out_gen) ;
  839. filter->out_gen += psrc->channels ;
  840. /* Figure out the next index. */
  841. input_index += 1.0 / src_ratio ;
  842. rem = fmod_one (input_index) ;
  843. filter->b_current = (filter->b_current + filter->channels * lrint (input_index - rem)) % filter->b_len ;
  844. input_index = rem ;
  845. } ;
  846. psrc->last_position = input_index ;
  847. /* Save current ratio rather then target ratio. */
  848. psrc->last_ratio = src_ratio ;
  849. data->input_frames_used = filter->in_used / filter->channels ;
  850. data->output_frames_gen = filter->out_gen / filter->channels ;
  851. return SRC_ERR_NO_ERROR ;
  852. } /* sinc_multichan_vari_process */
  853. /*----------------------------------------------------------------------------------------
  854. */
  855. static int
  856. prepare_data (SINC_FILTER *filter, SRC_DATA *data, int half_filter_chan_len)
  857. { int len = 0 ;
  858. if (filter->b_real_end >= 0)
  859. return 0 ; /* Should be terminating. Just return. */
  860. if (filter->b_current == 0)
  861. { /* Initial state. Set up zeros at the start of the buffer and
  862. ** then load new data after that.
  863. */
  864. len = filter->b_len - 2 * half_filter_chan_len ;
  865. filter->b_current = filter->b_end = half_filter_chan_len ;
  866. }
  867. else if (filter->b_end + half_filter_chan_len + filter->channels < filter->b_len)
  868. { /* Load data at current end position. */
  869. len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
  870. }
  871. else
  872. { /* Move data at end of buffer back to the start of the buffer. */
  873. len = filter->b_end - filter->b_current ;
  874. memmove (filter->buffer, filter->buffer + filter->b_current - half_filter_chan_len,
  875. (half_filter_chan_len + len) * sizeof (filter->buffer [0])) ;
  876. filter->b_current = half_filter_chan_len ;
  877. filter->b_end = filter->b_current + len ;
  878. /* Now load data at current end of buffer. */
  879. len = MAX (filter->b_len - filter->b_current - half_filter_chan_len, 0) ;
  880. } ;
  881. len = MIN (filter->in_count - filter->in_used, len) ;
  882. len -= (len % filter->channels) ;
  883. if (len < 0 || filter->b_end + len > filter->b_len)
  884. return SRC_ERR_SINC_PREPARE_DATA_BAD_LEN ;
  885. memcpy (filter->buffer + filter->b_end, data->data_in + filter->in_used,
  886. len * sizeof (filter->buffer [0])) ;
  887. filter->b_end += len ;
  888. filter->in_used += len ;
  889. if (filter->in_used == filter->in_count &&
  890. filter->b_end - filter->b_current < 2 * half_filter_chan_len && data->end_of_input)
  891. { /* Handle the case where all data in the current buffer has been
  892. ** consumed and this is the last buffer.
  893. */
  894. if (filter->b_len - filter->b_end < half_filter_chan_len + 5)
  895. { /* If necessary, move data down to the start of the buffer. */
  896. len = filter->b_end - filter->b_current ;
  897. memmove (filter->buffer, filter->buffer + filter->b_current - half_filter_chan_len,
  898. (half_filter_chan_len + len) * sizeof (filter->buffer [0])) ;
  899. filter->b_current = half_filter_chan_len ;
  900. filter->b_end = filter->b_current + len ;
  901. } ;
  902. filter->b_real_end = filter->b_end ;
  903. len = half_filter_chan_len + 5 ;
  904. if (len < 0 || filter->b_end + len > filter->b_len)
  905. len = filter->b_len - filter->b_end ;
  906. memset (filter->buffer + filter->b_end, 0, len * sizeof (filter->buffer [0])) ;
  907. filter->b_end += len ;
  908. } ;
  909. return 0 ;
  910. } /* prepare_data */