mpeg_test.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. ** Copyright (C) 2007-2019 Erik de Castro Lopo <[email protected]>
  3. ** Copyright (C) 2019 John ffitch <[email protected]>
  4. **
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation; either version 2 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. #include "sfconfig.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #if HAVE_UNISTD_H
  24. #include <unistd.h>
  25. #else
  26. #include "sf_unistd.h"
  27. #endif
  28. #include <math.h>
  29. #include <sndfile.h>
  30. #include "utils.h"
  31. #define SAMPLE_RATE 44100
  32. #define DATA_LENGTH (SAMPLE_RATE / 8)
  33. typedef union
  34. { double d [DATA_LENGTH] ;
  35. float f [DATA_LENGTH] ;
  36. int i [DATA_LENGTH] ;
  37. short s [DATA_LENGTH] ;
  38. } BUFFER ;
  39. static BUFFER data_out ;
  40. static BUFFER data_in ;
  41. static void
  42. mpeg_short_test (void)
  43. { const char * filename = "mpeg_short.mp3" ;
  44. SNDFILE * file ;
  45. SF_INFO sfinfo ;
  46. short seek_data [10] ;
  47. unsigned k ;
  48. print_test_name ("mpeg_short_test", filename) ;
  49. /* Generate float data. */
  50. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7F00) ;
  51. /* Convert to shorteger. */
  52. for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
  53. data_out.s [k] = lrintf (data_out.f [k]) ;
  54. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  55. /* Set up output file type. */
  56. sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
  57. sfinfo.channels = 1 ;
  58. sfinfo.samplerate = SAMPLE_RATE ;
  59. /* Write the output file. */
  60. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  61. test_write_short_or_die (file, 0, data_out.s, ARRAY_LEN (data_out.s), __LINE__) ;
  62. sf_close (file) ;
  63. /* Read the file in again. */
  64. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  65. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  66. test_read_short_or_die (file, 0, data_in.s, ARRAY_LEN (data_in.s), __LINE__) ;
  67. sf_close (file) ;
  68. puts ("ok") ;
  69. /* Test seeking. */
  70. print_test_name ("mpeg_seek_test", filename) ;
  71. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  72. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  73. test_read_short_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  74. compare_short_or_die (seek_data, data_in.s + 10, ARRAY_LEN (seek_data), __LINE__) ;
  75. /* Test seek to end of file. */
  76. test_seek_or_die (file, 0, SEEK_END, sfinfo.frames, sfinfo.channels, __LINE__) ;
  77. sf_close (file) ;
  78. puts ("ok") ;
  79. unlink (filename) ;
  80. } /* mpeg_short_test */
  81. static void
  82. mpeg_int_test (void)
  83. { const char * filename = "mpeg_int.mp3" ;
  84. SNDFILE * file ;
  85. SF_INFO sfinfo ;
  86. int seek_data [10] ;
  87. unsigned k ;
  88. print_test_name ("mpeg_int_test", filename) ;
  89. /* Generate float data. */
  90. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7FFF0000) ;
  91. /* Convert to integer. */
  92. for (k = 0 ; k < ARRAY_LEN (data_out.i) ; k++)
  93. data_out.i [k] = lrintf (data_out.f [k]) ;
  94. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  95. /* Set up output file type. */
  96. sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
  97. sfinfo.channels = 1 ;
  98. sfinfo.samplerate = SAMPLE_RATE ;
  99. /* Write the output file. */
  100. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  101. test_write_int_or_die (file, 0, data_out.i, ARRAY_LEN (data_out.i), __LINE__) ;
  102. sf_close (file) ;
  103. /* Read the file in again. */
  104. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  105. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  106. test_read_int_or_die (file, 0, data_in.i, ARRAY_LEN (data_in.i), __LINE__) ;
  107. sf_close (file) ;
  108. puts ("ok") ;
  109. /* Test seeking. */
  110. print_test_name ("mpeg_seek_test", filename) ;
  111. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  112. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  113. test_read_int_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  114. compare_int_or_die (seek_data, data_in.i + 10, ARRAY_LEN (seek_data), __LINE__) ;
  115. sf_close (file) ;
  116. puts ("ok") ;
  117. unlink (filename) ;
  118. } /* mpeg_int_test */
  119. static void
  120. mpeg_float_test (void)
  121. { const char * filename = "mpeg_float.mp3" ;
  122. SNDFILE * file ;
  123. SF_INFO sfinfo ;
  124. float seek_data [10] ;
  125. print_test_name ("mpeg_float_test", filename) ;
  126. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 0.95) ;
  127. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  128. /* Set up output file type. */
  129. sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
  130. sfinfo.channels = 1 ;
  131. sfinfo.samplerate = SAMPLE_RATE ;
  132. /* Write the output file. */
  133. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  134. test_write_float_or_die (file, 0, data_out.f, ARRAY_LEN (data_out.f), __LINE__) ;
  135. sf_close (file) ;
  136. /* Read the file in again. */
  137. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  138. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  139. test_read_float_or_die (file, 0, data_in.f, ARRAY_LEN (data_in.f), __LINE__) ;
  140. sf_close (file) ;
  141. puts ("ok") ;
  142. /* Test seeking. */
  143. print_test_name ("mpeg_seek_test", filename) ;
  144. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  145. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  146. test_read_float_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  147. compare_float_or_die (seek_data, data_in.f + 10, ARRAY_LEN (seek_data), __LINE__) ;
  148. sf_close (file) ;
  149. puts ("ok") ;
  150. unlink (filename) ;
  151. } /* mpeg_float_test */
  152. static void
  153. mpeg_double_test (void)
  154. { const char * filename = "mpeg_double.mp3" ;
  155. SNDFILE * file ;
  156. SF_INFO sfinfo ;
  157. double seek_data [10] ;
  158. print_test_name ("mpeg_double_test", filename) ;
  159. gen_windowed_sine_double (data_out.d, ARRAY_LEN (data_out.d), 0.95) ;
  160. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  161. /* Set up output file type. */
  162. sfinfo.format = SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III ;
  163. sfinfo.channels = 1 ;
  164. sfinfo.samplerate = SAMPLE_RATE ;
  165. /* Write the output file. */
  166. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  167. test_write_double_or_die (file, 0, data_out.d, ARRAY_LEN (data_out.d), __LINE__) ;
  168. sf_close (file) ;
  169. /* Read the file in again. */
  170. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  171. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  172. test_read_double_or_die (file, 0, data_in.d, ARRAY_LEN (data_in.d), __LINE__) ;
  173. sf_close (file) ;
  174. puts ("ok") ;
  175. /* Test seeking. */
  176. print_test_name ("mpeg_seek_test", filename) ;
  177. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  178. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  179. test_read_double_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  180. compare_double_or_die (seek_data, data_in.d + 10, ARRAY_LEN (seek_data), __LINE__) ;
  181. sf_close (file) ;
  182. puts ("ok") ;
  183. unlink (filename) ;
  184. } /* mpeg_double_test */
  185. static void
  186. mpeg_stereo_seek_test (const char * filename, int format)
  187. { static float data [SAMPLE_RATE] ;
  188. static float stereo_out [SAMPLE_RATE * 2] ;
  189. SNDFILE * file ;
  190. SF_INFO sfinfo ;
  191. sf_count_t pos ;
  192. unsigned k ;
  193. print_test_name (__func__, filename) ;
  194. gen_windowed_sine_float (data, ARRAY_LEN (data), 0.95) ;
  195. for (k = 0 ; k < ARRAY_LEN (data) ; k++)
  196. { stereo_out [2 * k] = data [k] ;
  197. stereo_out [2 * k + 1] = data [ARRAY_LEN (data) - k - 1] ;
  198. } ;
  199. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  200. /* Set up output file type. */
  201. sfinfo.format = format ;
  202. sfinfo.channels = 2 ;
  203. sfinfo.samplerate = SAMPLE_RATE ;
  204. /* Write the output file. */
  205. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  206. test_write_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
  207. sf_close (file) ;
  208. /* Open file in again for reading. */
  209. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  210. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  211. /* Read in the whole file. */
  212. test_read_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
  213. /* Now hammer seeking code. */
  214. test_seek_or_die (file, 234, SEEK_SET, 234, sfinfo.channels, __LINE__) ;
  215. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  216. compare_float_or_die (data, stereo_out + (234 * sfinfo.channels), 10, __LINE__) ;
  217. test_seek_or_die (file, 442, SEEK_SET, 442, sfinfo.channels, __LINE__) ;
  218. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  219. compare_float_or_die (data, stereo_out + (442 * sfinfo.channels), 10, __LINE__) ;
  220. test_seek_or_die (file, 12, SEEK_CUR, 442 + 10 + 12, sfinfo.channels, __LINE__) ;
  221. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  222. compare_float_or_die (data, stereo_out + ((442 + 10 + 12) * sfinfo.channels), 10, __LINE__) ;
  223. test_seek_or_die (file, 12, SEEK_CUR, 442 + 20 + 24, sfinfo.channels, __LINE__) ;
  224. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  225. compare_float_or_die (data, stereo_out + ((442 + 20 + 24) * sfinfo.channels), 10, __LINE__) ;
  226. pos = 500 - sfinfo.frames ;
  227. test_seek_or_die (file, pos, SEEK_END, 500, sfinfo.channels, __LINE__) ;
  228. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  229. compare_float_or_die (data, stereo_out + (500 * sfinfo.channels), 10, __LINE__) ;
  230. pos = 10 - sfinfo.frames ;
  231. test_seek_or_die (file, pos, SEEK_END, 10, sfinfo.channels, __LINE__) ;
  232. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  233. compare_float_or_die (data, stereo_out + (10 * sfinfo.channels), 10, __LINE__) ;
  234. sf_close (file) ;
  235. puts ("ok") ;
  236. unlink (filename) ;
  237. } /* mpeg_stereo_seek_test */
  238. int
  239. main (void)
  240. {
  241. if (HAVE_MPEG)
  242. { mpeg_short_test () ;
  243. mpeg_int_test () ;
  244. mpeg_float_test () ;
  245. mpeg_double_test () ;
  246. mpeg_stereo_seek_test ("mpeg_seek.mp3", SF_FORMAT_MPEG | SF_FORMAT_MPEG_LAYER_III) ;
  247. }
  248. else
  249. puts (" No MPEG tests because mpg123/lame support was not compiled in.") ;
  250. return 0 ;
  251. } /* main */