ogg_test.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. ** Copyright (C) 2007-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
  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. #include <unistd.h>
  23. #include <math.h>
  24. #include <sndfile.h>
  25. #include "utils.h"
  26. #define SAMPLE_RATE 44100
  27. #define DATA_LENGTH (SAMPLE_RATE / 8)
  28. typedef union
  29. { double d [DATA_LENGTH] ;
  30. float f [DATA_LENGTH] ;
  31. int i [DATA_LENGTH] ;
  32. short s [DATA_LENGTH] ;
  33. } BUFFER ;
  34. static BUFFER data_out ;
  35. static BUFFER data_in ;
  36. static void
  37. ogg_short_test (void)
  38. { const char * filename = "vorbis_short.oga" ;
  39. SNDFILE * file ;
  40. SF_INFO sfinfo ;
  41. short seek_data [10] ;
  42. unsigned k ;
  43. print_test_name ("ogg_short_test", filename) ;
  44. /* Generate float data. */
  45. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7F00) ;
  46. /* Convert to shorteger. */
  47. for (k = 0 ; k < ARRAY_LEN (data_out.s) ; k++)
  48. data_out.s [k] = lrintf (data_out.f [k]) ;
  49. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  50. /* Set up output file type. */
  51. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  52. sfinfo.channels = 1 ;
  53. sfinfo.samplerate = SAMPLE_RATE ;
  54. /* Write the output file. */
  55. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  56. test_write_short_or_die (file, 0, data_out.s, ARRAY_LEN (data_out.s), __LINE__) ;
  57. sf_close (file) ;
  58. /* Read the file in again. */
  59. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  60. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  61. test_read_short_or_die (file, 0, data_in.s, ARRAY_LEN (data_in.s), __LINE__) ;
  62. sf_close (file) ;
  63. puts ("ok") ;
  64. /* Test seeking. */
  65. print_test_name ("ogg_seek_test", filename) ;
  66. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  67. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  68. test_read_short_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  69. compare_short_or_die (seek_data, data_in.s + 10, ARRAY_LEN (seek_data), __LINE__) ;
  70. /* Test seek to end of file. */
  71. test_seek_or_die (file, 0, SEEK_END, sfinfo.frames, sfinfo.channels, __LINE__) ;
  72. sf_close (file) ;
  73. puts ("ok") ;
  74. unlink (filename) ;
  75. } /* ogg_short_test */
  76. static void
  77. ogg_int_test (void)
  78. { const char * filename = "vorbis_int.oga" ;
  79. SNDFILE * file ;
  80. SF_INFO sfinfo ;
  81. int seek_data [10] ;
  82. unsigned k ;
  83. print_test_name ("ogg_int_test", filename) ;
  84. /* Generate float data. */
  85. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7FFF0000) ;
  86. /* Convert to integer. */
  87. for (k = 0 ; k < ARRAY_LEN (data_out.i) ; k++)
  88. data_out.i [k] = lrintf (data_out.f [k]) ;
  89. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  90. /* Set up output file type. */
  91. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  92. sfinfo.channels = 1 ;
  93. sfinfo.samplerate = SAMPLE_RATE ;
  94. /* Write the output file. */
  95. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  96. test_write_int_or_die (file, 0, data_out.i, ARRAY_LEN (data_out.i), __LINE__) ;
  97. sf_close (file) ;
  98. /* Read the file in again. */
  99. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  100. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  101. test_read_int_or_die (file, 0, data_in.i, ARRAY_LEN (data_in.i), __LINE__) ;
  102. sf_close (file) ;
  103. puts ("ok") ;
  104. /* Test seeking. */
  105. print_test_name ("ogg_seek_test", filename) ;
  106. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  107. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  108. test_read_int_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  109. compare_int_or_die (seek_data, data_in.i + 10, ARRAY_LEN (seek_data), __LINE__) ;
  110. sf_close (file) ;
  111. puts ("ok") ;
  112. unlink (filename) ;
  113. } /* ogg_int_test */
  114. static void
  115. ogg_float_test (void)
  116. { const char * filename = "vorbis_float.oga" ;
  117. SNDFILE * file ;
  118. SF_INFO sfinfo ;
  119. float seek_data [10] ;
  120. print_test_name ("ogg_float_test", filename) ;
  121. gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 0.95) ;
  122. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  123. /* Set up output file type. */
  124. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  125. sfinfo.channels = 1 ;
  126. sfinfo.samplerate = SAMPLE_RATE ;
  127. /* Write the output file. */
  128. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  129. test_write_float_or_die (file, 0, data_out.f, ARRAY_LEN (data_out.f), __LINE__) ;
  130. sf_close (file) ;
  131. /* Read the file in again. */
  132. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  133. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  134. test_read_float_or_die (file, 0, data_in.f, ARRAY_LEN (data_in.f), __LINE__) ;
  135. sf_close (file) ;
  136. puts ("ok") ;
  137. /* Test seeking. */
  138. print_test_name ("ogg_seek_test", filename) ;
  139. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  140. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  141. test_read_float_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  142. compare_float_or_die (seek_data, data_in.f + 10, ARRAY_LEN (seek_data), __LINE__) ;
  143. sf_close (file) ;
  144. puts ("ok") ;
  145. unlink (filename) ;
  146. } /* ogg_float_test */
  147. static void
  148. ogg_double_test (void)
  149. { const char * filename = "vorbis_double.oga" ;
  150. SNDFILE * file ;
  151. SF_INFO sfinfo ;
  152. double seek_data [10] ;
  153. print_test_name ("ogg_double_test", filename) ;
  154. gen_windowed_sine_double (data_out.d, ARRAY_LEN (data_out.d), 0.95) ;
  155. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  156. /* Set up output file type. */
  157. sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ;
  158. sfinfo.channels = 1 ;
  159. sfinfo.samplerate = SAMPLE_RATE ;
  160. /* Write the output file. */
  161. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  162. test_write_double_or_die (file, 0, data_out.d, ARRAY_LEN (data_out.d), __LINE__) ;
  163. sf_close (file) ;
  164. /* Read the file in again. */
  165. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  166. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  167. test_read_double_or_die (file, 0, data_in.d, ARRAY_LEN (data_in.d), __LINE__) ;
  168. sf_close (file) ;
  169. puts ("ok") ;
  170. /* Test seeking. */
  171. print_test_name ("ogg_seek_test", filename) ;
  172. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  173. test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ;
  174. test_read_double_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ;
  175. compare_double_or_die (seek_data, data_in.d + 10, ARRAY_LEN (seek_data), __LINE__) ;
  176. sf_close (file) ;
  177. puts ("ok") ;
  178. unlink (filename) ;
  179. } /* ogg_double_test */
  180. static void
  181. ogg_stereo_seek_test (const char * filename, int format)
  182. { static float data [SAMPLE_RATE] ;
  183. static float stereo_out [SAMPLE_RATE * 2] ;
  184. SNDFILE * file ;
  185. SF_INFO sfinfo ;
  186. sf_count_t pos ;
  187. unsigned k ;
  188. print_test_name (__func__, filename) ;
  189. gen_windowed_sine_float (data, ARRAY_LEN (data), 0.95) ;
  190. for (k = 0 ; k < ARRAY_LEN (data) ; k++)
  191. { stereo_out [2 * k] = data [k] ;
  192. stereo_out [2 * k + 1] = data [ARRAY_LEN (data) - k - 1] ;
  193. } ;
  194. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  195. /* Set up output file type. */
  196. sfinfo.format = format ;
  197. sfinfo.channels = 2 ;
  198. sfinfo.samplerate = SAMPLE_RATE ;
  199. /* Write the output file. */
  200. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  201. test_write_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
  202. sf_close (file) ;
  203. /* Open file in again for reading. */
  204. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  205. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  206. /* Read in the whole file. */
  207. test_read_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ;
  208. /* Now hammer seeking code. */
  209. test_seek_or_die (file, 234, SEEK_SET, 234, sfinfo.channels, __LINE__) ;
  210. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  211. compare_float_or_die (data, stereo_out + (234 * sfinfo.channels), 10, __LINE__) ;
  212. test_seek_or_die (file, 442, SEEK_SET, 442, sfinfo.channels, __LINE__) ;
  213. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  214. compare_float_or_die (data, stereo_out + (442 * sfinfo.channels), 10, __LINE__) ;
  215. test_seek_or_die (file, 12, SEEK_CUR, 442 + 10 + 12, sfinfo.channels, __LINE__) ;
  216. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  217. compare_float_or_die (data, stereo_out + ((442 + 10 + 12) * sfinfo.channels), 10, __LINE__) ;
  218. test_seek_or_die (file, 12, SEEK_CUR, 442 + 20 + 24, sfinfo.channels, __LINE__) ;
  219. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  220. compare_float_or_die (data, stereo_out + ((442 + 20 + 24) * sfinfo.channels), 10, __LINE__) ;
  221. pos = 500 - sfinfo.frames ;
  222. test_seek_or_die (file, pos, SEEK_END, 500, sfinfo.channels, __LINE__) ;
  223. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  224. compare_float_or_die (data, stereo_out + (500 * sfinfo.channels), 10, __LINE__) ;
  225. pos = 10 - sfinfo.frames ;
  226. test_seek_or_die (file, pos, SEEK_END, 10, sfinfo.channels, __LINE__) ;
  227. test_readf_float_or_die (file, 0, data, 10, __LINE__) ;
  228. compare_float_or_die (data, stereo_out + (10 * sfinfo.channels), 10, __LINE__) ;
  229. sf_close (file) ;
  230. puts ("ok") ;
  231. unlink (filename) ;
  232. } /* ogg_stereo_seek_test */
  233. int
  234. main (void)
  235. {
  236. if (HAVE_EXTERNAL_LIBS)
  237. { ogg_short_test () ;
  238. ogg_int_test () ;
  239. ogg_float_test () ;
  240. ogg_double_test () ;
  241. /*-ogg_stereo_seek_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;-*/
  242. ogg_stereo_seek_test ("vorbis_seek.ogg", SF_FORMAT_OGG | SF_FORMAT_VORBIS) ;
  243. }
  244. else
  245. puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
  246. return 0 ;
  247. } /* main */