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.

152 lines
3.9KB

  1. /*
  2. ** Copyright (c) 2006-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 "config.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <string.h>
  13. #include <samplerate.h>
  14. #include "util.h"
  15. #if HAVE_FFTW3
  16. #include <fftw3.h>
  17. #else
  18. #define fftw_cleanup()
  19. #endif
  20. #define BUFFER_LEN (1 << 16)
  21. static void varispeed_test (int converter, double target_snr) ;
  22. int
  23. main (void)
  24. {
  25. puts ("") ;
  26. printf (" Zero Order Hold interpolator : ") ;
  27. varispeed_test (SRC_ZERO_ORDER_HOLD, 10.0) ;
  28. printf (" Linear interpolator : ") ;
  29. varispeed_test (SRC_LINEAR, 10.0) ;
  30. printf (" Sinc interpolator : ") ;
  31. varispeed_test (SRC_SINC_FASTEST, 115.0) ;
  32. fftw_cleanup () ;
  33. puts ("") ;
  34. return 0 ;
  35. } /* main */
  36. static void
  37. varispeed_test (int converter, double target_snr)
  38. { static float input [BUFFER_LEN], output [BUFFER_LEN] ;
  39. double sine_freq, snr ;
  40. SRC_STATE *src_state ;
  41. SRC_DATA src_data ;
  42. int input_len, error ;
  43. memset (input, 0, sizeof (input)) ;
  44. input_len = ARRAY_LEN (input) / 2 ;
  45. sine_freq = 0.0111 ;
  46. gen_windowed_sines (1, &sine_freq, 1.0, input, input_len) ;
  47. /* Perform sample rate conversion. */
  48. if ((src_state = src_new (converter, 1, &error)) == NULL)
  49. { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
  50. exit (1) ;
  51. } ;
  52. src_data.end_of_input = 1 ;
  53. src_data.data_in = input ;
  54. src_data.input_frames = input_len ;
  55. src_data.src_ratio = 3.0 ;
  56. src_data.data_out = output ;
  57. src_data.output_frames = ARRAY_LEN (output) ;
  58. if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
  59. { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
  60. exit (1) ;
  61. } ;
  62. if ((error = src_process (src_state, &src_data)))
  63. { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
  64. printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
  65. printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
  66. exit (1) ;
  67. } ;
  68. if (src_data.input_frames_used != input_len)
  69. { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
  70. printf ("\tinput_len : %d\n", input_len) ;
  71. printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
  72. exit (1) ;
  73. } ;
  74. /* Copy the last output to the input. */
  75. memcpy (input, output, sizeof (input)) ;
  76. reverse_data (input, src_data.output_frames_gen) ;
  77. if ((error = src_reset (src_state)))
  78. { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
  79. exit (1) ;
  80. } ;
  81. src_data.end_of_input = 1 ;
  82. src_data.data_in = input ;
  83. input_len = src_data.input_frames = src_data.output_frames_gen ;
  84. src_data.data_out = output ;
  85. src_data.output_frames = ARRAY_LEN (output) ;
  86. if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
  87. { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
  88. exit (1) ;
  89. } ;
  90. if ((error = src_process (src_state, &src_data)))
  91. { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
  92. printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
  93. printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
  94. exit (1) ;
  95. } ;
  96. if (src_data.input_frames_used != input_len)
  97. { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
  98. printf ("\tinput_len : %d\n", input_len) ;
  99. printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
  100. exit (1) ;
  101. } ;
  102. src_state = src_delete (src_state) ;
  103. snr = calculate_snr (output, src_data.output_frames_gen, 1) ;
  104. if (target_snr > snr)
  105. { printf ("\n\nLine %d : snr (%3.1f) does not meet target (%3.1f)\n\n", __LINE__, snr, target_snr) ;
  106. save_oct_float ("varispeed.mat", input, src_data.input_frames, output, src_data.output_frames_gen) ;
  107. exit (1) ;
  108. } ;
  109. puts ("ok") ;
  110. return ;
  111. } /* varispeed_test */