1 /*
2 * Copyright (c) 2011 Tim van der Molen <tim@kariliq.nl>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 #include "../siren.h"
21
22 #ifdef HAVE_NEW_FLAC_INCLUDE_PATH
23 #include <FLAC/metadata.h>
24 #include <FLAC/stream_decoder.h>
25 #else
26 #include <metadata.h>
27 #include <stream_decoder.h>
28 #endif
29
30 #define IP_FLAC_ERROR -1
31 #define IP_FLAC_EOF 0
32 #define IP_FLAC_OK 1
33
34 struct ip_flac_ipdata {
35 FLAC__StreamDecoder *decoder;
36
37 unsigned int cursample;
38
39 const FLAC__int32 * const *buf;
40 unsigned int bufidx;
41 unsigned int buflen;
42 };
43
44 static void ip_flac_close(struct track *);
45 static void ip_flac_get_metadata(struct track *);
46 static int ip_flac_get_position(struct track *, unsigned int *);
47 static int ip_flac_open(struct track *);
48 static int ip_flac_read(struct track *, struct sample_buffer *);
49 static void ip_flac_seek(struct track *, unsigned int);
50 static FLAC__StreamDecoderWriteStatus ip_flac_write_cb(
51 const FLAC__StreamDecoder *, const FLAC__Frame *,
52 const FLAC__int32 * const *, void *);
53
54 static const char *ip_flac_error_status_to_string(
55 FLAC__StreamDecoderErrorStatus);
56 static const char *ip_flac_init_status_to_string(
57 FLAC__StreamDecoderInitStatus);
58 static const char *ip_flac_state_to_string(FLAC__StreamDecoderState);
59
60 static const char *ip_flac_extensions[] = { "flac", NULL };
61
62 const struct ip ip = {
63 "flac",
64 IP_PRIORITY_FLAC,
65 ip_flac_extensions,
66 ip_flac_close,
67 ip_flac_get_metadata,
68 ip_flac_get_position,
69 NULL,
70 ip_flac_open,
71 ip_flac_read,
72 ip_flac_seek
73 };
74
75 static void
ip_flac_close(struct track * t)76 ip_flac_close(struct track *t)
77 {
78 struct ip_flac_ipdata *ipd;
79
80 ipd = t->ipdata;
81 FLAC__stream_decoder_finish(ipd->decoder);
82 FLAC__stream_decoder_delete(ipd->decoder);
83 free(ipd);
84 }
85
86 static void
ip_flac_error_cb(UNUSED const FLAC__StreamDecoder * decoder,FLAC__StreamDecoderErrorStatus error,void * tp)87 ip_flac_error_cb(UNUSED const FLAC__StreamDecoder *decoder,
88 FLAC__StreamDecoderErrorStatus error, void *tp)
89 {
90 struct track *t;
91
92 t = tp;
93 LOG_ERRX("%s: %s", t->path, ip_flac_error_status_to_string(error));
94 }
95
96 static int
ip_flac_fill_buffer(const char * path,struct ip_flac_ipdata * ipd)97 ip_flac_fill_buffer(const char *path, struct ip_flac_ipdata *ipd)
98 {
99 FLAC__bool ret;
100 FLAC__StreamDecoderState state;
101
102 ipd->bufidx = 0;
103 ipd->buflen = 0;
104
105 for (;;) {
106 ret = FLAC__stream_decoder_process_single(ipd->decoder);
107 state = FLAC__stream_decoder_get_state(ipd->decoder);
108
109 if (ipd->buflen)
110 return IP_FLAC_OK;
111 if (state == FLAC__STREAM_DECODER_END_OF_STREAM)
112 return IP_FLAC_EOF;
113 if (ret == false) {
114 LOG_ERRX("FLAC__stream_decoder_process_single: %s: %s",
115 path, ip_flac_state_to_string(state));
116 msg_errx("Cannot read from track: %s",
117 ip_flac_state_to_string(state));
118 return IP_FLAC_ERROR;
119 }
120 }
121 }
122
123 static void
ip_flac_get_metadata(struct track * t)124 ip_flac_get_metadata(struct track *t)
125 {
126 FLAC__StreamMetadata streaminfo, *comments;
127 FLAC__uint32 i;
128
129 if (FLAC__metadata_get_tags(t->path, &comments) == false) {
130 LOG_ERRX("%s: FLAC__metadata_get_tags() failed", t->path);
131 msg_errx("%s: Cannot get metadata", t->path);
132 return;
133 }
134
135 for (i = 0; i < comments->data.vorbis_comment.num_comments; i++)
136 track_copy_vorbis_comment(t,
137 (char *)comments->data.vorbis_comment.comments[i].entry);
138
139 FLAC__metadata_object_delete(comments);
140
141 if (FLAC__metadata_get_streaminfo(t->path, &streaminfo) == false) {
142 LOG_ERRX("%s: FLAC__metadata_get_streaminfo() failed",
143 t->path);
144 msg_errx("%s: Cannot get stream information", t->path);
145 return;
146 }
147
148 if (streaminfo.data.stream_info.sample_rate != 0)
149 t->duration = streaminfo.data.stream_info.total_samples /
150 streaminfo.data.stream_info.sample_rate;
151 }
152
153 static int
ip_flac_get_position(struct track * t,unsigned int * pos)154 ip_flac_get_position(struct track *t, unsigned int *pos)
155 {
156 struct ip_flac_ipdata *ipd;
157
158 if (t->format.rate == 0)
159 *pos = 0;
160 else {
161 ipd = t->ipdata;
162 *pos = (ipd->cursample + ipd->bufidx) / t->format.rate;
163 }
164
165 return 0;
166 }
167
168 static int
ip_flac_open(struct track * t)169 ip_flac_open(struct track *t)
170 {
171 struct ip_flac_ipdata *ipd;
172 FLAC__StreamDecoderInitStatus status;
173 FLAC__StreamMetadata metadata;
174 FILE *fp;
175
176 ipd = xmalloc(sizeof *ipd);
177
178 if ((ipd->decoder = FLAC__stream_decoder_new()) == NULL) {
179 LOG_ERRX("%s: FLAC__stream_decoder_new() failed", t->path);
180 msg_errx("%s: Cannot allocate memory for FLAC decoder",
181 t->path);
182 goto error1;
183 }
184
185 if ((fp = fopen(t->path, "r")) == NULL) {
186 LOG_ERR("fopen: %s", t->path);
187 msg_err("%s: Cannot open track", t->path);
188 goto error2;
189 }
190
191 status = FLAC__stream_decoder_init_FILE(ipd->decoder, fp,
192 ip_flac_write_cb, NULL, ip_flac_error_cb, t);
193
194 if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
195 LOG_ERRX("FLAC__stream_decoder_init: %s: %s", t->path,
196 ip_flac_init_status_to_string(status));
197 msg_errx("%s: Cannot initialise FLAC decoder: %s", t->path,
198 ip_flac_init_status_to_string(status));
199 fclose(fp);
200 goto error2;
201 }
202
203 if (FLAC__metadata_get_streaminfo(t->path, &metadata) == false) {
204 LOG_ERRX("%s: FLAC__metadata_get_streaminfo() failed",
205 t->path);
206 msg_errx("%s: Cannot get stream information", t->path);
207 goto error3;
208 }
209
210 t->format.nbits = metadata.data.stream_info.bits_per_sample;
211 t->format.nchannels = metadata.data.stream_info.channels;
212 t->format.rate = metadata.data.stream_info.sample_rate;
213
214 ipd->bufidx = 0;
215 ipd->buflen = 0;
216 ipd->cursample = 0;
217
218 t->ipdata = ipd;
219 return 0;
220
221 error3:
222 FLAC__stream_decoder_finish(ipd->decoder);
223 error2:
224 FLAC__stream_decoder_delete(ipd->decoder);
225 error1:
226 free(ipd);
227 return -1;
228 }
229
230 static int
ip_flac_read(struct track * t,struct sample_buffer * sb)231 ip_flac_read(struct track *t, struct sample_buffer *sb)
232 {
233 struct ip_flac_ipdata *ipd;
234 size_t i;
235 unsigned int j;
236 int ret;
237
238 ipd = t->ipdata;
239
240 i = 0;
241 while (i + t->format.nchannels <= sb->size_s) {
242 if (ipd->bufidx == ipd->buflen) {
243 ret = ip_flac_fill_buffer(t->path, ipd);
244 if (ret == IP_FLAC_EOF)
245 break;
246 if (ret == IP_FLAC_ERROR)
247 return -1;
248 }
249
250 switch (sb->nbytes) {
251 case 1:
252 for (j = 0; j < t->format.nchannels; j++)
253 sb->data1[i++] = ipd->buf[j][ipd->bufidx];
254 break;
255 case 2:
256 for (j = 0; j < t->format.nchannels; j++)
257 sb->data2[i++] = ipd->buf[j][ipd->bufidx];
258 break;
259 case 4:
260 for (j = 0; j < t->format.nchannels; j++)
261 sb->data4[i++] = ipd->buf[j][ipd->bufidx];
262 break;
263 }
264
265 ipd->bufidx++;
266 }
267
268 sb->len_s = i;
269 sb->len_b = sb->len_s * sb->nbytes;
270 return sb->len_s != 0;
271 }
272
273 static void
ip_flac_seek(struct track * t,unsigned int sec)274 ip_flac_seek(struct track *t, unsigned int sec)
275 {
276 struct ip_flac_ipdata *ipd;
277 FLAC__StreamDecoderState state;
278 unsigned int nsamples, sample;
279
280 ipd = t->ipdata;
281 sample = sec * t->format.rate;
282 nsamples = FLAC__stream_decoder_get_total_samples(ipd->decoder);
283
284 if (sample >= nsamples)
285 sample = nsamples > 0 ? nsamples - 1 : 0;
286
287 if (FLAC__stream_decoder_seek_absolute(ipd->decoder, sample) ==
288 false) {
289 state = FLAC__stream_decoder_get_state(ipd->decoder);
290
291 LOG_ERRX("FLAC__stream_decoder_seek_absolute: %s: %s", t->path,
292 ip_flac_state_to_string(state));
293 msg_errx("Cannot seek: %s", ip_flac_state_to_string(state));
294
295 /* The decoder must be flushed after a seek error. */
296 if (state == FLAC__STREAM_DECODER_SEEK_ERROR) {
297 FLAC__stream_decoder_flush(ipd->decoder);
298 ipd->bufidx = 0;
299 }
300 } else {
301 ipd->cursample = sample;
302 ipd->bufidx = 0;
303 ipd->buflen = 0;
304 }
305 }
306
307 static FLAC__StreamDecoderWriteStatus
ip_flac_write_cb(UNUSED const FLAC__StreamDecoder * decoder,const FLAC__Frame * frame,const FLAC__int32 * const * buffer,void * tp)308 ip_flac_write_cb(UNUSED const FLAC__StreamDecoder *decoder,
309 const FLAC__Frame *frame, const FLAC__int32 * const *buffer, void *tp)
310 {
311 struct track *t;
312 struct ip_flac_ipdata *ipd;
313
314 t = tp;
315 ipd = t->ipdata;
316
317 if (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)
318 /* Fixed blocksize. */
319 ipd->cursample += frame->header.blocksize;
320 else
321 /* Variable blocksize. */
322 ipd->cursample = frame->header.number.sample_number;
323
324 ipd->buf = buffer;
325 ipd->buflen = frame->header.blocksize;
326
327 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
328 }
329
330 /*
331 * The FLAC__StreamDecoderErrorStatusString,
332 * FLAC__StreamDecoderInitStatusString and FLAC__StreamDecoderStateString
333 * string arrays do not provide very useful messages, so we use the messages
334 * from the functions below instead. The messages are based on information in
335 * <https://www.xiph.org/flac/api/group__flac__stream__decoder.html>.
336 */
337
338 static const char *
ip_flac_error_status_to_string(FLAC__StreamDecoderErrorStatus status)339 ip_flac_error_status_to_string(FLAC__StreamDecoderErrorStatus status)
340 {
341 switch (status) {
342 case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
343 return "Lost synchronisation";
344 case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
345 return "Corrupted frame header";
346 case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
347 return "Frame CRC mismatched";
348 case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
349 return "Reserved fields encountered";
350 default:
351 return "Unknown error status";
352 }
353 }
354
355 static const char *
ip_flac_init_status_to_string(FLAC__StreamDecoderInitStatus status)356 ip_flac_init_status_to_string(FLAC__StreamDecoderInitStatus status)
357 {
358 switch (status) {
359 case FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER:
360 return "Unsupported container format";
361 case FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS:
362 return "Required callback not supplied";
363 case FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR:
364 return "Memory allocation error";
365 case FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED:
366 return "Already initialised";
367 default:
368 return "Unknown initialisation status";
369 }
370 }
371
372 static const char *
ip_flac_state_to_string(FLAC__StreamDecoderState state)373 ip_flac_state_to_string(FLAC__StreamDecoderState state)
374 {
375 switch (state) {
376 case FLAC__STREAM_DECODER_SEARCH_FOR_METADATA:
377 return "Ready to search for metadata";
378 case FLAC__STREAM_DECODER_READ_METADATA:
379 return "Reading metadata or ready to do so";
380 case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
381 return "Searching for frame sync code or ready to do so";
382 case FLAC__STREAM_DECODER_READ_FRAME:
383 return "Reading frame or ready to do so";
384 case FLAC__STREAM_DECODER_END_OF_STREAM:
385 return "End of stream reached";
386 case FLAC__STREAM_DECODER_OGG_ERROR:
387 return "Error in Ogg layer";
388 case FLAC__STREAM_DECODER_SEEK_ERROR:
389 return "Seek error";
390 case FLAC__STREAM_DECODER_ABORTED:
391 return "Aborted by read callback-function";
392 case FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR:
393 return "Memory allocation error";
394 case FLAC__STREAM_DECODER_UNINITIALIZED:
395 return "Not initialised";
396 default:
397 return "Unknown decoder state";
398 }
399 }
400