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