fix_this.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:10k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 1999-2009 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 <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <math.h>
  23. #include <sndfile.h>
  24. #include "utils.h"
  25. #define BUFFER_SIZE (1<<14) /* Should be (1<<14) */
  26. #define SAMPLE_RATE (11025)
  27. #ifndef M_PI
  28. #define M_PI 3.14159265358979323846264338
  29. #endif
  30. static void lcomp_test_int (const char *str, const char *filename, int filetype, double margin) ;
  31. static int error_function (double data, double orig, double margin) ;
  32. static int decay_response (int k) ;
  33. static void gen_signal_double (double *data, double scale, int datalen) ;
  34. /* Force the start of these buffers to be double aligned. Sparc-solaris will
  35. ** choke if they are not.
  36. */
  37. typedef union
  38. { double d [BUFFER_SIZE + 1] ;
  39. int  i [BUFFER_SIZE + 1] ;
  40. } BUFFER ;
  41. static BUFFER data_buffer ;
  42. static BUFFER orig_buffer ;
  43. int
  44. main (void)
  45. { const char *filename = "test.au" ;
  46. lcomp_test_int ("au_g721", filename, SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 0.06) ;
  47. return 0 ;
  48. } /* main */
  49. /*============================================================================================
  50. ** Here are the test functions.
  51. */
  52. static void
  53. lcomp_test_int (const char *str, const char *filename, int filetype, double margin)
  54. { SNDFILE *file ;
  55. SF_INFO sfinfo ;
  56. int k, m, *orig, *data, sum_abs ;
  57. long datalen, seekpos ;
  58. double scale ;
  59. printf ("nThis is program is not part of the libsndfile test suite.nn") ;
  60. printf ("    lcomp_test_int      : %s ... ", str) ;
  61. fflush (stdout) ;
  62. datalen = BUFFER_SIZE ;
  63. scale = 1.0 * 0x10000 ;
  64. data = data_buffer.i ;
  65. orig = orig_buffer.i ;
  66. gen_signal_double (orig_buffer.d, 32000.0 * scale, datalen) ;
  67. for (k = 0 ; k < datalen ; k++)
  68. orig [k] = orig_buffer.d [k] ;
  69. sfinfo.samplerate = SAMPLE_RATE ;
  70. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  71. sfinfo.channels = 1 ;
  72. sfinfo.format = filetype ;
  73. if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
  74. { printf ("sf_open_write failed with error : ") ;
  75. puts (sf_strerror (NULL)) ;
  76. exit (1) ;
  77. } ;
  78. if ((k = sf_writef_int (file, orig, datalen)) != datalen)
  79. { printf ("sf_writef_int failed with short write (%ld => %d).n", datalen, k) ;
  80. exit (1) ;
  81. } ;
  82. sf_close (file) ;
  83. memset (data, 0, datalen * sizeof (int)) ;
  84. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  85. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  86. if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
  87. { printf ("sf_open_read failed with error : ") ;
  88. puts (sf_strerror (NULL)) ;
  89. exit (1) ;
  90. } ;
  91. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  92. { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).n", __LINE__, filetype, sfinfo.format) ;
  93. exit (1) ;
  94. } ;
  95. if (sfinfo.frames < datalen)
  96. { printf ("Too few.frames in file. (%ld should be a little more than %ld)n", datalen, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  97. exit (1) ;
  98. } ;
  99. if (sfinfo.frames > (datalen + datalen / 2))
  100. { printf ("Too many.frames in file. (%ld should be a little more than %ld)n", datalen, SF_COUNT_TO_LONG (sfinfo.frames)) ;
  101. exit (1) ;
  102. } ;
  103. if (sfinfo.channels != 1)
  104. { printf ("Incorrect number of channels in file.n") ;
  105. exit (1) ;
  106. } ;
  107. check_log_buffer_or_die (file, __LINE__) ;
  108. if ((k = sf_readf_int (file, data, datalen)) != datalen)
  109. { printf ("Line %d: short read (%d should be %ld).n", __LINE__, k, datalen) ;
  110. exit (1) ;
  111. } ;
  112. sum_abs = 0 ;
  113. for (k = 0 ; k < datalen ; k++)
  114. { if (error_function (data [k] / scale, orig [k] / scale, margin))
  115. { printf ("Line %d: Incorrect sample (#%d : %f should be %f).n", __LINE__, k, data [k] / scale, orig [k] / scale) ;
  116. oct_save_int (orig, data, datalen) ;
  117. exit (1) ;
  118. } ;
  119. sum_abs = abs (sum_abs + abs (data [k])) ;
  120. } ;
  121. if (sum_abs < 1.0)
  122. { printf ("Line %d: Signal is all zeros.n", __LINE__) ;
  123. exit (1) ;
  124. } ;
  125. if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
  126. { printf ("Line %d: Incorrect read length (%ld should be %d).n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames - datalen), k) ;
  127. exit (1) ;
  128. } ;
  129. /* This check is only for block based encoders which must append silence
  130. ** to the end of a file so as to fill out a block.
  131. */
  132. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  133. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  134. if (abs (data [k] / scale) > decay_response (k))
  135. { printf ("Line %d : Incorrect sample B (#%d : abs (%d) should be < %d).n", __LINE__, k, data [k], decay_response (k)) ;
  136. exit (1) ;
  137. } ;
  138. if (! sfinfo.seekable)
  139. { printf ("okn") ;
  140. return ;
  141. } ;
  142. /* Now test sf_seek function. */
  143. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  144. { printf ("Line %d: Seek to start of file failed (%d).n", __LINE__, k) ;
  145. exit (1) ;
  146. } ;
  147. for (m = 0 ; m < 3 ; m++)
  148. { int n  ;
  149. if ((k = sf_readf_int (file, data, 11)) != 11)
  150. { printf ("Line %d: Incorrect read length (11 => %d).n", __LINE__, k) ;
  151. exit (1) ;
  152. } ;
  153. for (k = 0 ; k < 11 ; k++)
  154. if (error_function (data [k] / scale, orig [k + m * 11] / scale, margin))
  155. { printf ("Line %d: Incorrect sample (m = %d) (#%d : %d => %d).n", __LINE__, m, k + m * 11, orig [k + m * 11], data [k]) ;
  156. for (n = 0 ; n < 1 ; n++)
  157. printf ("%d ", data [n]) ;
  158. printf ("n") ;
  159. exit (1) ;
  160. } ;
  161. } ;
  162. seekpos = BUFFER_SIZE / 10 ;
  163. /* Check seek from start of file. */
  164. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  165. { printf ("Seek to start of file + %ld failed (%d).n", seekpos, k) ;
  166. exit (1) ;
  167. } ;
  168. if ((k = sf_readf_int (file, data, 1)) != 1)
  169. { printf ("Line %d: sf_readf_int (file, data, 1) returned %d.n", __LINE__, k) ;
  170. exit (1) ;
  171. } ;
  172. if (error_function ((double) data [0], (double) orig [seekpos], margin))
  173. { printf ("Line %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).n", __LINE__, orig [1], data [0]) ;
  174. exit (1) ;
  175. } ;
  176. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  177. { printf ("Line %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %ld)n", __LINE__, k, seekpos + 1) ;
  178. exit (1) ;
  179. } ;
  180. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  181. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  182. sf_readf_int (file, data, 1) ;
  183. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  184. { printf ("Line %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %ld).n", __LINE__, data [0], orig [seekpos], k, seekpos + 1) ;
  185. exit (1) ;
  186. } ;
  187. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  188. /* Check seek backward from current position. */
  189. k = sf_seek (file, -20, SEEK_CUR) ;
  190. sf_readf_int (file, data, 1) ;
  191. if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
  192. { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %ld).n", data [0], orig [seekpos], k, seekpos) ;
  193. exit (1) ;
  194. } ;
  195. /* Check that read past end of file returns number of items. */
  196. sf_seek (file, (int) sfinfo.frames, SEEK_SET) ;
  197.   if ((k = sf_readf_int (file, data, datalen)) != 0)
  198.   { printf ("Line %d: Return value from sf_readf_int past end of file incorrect (%d).n", __LINE__, k) ;
  199.   exit (1) ;
  200.   } ;
  201. /* Check seek backward from end. */
  202. if ((k = sf_seek (file, 5 - (int) sfinfo.frames, SEEK_END)) != 5)
  203. { printf ("sf_seek (SEEK_END) returned %d instead of %d.n", k, 5) ;
  204. exit (1) ;
  205. } ;
  206. sf_readf_int (file, data, 1) ;
  207. if (error_function (data [0] / scale, orig [5] / scale, margin))
  208. { printf ("Line %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).n", __LINE__, data [0], orig [5]) ;
  209. exit (1) ;
  210. } ;
  211. sf_close (file) ;
  212. printf ("okn") ;
  213. } /* lcomp_test_int */
  214. /*========================================================================================
  215. ** Auxiliary functions
  216. */
  217. #define SIGNAL_MAXVAL 30000.0
  218. #define DECAY_COUNT 800
  219. static int
  220. decay_response (int k)
  221. { if (k < 1)
  222. return (int) (1.2 * SIGNAL_MAXVAL) ;
  223. if (k > DECAY_COUNT)
  224. return 0 ;
  225. return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ;
  226. } /* decay_response */
  227. static void
  228. gen_signal_double (double *data, double scale, int datalen)
  229. { int k, ramplen ;
  230. double amp = 0.0 ;
  231. ramplen = datalen / 18 ;
  232. for (k = 0 ; k < datalen ; k++)
  233. { if (k <= ramplen)
  234. amp = scale * k / ((double) ramplen) ;
  235. else if (k > datalen - ramplen)
  236. amp = scale * (datalen - k) / ((double) ramplen) ;
  237. data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k + 1)) / ((double) SAMPLE_RATE))
  238. + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k + 1)) / ((double) SAMPLE_RATE))) ;
  239. } ;
  240. return ;
  241. } /* gen_signal_double */
  242. static int
  243. error_function (double data, double orig, double margin)
  244. { double error ;
  245. if (fabs (orig) <= 500.0)
  246. error = fabs (fabs (data) - fabs (orig)) / 2000.0 ;
  247. else if (fabs (orig) <= 1000.0)
  248. error = fabs (data - orig) / 3000.0 ;
  249. else
  250. error = fabs (data - orig) / fabs (orig) ;
  251. if (error > margin)
  252. { printf ("nn*******************nError : %fn", error) ;
  253. return 1 ;
  254. } ;
  255. return 0 ;
  256. } /* error_function */