ogg_test.c 10 KB

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