wav_float.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2. ** Copyright (C) 1999-2000 Erik de Castro Lopo <erikd@zip.com.au>
  3. **  
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU Lesser General Public License as published by
  6. ** the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU Lesser 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 <unistd.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include "sndfile.h"
  23. #include "config.h"
  24. #include "sfendian.h"
  25. #include "common.h"
  26. #include "wav.h"
  27. /*--------------------------------------------------------------------------------------------
  28. ** Prototypes for private functions.
  29. */
  30. static void x86f2s_array (float *buffer, unsigned int count, short *ptr, int index) ;
  31. static void x86f2i_array (float *buffer, unsigned int count, int *ptr, int index) ;
  32. static void x86f2d_array (float *buffer, unsigned int count, double *ptr, int index, double normfact) ;
  33. static void s2x86f_array (short *ptr, int index, float *buffer, unsigned int count) ;
  34. static void i2x86f_array (int *ptr, int index, float *buffer, unsigned int count) ;
  35. static void d2x86f_array (double *ptr, int index, float *buffer, unsigned int count, double normfact) ;
  36. /*--------------------------------------------------------------------------------------------
  37. ** Exported functions.
  38. */
  39. int wav_read_x86f2s (SF_PRIVATE *psf, short *ptr, int len)
  40. { unsigned int bytecount, readcount, bufferlen, thisread ;
  41. int index = 0, total = 0 ;
  42. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  43. bytecount = len * psf->bytewidth ;
  44. while (bytecount > 0)
  45. { readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  46. thisread = fread (psf->buffer, 1, readcount, psf->file) ;
  47. x86f2s_array ((float*) (psf->buffer), thisread / psf->bytewidth, ptr, index) ;
  48. total += thisread ;
  49. if (thisread < readcount)
  50. break ;
  51. index += thisread / psf->bytewidth ;
  52. bytecount -= thisread ;
  53. } ;
  54. total /= psf->bytewidth ;
  55. if (total < len)
  56. psf->error = SFE_SHORT_READ ;
  57. return total ;
  58. } /* wav_read_x86f2s */
  59. int wav_read_x86f2i (SF_PRIVATE *psf, int *ptr, int len)
  60. { unsigned int bytecount, readcount, bufferlen, thisread ;
  61. int index = 0, total = 0 ;
  62. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  63. bytecount = len * psf->bytewidth ;
  64. while (bytecount > 0)
  65. { readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  66. thisread = fread (psf->buffer, 1, readcount, psf->file) ;
  67. x86f2i_array ((float*) (psf->buffer), thisread / psf->bytewidth, ptr, index) ;
  68. total += thisread ;
  69. if (thisread < readcount)
  70. break ;
  71. index += thisread / psf->bytewidth ;
  72. bytecount -= thisread ;
  73. } ;
  74. total /= psf->bytewidth ;
  75. if (total < len)
  76. psf->error = SFE_SHORT_READ ;
  77. return total ;
  78. } /* wav_read_x86f2i */
  79. int wav_read_x86f2d (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  80. { unsigned int bytecount, readcount, bufferlen, thisread ;
  81. int index = 0, total = 0 ;
  82. double normfact ;
  83. normfact = normalize ? 1.0 : 1.0 ;
  84. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  85. bytecount = len * psf->bytewidth ;
  86. while (bytecount > 0)
  87. { readcount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  88. thisread = fread (psf->buffer, 1, readcount, psf->file) ;
  89. x86f2d_array ((float*) (psf->buffer), thisread / psf->bytewidth, ptr, index, normfact) ;
  90. total += thisread ;
  91. if (thisread < readcount)
  92. break ;
  93. index += thisread / psf->bytewidth ;
  94. bytecount -= thisread ;
  95. } ;
  96. total /= psf->bytewidth ;
  97. if (total < len)
  98. psf->error = SFE_SHORT_READ ;
  99. return total ;
  100. } /* wav_read_x86f2d */
  101. int wav_write_s2x86f (SF_PRIVATE *psf, short *ptr, int len)
  102. { unsigned int bytecount, writecount, bufferlen, thiswrite ;
  103. int index = 0, total = 0 ;
  104. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  105. bytecount = len * psf->bytewidth ;
  106. while (bytecount > 0)
  107. { writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  108. s2x86f_array (ptr, index, (float*) (psf->buffer), writecount / psf->bytewidth) ;
  109. thiswrite = fwrite (psf->buffer, 1, writecount, psf->file) ;
  110. total += thiswrite ;
  111. if (thiswrite < writecount)
  112. break ;
  113. index += thiswrite / psf->bytewidth ;
  114. bytecount -= thiswrite ;
  115. } ;
  116. total /= psf->bytewidth ;
  117. if (total < len)
  118. psf->error = SFE_SHORT_WRITE ;
  119. return total ;
  120. } /* wav_write_s2x86f */
  121. int wav_write_i2x86f (SF_PRIVATE *psf, int *ptr, int len) 
  122. { unsigned int bytecount, writecount, bufferlen, thiswrite ;
  123. int index = 0, total = 0 ;
  124. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  125. bytecount = len * psf->bytewidth ;
  126. while (bytecount > 0)
  127. { writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  128. i2x86f_array (ptr, index, (float*) (psf->buffer), writecount / psf->bytewidth) ;
  129. thiswrite = fwrite (psf->buffer, 1, writecount, psf->file) ;
  130. total += thiswrite ;
  131. if (thiswrite < writecount)
  132. break ;
  133. index += thiswrite / psf->bytewidth ;
  134. bytecount -= thiswrite ;
  135. } ;
  136. total /= psf->bytewidth ;
  137. if (total < len)
  138. psf->error = SFE_SHORT_WRITE ;
  139. return total ;
  140. } /* wav_write_i2x86f */
  141. int wav_write_d2x86f (SF_PRIVATE *psf, double *ptr, int len, int normalize)
  142. { unsigned int bytecount, writecount, bufferlen, thiswrite ;
  143. int index = 0, total = 0 ;
  144. double normfact ;
  145. normfact = (normalize) ? 1.0 : 1.0 ;
  146. bufferlen = (SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth ;
  147. bytecount = len * psf->bytewidth ;
  148. while (bytecount > 0)
  149. { writecount = (bytecount >= bufferlen) ? bufferlen : bytecount ;
  150. d2x86f_array (ptr, index, (float*) (psf->buffer), writecount / psf->bytewidth, normfact) ;
  151. thiswrite = fwrite (psf->buffer, 1, writecount, psf->file) ;
  152. total += thiswrite ;
  153. if (thiswrite < writecount)
  154. break ;
  155. index += thiswrite / psf->bytewidth ;
  156. bytecount -= thiswrite ;
  157. } ;
  158. total /= psf->bytewidth ;
  159. if (total < len)
  160. psf->error = SFE_SHORT_WRITE ;
  161. return total ;
  162. } /* wav_write_d2x86f */
  163. /*==============================================================================================
  164. ** Private functions.
  165. */
  166. static
  167. float read_x86float (unsigned char *cptr)
  168. { int exponent, mantissa ;
  169. float fvalue ;
  170. exponent = ((cptr [3] & 0x7F) << 1) | ((cptr [2] & 0x80) ? 1 : 0);
  171. mantissa = ((cptr [2] & 0x7F) << 16) | (cptr [1] << 8) | (cptr [0]) ;
  172. if (! (exponent || mantissa))
  173. return 0.0 ;
  174. mantissa |= 0x800000 ;
  175. exponent = exponent ? exponent - 127 : 0 ;
  176.                 
  177. fvalue = mantissa ? ((float) mantissa) / ((float) 0x800000) : 0.0 ;
  178.                 
  179. if (cptr [3] & 0x80)
  180. fvalue *= -1 ;
  181.                 
  182. if (exponent > 0)
  183. fvalue *= (1 << exponent) ;
  184. else if (exponent < 0)
  185. fvalue /= (1 << abs (exponent)) ;
  186. return fvalue ;
  187. } /* read_x86float */
  188. static
  189. void write_x86float (double in, unsigned char *out)
  190. { int exponent, mantissa ;
  191. *((int*) out) = 0 ;
  192. if (in == 0.0)
  193. return ;
  194. if (in < 0.0)
  195. { in *= -1.0 ;
  196. out [3] |= 0x80 ;
  197. } ;
  198. in = frexp (in, &exponent) ;
  199. exponent += 126 ;
  200. if (exponent & 0x01)
  201. out [2] |= 0x80 ;
  202. out [3] |= (exponent >> 1) & 0x7F ;
  203. in *= (float) 0x1000000 ;
  204. mantissa = (((int) in) & 0x7FFFFF) ;
  205. out [0]  = mantissa & 0xFF ;
  206. out [1]  = (mantissa >> 8) & 0xFF ;
  207. out [2] |= (mantissa >> 16) & 0x7F ;
  208. return ;
  209. } /* write_x86float */
  210. /*----------------------------------------------------------------------------------------------
  211. */
  212. static
  213. void x86f2s_array (float *buffer, unsigned int count, short *ptr, int index)
  214. { int k ;
  215. for (k = 0 ; k < count ; k++)
  216. { ptr [index] = ((short) read_x86float ((unsigned char *) (buffer +k))) ;
  217. index ++ ;
  218. } ;
  219. } /* x86f2s_array */
  220. static
  221. void x86f2i_array (float *buffer, unsigned int count, int *ptr, int index)
  222. { int k ;
  223. for (k = 0 ; k < count ; k++)
  224. { ptr [index] = ((int) read_x86float ((unsigned char *) (buffer +k))) ;
  225. index ++ ;
  226. } ;
  227. } /* x86f2i_array */
  228. static
  229. void x86f2d_array (float *buffer, unsigned int count, double *ptr, int index, double normfact)
  230. { int k ;
  231. for (k = 0 ; k < count ; k++)
  232. { ptr [index] = ((double) read_x86float ((unsigned char *) (buffer +k))) * normfact  ;
  233. index ++ ;
  234. } ;
  235. } /* x86f2d_array */
  236. static 
  237. void s2x86f_array (short *ptr, int index, float *buffer, unsigned int count)
  238. { int k ;
  239. float value ;
  240. for (k = 0 ; k < count ; k++)
  241. { value = (float) (ptr [index]) ;
  242. write_x86float (value, (unsigned char*) (buffer + k)) ;
  243. index ++ ;
  244. } ;
  245. } /* s2x86f_array */
  246. static 
  247. void i2x86f_array (int *ptr, int index, float *buffer, unsigned int count)
  248. { int k ;
  249. float value ;
  250. for (k = 0 ; k < count ; k++)
  251. { value = (float) (ptr [index]) ;
  252. write_x86float (value, (unsigned char*) (buffer + k)) ;
  253. index ++ ;
  254. } ;
  255. } /* i2x86f_array */
  256. static 
  257. void d2x86f_array (double *ptr, int index, float *buffer, unsigned int count, double normfact)
  258. { int k ;
  259. float value ;
  260. for (k = 0 ; k < count ; k++)
  261. { value = (float) (ptr [index] * normfact) ;
  262. write_x86float (value, (unsigned char*) (buffer + k)) ;
  263. index ++ ;
  264. } ;
  265. } /* d2x86f_array */