3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
6 ** Copyright 2002, Stan Seibert <volsung@xiph.org>
17 #include <sys/types.h>
19 #include <FLAC/metadata.h>
26 #if !defined(FLAC_API_VERSION_CURRENT) || (FLAC_API_VERSION_CURRENT < 8)
27 #define NEED_EASYFLAC 1
31 static FLAC__StreamDecoderReadStatus
easyflac_read_callback(const EasyFLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
);
32 static FLAC__StreamDecoderWriteStatus
easyflac_write_callback(const EasyFLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
);
33 static void easyflac_metadata_callback(const EasyFLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
);
34 static void easyflac_error_callback(const EasyFLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
);
36 static FLAC__StreamDecoderReadStatus
read_callback(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], size_t *bytes
, void *client_data
);
37 static FLAC__StreamDecoderWriteStatus
write_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
);
38 static void metadata_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
);
39 static void error_callback(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
);
40 static FLAC__bool
eof_callback(const FLAC__StreamDecoder
*decoder
, void *client_data
);
43 static void resize_buffer(flacfile
*flac
, int newchannels
, int newsamples
);
44 static void copy_comments (vorbis_comment
*v_comments
, FLAC__StreamMetadata_VorbisComment
*f_comments
);
47 int flac_id(unsigned char *buf
, int len
)
49 if (len
< 4) return 0;
51 return memcmp(buf
, "fLaC", 4) == 0;
55 int oggflac_id(unsigned char *buf
, int len
)
57 if (len
< 33) return 0;
59 return memcmp(buf
, "OggS", 4) == 0 &&
60 (memcmp (buf
+28, "\177FLAC", 5) == 0 || flac_id(buf
+28, len
- 28));
64 int flac_open(FILE *in
, oe_enc_opt
*opt
, unsigned char *oldbuf
, int buflen
)
66 flacfile
*flac
= malloc(sizeof(flacfile
));
71 flac
->totalsamples
= 0;
72 flac
->comments
= NULL
;
76 /* Setup empty audio buffer that will be resized on first frame
83 /* Copy old input data over */
84 flac
->oldbuf
= malloc(buflen
);
85 flac
->oldbuf_len
= buflen
;
86 memcpy(flac
->oldbuf
, oldbuf
, buflen
);
87 flac
->oldbuf_start
= 0;
89 /* Need to save FILE pointer for read callback */
92 /* Setup FLAC decoder */
94 flac
->decoder
= EasyFLAC__stream_decoder_new(oggflac_id(oldbuf
, buflen
));
95 EasyFLAC__set_client_data(flac
->decoder
, flac
);
96 EasyFLAC__set_read_callback(flac
->decoder
, &easyflac_read_callback
);
97 EasyFLAC__set_write_callback(flac
->decoder
, &easyflac_write_callback
);
98 EasyFLAC__set_metadata_callback(flac
->decoder
, &easyflac_metadata_callback
);
99 EasyFLAC__set_error_callback(flac
->decoder
, &easyflac_error_callback
);
100 EasyFLAC__set_metadata_respond(flac
->decoder
, FLAC__METADATA_TYPE_STREAMINFO
);
101 EasyFLAC__set_metadata_respond(flac
->decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
);
102 EasyFLAC__init(flac
->decoder
);
104 flac
->decoder
= FLAC__stream_decoder_new();
105 FLAC__stream_decoder_set_md5_checking(flac
->decoder
, false);
106 FLAC__stream_decoder_set_metadata_respond(flac
->decoder
, FLAC__METADATA_TYPE_STREAMINFO
);
107 FLAC__stream_decoder_set_metadata_respond(flac
->decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
);
108 if(oggflac_id(oldbuf
, buflen
))
109 FLAC__stream_decoder_init_ogg_stream(flac
->decoder
, read_callback
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, eof_callback
, write_callback
, metadata_callback
, error_callback
, flac
);
111 FLAC__stream_decoder_init_stream(flac
->decoder
, read_callback
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, eof_callback
, write_callback
, metadata_callback
, error_callback
, flac
);
114 /* Callback will set the total samples and sample rate */
116 EasyFLAC__process_until_end_of_metadata(flac
->decoder
);
118 FLAC__stream_decoder_process_until_end_of_metadata(flac
->decoder
);
121 /* Callback will set the number of channels and resize the
124 EasyFLAC__process_single(flac
->decoder
);
126 FLAC__stream_decoder_process_single(flac
->decoder
);
129 /* Copy format info for caller */
130 opt
->rate
= flac
->rate
;
131 opt
->channels
= flac
->channels
;
132 /* flac->total_samples_per_channel was already set by metadata
133 callback when metadata was processed. */
134 opt
->total_samples_per_channel
= flac
->totalsamples
;
135 /* Copy Vorbis-style comments from FLAC file (read in metadata
137 if (flac
->comments
!= NULL
&& opt
->copy_comments
)
138 copy_comments(opt
->comments
, &flac
->comments
->data
.vorbis_comment
);
139 opt
->read_samples
= flac_read
;
140 opt
->readdata
= (void *)flac
;
145 /* FLAC follows the WAV channel ordering pattern; we must permute to
146 put things in Vorbis channel order */
147 static int wav_permute_matrix
[8][8] =
150 {0,1}, /* 2.0 stereo */
151 {0,2,1}, /* 3.0 channel ('wide') stereo */
152 {0,1,2,3}, /* 4.0 discrete quadraphonic */
153 {0,2,1,3,4}, /* 5.0 surround */
154 {0,2,1,4,5,3}, /* 5.1 surround */
155 {0,2,1,5,6,4,3}, /* 6.1 surround */
156 {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */
159 long flac_read(void *in
, float **buffer
, int samples
)
161 flacfile
*flac
= (flacfile
*)in
;
162 long realsamples
= 0;
165 while (realsamples
< samples
)
167 if (flac
->buf_fill
> 0)
169 int copy
= flac
->buf_fill
< (samples
- realsamples
) ?
170 flac
->buf_fill
: (samples
- realsamples
);
172 for (i
= 0; i
< flac
->channels
; i
++){
173 int permute
= wav_permute_matrix
[flac
->channels
-1][i
];
174 for (j
= 0; j
< copy
; j
++)
175 buffer
[i
][j
+realsamples
] =
176 flac
->buf
[permute
][j
+flac
->buf_start
];
178 flac
->buf_start
+= copy
;
179 flac
->buf_fill
-= copy
;
185 ret
= EasyFLAC__process_single(flac
->decoder
);
187 EasyFLAC__get_state(flac
->decoder
)
188 == FLAC__STREAM_DECODER_END_OF_STREAM
)
189 flac
->eos
= 1; /* Bail out! */
191 ret
= FLAC__stream_decoder_process_single(flac
->decoder
);
193 FLAC__stream_decoder_get_state(flac
->decoder
)
194 == FLAC__STREAM_DECODER_END_OF_STREAM
)
195 flac
->eos
= 1; /* Bail out! */
204 void flac_close(void *info
)
207 flacfile
*flac
= (flacfile
*) info
;
209 for (i
= 0; i
< flac
->channels
; i
++)
214 free(flac
->comments
);
216 EasyFLAC__finish(flac
->decoder
);
217 EasyFLAC__stream_decoder_delete(flac
->decoder
);
219 FLAC__stream_decoder_finish(flac
->decoder
);
220 FLAC__stream_decoder_delete(flac
->decoder
);
226 FLAC__StreamDecoderReadStatus
easyflac_read_callback(const EasyFLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], unsigned *bytes
, void *client_data
)
228 FLAC__StreamDecoderReadStatus
read_callback(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
231 flacfile
*flac
= (flacfile
*) client_data
;
233 int oldbuf_fill
= flac
->oldbuf_len
- flac
->oldbuf_start
;
235 /* Immediately return if errors occured */
239 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
241 else if(ferror(flac
->in
))
244 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
252 copy
= oldbuf_fill
< (*bytes
- i
) ? oldbuf_fill
: (*bytes
- i
);
253 memcpy(buffer
+ i
, flac
->oldbuf
, copy
);
255 flac
->oldbuf_start
+= copy
;
259 i
+= fread(buffer
+i
, sizeof(FLAC__byte
), *bytes
- i
, flac
->in
);
263 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
267 FLAC__StreamDecoderWriteStatus
easyflac_write_callback(const EasyFLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
269 FLAC__StreamDecoderWriteStatus
write_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
272 flacfile
*flac
= (flacfile
*) client_data
;
273 int samples
= frame
->header
.blocksize
;
274 int channels
= frame
->header
.channels
;
275 int bits_per_sample
= frame
->header
.bits_per_sample
;
278 resize_buffer(flac
, channels
, samples
);
280 for (i
= 0; i
< channels
; i
++)
281 for (j
= 0; j
< samples
; j
++)
282 flac
->buf
[i
][j
] = buffer
[i
][j
] /
283 (float) (1 << (bits_per_sample
- 1));
286 flac
->buf_fill
= samples
;
288 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
292 void easyflac_metadata_callback(const EasyFLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
294 void metadata_callback(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
297 flacfile
*flac
= (flacfile
*) client_data
;
299 switch (metadata
->type
)
301 case FLAC__METADATA_TYPE_STREAMINFO
:
302 flac
->totalsamples
= metadata
->data
.stream_info
.total_samples
;
303 flac
->rate
= metadata
->data
.stream_info
.sample_rate
;
306 case FLAC__METADATA_TYPE_VORBIS_COMMENT
:
307 flac
->comments
= FLAC__metadata_object_clone(metadata
);
315 void easyflac_error_callback(const EasyFLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
317 void error_callback(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
320 flacfile
*flac
= (flacfile
*) client_data
;
325 FLAC__bool
eof_callback(const FLAC__StreamDecoder
*decoder
, void *client_data
)
327 flacfile
*flac
= (flacfile
*) client_data
;
329 return feof(flac
->in
)? true : false;
333 void resize_buffer(flacfile
*flac
, int newchannels
, int newsamples
)
337 if (newchannels
== flac
->channels
&& newsamples
== flac
->buf_len
)
344 /* Deallocate all of the sample vectors */
345 for (i
= 0; i
< flac
->channels
; i
++)
348 /* Not the most efficient approach, but it is easy to follow */
349 if(newchannels
!= flac
->channels
)
351 flac
->buf
= realloc(flac
->buf
, sizeof(float*) * newchannels
);
352 flac
->channels
= newchannels
;
355 for (i
= 0; i
< newchannels
; i
++)
356 flac
->buf
[i
] = malloc(sizeof(float) * newsamples
);
358 flac
->buf_len
= newsamples
;
363 void copy_comments (vorbis_comment
*v_comments
, FLAC__StreamMetadata_VorbisComment
*f_comments
)
367 for (i
= 0; i
< f_comments
->num_comments
; i
++)
369 char *comment
= malloc(f_comments
->comments
[i
].length
+ 1);
370 memset(comment
, '\0', f_comments
->comments
[i
].length
+ 1);
371 strncpy(comment
, f_comments
->comments
[i
].entry
, f_comments
->comments
[i
].length
);
372 vorbis_comment_add(v_comments
, comment
);