annotate src/libsndfile-1.0.25/src/flac.c @ 0:c7265573341e

Import initial set of sources
author Chris Cannam
date Mon, 18 Mar 2013 14:12:14 +0000
parents
children
rev   line source
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