time_scale_tests.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * SpanDSP - a series of DSP components for telephony
  3. *
  4. * time_scale_tests.c
  5. *
  6. * Written by Steve Underwood <steveu@coppice.org>
  7. *
  8. * Copyright (C) 2004 Steve Underwood
  9. *
  10. * All rights reserved.
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2, as
  14. * published by the Free Software Foundation.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. */
  25. /*! \page time_scale_tests_page Time scaling tests
  26. \section time_scale_tests_page_sec_1 What does it do?
  27. These tests run a speech file through the time scaling routines.
  28. \section time_scale_tests_page_sec_2 How are the tests run?
  29. These tests process a speech file called pre_time_scale.wav. This file should contain
  30. 8000 sample/second 16 bits/sample linear audio. The tests read this file, change the
  31. time scale of its contents, and write the resulting audio to post_time_scale.wav.
  32. This file also contains 8000 sample/second 16 bits/sample linear audio.
  33. */
  34. #if defined(HAVE_CONFIG_H)
  35. #include "config.h"
  36. #endif
  37. #include <stdlib.h>
  38. #include <stdio.h>
  39. #include <unistd.h>
  40. #include <string.h>
  41. #include <sndfile.h>
  42. #include "spandsp.h"
  43. #include "spandsp/private/time_scale.h"
  44. #define BLOCK_LEN 160
  45. #define IN_FILE_NAME "../test-data/local/short_nb_voice.wav"
  46. #define OUT_FILE_NAME "time_scale_result.wav"
  47. int main(int argc, char *argv[])
  48. {
  49. SNDFILE *inhandle;
  50. SNDFILE *outhandle;
  51. SF_INFO info;
  52. int16_t in[BLOCK_LEN];
  53. int16_t out[5*(BLOCK_LEN + TIME_SCALE_MAX_SAMPLE_RATE/TIME_SCALE_MIN_PITCH)];
  54. int frames;
  55. int new_frames;
  56. int out_frames;
  57. int count;
  58. int max;
  59. int samples_in;
  60. int samples_out;
  61. time_scale_state_t state;
  62. float rate;
  63. float sample_rate;
  64. const char *in_file_name;
  65. bool sweep_rate;
  66. int opt;
  67. rate = 1.8f;
  68. sweep_rate = false;
  69. in_file_name = IN_FILE_NAME;
  70. while ((opt = getopt(argc, argv, "i:r:s")) != -1)
  71. {
  72. switch (opt)
  73. {
  74. case 'i':
  75. in_file_name = optarg;
  76. break;
  77. case 'r':
  78. rate = atof(optarg);
  79. break;
  80. case 's':
  81. sweep_rate = true;
  82. break;
  83. default:
  84. //usage();
  85. exit(2);
  86. break;
  87. }
  88. }
  89. memset(&info, 0, sizeof(info));
  90. if ((inhandle = sf_open(in_file_name, SFM_READ, &info)) == NULL)
  91. {
  92. printf(" Cannot open audio file '%s'\n", in_file_name);
  93. exit(2);
  94. }
  95. if (info.channels != 1)
  96. {
  97. printf(" Unexpected number of channels in audio file '%s'\n", in_file_name);
  98. exit(2);
  99. }
  100. sample_rate = info.samplerate;
  101. memset(&info, 0, sizeof(info));
  102. info.frames = 0;
  103. info.samplerate = sample_rate;
  104. info.channels = 1;
  105. info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
  106. info.sections = 1;
  107. info.seekable = 1;
  108. if ((outhandle = sf_open(OUT_FILE_NAME, SFM_WRITE, &info)) == NULL)
  109. {
  110. fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
  111. exit(2);
  112. }
  113. if ((time_scale_init(&state, (int) sample_rate, rate)) == NULL)
  114. {
  115. fprintf(stderr, " Cannot start the time scaler\n");
  116. exit(2);
  117. }
  118. max = time_scale_max_output_len(&state, BLOCK_LEN);
  119. printf("Rate is %f, longest output block is %d\n", rate, max);
  120. count = 0;
  121. samples_in = 0;
  122. samples_out = 0;
  123. while ((frames = sf_readf_short(inhandle, in, BLOCK_LEN)))
  124. {
  125. samples_in += frames;
  126. new_frames = time_scale(&state, out, in, frames);
  127. if (new_frames > max)
  128. {
  129. printf("Generated signal has more than the expected maximum samples - %d vs %d\n", new_frames, max);
  130. printf("Tests failed\n");
  131. exit(2);
  132. }
  133. samples_out += new_frames;
  134. out_frames = sf_writef_short(outhandle, out, new_frames);
  135. if (out_frames != new_frames)
  136. {
  137. fprintf(stderr, " Error writing audio file\n");
  138. exit(2);
  139. }
  140. if (sweep_rate && ++count > 100)
  141. {
  142. if (rate > 0.5f)
  143. {
  144. rate -= 0.1f;
  145. if (rate >= 0.99f && rate <= 1.01f)
  146. rate -= 0.1f;
  147. time_scale_init(&state, SAMPLE_RATE, rate);
  148. max = time_scale_max_output_len(&state, BLOCK_LEN);
  149. printf("Rate is %f, longest output block is %d\n", rate, max);
  150. }
  151. count = 0;
  152. }
  153. }
  154. new_frames = time_scale_flush(&state, out);
  155. if (new_frames > max)
  156. {
  157. printf("Generated signal has more than the expected maximum samples - %d vs %d\n", new_frames, max);
  158. printf("Tests failed\n");
  159. exit(2);
  160. }
  161. samples_out += new_frames;
  162. out_frames = sf_writef_short(outhandle, out, new_frames);
  163. if (out_frames != new_frames)
  164. {
  165. fprintf(stderr, " Error writing audio file\n");
  166. exit(2);
  167. }
  168. time_scale_release(&state);
  169. if ((int) (rate*samples_in) < samples_out - 1 || (int) (rate*samples_in) > samples_out + 1)
  170. {
  171. printf("%d samples became %d samples\n", (int) (rate*samples_in), samples_out);
  172. printf("Tests failed\n");
  173. exit(2);
  174. }
  175. if (sf_close(inhandle))
  176. {
  177. printf(" Cannot close audio file '%s'\n", in_file_name);
  178. exit(2);
  179. }
  180. if (sf_close(outhandle))
  181. {
  182. printf(" Cannot close audio file '%s'\n", OUT_FILE_NAME);
  183. exit(2);
  184. }
  185. return 0;
  186. }
  187. /*- End of function --------------------------------------------------------*/
  188. /*- End of file ------------------------------------------------------------*/