2 ** Copyright (C) 2002,2003 Erik de Castro Lopo <erikd@zip.com.au>
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.
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.
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.
24 #define INTERLEAVE_CHANNELS 6
27 { double buffer
[SF_BUFFER_LEN
/ sizeof (double)] ;
29 sf_count_t channel_len
;
31 sf_count_t (*read_short
) (SF_PRIVATE
*, short *ptr
, sf_count_t len
) ;
32 sf_count_t (*read_int
) (SF_PRIVATE
*, int *ptr
, sf_count_t len
) ;
33 sf_count_t (*read_float
) (SF_PRIVATE
*, float *ptr
, sf_count_t len
) ;
34 sf_count_t (*read_double
) (SF_PRIVATE
*, double *ptr
, sf_count_t len
) ;
40 static sf_count_t
interleave_read_short (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
) ;
41 static sf_count_t
interleave_read_int (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
) ;
42 static sf_count_t
interleave_read_float (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
) ;
43 static sf_count_t
interleave_read_double (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
) ;
45 static sf_count_t
interleave_seek (SF_PRIVATE
*, int mode
, sf_count_t samples_from_start
) ;
51 interleave_init (SF_PRIVATE
*psf
)
52 { INTERLEAVE_DATA
*pdata
;
54 if (psf
->mode
!= SFM_READ
)
55 return SFE_INTERLEAVE_MODE
;
58 { psf_log_printf (psf
, "*** Weird, already have interleave.\n") ;
62 /* Free this in sf_close() function. */
63 if (! (pdata
= malloc (sizeof (INTERLEAVE_DATA
))))
64 return SFE_MALLOC_FAILED
;
66 puts ("interleave_init") ;
68 psf
->interleave
= pdata
;
70 /* Save the existing methods. */
71 pdata
->read_short
= psf
->read_short
;
72 pdata
->read_int
= psf
->read_int
;
73 pdata
->read_float
= psf
->read_float
;
74 pdata
->read_double
= psf
->read_double
;
76 pdata
->channel_len
= psf
->sf
.frames
* psf
->bytewidth
;
78 /* Insert our new methods. */
79 psf
->read_short
= interleave_read_short
;
80 psf
->read_int
= interleave_read_int
;
81 psf
->read_float
= interleave_read_float
;
82 psf
->read_double
= interleave_read_double
;
84 psf
->seek
= interleave_seek
;
87 } /* pcm_interleave_init */
89 /*------------------------------------------------------------------------------
93 interleave_read_short (SF_PRIVATE
*psf
, short *ptr
, sf_count_t len
)
94 { INTERLEAVE_DATA
*pdata
;
95 sf_count_t offset
, templen
;
97 short *inptr
, *outptr
;
99 if (! (pdata
= psf
->interleave
))
102 inptr
= (short*) pdata
->buffer
;
104 for (chan
= 0 ; chan
< psf
->sf
.channels
; chan
++)
105 { outptr
= ptr
+ chan
;
107 offset
= psf
->dataoffset
+ chan
* psf
->bytewidth
* psf
->read_current
;
109 if (psf_fseek (psf
, offset
, SEEK_SET
) != offset
)
110 { psf
->error
= SFE_INTERLEAVE_SEEK
;
114 templen
= len
/ psf
->sf
.channels
;
117 { if (templen
> sizeof (pdata
->buffer
) / sizeof (short))
118 count
= sizeof (pdata
->buffer
) / sizeof (short) ;
120 count
= (int) templen
;
122 if (pdata
->read_short (psf
, inptr
, count
) != count
)
123 { psf
->error
= SFE_INTERLEAVE_READ
;
127 for (k
= 0 ; k
< count
; k
++)
128 { *outptr
= inptr
[k
] ;
129 outptr
+= psf
->sf
.channels
;
137 } /* interleave_read_short */
140 interleave_read_int (SF_PRIVATE
*psf
, int *ptr
, sf_count_t len
)
141 { INTERLEAVE_DATA
*pdata
;
142 sf_count_t offset
, templen
;
144 int *inptr
, *outptr
;
146 if (! (pdata
= psf
->interleave
))
149 inptr
= (int*) pdata
->buffer
;
151 for (chan
= 0 ; chan
< psf
->sf
.channels
; chan
++)
152 { outptr
= ptr
+ chan
;
154 offset
= psf
->dataoffset
+ chan
* psf
->bytewidth
* psf
->read_current
;
156 if (psf_fseek (psf
, offset
, SEEK_SET
) != offset
)
157 { psf
->error
= SFE_INTERLEAVE_SEEK
;
161 templen
= len
/ psf
->sf
.channels
;
164 { if (templen
> sizeof (pdata
->buffer
) / sizeof (int))
165 count
= sizeof (pdata
->buffer
) / sizeof (int) ;
167 count
= (int) templen
;
169 if (pdata
->read_int (psf
, inptr
, count
) != count
)
170 { psf
->error
= SFE_INTERLEAVE_READ
;
174 for (k
= 0 ; k
< count
; k
++)
175 { *outptr
= inptr
[k
] ;
176 outptr
+= psf
->sf
.channels
;
184 } /* interleave_read_int */
187 interleave_read_float (SF_PRIVATE
*psf
, float *ptr
, sf_count_t len
)
188 { INTERLEAVE_DATA
*pdata
;
189 sf_count_t offset
, templen
;
191 float *inptr
, *outptr
;
193 if (! (pdata
= psf
->interleave
))
196 inptr
= (float*) pdata
->buffer
;
198 for (chan
= 0 ; chan
< psf
->sf
.channels
; chan
++)
199 { outptr
= ptr
+ chan
;
201 offset
= psf
->dataoffset
+ pdata
->channel_len
* chan
+ psf
->read_current
* psf
->bytewidth
;
203 /*-printf ("chan : %d read_current : %6lld offset : %6lld\n", chan, psf->read_current, offset) ;-*/
205 if (psf_fseek (psf
, offset
, SEEK_SET
) != offset
)
206 { psf
->error
= SFE_INTERLEAVE_SEEK
;
207 /*-puts ("interleave_seek error") ; exit (1) ;-*/
211 templen
= len
/ psf
->sf
.channels
;
214 { if (templen
> sizeof (pdata
->buffer
) / sizeof (float))
215 count
= sizeof (pdata
->buffer
) / sizeof (float) ;
217 count
= (int) templen
;
219 if (pdata
->read_float (psf
, inptr
, count
) != count
)
220 { psf
->error
= SFE_INTERLEAVE_READ
;
221 /*-puts ("interleave_read error") ; exit (1) ;-*/
225 for (k
= 0 ; k
< count
; k
++)
226 { *outptr
= inptr
[k
] ;
227 outptr
+= psf
->sf
.channels
;
235 } /* interleave_read_float */
238 interleave_read_double (SF_PRIVATE
*psf
, double *ptr
, sf_count_t len
)
239 { INTERLEAVE_DATA
*pdata
;
240 sf_count_t offset
, templen
;
242 double *inptr
, *outptr
;
244 if (! (pdata
= psf
->interleave
))
247 inptr
= (double*) pdata
->buffer
;
249 for (chan
= 0 ; chan
< psf
->sf
.channels
; chan
++)
250 { outptr
= ptr
+ chan
;
252 offset
= psf
->dataoffset
+ chan
* psf
->bytewidth
* psf
->read_current
;
254 if (psf_fseek (psf
, offset
, SEEK_SET
) != offset
)
255 { psf
->error
= SFE_INTERLEAVE_SEEK
;
259 templen
= len
/ psf
->sf
.channels
;
262 { if (templen
> sizeof (pdata
->buffer
) / sizeof (double))
263 count
= sizeof (pdata
->buffer
) / sizeof (double) ;
265 count
= (int) templen
;
267 if (pdata
->read_double (psf
, inptr
, count
) != count
)
268 { psf
->error
= SFE_INTERLEAVE_READ
;
272 for (k
= 0 ; k
< count
; k
++)
273 { *outptr
= inptr
[k
] ;
274 outptr
+= psf
->sf
.channels
;
282 } /* interleave_read_double */
284 /*------------------------------------------------------------------------------
288 interleave_seek (SF_PRIVATE
*psf
, int mode
, sf_count_t samples_from_start
)
289 { psf
= psf
; mode
= mode
;
292 ** Do nothing here. This is a place holder to prevent the default
293 ** seek function from being called.
296 return samples_from_start
;
297 } /* interleave_seek */