Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / vorbis-tools / oggenc / flac.c
blobca9a1f00e9bbba7eb7747873c053efcca76e7916
1 /* OggEnc
2 **
3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
5 **
6 ** Copyright 2002, Stan Seibert <volsung@xiph.org>
7 **
8 **/
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <sys/types.h>
18 #include <math.h>
19 #include <FLAC/metadata.h>
20 #include "audio.h"
21 #include "flac.h"
22 #include "i18n.h"
23 #include "platform.h"
24 #include "resample.h"
26 #if !defined(FLAC_API_VERSION_CURRENT) || (FLAC_API_VERSION_CURRENT < 8)
27 #define NEED_EASYFLAC 1
28 #endif
30 #if NEED_EASYFLAC
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);
35 #else
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);
41 #endif
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));
68 flac->decoder = NULL;
69 flac->channels = 0;
70 flac->rate = 0;
71 flac->totalsamples = 0;
72 flac->comments = NULL;
73 flac->in = NULL;
74 flac->eos = 0;
76 /* Setup empty audio buffer that will be resized on first frame
77 callback */
78 flac->buf = NULL;
79 flac->buf_len = 0;
80 flac->buf_start = 0;
81 flac->buf_fill = 0;
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 */
90 flac->in = in;
92 /* Setup FLAC decoder */
93 #if NEED_EASYFLAC
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);
103 #else
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);
110 else
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);
112 #endif
114 /* Callback will set the total samples and sample rate */
115 #if NEED_EASYFLAC
116 EasyFLAC__process_until_end_of_metadata(flac->decoder);
117 #else
118 FLAC__stream_decoder_process_until_end_of_metadata(flac->decoder);
119 #endif
121 /* Callback will set the number of channels and resize the
122 audio buffer */
123 #if NEED_EASYFLAC
124 EasyFLAC__process_single(flac->decoder);
125 #else
126 FLAC__stream_decoder_process_single(flac->decoder);
127 #endif
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
136 callback)*/
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;
142 return 1;
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] =
149 {0}, /* 1.0 mono */
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;
163 FLAC__bool ret;
164 int i,j;
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;
180 realsamples += copy;
182 else if (!flac->eos)
184 #if NEED_EASYFLAC
185 ret = EasyFLAC__process_single(flac->decoder);
186 if (!ret ||
187 EasyFLAC__get_state(flac->decoder)
188 == FLAC__STREAM_DECODER_END_OF_STREAM)
189 flac->eos = 1; /* Bail out! */
190 #else
191 ret = FLAC__stream_decoder_process_single(flac->decoder);
192 if (!ret ||
193 FLAC__stream_decoder_get_state(flac->decoder)
194 == FLAC__STREAM_DECODER_END_OF_STREAM)
195 flac->eos = 1; /* Bail out! */
196 #endif
197 } else
198 break;
201 return realsamples;
204 void flac_close(void *info)
206 int i;
207 flacfile *flac = (flacfile *) info;
209 for (i = 0; i < flac->channels; i++)
210 free(flac->buf[i]);
212 free(flac->buf);
213 free(flac->oldbuf);
214 free(flac->comments);
215 #if NEED_EASYFLAC
216 EasyFLAC__finish(flac->decoder);
217 EasyFLAC__stream_decoder_delete(flac->decoder);
218 #else
219 FLAC__stream_decoder_finish(flac->decoder);
220 FLAC__stream_decoder_delete(flac->decoder);
221 #endif
222 free(flac);
225 #if NEED_EASYFLAC
226 FLAC__StreamDecoderReadStatus easyflac_read_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
227 #else
228 FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
229 #endif
231 flacfile *flac = (flacfile *) client_data;
232 int i = 0;
233 int oldbuf_fill = flac->oldbuf_len - flac->oldbuf_start;
235 /* Immediately return if errors occured */
236 if(feof(flac->in))
238 *bytes = 0;
239 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
241 else if(ferror(flac->in))
243 *bytes = 0;
244 return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
248 if(oldbuf_fill > 0)
250 int copy;
252 copy = oldbuf_fill < (*bytes - i) ? oldbuf_fill : (*bytes - i);
253 memcpy(buffer + i, flac->oldbuf, copy);
254 i += copy;
255 flac->oldbuf_start += copy;
258 if(i < *bytes)
259 i += fread(buffer+i, sizeof(FLAC__byte), *bytes - i, flac->in);
261 *bytes = i;
263 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
266 #if NEED_EASYFLAC
267 FLAC__StreamDecoderWriteStatus easyflac_write_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
268 #else
269 FLAC__StreamDecoderWriteStatus write_callback(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
270 #endif
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;
276 int i, j;
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));
285 flac->buf_start = 0;
286 flac->buf_fill = samples;
288 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
291 #if NEED_EASYFLAC
292 void easyflac_metadata_callback(const EasyFLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
293 #else
294 void metadata_callback(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
295 #endif
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;
304 break;
306 case FLAC__METADATA_TYPE_VORBIS_COMMENT:
307 flac->comments = FLAC__metadata_object_clone(metadata);
308 break;
309 default:
310 break;
314 #if NEED_EASYFLAC
315 void easyflac_error_callback(const EasyFLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
316 #else
317 void error_callback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
318 #endif
320 flacfile *flac = (flacfile *) client_data;
324 #if !NEED_EASYFLAC
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;
331 #endif
333 void resize_buffer(flacfile *flac, int newchannels, int newsamples)
335 int i;
337 if (newchannels == flac->channels && newsamples == flac->buf_len)
339 flac->buf_start = 0;
340 flac->buf_fill = 0;
341 return;
344 /* Deallocate all of the sample vectors */
345 for (i = 0; i < flac->channels; i++)
346 free(flac->buf[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;
359 flac->buf_start = 0;
360 flac->buf_fill = 0;
363 void copy_comments (vorbis_comment *v_comments, FLAC__StreamMetadata_VorbisComment *f_comments)
365 int i;
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);
373 free(comment);