]> 4ch.mooo.com Git - 16.git/blob - src/lib/dl/ext/vorbtool/flac.c
meh did some cleanings and i will work on mapread to mm thingy sometime soon! oops...
[16.git] / src / lib / dl / ext / vorbtool / flac.c
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  **/
9
10 #ifdef HAVE_CONFIG_H
11 #include "config.h"
12 #endif
13
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"
25
26 #if !defined(FLAC_API_VERSION_CURRENT) || (FLAC_API_VERSION_CURRENT < 8)
27 #define NEED_EASYFLAC 1
28 #endif
29
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
42
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);
45
46
47 int flac_id(unsigned char *buf, int len)
48 {
49     if (len < 4) return 0;
50
51     return memcmp(buf, "fLaC", 4) == 0;
52 }
53
54
55 int oggflac_id(unsigned char *buf, int len)
56 {
57     if (len < 33) return 0;
58
59     return memcmp(buf, "OggS", 4) == 0 &&
60            (memcmp (buf+28, "\177FLAC", 5) == 0 || flac_id(buf+28, len - 28));
61 }
62
63
64 int flac_open(FILE *in, oe_enc_opt *opt, unsigned char *oldbuf, int buflen)
65 {
66     flacfile *flac = malloc(sizeof(flacfile));
67
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;
75
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;
82
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;
88
89     /* Need to save FILE pointer for read callback */
90     flac->in = in;
91
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
113
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
120
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
128
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;
141
142     return 1;
143 }
144
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] = 
148 {
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,4,5,6,3},  /* 6.1 surround */
156   {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */
157 };
158
159 long flac_read(void *in, float **buffer, int samples)
160 {
161     flacfile *flac = (flacfile *)in;
162     long realsamples = 0;
163     FLAC__bool ret;
164     int i,j;
165     while (realsamples < samples)
166     {
167         if (flac->buf_fill > 0)
168         {
169             int copy = flac->buf_fill < (samples - realsamples) ?
170                 flac->buf_fill : (samples - realsamples);
171
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];
177             }
178             flac->buf_start += copy;
179             flac->buf_fill -= copy;
180             realsamples += copy;
181         }
182         else if (!flac->eos)
183         {
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;
199     }
200
201     return realsamples;
202 }
203
204 void flac_close(void *info)
205 {
206     int i;
207     flacfile *flac =  (flacfile *) info;
208
209     for (i = 0; i < flac->channels; i++)
210         free(flac->buf[i]);
211
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);
223 }
224
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
230 {
231     flacfile *flac = (flacfile *) client_data;
232     int i = 0;
233     int oldbuf_fill = flac->oldbuf_len - flac->oldbuf_start;
234
235     /* Immediately return if errors occured */
236     if(feof(flac->in))
237     {
238         *bytes = 0;
239         return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
240     }
241     else if(ferror(flac->in))
242     {
243         *bytes = 0;
244         return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
245     }
246
247
248     if(oldbuf_fill > 0) 
249     {
250         int copy;
251
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;
256     }
257
258     if(i < *bytes)
259         i += fread(buffer+i, sizeof(FLAC__byte), *bytes - i, flac->in);
260
261     *bytes = i;
262
263     return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
264 }
265
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
271 {
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;
277
278     resize_buffer(flac, channels, samples);
279
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));
284
285     flac->buf_start = 0;
286     flac->buf_fill = samples;
287
288     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
289 }
290
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
296 {
297     flacfile *flac = (flacfile *) client_data;
298
299     switch (metadata->type)
300     {
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;
305
306     case FLAC__METADATA_TYPE_VORBIS_COMMENT:
307         flac->comments = FLAC__metadata_object_clone(metadata);
308         break;
309     default:
310         break;
311     }
312 }
313
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
319 {
320     flacfile *flac = (flacfile *) client_data;
321
322 }
323
324 #if !NEED_EASYFLAC
325 FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
326 {
327     flacfile *flac = (flacfile *) client_data;
328
329     return feof(flac->in)? true : false;
330 }
331 #endif
332
333 void resize_buffer(flacfile *flac, int newchannels, int newsamples)
334 {
335     int i;
336
337     if (newchannels == flac->channels && newsamples == flac->buf_len)
338     {
339         flac->buf_start = 0;
340         flac->buf_fill = 0;
341         return;
342     }
343
344
345     /* Not the most efficient approach, but it is easy to follow */
346     if(newchannels != flac->channels)
347     {
348         /* Deallocate all of the sample vectors */
349         for (i = 0; i < flac->channels; i++)
350             free(flac->buf[i]);
351
352         flac->buf = realloc(flac->buf, sizeof(float*) * newchannels);
353         flac->channels = newchannels;
354
355     }
356
357     for (i = 0; i < newchannels; i++)
358         flac->buf[i] = malloc(sizeof(float) * newsamples);
359
360     flac->buf_len = newsamples;
361     flac->buf_start = 0;
362     flac->buf_fill = 0;
363 }
364
365 void copy_comments (vorbis_comment *v_comments, FLAC__StreamMetadata_VorbisComment *f_comments)
366 {
367     int i;
368
369     for (i = 0; i < f_comments->num_comments; i++)
370     {
371         char *comment = malloc(f_comments->comments[i].length + 1);
372         memset(comment, '\0', f_comments->comments[i].length + 1);
373         strncpy(comment, f_comments->comments[i].entry, f_comments->comments[i].length);
374         vorbis_comment_add(v_comments, comment);
375         free(comment);
376     }
377 }