Chris@0
|
1 /*
|
Chris@0
|
2 ** Copyright (C) 2004-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
Chris@0
|
3 ** Copyright (C) 2004 Tobias Gehrig <tgehrig@ira.uka.de>
|
Chris@0
|
4 **
|
Chris@0
|
5 ** This program is free software ; you can redistribute it and/or modify
|
Chris@0
|
6 ** it under the terms of the GNU Lesser General Public License as published by
|
Chris@0
|
7 ** the Free Software Foundation ; either version 2.1 of the License, or
|
Chris@0
|
8 ** (at your option) any later version.
|
Chris@0
|
9 **
|
Chris@0
|
10 ** This program is distributed in the hope that it will be useful,
|
Chris@0
|
11 ** but WITHOUT ANY WARRANTY ; without even the implied warranty of
|
Chris@0
|
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@0
|
13 ** GNU Lesser General Public License for more details.
|
Chris@0
|
14 **
|
Chris@0
|
15 ** You should have received a copy of the GNU Lesser General Public License
|
Chris@0
|
16 ** along with this program ; if not, write to the Free Software
|
Chris@0
|
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Chris@0
|
18 */
|
Chris@0
|
19
|
Chris@0
|
20 #include "sfconfig.h"
|
Chris@0
|
21
|
Chris@0
|
22 #include <stdio.h>
|
Chris@0
|
23 #include <stdlib.h>
|
Chris@0
|
24 #include <fcntl.h>
|
Chris@0
|
25 #include <string.h>
|
Chris@0
|
26 #include <ctype.h>
|
Chris@0
|
27 #include <math.h>
|
Chris@0
|
28
|
Chris@0
|
29 #include "sndfile.h"
|
Chris@0
|
30 #include "common.h"
|
Chris@0
|
31
|
Chris@0
|
32 #if HAVE_EXTERNAL_LIBS
|
Chris@0
|
33
|
Chris@0
|
34 #include <FLAC/stream_decoder.h>
|
Chris@0
|
35 #include <FLAC/stream_encoder.h>
|
Chris@0
|
36 #include <FLAC/metadata.h>
|
Chris@0
|
37
|
Chris@0
|
38 /*------------------------------------------------------------------------------
|
Chris@0
|
39 ** Private static functions.
|
Chris@0
|
40 */
|
Chris@0
|
41
|
Chris@0
|
42 #define ENC_BUFFER_SIZE 8192
|
Chris@0
|
43
|
Chris@0
|
44 typedef enum
|
Chris@0
|
45 { PFLAC_PCM_SHORT = 50,
|
Chris@0
|
46 PFLAC_PCM_INT = 51,
|
Chris@0
|
47 PFLAC_PCM_FLOAT = 52,
|
Chris@0
|
48 PFLAC_PCM_DOUBLE = 53
|
Chris@0
|
49 } PFLAC_PCM ;
|
Chris@0
|
50
|
Chris@0
|
51 typedef struct
|
Chris@0
|
52 {
|
Chris@0
|
53 FLAC__StreamDecoder *fsd ;
|
Chris@0
|
54 FLAC__StreamEncoder *fse ;
|
Chris@0
|
55
|
Chris@0
|
56 PFLAC_PCM pcmtype ;
|
Chris@0
|
57 void* ptr ;
|
Chris@0
|
58 unsigned pos, len, remain ;
|
Chris@0
|
59
|
Chris@0
|
60 FLAC__StreamMetadata *metadata ;
|
Chris@0
|
61
|
Chris@0
|
62 const FLAC__int32 * const * wbuffer ;
|
Chris@0
|
63 FLAC__int32 * rbuffer [FLAC__MAX_CHANNELS] ;
|
Chris@0
|
64
|
Chris@0
|
65 FLAC__int32* encbuffer ;
|
Chris@0
|
66 unsigned bufferpos ;
|
Chris@0
|
67
|
Chris@0
|
68 const FLAC__Frame *frame ;
|
Chris@0
|
69 FLAC__bool bufferbackup ;
|
Chris@0
|
70 } FLAC_PRIVATE ;
|
Chris@0
|
71
|
Chris@0
|
72 typedef struct
|
Chris@0
|
73 { const char *tag ;
|
Chris@0
|
74 int type ;
|
Chris@0
|
75 } FLAC_TAG ;
|
Chris@0
|
76
|
Chris@0
|
77 static sf_count_t flac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
|
Chris@0
|
78 static int flac_close (SF_PRIVATE *psf) ;
|
Chris@0
|
79
|
Chris@0
|
80 static int flac_enc_init (SF_PRIVATE *psf) ;
|
Chris@0
|
81 static int flac_read_header (SF_PRIVATE *psf) ;
|
Chris@0
|
82
|
Chris@0
|
83 static sf_count_t flac_read_flac2s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
|
Chris@0
|
84 static sf_count_t flac_read_flac2i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
|
Chris@0
|
85 static sf_count_t flac_read_flac2f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
|
Chris@0
|
86 static sf_count_t flac_read_flac2d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
|
Chris@0
|
87
|
Chris@0
|
88 static sf_count_t flac_write_s2flac (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
|
Chris@0
|
89 static sf_count_t flac_write_i2flac (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
|
Chris@0
|
90 static sf_count_t flac_write_f2flac (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
|
Chris@0
|
91 static sf_count_t flac_write_d2flac (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
|
Chris@0
|
92
|
Chris@0
|
93 static void f2flac8_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
94 static void f2flac16_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
95 static void f2flac24_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
96 static void f2flac8_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
97 static void f2flac16_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
98 static void f2flac24_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
99 static void d2flac8_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
100 static void d2flac16_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
101 static void d2flac24_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
102 static void d2flac8_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
103 static void d2flac16_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
104 static void d2flac24_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize) ;
|
Chris@0
|
105
|
Chris@0
|
106 static int flac_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
|
Chris@0
|
107
|
Chris@0
|
108 /* Decoder Callbacks */
|
Chris@0
|
109 static FLAC__StreamDecoderReadStatus sf_flac_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer [], size_t *bytes, void *client_data) ;
|
Chris@0
|
110 static FLAC__StreamDecoderSeekStatus sf_flac_seek_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) ;
|
Chris@0
|
111 static FLAC__StreamDecoderTellStatus sf_flac_tell_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
|
Chris@0
|
112 static FLAC__StreamDecoderLengthStatus sf_flac_length_callback (const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) ;
|
Chris@0
|
113 static FLAC__bool sf_flac_eof_callback (const FLAC__StreamDecoder *decoder, void *client_data) ;
|
Chris@0
|
114 static FLAC__StreamDecoderWriteStatus sf_flac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer [], void *client_data) ;
|
Chris@0
|
115 static void sf_flac_meta_callback (const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) ;
|
Chris@0
|
116 static void sf_flac_error_callback (const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) ;
|
Chris@0
|
117
|
Chris@0
|
118 /* Encoder Callbacks */
|
Chris@0
|
119 static FLAC__StreamEncoderSeekStatus sf_flac_enc_seek_callback (const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) ;
|
Chris@0
|
120 static FLAC__StreamEncoderTellStatus sf_flac_enc_tell_callback (const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
|
Chris@0
|
121 static FLAC__StreamEncoderWriteStatus sf_flac_enc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte buffer [], size_t bytes, unsigned samples, unsigned current_frame, void *client_data) ;
|
Chris@0
|
122
|
Chris@0
|
123 static void
|
Chris@0
|
124 s2flac8_array (const short *src, FLAC__int32 *dest, int count)
|
Chris@0
|
125 { while (--count >= 0)
|
Chris@0
|
126 dest [count] = src [count] >> 8 ;
|
Chris@0
|
127 } /* s2flac8_array */
|
Chris@0
|
128
|
Chris@0
|
129 static void
|
Chris@0
|
130 s2flac16_array (const short *src, FLAC__int32 *dest, int count)
|
Chris@0
|
131 { while (--count >= 0)
|
Chris@0
|
132 dest [count] = src [count] ;
|
Chris@0
|
133 } /* s2flac16_array */
|
Chris@0
|
134
|
Chris@0
|
135 static void
|
Chris@0
|
136 s2flac24_array (const short *src, FLAC__int32 *dest, int count)
|
Chris@0
|
137 { while (--count >= 0)
|
Chris@0
|
138 dest [count] = src [count] << 8 ;
|
Chris@0
|
139 } /* s2flac24_array */
|
Chris@0
|
140
|
Chris@0
|
141 static void
|
Chris@0
|
142 i2flac8_array (const int *src, FLAC__int32 *dest, int count)
|
Chris@0
|
143 { while (--count >= 0)
|
Chris@0
|
144 dest [count] = src [count] >> 24 ;
|
Chris@0
|
145 } /* i2flac8_array */
|
Chris@0
|
146
|
Chris@0
|
147 static void
|
Chris@0
|
148 i2flac16_array (const int *src, FLAC__int32 *dest, int count)
|
Chris@0
|
149 {
|
Chris@0
|
150 while (--count >= 0)
|
Chris@0
|
151 dest [count] = src [count] >> 16 ;
|
Chris@0
|
152 } /* i2flac16_array */
|
Chris@0
|
153
|
Chris@0
|
154 static void
|
Chris@0
|
155 i2flac24_array (const int *src, FLAC__int32 *dest, int count)
|
Chris@0
|
156 { while (--count >= 0)
|
Chris@0
|
157 dest [count] = src [count] >> 8 ;
|
Chris@0
|
158 } /* i2flac24_array */
|
Chris@0
|
159
|
Chris@0
|
160 static sf_count_t
|
Chris@0
|
161 flac_buffer_copy (SF_PRIVATE *psf)
|
Chris@0
|
162 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
163 const FLAC__Frame *frame = pflac->frame ;
|
Chris@0
|
164 const FLAC__int32* const *buffer = pflac->wbuffer ;
|
Chris@0
|
165 unsigned i = 0, j, offset ;
|
Chris@0
|
166
|
Chris@0
|
167 /*
|
Chris@0
|
168 ** frame->header.blocksize is variable and we're using a constant blocksize
|
Chris@0
|
169 ** of FLAC__MAX_BLOCK_SIZE.
|
Chris@0
|
170 ** Check our assumptions here.
|
Chris@0
|
171 */
|
Chris@0
|
172 if (frame->header.blocksize > FLAC__MAX_BLOCK_SIZE)
|
Chris@0
|
173 { psf_log_printf (psf, "Ooops : frame->header.blocksize (%d) > FLAC__MAX_BLOCK_SIZE (%d)\n", __func__, __LINE__, frame->header.blocksize, FLAC__MAX_BLOCK_SIZE) ;
|
Chris@0
|
174 psf->error = SFE_INTERNAL ;
|
Chris@0
|
175 return 0 ;
|
Chris@0
|
176 } ;
|
Chris@0
|
177
|
Chris@0
|
178 if (pflac->ptr == NULL)
|
Chris@0
|
179 { /*
|
Chris@0
|
180 ** Not sure why this code is here and not elsewhere.
|
Chris@0
|
181 ** Removing it causes valgrind errors.
|
Chris@0
|
182 */
|
Chris@0
|
183 pflac->bufferbackup = SF_TRUE ;
|
Chris@0
|
184 for (i = 0 ; i < frame->header.channels ; i++)
|
Chris@0
|
185 {
|
Chris@0
|
186 if (pflac->rbuffer [i] == NULL)
|
Chris@0
|
187 pflac->rbuffer [i] = calloc (FLAC__MAX_BLOCK_SIZE, sizeof (FLAC__int32)) ;
|
Chris@0
|
188
|
Chris@0
|
189 memcpy (pflac->rbuffer [i], buffer [i], frame->header.blocksize * sizeof (FLAC__int32)) ;
|
Chris@0
|
190 } ;
|
Chris@0
|
191 pflac->wbuffer = (const FLAC__int32* const*) pflac->rbuffer ;
|
Chris@0
|
192
|
Chris@0
|
193 return 0 ;
|
Chris@0
|
194 } ;
|
Chris@0
|
195
|
Chris@0
|
196 switch (pflac->pcmtype)
|
Chris@0
|
197 { case PFLAC_PCM_SHORT :
|
Chris@0
|
198 { short *retpcm = (short*) pflac->ptr ;
|
Chris@0
|
199 int shift = 16 - frame->header.bits_per_sample ;
|
Chris@0
|
200 if (shift < 0)
|
Chris@0
|
201 { shift = abs (shift) ;
|
Chris@0
|
202 for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
|
Chris@0
|
203 { offset = pflac->pos + i * frame->header.channels ;
|
Chris@0
|
204
|
Chris@0
|
205 if (pflac->bufferpos >= frame->header.blocksize)
|
Chris@0
|
206 break ;
|
Chris@0
|
207
|
Chris@0
|
208 for (j = 0 ; j < frame->header.channels ; j++)
|
Chris@0
|
209 retpcm [offset + j] = buffer [j][pflac->bufferpos] >> shift ;
|
Chris@0
|
210 pflac->remain -= frame->header.channels ;
|
Chris@0
|
211 pflac->bufferpos++ ;
|
Chris@0
|
212 }
|
Chris@0
|
213 }
|
Chris@0
|
214 else
|
Chris@0
|
215 { for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
|
Chris@0
|
216 { offset = pflac->pos + i * frame->header.channels ;
|
Chris@0
|
217
|
Chris@0
|
218 if (pflac->bufferpos >= frame->header.blocksize)
|
Chris@0
|
219 break ;
|
Chris@0
|
220
|
Chris@0
|
221 for (j = 0 ; j < frame->header.channels ; j++)
|
Chris@0
|
222 retpcm [offset + j] = (buffer [j][pflac->bufferpos]) << shift ;
|
Chris@0
|
223
|
Chris@0
|
224 pflac->remain -= frame->header.channels ;
|
Chris@0
|
225 pflac->bufferpos++ ;
|
Chris@0
|
226 } ;
|
Chris@0
|
227 } ;
|
Chris@0
|
228 } ;
|
Chris@0
|
229 break ;
|
Chris@0
|
230
|
Chris@0
|
231 case PFLAC_PCM_INT :
|
Chris@0
|
232 { int *retpcm = (int*) pflac->ptr ;
|
Chris@0
|
233 int shift = 32 - frame->header.bits_per_sample ;
|
Chris@0
|
234 for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
|
Chris@0
|
235 { offset = pflac->pos + i * frame->header.channels ;
|
Chris@0
|
236
|
Chris@0
|
237 if (pflac->bufferpos >= frame->header.blocksize)
|
Chris@0
|
238 break ;
|
Chris@0
|
239
|
Chris@0
|
240 for (j = 0 ; j < frame->header.channels ; j++)
|
Chris@0
|
241 retpcm [offset + j] = buffer [j][pflac->bufferpos] << shift ;
|
Chris@0
|
242 pflac->remain -= frame->header.channels ;
|
Chris@0
|
243 pflac->bufferpos++ ;
|
Chris@0
|
244 } ;
|
Chris@0
|
245 } ;
|
Chris@0
|
246 break ;
|
Chris@0
|
247
|
Chris@0
|
248 case PFLAC_PCM_FLOAT :
|
Chris@0
|
249 { float *retpcm = (float*) pflac->ptr ;
|
Chris@0
|
250 float norm = (psf->norm_float == SF_TRUE) ? 1.0 / (1 << (frame->header.bits_per_sample - 1)) : 1.0 ;
|
Chris@0
|
251
|
Chris@0
|
252 for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
|
Chris@0
|
253 { offset = pflac->pos + i * frame->header.channels ;
|
Chris@0
|
254
|
Chris@0
|
255 if (pflac->bufferpos >= frame->header.blocksize)
|
Chris@0
|
256 break ;
|
Chris@0
|
257
|
Chris@0
|
258 for (j = 0 ; j < frame->header.channels ; j++)
|
Chris@0
|
259 retpcm [offset + j] = buffer [j][pflac->bufferpos] * norm ;
|
Chris@0
|
260 pflac->remain -= frame->header.channels ;
|
Chris@0
|
261 pflac->bufferpos++ ;
|
Chris@0
|
262 } ;
|
Chris@0
|
263 } ;
|
Chris@0
|
264 break ;
|
Chris@0
|
265
|
Chris@0
|
266 case PFLAC_PCM_DOUBLE :
|
Chris@0
|
267 { double *retpcm = (double*) pflac->ptr ;
|
Chris@0
|
268 double norm = (psf->norm_double == SF_TRUE) ? 1.0 / (1 << (frame->header.bits_per_sample - 1)) : 1.0 ;
|
Chris@0
|
269
|
Chris@0
|
270 for (i = 0 ; i < frame->header.blocksize && pflac->remain > 0 ; i++)
|
Chris@0
|
271 { offset = pflac->pos + i * frame->header.channels ;
|
Chris@0
|
272
|
Chris@0
|
273 if (pflac->bufferpos >= frame->header.blocksize)
|
Chris@0
|
274 break ;
|
Chris@0
|
275
|
Chris@0
|
276 for (j = 0 ; j < frame->header.channels ; j++)
|
Chris@0
|
277 retpcm [offset + j] = buffer [j][pflac->bufferpos] * norm ;
|
Chris@0
|
278 pflac->remain -= frame->header.channels ;
|
Chris@0
|
279 pflac->bufferpos++ ;
|
Chris@0
|
280 } ;
|
Chris@0
|
281 } ;
|
Chris@0
|
282 break ;
|
Chris@0
|
283
|
Chris@0
|
284 default :
|
Chris@0
|
285 return 0 ;
|
Chris@0
|
286 } ;
|
Chris@0
|
287
|
Chris@0
|
288 offset = i * frame->header.channels ;
|
Chris@0
|
289 pflac->pos += i * frame->header.channels ;
|
Chris@0
|
290
|
Chris@0
|
291 return offset ;
|
Chris@0
|
292 } /* flac_buffer_copy */
|
Chris@0
|
293
|
Chris@0
|
294
|
Chris@0
|
295 static FLAC__StreamDecoderReadStatus
|
Chris@0
|
296 sf_flac_read_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__byte buffer [], size_t *bytes, void *client_data)
|
Chris@0
|
297 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
298
|
Chris@0
|
299 *bytes = psf_fread (buffer, 1, *bytes, psf) ;
|
Chris@0
|
300 if (*bytes > 0 && psf->error == 0)
|
Chris@0
|
301 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE ;
|
Chris@0
|
302
|
Chris@0
|
303 return FLAC__STREAM_DECODER_READ_STATUS_ABORT ;
|
Chris@0
|
304 } /* sf_flac_read_callback */
|
Chris@0
|
305
|
Chris@0
|
306 static FLAC__StreamDecoderSeekStatus
|
Chris@0
|
307 sf_flac_seek_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__uint64 absolute_byte_offset, void *client_data)
|
Chris@0
|
308 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
309
|
Chris@0
|
310 psf_fseek (psf, absolute_byte_offset, SEEK_SET) ;
|
Chris@0
|
311 if (psf->error)
|
Chris@0
|
312 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR ;
|
Chris@0
|
313
|
Chris@0
|
314 return FLAC__STREAM_DECODER_SEEK_STATUS_OK ;
|
Chris@0
|
315 } /* sf_flac_seek_callback */
|
Chris@0
|
316
|
Chris@0
|
317 static FLAC__StreamDecoderTellStatus
|
Chris@0
|
318 sf_flac_tell_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__uint64 *absolute_byte_offset, void *client_data)
|
Chris@0
|
319 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
320
|
Chris@0
|
321 *absolute_byte_offset = psf_ftell (psf) ;
|
Chris@0
|
322 if (psf->error)
|
Chris@0
|
323 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR ;
|
Chris@0
|
324
|
Chris@0
|
325 return FLAC__STREAM_DECODER_TELL_STATUS_OK ;
|
Chris@0
|
326 } /* sf_flac_tell_callback */
|
Chris@0
|
327
|
Chris@0
|
328 static FLAC__StreamDecoderLengthStatus
|
Chris@0
|
329 sf_flac_length_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__uint64 *stream_length, void *client_data)
|
Chris@0
|
330 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
331
|
Chris@0
|
332 if ((*stream_length = psf->filelength) == 0)
|
Chris@0
|
333 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR ;
|
Chris@0
|
334
|
Chris@0
|
335 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK ;
|
Chris@0
|
336 } /* sf_flac_length_callback */
|
Chris@0
|
337
|
Chris@0
|
338 static FLAC__bool
|
Chris@0
|
339 sf_flac_eof_callback (const FLAC__StreamDecoder *UNUSED (decoder), void *client_data)
|
Chris@0
|
340 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
341
|
Chris@0
|
342 if (psf_ftell (psf) == psf->filelength)
|
Chris@0
|
343 return SF_TRUE ;
|
Chris@0
|
344
|
Chris@0
|
345 return SF_FALSE ;
|
Chris@0
|
346 } /* sf_flac_eof_callback */
|
Chris@0
|
347
|
Chris@0
|
348 static FLAC__StreamDecoderWriteStatus
|
Chris@0
|
349 sf_flac_write_callback (const FLAC__StreamDecoder * UNUSED (decoder), const FLAC__Frame *frame, const FLAC__int32 * const buffer [], void *client_data)
|
Chris@0
|
350 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
351 FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
352
|
Chris@0
|
353 pflac->frame = frame ;
|
Chris@0
|
354 pflac->bufferpos = 0 ;
|
Chris@0
|
355
|
Chris@0
|
356 pflac->bufferbackup = SF_FALSE ;
|
Chris@0
|
357 pflac->wbuffer = buffer ;
|
Chris@0
|
358
|
Chris@0
|
359 flac_buffer_copy (psf) ;
|
Chris@0
|
360
|
Chris@0
|
361 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE ;
|
Chris@0
|
362 } /* sf_flac_write_callback */
|
Chris@0
|
363
|
Chris@0
|
364 static void
|
Chris@0
|
365 sf_flac_meta_get_vorbiscomments (SF_PRIVATE *psf, const FLAC__StreamMetadata *metadata)
|
Chris@0
|
366 { FLAC_TAG tags [] =
|
Chris@0
|
367 { { "title", SF_STR_TITLE },
|
Chris@0
|
368 { "copyright", SF_STR_COPYRIGHT },
|
Chris@0
|
369 { "software", SF_STR_SOFTWARE },
|
Chris@0
|
370 { "artist", SF_STR_ARTIST },
|
Chris@0
|
371 { "comment", SF_STR_COMMENT },
|
Chris@0
|
372 { "date", SF_STR_DATE },
|
Chris@0
|
373 { "album", SF_STR_ALBUM },
|
Chris@0
|
374 { "license", SF_STR_LICENSE },
|
Chris@0
|
375 { "tracknumber", SF_STR_TRACKNUMBER },
|
Chris@0
|
376 { "genre", SF_STR_GENRE }
|
Chris@0
|
377 } ;
|
Chris@0
|
378
|
Chris@0
|
379 const char *value, *cptr ;
|
Chris@0
|
380 int k, tag_num ;
|
Chris@0
|
381
|
Chris@0
|
382 for (k = 0 ; k < ARRAY_LEN (tags) ; k++)
|
Chris@0
|
383 { tag_num = FLAC__metadata_object_vorbiscomment_find_entry_from (metadata, 0, tags [k].tag) ;
|
Chris@0
|
384
|
Chris@0
|
385 if (tag_num < 0)
|
Chris@0
|
386 continue ;
|
Chris@0
|
387
|
Chris@0
|
388 value = (const char*) metadata->data.vorbis_comment.comments [tag_num].entry ;
|
Chris@0
|
389 if ((cptr = strchr (value, '=')) != NULL)
|
Chris@0
|
390 value = cptr + 1 ;
|
Chris@0
|
391
|
Chris@0
|
392 psf_log_printf (psf, " %-10s : %s\n", tags [k].tag, value) ;
|
Chris@0
|
393 psf_store_string (psf, tags [k].type, value) ;
|
Chris@0
|
394 } ;
|
Chris@0
|
395
|
Chris@0
|
396 return ;
|
Chris@0
|
397 } /* sf_flac_meta_get_vorbiscomments */
|
Chris@0
|
398
|
Chris@0
|
399 static void
|
Chris@0
|
400 sf_flac_meta_callback (const FLAC__StreamDecoder * UNUSED (decoder), const FLAC__StreamMetadata *metadata, void *client_data)
|
Chris@0
|
401 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
402 int bitwidth = 0 ;
|
Chris@0
|
403
|
Chris@0
|
404 switch (metadata->type)
|
Chris@0
|
405 { case FLAC__METADATA_TYPE_STREAMINFO :
|
Chris@0
|
406 psf->sf.channels = metadata->data.stream_info.channels ;
|
Chris@0
|
407 psf->sf.samplerate = metadata->data.stream_info.sample_rate ;
|
Chris@0
|
408 psf->sf.frames = metadata->data.stream_info.total_samples ;
|
Chris@0
|
409
|
Chris@0
|
410 psf_log_printf (psf, "FLAC Stream Metadata\n Channels : %d\n Sample rate : %d\n", psf->sf.channels, psf->sf.samplerate) ;
|
Chris@0
|
411
|
Chris@0
|
412 if (psf->sf.frames == 0)
|
Chris@0
|
413 { psf_log_printf (psf, " Frames : 0 (bumping to SF_COUNT_MAX)\n") ;
|
Chris@0
|
414 psf->sf.frames = SF_COUNT_MAX ;
|
Chris@0
|
415 }
|
Chris@0
|
416 else
|
Chris@0
|
417 psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
|
Chris@0
|
418
|
Chris@0
|
419 switch (metadata->data.stream_info.bits_per_sample)
|
Chris@0
|
420 { case 8 :
|
Chris@0
|
421 psf->sf.format |= SF_FORMAT_PCM_S8 ;
|
Chris@0
|
422 bitwidth = 8 ;
|
Chris@0
|
423 break ;
|
Chris@0
|
424 case 16 :
|
Chris@0
|
425 psf->sf.format |= SF_FORMAT_PCM_16 ;
|
Chris@0
|
426 bitwidth = 16 ;
|
Chris@0
|
427 break ;
|
Chris@0
|
428 case 24 :
|
Chris@0
|
429 psf->sf.format |= SF_FORMAT_PCM_24 ;
|
Chris@0
|
430 bitwidth = 24 ;
|
Chris@0
|
431 break ;
|
Chris@0
|
432 default :
|
Chris@0
|
433 psf_log_printf (psf, "sf_flac_meta_callback : bits_per_sample %d not yet implemented.\n", metadata->data.stream_info.bits_per_sample) ;
|
Chris@0
|
434 break ;
|
Chris@0
|
435 } ;
|
Chris@0
|
436
|
Chris@0
|
437 if (bitwidth > 0)
|
Chris@0
|
438 psf_log_printf (psf, " Bit width : %d\n", bitwidth) ;
|
Chris@0
|
439 break ;
|
Chris@0
|
440
|
Chris@0
|
441 case FLAC__METADATA_TYPE_VORBIS_COMMENT :
|
Chris@0
|
442 psf_log_printf (psf, "Vorbis Comment Metadata\n") ;
|
Chris@0
|
443 sf_flac_meta_get_vorbiscomments (psf, metadata) ;
|
Chris@0
|
444 break ;
|
Chris@0
|
445
|
Chris@0
|
446 case FLAC__METADATA_TYPE_PADDING :
|
Chris@0
|
447 psf_log_printf (psf, "Padding Metadata\n") ;
|
Chris@0
|
448 break ;
|
Chris@0
|
449
|
Chris@0
|
450 case FLAC__METADATA_TYPE_APPLICATION :
|
Chris@0
|
451 psf_log_printf (psf, "Application Metadata\n") ;
|
Chris@0
|
452 break ;
|
Chris@0
|
453
|
Chris@0
|
454 case FLAC__METADATA_TYPE_SEEKTABLE :
|
Chris@0
|
455 psf_log_printf (psf, "Seektable Metadata\n") ;
|
Chris@0
|
456 break ;
|
Chris@0
|
457
|
Chris@0
|
458 case FLAC__METADATA_TYPE_CUESHEET :
|
Chris@0
|
459 psf_log_printf (psf, "Cuesheet Metadata\n") ;
|
Chris@0
|
460 break ;
|
Chris@0
|
461
|
Chris@0
|
462 case FLAC__METADATA_TYPE_PICTURE :
|
Chris@0
|
463 psf_log_printf (psf, "Picture Metadata\n") ;
|
Chris@0
|
464 break ;
|
Chris@0
|
465
|
Chris@0
|
466 case FLAC__METADATA_TYPE_UNDEFINED :
|
Chris@0
|
467 psf_log_printf (psf, "Undefined Metadata\n") ;
|
Chris@0
|
468 break ;
|
Chris@0
|
469
|
Chris@0
|
470 default :
|
Chris@0
|
471 psf_log_printf (psf, "sf_flac_meta_callback : metadata-type %d not yet implemented.\n", metadata->type) ;
|
Chris@0
|
472 break ;
|
Chris@0
|
473 } ;
|
Chris@0
|
474
|
Chris@0
|
475 return ;
|
Chris@0
|
476 } /* sf_flac_meta_callback */
|
Chris@0
|
477
|
Chris@0
|
478 static void
|
Chris@0
|
479 sf_flac_error_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__StreamDecoderErrorStatus status, void *client_data)
|
Chris@0
|
480 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
481
|
Chris@0
|
482 psf_log_printf (psf, "ERROR : %s\n", FLAC__StreamDecoderErrorStatusString [status]) ;
|
Chris@0
|
483
|
Chris@0
|
484 switch (status)
|
Chris@0
|
485 { case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC :
|
Chris@0
|
486 psf->error = SFE_FLAC_LOST_SYNC ;
|
Chris@0
|
487 break ;
|
Chris@0
|
488 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER :
|
Chris@0
|
489 psf->error = SFE_FLAC_BAD_HEADER ;
|
Chris@0
|
490 break ;
|
Chris@0
|
491 default :
|
Chris@0
|
492 psf->error = SFE_FLAC_UNKOWN_ERROR ;
|
Chris@0
|
493 break ;
|
Chris@0
|
494 } ;
|
Chris@0
|
495
|
Chris@0
|
496 return ;
|
Chris@0
|
497 } /* sf_flac_error_callback */
|
Chris@0
|
498
|
Chris@0
|
499 static FLAC__StreamEncoderSeekStatus
|
Chris@0
|
500 sf_flac_enc_seek_callback (const FLAC__StreamEncoder * UNUSED (encoder), FLAC__uint64 absolute_byte_offset, void *client_data)
|
Chris@0
|
501 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
502
|
Chris@0
|
503 psf_fseek (psf, absolute_byte_offset, SEEK_SET) ;
|
Chris@0
|
504 if (psf->error)
|
Chris@0
|
505 return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR ;
|
Chris@0
|
506
|
Chris@0
|
507 return FLAC__STREAM_ENCODER_SEEK_STATUS_OK ;
|
Chris@0
|
508 } /* sf_flac_enc_seek_callback */
|
Chris@0
|
509
|
Chris@0
|
510 static FLAC__StreamEncoderTellStatus
|
Chris@0
|
511 sf_flac_enc_tell_callback (const FLAC__StreamEncoder *UNUSED (encoder), FLAC__uint64 *absolute_byte_offset, void *client_data)
|
Chris@0
|
512 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
513
|
Chris@0
|
514 *absolute_byte_offset = psf_ftell (psf) ;
|
Chris@0
|
515 if (psf->error)
|
Chris@0
|
516 return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR ;
|
Chris@0
|
517
|
Chris@0
|
518 return FLAC__STREAM_ENCODER_TELL_STATUS_OK ;
|
Chris@0
|
519 } /* sf_flac_enc_tell_callback */
|
Chris@0
|
520
|
Chris@0
|
521 static FLAC__StreamEncoderWriteStatus
|
Chris@0
|
522 sf_flac_enc_write_callback (const FLAC__StreamEncoder * UNUSED (encoder), const FLAC__byte buffer [], size_t bytes, unsigned UNUSED (samples), unsigned UNUSED (current_frame), void *client_data)
|
Chris@0
|
523 { SF_PRIVATE *psf = (SF_PRIVATE*) client_data ;
|
Chris@0
|
524
|
Chris@0
|
525 if (psf_fwrite (buffer, 1, bytes, psf) == (sf_count_t) bytes && psf->error == 0)
|
Chris@0
|
526 return FLAC__STREAM_ENCODER_WRITE_STATUS_OK ;
|
Chris@0
|
527
|
Chris@0
|
528 return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR ;
|
Chris@0
|
529 } /* sf_flac_enc_write_callback */
|
Chris@0
|
530
|
Chris@0
|
531 static void
|
Chris@0
|
532 flac_write_strings (SF_PRIVATE *psf, FLAC_PRIVATE* pflac)
|
Chris@0
|
533 { FLAC__StreamMetadata_VorbisComment_Entry entry ;
|
Chris@0
|
534 int k, string_count = 0 ;
|
Chris@0
|
535
|
Chris@0
|
536 for (k = 0 ; k < SF_MAX_STRINGS ; k++)
|
Chris@0
|
537 { if (psf->strings [k].type != 0)
|
Chris@0
|
538 string_count ++ ;
|
Chris@0
|
539 } ;
|
Chris@0
|
540
|
Chris@0
|
541 if (string_count == 0)
|
Chris@0
|
542 return ;
|
Chris@0
|
543
|
Chris@0
|
544 if (pflac->metadata == NULL && (pflac->metadata = FLAC__metadata_object_new (FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL)
|
Chris@0
|
545 { psf_log_printf (psf, "FLAC__metadata_object_new returned NULL\n") ;
|
Chris@0
|
546 return ;
|
Chris@0
|
547 } ;
|
Chris@0
|
548
|
Chris@0
|
549 for (k = 0 ; k < SF_MAX_STRINGS && psf->strings [k].type != 0 ; k++)
|
Chris@0
|
550 { const char * key, * value ;
|
Chris@0
|
551
|
Chris@0
|
552 switch (psf->strings [k].type)
|
Chris@0
|
553 { case SF_STR_SOFTWARE :
|
Chris@0
|
554 key = "software" ;
|
Chris@0
|
555 break ;
|
Chris@0
|
556 case SF_STR_TITLE :
|
Chris@0
|
557 key = "title" ;
|
Chris@0
|
558 break ;
|
Chris@0
|
559 case SF_STR_COPYRIGHT :
|
Chris@0
|
560 key = "copyright" ;
|
Chris@0
|
561 break ;
|
Chris@0
|
562 case SF_STR_ARTIST :
|
Chris@0
|
563 key = "artist" ;
|
Chris@0
|
564 break ;
|
Chris@0
|
565 case SF_STR_COMMENT :
|
Chris@0
|
566 key = "comment" ;
|
Chris@0
|
567 break ;
|
Chris@0
|
568 case SF_STR_DATE :
|
Chris@0
|
569 key = "date" ;
|
Chris@0
|
570 break ;
|
Chris@0
|
571 case SF_STR_ALBUM :
|
Chris@0
|
572 key = "album" ;
|
Chris@0
|
573 break ;
|
Chris@0
|
574 case SF_STR_LICENSE :
|
Chris@0
|
575 key = "license" ;
|
Chris@0
|
576 break ;
|
Chris@0
|
577 case SF_STR_TRACKNUMBER :
|
Chris@0
|
578 key = "tracknumber" ;
|
Chris@0
|
579 break ;
|
Chris@0
|
580 case SF_STR_GENRE :
|
Chris@0
|
581 key = "genre" ;
|
Chris@0
|
582 break ;
|
Chris@0
|
583 default :
|
Chris@0
|
584 continue ;
|
Chris@0
|
585 } ;
|
Chris@0
|
586
|
Chris@0
|
587 value = psf->strings [k].str ;
|
Chris@0
|
588
|
Chris@0
|
589 FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair (&entry, key, value) ;
|
Chris@0
|
590 FLAC__metadata_object_vorbiscomment_append_comment (pflac->metadata, entry, /* copy */ SF_FALSE) ;
|
Chris@0
|
591 } ;
|
Chris@0
|
592
|
Chris@0
|
593 if (! FLAC__stream_encoder_set_metadata (pflac->fse, &pflac->metadata, 1))
|
Chris@0
|
594 { printf ("%s %d : fail\n", __func__, __LINE__) ;
|
Chris@0
|
595 return ;
|
Chris@0
|
596 } ;
|
Chris@0
|
597
|
Chris@0
|
598 return ;
|
Chris@0
|
599 } /* flac_write_strings */
|
Chris@0
|
600
|
Chris@0
|
601 static int
|
Chris@0
|
602 flac_write_header (SF_PRIVATE *psf, int UNUSED (calc_length))
|
Chris@0
|
603 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
604 int err ;
|
Chris@0
|
605
|
Chris@0
|
606 flac_write_strings (psf, pflac) ;
|
Chris@0
|
607
|
Chris@0
|
608 if ((err = FLAC__stream_encoder_init_stream (pflac->fse, sf_flac_enc_write_callback, sf_flac_enc_seek_callback, sf_flac_enc_tell_callback, NULL, psf)) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
Chris@0
|
609 { psf_log_printf (psf, "Error : FLAC encoder init returned error : %s\n", FLAC__StreamEncoderInitStatusString [err]) ;
|
Chris@0
|
610 return SFE_FLAC_INIT_DECODER ;
|
Chris@0
|
611 } ;
|
Chris@0
|
612
|
Chris@0
|
613 if (psf->error == 0)
|
Chris@0
|
614 psf->dataoffset = psf_ftell (psf) ;
|
Chris@0
|
615 pflac->encbuffer = calloc (ENC_BUFFER_SIZE, sizeof (FLAC__int32)) ;
|
Chris@0
|
616
|
Chris@0
|
617 return psf->error ;
|
Chris@0
|
618 } /* flac_write_header */
|
Chris@0
|
619
|
Chris@0
|
620 /*------------------------------------------------------------------------------
|
Chris@0
|
621 ** Public function.
|
Chris@0
|
622 */
|
Chris@0
|
623
|
Chris@0
|
624 int
|
Chris@0
|
625 flac_open (SF_PRIVATE *psf)
|
Chris@0
|
626 { int subformat ;
|
Chris@0
|
627 int error = 0 ;
|
Chris@0
|
628
|
Chris@0
|
629 FLAC_PRIVATE* pflac = calloc (1, sizeof (FLAC_PRIVATE)) ;
|
Chris@0
|
630 psf->codec_data = pflac ;
|
Chris@0
|
631
|
Chris@0
|
632 if (psf->file.mode == SFM_RDWR)
|
Chris@0
|
633 return SFE_BAD_MODE_RW ;
|
Chris@0
|
634
|
Chris@0
|
635 if (psf->file.mode == SFM_READ)
|
Chris@0
|
636 { if ((error = flac_read_header (psf)))
|
Chris@0
|
637 return error ;
|
Chris@0
|
638 } ;
|
Chris@0
|
639
|
Chris@0
|
640 subformat = SF_CODEC (psf->sf.format) ;
|
Chris@0
|
641
|
Chris@0
|
642 if (psf->file.mode == SFM_WRITE)
|
Chris@0
|
643 { if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_FLAC)
|
Chris@0
|
644 return SFE_BAD_OPEN_FORMAT ;
|
Chris@0
|
645
|
Chris@0
|
646 psf->endian = SF_ENDIAN_BIG ;
|
Chris@0
|
647 psf->sf.seekable = 0 ;
|
Chris@0
|
648
|
Chris@0
|
649 psf->str_flags = SF_STR_ALLOW_START ;
|
Chris@0
|
650
|
Chris@0
|
651 if ((error = flac_enc_init (psf)))
|
Chris@0
|
652 return error ;
|
Chris@0
|
653
|
Chris@0
|
654 psf->write_header = flac_write_header ;
|
Chris@0
|
655 } ;
|
Chris@0
|
656
|
Chris@0
|
657 psf->datalength = psf->filelength ;
|
Chris@0
|
658 psf->dataoffset = 0 ;
|
Chris@0
|
659 psf->blockwidth = 0 ;
|
Chris@0
|
660 psf->bytewidth = 1 ;
|
Chris@0
|
661
|
Chris@0
|
662 psf->container_close = flac_close ;
|
Chris@0
|
663 psf->seek = flac_seek ;
|
Chris@0
|
664 psf->command = flac_command ;
|
Chris@0
|
665
|
Chris@0
|
666 psf->blockwidth = psf->bytewidth * psf->sf.channels ;
|
Chris@0
|
667
|
Chris@0
|
668 switch (subformat)
|
Chris@0
|
669 { case SF_FORMAT_PCM_S8 : /* 8-bit FLAC. */
|
Chris@0
|
670 case SF_FORMAT_PCM_16 : /* 16-bit FLAC. */
|
Chris@0
|
671 case SF_FORMAT_PCM_24 : /* 24-bit FLAC. */
|
Chris@0
|
672 error = flac_init (psf) ;
|
Chris@0
|
673 break ;
|
Chris@0
|
674
|
Chris@0
|
675 default : return SFE_UNIMPLEMENTED ;
|
Chris@0
|
676 } ;
|
Chris@0
|
677
|
Chris@0
|
678 return error ;
|
Chris@0
|
679 } /* flac_open */
|
Chris@0
|
680
|
Chris@0
|
681 /*------------------------------------------------------------------------------
|
Chris@0
|
682 */
|
Chris@0
|
683
|
Chris@0
|
684 static int
|
Chris@0
|
685 flac_close (SF_PRIVATE *psf)
|
Chris@0
|
686 { FLAC_PRIVATE* pflac ;
|
Chris@0
|
687 int k ;
|
Chris@0
|
688
|
Chris@0
|
689 if ((pflac = (FLAC_PRIVATE*) psf->codec_data) == NULL)
|
Chris@0
|
690 return 0 ;
|
Chris@0
|
691
|
Chris@0
|
692 if (pflac->metadata != NULL)
|
Chris@0
|
693 FLAC__metadata_object_delete (pflac->metadata) ;
|
Chris@0
|
694
|
Chris@0
|
695 if (psf->file.mode == SFM_WRITE)
|
Chris@0
|
696 { FLAC__stream_encoder_finish (pflac->fse) ;
|
Chris@0
|
697 FLAC__stream_encoder_delete (pflac->fse) ;
|
Chris@0
|
698
|
Chris@0
|
699 if (pflac->encbuffer)
|
Chris@0
|
700 free (pflac->encbuffer) ;
|
Chris@0
|
701 } ;
|
Chris@0
|
702
|
Chris@0
|
703 if (psf->file.mode == SFM_READ)
|
Chris@0
|
704 { FLAC__stream_decoder_finish (pflac->fsd) ;
|
Chris@0
|
705 FLAC__stream_decoder_delete (pflac->fsd) ;
|
Chris@0
|
706 } ;
|
Chris@0
|
707
|
Chris@0
|
708 for (k = 0 ; k < ARRAY_LEN (pflac->rbuffer) ; k++)
|
Chris@0
|
709 free (pflac->rbuffer [k]) ;
|
Chris@0
|
710
|
Chris@0
|
711 free (pflac) ;
|
Chris@0
|
712 psf->codec_data = NULL ;
|
Chris@0
|
713
|
Chris@0
|
714 return 0 ;
|
Chris@0
|
715 } /* flac_close */
|
Chris@0
|
716
|
Chris@0
|
717 static int
|
Chris@0
|
718 flac_enc_init (SF_PRIVATE *psf)
|
Chris@0
|
719 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
720 unsigned bps ;
|
Chris@0
|
721
|
Chris@0
|
722 /* To cite the flac FAQ at
|
Chris@0
|
723 ** http://flac.sourceforge.net/faq.html#general__samples
|
Chris@0
|
724 ** "FLAC supports linear sample rates from 1Hz - 655350Hz in 1Hz
|
Chris@0
|
725 ** increments."
|
Chris@0
|
726 */
|
Chris@0
|
727 if ( psf->sf.samplerate < 1 || psf->sf.samplerate > 655350 )
|
Chris@0
|
728 { psf_log_printf (psf, "flac sample rate out of range.\n", psf->sf.samplerate) ;
|
Chris@0
|
729 return SFE_FLAC_BAD_SAMPLE_RATE ;
|
Chris@0
|
730 } ;
|
Chris@0
|
731
|
Chris@0
|
732 psf_fseek (psf, 0, SEEK_SET) ;
|
Chris@0
|
733
|
Chris@0
|
734 switch (SF_CODEC (psf->sf.format))
|
Chris@0
|
735 { case SF_FORMAT_PCM_S8 :
|
Chris@0
|
736 bps = 8 ;
|
Chris@0
|
737 break ;
|
Chris@0
|
738 case SF_FORMAT_PCM_16 :
|
Chris@0
|
739 bps = 16 ;
|
Chris@0
|
740 break ;
|
Chris@0
|
741 case SF_FORMAT_PCM_24 :
|
Chris@0
|
742 bps = 24 ;
|
Chris@0
|
743 break ;
|
Chris@0
|
744
|
Chris@0
|
745 default :
|
Chris@0
|
746 bps = 0 ;
|
Chris@0
|
747 break ;
|
Chris@0
|
748 } ;
|
Chris@0
|
749
|
Chris@0
|
750 if ((pflac->fse = FLAC__stream_encoder_new ()) == NULL)
|
Chris@0
|
751 return SFE_FLAC_NEW_DECODER ;
|
Chris@0
|
752
|
Chris@0
|
753 if (! FLAC__stream_encoder_set_channels (pflac->fse, psf->sf.channels))
|
Chris@0
|
754 { psf_log_printf (psf, "FLAC__stream_encoder_set_channels (%d) return false.\n", psf->sf.channels) ;
|
Chris@0
|
755 return SFE_FLAC_INIT_DECODER ;
|
Chris@0
|
756 } ;
|
Chris@0
|
757
|
Chris@0
|
758 if (! FLAC__stream_encoder_set_sample_rate (pflac->fse, psf->sf.samplerate))
|
Chris@0
|
759 { psf_log_printf (psf, "FLAC__stream_encoder_set_sample_rate (%d) returned false.\n", psf->sf.samplerate) ;
|
Chris@0
|
760 return SFE_FLAC_BAD_SAMPLE_RATE ;
|
Chris@0
|
761 } ;
|
Chris@0
|
762
|
Chris@0
|
763 if (! FLAC__stream_encoder_set_bits_per_sample (pflac->fse, bps))
|
Chris@0
|
764 { psf_log_printf (psf, "FLAC__stream_encoder_set_bits_per_sample (%d) return false.\n", bps) ;
|
Chris@0
|
765 return SFE_FLAC_INIT_DECODER ;
|
Chris@0
|
766 } ;
|
Chris@0
|
767
|
Chris@0
|
768 return 0 ;
|
Chris@0
|
769 } /* flac_enc_init */
|
Chris@0
|
770
|
Chris@0
|
771 static int
|
Chris@0
|
772 flac_read_header (SF_PRIVATE *psf)
|
Chris@0
|
773 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
774
|
Chris@0
|
775 psf_fseek (psf, 0, SEEK_SET) ;
|
Chris@0
|
776 if ((pflac->fsd = FLAC__stream_decoder_new ()) == NULL)
|
Chris@0
|
777 return SFE_FLAC_NEW_DECODER ;
|
Chris@0
|
778
|
Chris@0
|
779 FLAC__stream_decoder_set_metadata_respond_all (pflac->fsd) ;
|
Chris@0
|
780
|
Chris@0
|
781 if (FLAC__stream_decoder_init_stream (pflac->fsd, sf_flac_read_callback, sf_flac_seek_callback, sf_flac_tell_callback, sf_flac_length_callback, sf_flac_eof_callback, sf_flac_write_callback, sf_flac_meta_callback, sf_flac_error_callback, psf) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
|
Chris@0
|
782 return SFE_FLAC_INIT_DECODER ;
|
Chris@0
|
783
|
Chris@0
|
784 FLAC__stream_decoder_process_until_end_of_metadata (pflac->fsd) ;
|
Chris@0
|
785
|
Chris@0
|
786 psf_log_printf (psf, "End\n") ;
|
Chris@0
|
787
|
Chris@0
|
788 if (psf->error == 0)
|
Chris@0
|
789 { FLAC__uint64 position ;
|
Chris@0
|
790
|
Chris@0
|
791 FLAC__stream_decoder_get_decode_position (pflac->fsd, &position) ;
|
Chris@0
|
792 psf->dataoffset = position ;
|
Chris@0
|
793 } ;
|
Chris@0
|
794
|
Chris@0
|
795 return psf->error ;
|
Chris@0
|
796 } /* flac_read_header */
|
Chris@0
|
797
|
Chris@0
|
798 static int
|
Chris@0
|
799 flac_command (SF_PRIVATE * UNUSED (psf), int UNUSED (command), void * UNUSED (data), int UNUSED (datasize))
|
Chris@0
|
800 {
|
Chris@0
|
801 return 0 ;
|
Chris@0
|
802 } /* flac_command */
|
Chris@0
|
803
|
Chris@0
|
804 int
|
Chris@0
|
805 flac_init (SF_PRIVATE *psf)
|
Chris@0
|
806 {
|
Chris@0
|
807 if (psf->file.mode == SFM_RDWR)
|
Chris@0
|
808 return SFE_BAD_MODE_RW ;
|
Chris@0
|
809
|
Chris@0
|
810 if (psf->file.mode == SFM_READ)
|
Chris@0
|
811 { psf->read_short = flac_read_flac2s ;
|
Chris@0
|
812 psf->read_int = flac_read_flac2i ;
|
Chris@0
|
813 psf->read_float = flac_read_flac2f ;
|
Chris@0
|
814 psf->read_double = flac_read_flac2d ;
|
Chris@0
|
815 } ;
|
Chris@0
|
816
|
Chris@0
|
817 if (psf->file.mode == SFM_WRITE)
|
Chris@0
|
818 { psf->write_short = flac_write_s2flac ;
|
Chris@0
|
819 psf->write_int = flac_write_i2flac ;
|
Chris@0
|
820 psf->write_float = flac_write_f2flac ;
|
Chris@0
|
821 psf->write_double = flac_write_d2flac ;
|
Chris@0
|
822 } ;
|
Chris@0
|
823
|
Chris@0
|
824 psf->bytewidth = 1 ;
|
Chris@0
|
825 psf->blockwidth = psf->sf.channels ;
|
Chris@0
|
826
|
Chris@0
|
827 if (psf->filelength > psf->dataoffset)
|
Chris@0
|
828 psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ;
|
Chris@0
|
829 else
|
Chris@0
|
830 psf->datalength = 0 ;
|
Chris@0
|
831
|
Chris@0
|
832 return 0 ;
|
Chris@0
|
833 } /* flac_init */
|
Chris@0
|
834
|
Chris@0
|
835 static unsigned
|
Chris@0
|
836 flac_read_loop (SF_PRIVATE *psf, unsigned len)
|
Chris@0
|
837 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
838
|
Chris@0
|
839 pflac->pos = 0 ;
|
Chris@0
|
840 pflac->len = len ;
|
Chris@0
|
841 pflac->remain = len ;
|
Chris@0
|
842 if (pflac->frame != NULL && pflac->bufferpos < pflac->frame->header.blocksize)
|
Chris@0
|
843 flac_buffer_copy (psf) ;
|
Chris@0
|
844
|
Chris@0
|
845 while (pflac->pos < pflac->len)
|
Chris@0
|
846 { if (FLAC__stream_decoder_process_single (pflac->fsd) == 0)
|
Chris@0
|
847 break ;
|
Chris@0
|
848 if (FLAC__stream_decoder_get_state (pflac->fsd) >= FLAC__STREAM_DECODER_END_OF_STREAM)
|
Chris@0
|
849 break ;
|
Chris@0
|
850 } ;
|
Chris@0
|
851
|
Chris@0
|
852 pflac->ptr = NULL ;
|
Chris@0
|
853
|
Chris@0
|
854 return pflac->pos ;
|
Chris@0
|
855 } /* flac_read_loop */
|
Chris@0
|
856
|
Chris@0
|
857 static sf_count_t
|
Chris@0
|
858 flac_read_flac2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
|
Chris@0
|
859 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
860 sf_count_t total = 0, current ;
|
Chris@0
|
861 unsigned readlen ;
|
Chris@0
|
862
|
Chris@0
|
863 pflac->pcmtype = PFLAC_PCM_SHORT ;
|
Chris@0
|
864
|
Chris@0
|
865 while (total < len)
|
Chris@0
|
866 { pflac->ptr = ptr + total ;
|
Chris@0
|
867 readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
|
Chris@0
|
868 current = flac_read_loop (psf, readlen) ;
|
Chris@0
|
869 if (current == 0)
|
Chris@0
|
870 break ;
|
Chris@0
|
871 total += current ;
|
Chris@0
|
872 } ;
|
Chris@0
|
873
|
Chris@0
|
874 return total ;
|
Chris@0
|
875 } /* flac_read_flac2s */
|
Chris@0
|
876
|
Chris@0
|
877 static sf_count_t
|
Chris@0
|
878 flac_read_flac2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
|
Chris@0
|
879 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
880 sf_count_t total = 0, current ;
|
Chris@0
|
881 unsigned readlen ;
|
Chris@0
|
882
|
Chris@0
|
883 pflac->pcmtype = PFLAC_PCM_INT ;
|
Chris@0
|
884
|
Chris@0
|
885 while (total < len)
|
Chris@0
|
886 { pflac->ptr = ptr + total ;
|
Chris@0
|
887 readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
|
Chris@0
|
888 current = flac_read_loop (psf, readlen) ;
|
Chris@0
|
889 if (current == 0)
|
Chris@0
|
890 break ;
|
Chris@0
|
891 total += current ;
|
Chris@0
|
892 } ;
|
Chris@0
|
893
|
Chris@0
|
894 return total ;
|
Chris@0
|
895 } /* flac_read_flac2i */
|
Chris@0
|
896
|
Chris@0
|
897 static sf_count_t
|
Chris@0
|
898 flac_read_flac2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
|
Chris@0
|
899 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
900 sf_count_t total = 0, current ;
|
Chris@0
|
901 unsigned readlen ;
|
Chris@0
|
902
|
Chris@0
|
903 pflac->pcmtype = PFLAC_PCM_FLOAT ;
|
Chris@0
|
904
|
Chris@0
|
905 while (total < len)
|
Chris@0
|
906 { pflac->ptr = ptr + total ;
|
Chris@0
|
907 readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
|
Chris@0
|
908 current = flac_read_loop (psf, readlen) ;
|
Chris@0
|
909 if (current == 0)
|
Chris@0
|
910 break ;
|
Chris@0
|
911 total += current ;
|
Chris@0
|
912 } ;
|
Chris@0
|
913
|
Chris@0
|
914 return total ;
|
Chris@0
|
915 } /* flac_read_flac2f */
|
Chris@0
|
916
|
Chris@0
|
917 static sf_count_t
|
Chris@0
|
918 flac_read_flac2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
|
Chris@0
|
919 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
920 sf_count_t total = 0, current ;
|
Chris@0
|
921 unsigned readlen ;
|
Chris@0
|
922
|
Chris@0
|
923 pflac->pcmtype = PFLAC_PCM_DOUBLE ;
|
Chris@0
|
924
|
Chris@0
|
925 while (total < len)
|
Chris@0
|
926 { pflac->ptr = ptr + total ;
|
Chris@0
|
927 readlen = (len - total > 0x1000000) ? 0x1000000 : (unsigned) (len - total) ;
|
Chris@0
|
928 current = flac_read_loop (psf, readlen) ;
|
Chris@0
|
929 if (current == 0)
|
Chris@0
|
930 break ;
|
Chris@0
|
931 total += current ;
|
Chris@0
|
932 } ;
|
Chris@0
|
933
|
Chris@0
|
934 return total ;
|
Chris@0
|
935 } /* flac_read_flac2d */
|
Chris@0
|
936
|
Chris@0
|
937 static sf_count_t
|
Chris@0
|
938 flac_write_s2flac (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
|
Chris@0
|
939 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
940 void (*convert) (const short *, FLAC__int32 *, int) ;
|
Chris@0
|
941 int bufferlen, writecount, thiswrite ;
|
Chris@0
|
942 sf_count_t total = 0 ;
|
Chris@0
|
943 FLAC__int32* buffer = pflac->encbuffer ;
|
Chris@0
|
944
|
Chris@0
|
945 switch (SF_CODEC (psf->sf.format))
|
Chris@0
|
946 { case SF_FORMAT_PCM_S8 :
|
Chris@0
|
947 convert = s2flac8_array ;
|
Chris@0
|
948 break ;
|
Chris@0
|
949 case SF_FORMAT_PCM_16 :
|
Chris@0
|
950 convert = s2flac16_array ;
|
Chris@0
|
951 break ;
|
Chris@0
|
952 case SF_FORMAT_PCM_24 :
|
Chris@0
|
953 convert = s2flac24_array ;
|
Chris@0
|
954 break ;
|
Chris@0
|
955 default :
|
Chris@0
|
956 return -1 ;
|
Chris@0
|
957 } ;
|
Chris@0
|
958
|
Chris@0
|
959 bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
|
Chris@0
|
960 bufferlen *= psf->sf.channels ;
|
Chris@0
|
961
|
Chris@0
|
962 while (len > 0)
|
Chris@0
|
963 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
|
Chris@0
|
964 convert (ptr + total, buffer, writecount) ;
|
Chris@0
|
965 if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
|
Chris@0
|
966 thiswrite = writecount ;
|
Chris@0
|
967 else
|
Chris@0
|
968 break ;
|
Chris@0
|
969 total += thiswrite ;
|
Chris@0
|
970 if (thiswrite < writecount)
|
Chris@0
|
971 break ;
|
Chris@0
|
972
|
Chris@0
|
973 len -= thiswrite ;
|
Chris@0
|
974 } ;
|
Chris@0
|
975
|
Chris@0
|
976 return total ;
|
Chris@0
|
977 } /* flac_write_s2flac */
|
Chris@0
|
978
|
Chris@0
|
979 static sf_count_t
|
Chris@0
|
980 flac_write_i2flac (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
|
Chris@0
|
981 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
982 void (*convert) (const int *, FLAC__int32 *, int) ;
|
Chris@0
|
983 int bufferlen, writecount, thiswrite ;
|
Chris@0
|
984 sf_count_t total = 0 ;
|
Chris@0
|
985 FLAC__int32* buffer = pflac->encbuffer ;
|
Chris@0
|
986
|
Chris@0
|
987 switch (SF_CODEC (psf->sf.format))
|
Chris@0
|
988 { case SF_FORMAT_PCM_S8 :
|
Chris@0
|
989 convert = i2flac8_array ;
|
Chris@0
|
990 break ;
|
Chris@0
|
991 case SF_FORMAT_PCM_16 :
|
Chris@0
|
992 convert = i2flac16_array ;
|
Chris@0
|
993 break ;
|
Chris@0
|
994 case SF_FORMAT_PCM_24 :
|
Chris@0
|
995 convert = i2flac24_array ;
|
Chris@0
|
996 break ;
|
Chris@0
|
997 default :
|
Chris@0
|
998 return -1 ;
|
Chris@0
|
999 } ;
|
Chris@0
|
1000
|
Chris@0
|
1001 bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
|
Chris@0
|
1002 bufferlen *= psf->sf.channels ;
|
Chris@0
|
1003
|
Chris@0
|
1004 while (len > 0)
|
Chris@0
|
1005 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
|
Chris@0
|
1006 convert (ptr + total, buffer, writecount) ;
|
Chris@0
|
1007 if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
|
Chris@0
|
1008 thiswrite = writecount ;
|
Chris@0
|
1009 else
|
Chris@0
|
1010 break ;
|
Chris@0
|
1011 total += thiswrite ;
|
Chris@0
|
1012 if (thiswrite < writecount)
|
Chris@0
|
1013 break ;
|
Chris@0
|
1014
|
Chris@0
|
1015 len -= thiswrite ;
|
Chris@0
|
1016 } ;
|
Chris@0
|
1017
|
Chris@0
|
1018 return total ;
|
Chris@0
|
1019 } /* flac_write_i2flac */
|
Chris@0
|
1020
|
Chris@0
|
1021 static sf_count_t
|
Chris@0
|
1022 flac_write_f2flac (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
|
Chris@0
|
1023 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
1024 void (*convert) (const float *, FLAC__int32 *, int, int) ;
|
Chris@0
|
1025 int bufferlen, writecount, thiswrite ;
|
Chris@0
|
1026 sf_count_t total = 0 ;
|
Chris@0
|
1027 FLAC__int32* buffer = pflac->encbuffer ;
|
Chris@0
|
1028
|
Chris@0
|
1029 switch (SF_CODEC (psf->sf.format))
|
Chris@0
|
1030 { case SF_FORMAT_PCM_S8 :
|
Chris@0
|
1031 convert = (psf->add_clipping) ? f2flac8_clip_array : f2flac8_array ;
|
Chris@0
|
1032 break ;
|
Chris@0
|
1033 case SF_FORMAT_PCM_16 :
|
Chris@0
|
1034 convert = (psf->add_clipping) ? f2flac16_clip_array : f2flac16_array ;
|
Chris@0
|
1035 break ;
|
Chris@0
|
1036 case SF_FORMAT_PCM_24 :
|
Chris@0
|
1037 convert = (psf->add_clipping) ? f2flac24_clip_array : f2flac24_array ;
|
Chris@0
|
1038 break ;
|
Chris@0
|
1039 default :
|
Chris@0
|
1040 return -1 ;
|
Chris@0
|
1041 } ;
|
Chris@0
|
1042
|
Chris@0
|
1043 bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
|
Chris@0
|
1044 bufferlen *= psf->sf.channels ;
|
Chris@0
|
1045
|
Chris@0
|
1046 while (len > 0)
|
Chris@0
|
1047 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
|
Chris@0
|
1048 convert (ptr + total, buffer, writecount, psf->norm_float) ;
|
Chris@0
|
1049 if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
|
Chris@0
|
1050 thiswrite = writecount ;
|
Chris@0
|
1051 else
|
Chris@0
|
1052 break ;
|
Chris@0
|
1053 total += thiswrite ;
|
Chris@0
|
1054 if (thiswrite < writecount)
|
Chris@0
|
1055 break ;
|
Chris@0
|
1056
|
Chris@0
|
1057 len -= thiswrite ;
|
Chris@0
|
1058 } ;
|
Chris@0
|
1059
|
Chris@0
|
1060 return total ;
|
Chris@0
|
1061 } /* flac_write_f2flac */
|
Chris@0
|
1062
|
Chris@0
|
1063 static void
|
Chris@0
|
1064 f2flac8_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1065 { float normfact, scaled_value ;
|
Chris@0
|
1066
|
Chris@0
|
1067 normfact = normalize ? (8.0 * 0x10) : 1.0 ;
|
Chris@0
|
1068
|
Chris@0
|
1069 while (--count >= 0)
|
Chris@0
|
1070 { scaled_value = src [count] * normfact ;
|
Chris@0
|
1071 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
|
Chris@0
|
1072 { dest [count] = 0x7F ;
|
Chris@0
|
1073 continue ;
|
Chris@0
|
1074 } ;
|
Chris@0
|
1075 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
|
Chris@0
|
1076 { dest [count] = 0x80 ;
|
Chris@0
|
1077 continue ;
|
Chris@0
|
1078 } ;
|
Chris@0
|
1079 dest [count] = lrintf (scaled_value) ;
|
Chris@0
|
1080 } ;
|
Chris@0
|
1081
|
Chris@0
|
1082 return ;
|
Chris@0
|
1083 } /* f2flac8_clip_array */
|
Chris@0
|
1084
|
Chris@0
|
1085 static void
|
Chris@0
|
1086 f2flac16_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1087 {
|
Chris@0
|
1088 float normfact, scaled_value ;
|
Chris@0
|
1089
|
Chris@0
|
1090 normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
|
Chris@0
|
1091
|
Chris@0
|
1092 while (--count >= 0) {
|
Chris@0
|
1093 scaled_value = src [count] * normfact ;
|
Chris@0
|
1094 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF)) {
|
Chris@0
|
1095 dest [count] = 0x7FFF ;
|
Chris@0
|
1096 continue ;
|
Chris@0
|
1097 }
|
Chris@0
|
1098 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000)) {
|
Chris@0
|
1099 dest [count] = 0x8000 ;
|
Chris@0
|
1100 continue ;
|
Chris@0
|
1101 }
|
Chris@0
|
1102 dest [count] = lrintf (scaled_value) ;
|
Chris@0
|
1103 }
|
Chris@0
|
1104 } /* f2flac16_clip_array */
|
Chris@0
|
1105
|
Chris@0
|
1106 static void
|
Chris@0
|
1107 f2flac24_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1108 { float normfact, scaled_value ;
|
Chris@0
|
1109
|
Chris@0
|
1110 normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
|
Chris@0
|
1111
|
Chris@0
|
1112 while (--count >= 0)
|
Chris@0
|
1113 { scaled_value = src [count] * normfact ;
|
Chris@0
|
1114 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
|
Chris@0
|
1115 { dest [count] = 0x7FFFFF ;
|
Chris@0
|
1116 continue ;
|
Chris@0
|
1117 } ;
|
Chris@0
|
1118
|
Chris@0
|
1119 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
|
Chris@0
|
1120 { dest [count] = 0x800000 ;
|
Chris@0
|
1121 continue ;
|
Chris@0
|
1122 }
|
Chris@0
|
1123 dest [count] = lrintf (scaled_value) ;
|
Chris@0
|
1124 } ;
|
Chris@0
|
1125
|
Chris@0
|
1126 return ;
|
Chris@0
|
1127 } /* f2flac24_clip_array */
|
Chris@0
|
1128
|
Chris@0
|
1129 static void
|
Chris@0
|
1130 f2flac8_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1131 { float normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
|
Chris@0
|
1132
|
Chris@0
|
1133 while (--count >= 0)
|
Chris@0
|
1134 dest [count] = lrintf (src [count] * normfact) ;
|
Chris@0
|
1135 } /* f2flac8_array */
|
Chris@0
|
1136
|
Chris@0
|
1137 static void
|
Chris@0
|
1138 f2flac16_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1139 { float normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
|
Chris@0
|
1140
|
Chris@0
|
1141 while (--count >= 0)
|
Chris@0
|
1142 dest [count] = lrintf (src [count] * normfact) ;
|
Chris@0
|
1143 } /* f2flac16_array */
|
Chris@0
|
1144
|
Chris@0
|
1145 static void
|
Chris@0
|
1146 f2flac24_array (const float *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1147 { float normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
|
Chris@0
|
1148
|
Chris@0
|
1149 while (--count >= 0)
|
Chris@0
|
1150 dest [count] = lrintf (src [count] * normfact) ;
|
Chris@0
|
1151 } /* f2flac24_array */
|
Chris@0
|
1152
|
Chris@0
|
1153 static sf_count_t
|
Chris@0
|
1154 flac_write_d2flac (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
|
Chris@0
|
1155 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
1156 void (*convert) (const double *, FLAC__int32 *, int, int) ;
|
Chris@0
|
1157 int bufferlen, writecount, thiswrite ;
|
Chris@0
|
1158 sf_count_t total = 0 ;
|
Chris@0
|
1159 FLAC__int32* buffer = pflac->encbuffer ;
|
Chris@0
|
1160
|
Chris@0
|
1161 switch (SF_CODEC (psf->sf.format))
|
Chris@0
|
1162 { case SF_FORMAT_PCM_S8 :
|
Chris@0
|
1163 convert = (psf->add_clipping) ? d2flac8_clip_array : d2flac8_array ;
|
Chris@0
|
1164 break ;
|
Chris@0
|
1165 case SF_FORMAT_PCM_16 :
|
Chris@0
|
1166 convert = (psf->add_clipping) ? d2flac16_clip_array : d2flac16_array ;
|
Chris@0
|
1167 break ;
|
Chris@0
|
1168 case SF_FORMAT_PCM_24 :
|
Chris@0
|
1169 convert = (psf->add_clipping) ? d2flac24_clip_array : d2flac24_array ;
|
Chris@0
|
1170 break ;
|
Chris@0
|
1171 default :
|
Chris@0
|
1172 return -1 ;
|
Chris@0
|
1173 } ;
|
Chris@0
|
1174
|
Chris@0
|
1175 bufferlen = ENC_BUFFER_SIZE / (sizeof (FLAC__int32) * psf->sf.channels) ;
|
Chris@0
|
1176 bufferlen *= psf->sf.channels ;
|
Chris@0
|
1177
|
Chris@0
|
1178 while (len > 0)
|
Chris@0
|
1179 { writecount = (len >= bufferlen) ? bufferlen : (int) len ;
|
Chris@0
|
1180 convert (ptr + total, buffer, writecount, psf->norm_double) ;
|
Chris@0
|
1181 if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
|
Chris@0
|
1182 thiswrite = writecount ;
|
Chris@0
|
1183 else
|
Chris@0
|
1184 break ;
|
Chris@0
|
1185 total += thiswrite ;
|
Chris@0
|
1186 if (thiswrite < writecount)
|
Chris@0
|
1187 break ;
|
Chris@0
|
1188
|
Chris@0
|
1189 len -= thiswrite ;
|
Chris@0
|
1190 } ;
|
Chris@0
|
1191
|
Chris@0
|
1192 return total ;
|
Chris@0
|
1193 } /* flac_write_d2flac */
|
Chris@0
|
1194
|
Chris@0
|
1195 static void
|
Chris@0
|
1196 d2flac8_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1197 { double normfact, scaled_value ;
|
Chris@0
|
1198
|
Chris@0
|
1199 normfact = normalize ? (8.0 * 0x10) : 1.0 ;
|
Chris@0
|
1200
|
Chris@0
|
1201 while (--count >= 0)
|
Chris@0
|
1202 { scaled_value = src [count] * normfact ;
|
Chris@0
|
1203 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7F))
|
Chris@0
|
1204 { dest [count] = 0x7F ;
|
Chris@0
|
1205 continue ;
|
Chris@0
|
1206 } ;
|
Chris@0
|
1207 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10))
|
Chris@0
|
1208 { dest [count] = 0x80 ;
|
Chris@0
|
1209 continue ;
|
Chris@0
|
1210 } ;
|
Chris@0
|
1211 dest [count] = lrint (scaled_value) ;
|
Chris@0
|
1212 } ;
|
Chris@0
|
1213
|
Chris@0
|
1214 return ;
|
Chris@0
|
1215 } /* d2flac8_clip_array */
|
Chris@0
|
1216
|
Chris@0
|
1217 static void
|
Chris@0
|
1218 d2flac16_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1219 { double normfact, scaled_value ;
|
Chris@0
|
1220
|
Chris@0
|
1221 normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
|
Chris@0
|
1222
|
Chris@0
|
1223 while (--count >= 0)
|
Chris@0
|
1224 { scaled_value = src [count] * normfact ;
|
Chris@0
|
1225 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
|
Chris@0
|
1226 { dest [count] = 0x7FFF ;
|
Chris@0
|
1227 continue ;
|
Chris@0
|
1228 } ;
|
Chris@0
|
1229 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
|
Chris@0
|
1230 { dest [count] = 0x8000 ;
|
Chris@0
|
1231 continue ;
|
Chris@0
|
1232 } ;
|
Chris@0
|
1233 dest [count] = lrint (scaled_value) ;
|
Chris@0
|
1234 } ;
|
Chris@0
|
1235
|
Chris@0
|
1236 return ;
|
Chris@0
|
1237 } /* d2flac16_clip_array */
|
Chris@0
|
1238
|
Chris@0
|
1239 static void
|
Chris@0
|
1240 d2flac24_clip_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1241 { double normfact, scaled_value ;
|
Chris@0
|
1242
|
Chris@0
|
1243 normfact = normalize ? (8.0 * 0x100000) : 1.0 ;
|
Chris@0
|
1244
|
Chris@0
|
1245 while (--count >= 0)
|
Chris@0
|
1246 { scaled_value = src [count] * normfact ;
|
Chris@0
|
1247 if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFF))
|
Chris@0
|
1248 { dest [count] = 0x7FFFFF ;
|
Chris@0
|
1249 continue ;
|
Chris@0
|
1250 } ;
|
Chris@0
|
1251 if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x100000))
|
Chris@0
|
1252 { dest [count] = 0x800000 ;
|
Chris@0
|
1253 continue ;
|
Chris@0
|
1254 } ;
|
Chris@0
|
1255 dest [count] = lrint (scaled_value) ;
|
Chris@0
|
1256 } ;
|
Chris@0
|
1257
|
Chris@0
|
1258 return ;
|
Chris@0
|
1259 } /* d2flac24_clip_array */
|
Chris@0
|
1260
|
Chris@0
|
1261 static void
|
Chris@0
|
1262 d2flac8_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1263 { double normfact = normalize ? (1.0 * 0x7F) : 1.0 ;
|
Chris@0
|
1264
|
Chris@0
|
1265 while (--count >= 0)
|
Chris@0
|
1266 dest [count] = lrint (src [count] * normfact) ;
|
Chris@0
|
1267 } /* d2flac8_array */
|
Chris@0
|
1268
|
Chris@0
|
1269 static void
|
Chris@0
|
1270 d2flac16_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1271 { double normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
|
Chris@0
|
1272
|
Chris@0
|
1273 while (--count >= 0)
|
Chris@0
|
1274 dest [count] = lrint (src [count] * normfact) ;
|
Chris@0
|
1275 } /* d2flac16_array */
|
Chris@0
|
1276
|
Chris@0
|
1277 static void
|
Chris@0
|
1278 d2flac24_array (const double *src, FLAC__int32 *dest, int count, int normalize)
|
Chris@0
|
1279 { double normfact = normalize ? (1.0 * 0x7FFFFF) : 1.0 ;
|
Chris@0
|
1280
|
Chris@0
|
1281 while (--count >= 0)
|
Chris@0
|
1282 dest [count] = lrint (src [count] * normfact) ;
|
Chris@0
|
1283 } /* d2flac24_array */
|
Chris@0
|
1284
|
Chris@0
|
1285 static sf_count_t
|
Chris@0
|
1286 flac_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
|
Chris@0
|
1287 { FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
|
Chris@0
|
1288
|
Chris@0
|
1289 if (pflac == NULL)
|
Chris@0
|
1290 return 0 ;
|
Chris@0
|
1291
|
Chris@0
|
1292 if (psf->dataoffset < 0)
|
Chris@0
|
1293 { psf->error = SFE_BAD_SEEK ;
|
Chris@0
|
1294 return ((sf_count_t) -1) ;
|
Chris@0
|
1295 } ;
|
Chris@0
|
1296
|
Chris@0
|
1297 pflac->frame = NULL ;
|
Chris@0
|
1298
|
Chris@0
|
1299 if (psf->file.mode == SFM_READ)
|
Chris@0
|
1300 { FLAC__uint64 position ;
|
Chris@0
|
1301 if (FLAC__stream_decoder_seek_absolute (pflac->fsd, offset))
|
Chris@0
|
1302 { FLAC__stream_decoder_get_decode_position (pflac->fsd, &position) ;
|
Chris@0
|
1303 return offset ;
|
Chris@0
|
1304 } ;
|
Chris@0
|
1305
|
Chris@0
|
1306 return ((sf_count_t) -1) ;
|
Chris@0
|
1307 } ;
|
Chris@0
|
1308
|
Chris@0
|
1309 /* Seeking in write mode not yet supported. */
|
Chris@0
|
1310 psf->error = SFE_BAD_SEEK ;
|
Chris@0
|
1311
|
Chris@0
|
1312 return ((sf_count_t) -1) ;
|
Chris@0
|
1313 } /* flac_seek */
|
Chris@0
|
1314
|
Chris@0
|
1315 #else /* HAVE_EXTERNAL_LIBS */
|
Chris@0
|
1316
|
Chris@0
|
1317 int
|
Chris@0
|
1318 flac_open (SF_PRIVATE *psf)
|
Chris@0
|
1319 {
|
Chris@0
|
1320 psf_log_printf (psf, "This version of libsndfile was compiled without FLAC support.\n") ;
|
Chris@0
|
1321 return SFE_UNIMPLEMENTED ;
|
Chris@0
|
1322 } /* flac_open */
|
Chris@0
|
1323
|
Chris@0
|
1324 #endif
|