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

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 2002-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 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 "sfendian.h"
  19. #include <stdlib.h>
  20. #include "sndfile.h"
  21. #include "common.h"
  22. #define INTERLEAVE_CHANNELS 6
  23. typedef struct
  24. { double buffer [SF_BUFFER_LEN / sizeof (double)] ;
  25. sf_count_t channel_len ;
  26. sf_count_t (*read_short) (SF_PRIVATE*, short *ptr, sf_count_t len) ;
  27. sf_count_t (*read_int) (SF_PRIVATE*, int *ptr, sf_count_t len) ;
  28. sf_count_t (*read_float) (SF_PRIVATE*, float *ptr, sf_count_t len) ;
  29. sf_count_t (*read_double) (SF_PRIVATE*, double *ptr, sf_count_t len) ;
  30. } INTERLEAVE_DATA ;
  31. static sf_count_t interleave_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
  32. static sf_count_t interleave_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
  33. static sf_count_t interleave_read_float (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
  34. static sf_count_t interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
  35. static sf_count_t interleave_seek (SF_PRIVATE*, int mode, sf_count_t samples_from_start) ;
  36. int
  37. interleave_init (SF_PRIVATE *psf)
  38. { INTERLEAVE_DATA *pdata ;
  39. if (psf->file.mode != SFM_READ)
  40. return SFE_INTERLEAVE_MODE ;
  41. if (psf->interleave)
  42. { psf_log_printf (psf, "*** Weird, already have interleave.n") ;
  43. return 666 ;
  44. } ;
  45. /* Free this in sf_close() function. */
  46. if (! (pdata = malloc (sizeof (INTERLEAVE_DATA))))
  47. return SFE_MALLOC_FAILED ;
  48. puts ("interleave_init") ;
  49. psf->interleave = pdata ;
  50. /* Save the existing methods. */
  51. pdata->read_short = psf->read_short ;
  52. pdata->read_int = psf->read_int ;
  53. pdata->read_float = psf->read_float ;
  54. pdata->read_double = psf->read_double ;
  55. pdata->channel_len = psf->sf.frames * psf->bytewidth ;
  56. /* Insert our new methods. */
  57. psf->read_short = interleave_read_short ;
  58. psf->read_int = interleave_read_int ;
  59. psf->read_float = interleave_read_float ;
  60. psf->read_double = interleave_read_double ;
  61. psf->seek = interleave_seek ;
  62. return 0 ;
  63. } /* pcm_interleave_init */
  64. /*------------------------------------------------------------------------------
  65. */
  66. static sf_count_t
  67. interleave_read_short (SF_PRIVATE *psf, short *ptr, sf_count_t len)
  68. { INTERLEAVE_DATA *pdata ;
  69. sf_count_t offset, templen ;
  70. int chan, count, k ;
  71. short *inptr, *outptr ;
  72. if (! (pdata = psf->interleave))
  73. return 0 ;
  74. inptr = (short*) pdata->buffer ;
  75. for (chan = 0 ; chan < psf->sf.channels ; chan++)
  76. { outptr = ptr + chan ;
  77. offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
  78. if (psf_fseek (psf, offset, SEEK_SET) != offset)
  79. { psf->error = SFE_INTERLEAVE_SEEK ;
  80. return 0 ;
  81. } ;
  82. templen = len / psf->sf.channels ;
  83. while (templen > 0)
  84. { if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short))
  85. count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (short) ;
  86. else
  87. count = (int) templen ;
  88. if (pdata->read_short (psf, inptr, count) != count)
  89. { psf->error = SFE_INTERLEAVE_READ ;
  90. return 0 ;
  91. } ;
  92. for (k = 0 ; k < count ; k++)
  93. { *outptr = inptr [k] ;
  94. outptr += psf->sf.channels ;
  95. } ;
  96. templen -= count ;
  97. } ;
  98. } ;
  99. return len ;
  100. } /* interleave_read_short */
  101. static sf_count_t
  102. interleave_read_int (SF_PRIVATE *psf, int *ptr, sf_count_t len)
  103. { INTERLEAVE_DATA *pdata ;
  104. sf_count_t offset, templen ;
  105. int chan, count, k ;
  106. int *inptr, *outptr ;
  107. if (! (pdata = psf->interleave))
  108. return 0 ;
  109. inptr = (int*) pdata->buffer ;
  110. for (chan = 0 ; chan < psf->sf.channels ; chan++)
  111. { outptr = ptr + chan ;
  112. offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
  113. if (psf_fseek (psf, offset, SEEK_SET) != offset)
  114. { psf->error = SFE_INTERLEAVE_SEEK ;
  115. return 0 ;
  116. } ;
  117. templen = len / psf->sf.channels ;
  118. while (templen > 0)
  119. { if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int))
  120. count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (int) ;
  121. else
  122. count = (int) templen ;
  123. if (pdata->read_int (psf, inptr, count) != count)
  124. { psf->error = SFE_INTERLEAVE_READ ;
  125. return 0 ;
  126. } ;
  127. for (k = 0 ; k < count ; k++)
  128. { *outptr = inptr [k] ;
  129. outptr += psf->sf.channels ;
  130. } ;
  131. templen -= count ;
  132. } ;
  133. } ;
  134. return len ;
  135. } /* interleave_read_int */
  136. static sf_count_t
  137. interleave_read_float (SF_PRIVATE *psf, float *ptr, sf_count_t len)
  138. { INTERLEAVE_DATA *pdata ;
  139. sf_count_t offset, templen ;
  140. int chan, count, k ;
  141. float *inptr, *outptr ;
  142. if (! (pdata = psf->interleave))
  143. return 0 ;
  144. inptr = (float*) pdata->buffer ;
  145. for (chan = 0 ; chan < psf->sf.channels ; chan++)
  146. { outptr = ptr + chan ;
  147. offset = psf->dataoffset + pdata->channel_len * chan + psf->read_current * psf->bytewidth ;
  148. /*-printf ("chan : %d     read_current : %6lld    offset : %6lldn", chan, psf->read_current, offset) ;-*/
  149. if (psf_fseek (psf, offset, SEEK_SET) != offset)
  150. { psf->error = SFE_INTERLEAVE_SEEK ;
  151. /*-puts ("interleave_seek error") ; exit (1) ;-*/
  152. return 0 ;
  153. } ;
  154. templen = len / psf->sf.channels ;
  155. while (templen > 0)
  156. { if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float))
  157. count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (float) ;
  158. else
  159. count = (int) templen ;
  160. if (pdata->read_float (psf, inptr, count) != count)
  161. { psf->error = SFE_INTERLEAVE_READ ;
  162. /*-puts ("interleave_read error") ; exit (1) ;-*/
  163. return 0 ;
  164. } ;
  165. for (k = 0 ; k < count ; k++)
  166. { *outptr = inptr [k] ;
  167. outptr += psf->sf.channels ;
  168. } ;
  169. templen -= count ;
  170. } ;
  171. } ;
  172. return len ;
  173. } /* interleave_read_float */
  174. static sf_count_t
  175. interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len)
  176. { INTERLEAVE_DATA *pdata ;
  177. sf_count_t offset, templen ;
  178. int chan, count, k ;
  179. double *inptr, *outptr ;
  180. if (! (pdata = psf->interleave))
  181. return 0 ;
  182. inptr = (double*) pdata->buffer ;
  183. for (chan = 0 ; chan < psf->sf.channels ; chan++)
  184. { outptr = ptr + chan ;
  185. offset = psf->dataoffset + chan * psf->bytewidth * psf->read_current ;
  186. if (psf_fseek (psf, offset, SEEK_SET) != offset)
  187. { psf->error = SFE_INTERLEAVE_SEEK ;
  188. return 0 ;
  189. } ;
  190. templen = len / psf->sf.channels ;
  191. while (templen > 0)
  192. { if (templen > SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double))
  193. count = SIGNED_SIZEOF (pdata->buffer) / SIGNED_SIZEOF (double) ;
  194. else
  195. count = (int) templen ;
  196. if (pdata->read_double (psf, inptr, count) != count)
  197. { psf->error = SFE_INTERLEAVE_READ ;
  198. return 0 ;
  199. } ;
  200. for (k = 0 ; k < count ; k++)
  201. { *outptr = inptr [k] ;
  202. outptr += psf->sf.channels ;
  203. } ;
  204. templen -= count ;
  205. } ;
  206. } ;
  207. return len ;
  208. } /* interleave_read_double */
  209. /*------------------------------------------------------------------------------
  210. */
  211. static sf_count_t
  212. interleave_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
  213. { psf = psf ; mode = mode ;
  214. /*
  215. ** Do nothing here. This is a place holder to prevent the default
  216. ** seek function from being called.
  217. */
  218. return samples_from_start ;
  219. } /* interleave_seek */