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 <limits.h>
18 #include <stdint.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 #include <id3tag.h>
24 #include <mad.h>
25 
26 #include "../siren.h"
27 
28 /*
29  * This value must be equal to or larger than the largest possible MPEG audio
30  * frame size, which, according to <https://marc.info/?m=113584709618786>, is
31  * 2880 bytes.
32  */
33 #define IP_MAD_BUFSIZE		65536
34 
35 #define IP_MAD_ERROR		-1
36 #define IP_MAD_EOF		0
37 #define IP_MAD_OK		1
38 
39 #define IP_MAD_NEED_REFILL(error) \
40     ((error) == MAD_ERROR_BUFLEN || (error) == MAD_ERROR_BUFPTR)
41 
42 struct ip_mad_ipdata {
43 	FILE			*fp;
44 
45 	struct mad_stream	 stream;
46 	struct mad_frame	 frame;
47 	struct mad_synth	 synth;
48 	mad_timer_t		 timer;
49 
50 	unsigned short int	 sampleidx;
51 	unsigned char		*buf;
52 };
53 
54 static void		 ip_mad_close(struct track *);
55 static int		 ip_mad_decode_frame_header(FILE *,
56 			    struct mad_stream *, struct mad_header *,
57 			    unsigned char *);
58 static int		 ip_mad_fill_stream(FILE *, struct mad_stream *,
59 			    unsigned char *);
60 static int		 ip_mad_get_position(struct track *, unsigned int *);
61 static void		 ip_mad_get_metadata(struct track *);
62 static int		 ip_mad_open(struct track *);
63 static int		 ip_mad_read(struct track *, struct sample_buffer *);
64 static void		 ip_mad_seek(struct track *, unsigned int);
65 
66 static const char	*ip_mad_extensions[] = { "mp1", "mp2", "mp3", NULL };
67 
68 const struct ip		 ip = {
69 	"mad",
70 	IP_PRIORITY_MAD,
71 	ip_mad_extensions,
72 	ip_mad_close,
73 	ip_mad_get_metadata,
74 	ip_mad_get_position,
75 	NULL,
76 	ip_mad_open,
77 	ip_mad_read,
78 	ip_mad_seek
79 };
80 
81 /*
82  * Calculate the duration in seconds of a file by reading it from start to end
83  * and summing the duration of all frames in it. This method is rather
84  * expensive and therefore used only if other methods have failed.
85  */
86 static unsigned int
87 ip_mad_calculate_duration(const char *file)
88 {
89 	FILE			*fp;
90 	struct mad_stream	 stream;
91 	struct mad_header	 header;
92 	mad_timer_t		 timer;
93 	int			 ret;
94 	unsigned char		*buf;
95 
96 	if ((fp = fopen(file, "r")) == NULL) {
97 		LOG_ERR("fopen: %s", file);
98 		msg_err("%s: Cannot open track", file);
99 		return 0;
100 	}
101 
102 	mad_stream_init(&stream);
103 	mad_header_init(&header);
104 	mad_timer_reset(&timer);
105 	buf = xmalloc(IP_MAD_BUFSIZE + MAD_BUFFER_GUARD);
106 
107 	/* Read the whole file and sum the duration of all frames. */
108 	while ((ret = ip_mad_decode_frame_header(fp, &stream, &header, buf)) ==
109 	    IP_MAD_OK)
110 		mad_timer_add(&timer, header.duration);
111 
112 	free(buf);
113 	mad_header_finish(&header);
114 	mad_stream_finish(&stream);
115 	fclose(fp);
ip_ffmpeg_log(UNUSED void * p,int level,const char * fmt,va_list ap)116 
117 	if (ret == IP_MAD_ERROR)
118 		return 0;
119 
120 	return mad_timer_count(timer, MAD_UNITS_SECONDS);
121 }
122 
123 static void
124 ip_mad_close(struct track *t)
125 {
126 	struct ip_mad_ipdata *ipd;
ip_ffmpeg_read_packet(struct track * t,struct ip_ffmpeg_ipdata * ipd)127 
128 	ipd = t->ipdata;
129 
130 	mad_synth_finish(&ipd->synth);
131 	mad_frame_finish(&ipd->frame);
132 	mad_stream_finish(&ipd->stream);
133 	fclose(ipd->fp);
134 
135 	free(ipd->buf);
136 	free(ipd);
137 }
138 
139 static int
140 ip_mad_decode_frame(struct ip_mad_ipdata *ipd)
141 {
142 	int		 ret;
143 	const char	*errstr;
144 
145 	for (;;) {
146 		if (mad_frame_decode(&ipd->frame, &ipd->stream) == 0) {
147 			mad_synth_frame(&ipd->synth, &ipd->frame);
148 			ipd->sampleidx = 0;
149 			return IP_MAD_OK;
150 		}
151 		if (IP_MAD_NEED_REFILL(ipd->stream.error)) {
152 			ret = ip_mad_fill_stream(ipd->fp, &ipd->stream,
153 			    ipd->buf);
154 			if (ret == IP_MAD_EOF || ret == IP_MAD_ERROR)
ip_ffmpeg_decode_frame(struct track * t,struct ip_ffmpeg_ipdata * ipd)155 				return ret;
156 		} else if (!MAD_RECOVERABLE(ipd->stream.error)) {
157 			errstr = mad_stream_errorstr(&ipd->stream);
158 			LOG_ERRX("mad_frame_decode: %s", errstr);
159 			msg_errx("Cannot decode frame: %s", errstr);
160 			return IP_MAD_ERROR;
161 		}
162 	}
163 }
164 
165 static int
166 ip_mad_decode_frame_header(FILE *fp, struct mad_stream *stream,
167     struct mad_header *header, unsigned char *buf)
168 {
169 	int		 ret;
170 	const char	*errstr;
171 
172 	for (;;) {
173 		if (mad_header_decode(header, stream) == 0)
174 			return IP_MAD_OK;
175 		if (IP_MAD_NEED_REFILL(stream->error)) {
176 			ret = ip_mad_fill_stream(fp, stream, buf);
177 			if (ret == IP_MAD_EOF || ret == IP_MAD_ERROR)
178 				return ret;
179 		} else if (!MAD_RECOVERABLE(stream->error)) {
180 			errstr = mad_stream_errorstr(stream);
181 			LOG_ERRX("mad_header_decode: %s", errstr);
182 			msg_errx("Cannot decode frame header: %s", errstr);
183 			return IP_MAD_ERROR;
184 		}
185 	}
186 }
187 
188 static int
189 ip_mad_fill_stream(FILE *fp, struct mad_stream *stream, unsigned char *buf)
190 {
191 	size_t buffree, buflen, nread;
192 
193 	if (feof(fp))
194 		return IP_MAD_EOF;
195 
196 	if (stream->next_frame == NULL)
197 		buflen = 0;
198 	else {
199 		buflen = stream->bufend - stream->next_frame;
200 		memmove(buf, stream->next_frame, buflen);
201 	}
202 	buffree = IP_MAD_BUFSIZE - buflen;
203 
ip_ffmpeg_read_interleaved(struct track * t,struct ip_ffmpeg_ipdata * ipd,struct sample_buffer * sb)204 	if ((nread = fread(buf + buflen, 1, buffree, fp)) < buffree) {
205 		if (ferror(fp)) {
206 			LOG_ERR("fread");
207 			msg_err("Cannot read from track");
208 			return IP_MAD_ERROR;
209 		}
210 		if (feof(fp)) {
211 			memset(buf + buflen + nread, 0, MAD_BUFFER_GUARD);
212 			buflen += MAD_BUFFER_GUARD;
213 		}
214 	}
215 
216 	buflen += nread;
217 	mad_stream_buffer(stream, buf, buflen);
218 	stream->error = MAD_ERROR_NONE;
219 	return IP_MAD_OK;
220 }
221 
222 /*
223  * Convert a fixed-point number to a 16-bit integer sample.
224  */
225 static int16_t
226 ip_mad_fixed_to_int(mad_fixed_t fixed)
227 {
228 	/* Round to the 15th most significant fraction bit. */
229 	fixed += (mad_fixed_t)1 << (MAD_F_FRACBITS - 16);
230 
231 	/* Clip samples equal to or higher than 1.0 or less than -1.0. */
232 	if (fixed >= MAD_F_ONE)
233 		fixed = MAD_F_ONE - 1;
234 	else if (fixed < -MAD_F_ONE)
235 		fixed = -MAD_F_ONE;
236 
237 	/* Save the sign bit and the 15 most significant fraction bits. */
238 	return fixed >> (MAD_F_FRACBITS - 15);
239 }
240 
241 static char *
242 ip_mad_get_id3_frame(const struct id3_tag *tag, const char *id)
243 {
244 	struct id3_frame	*frame;
245 	union id3_field		*field;
246 	const id3_ucs4_t	*value;
247 
248 	/* Note that some libid3tag functions return 0 instead of NULL. */
249 
250 	if ((frame = id3_tag_findframe(tag, id, 0)) == 0)
251 		return NULL;
ip_ffmpeg_read_planar(struct track * t,struct ip_ffmpeg_ipdata * ipd,struct sample_buffer * sb)252 
253 	/*
254 	 * The first field specifies the text encoding, while the second
255 	 * contains the actual text.
256 	 */
257 	if ((field = id3_frame_field(frame, 1)) == 0)
258 		return NULL;
259 
260 	/* Get the first string from the "string list" field. */
261 	if ((value = id3_field_getstrings(field, 0)) == 0)
262 		return NULL;
263 
264 	/*
265 	 * Note that id3_ucs4_utf8duplicate() returns NULL if its call to
266 	 * malloc() failed.
267 	 */
268 	return (char *)id3_ucs4_utf8duplicate(value);
269 }
270 
271 static char *
272 ip_mad_get_id3_genre(struct id3_tag *tag)
273 {
274 	struct id3_frame	*frame;
275 	union id3_field		*field;
276 	const id3_ucs4_t	*genre;
277 
278 	if ((frame = id3_tag_findframe(tag, ID3_FRAME_GENRE, 0)) == 0)
279 		return NULL;
280 
281 	if ((field = id3_frame_field(frame, 1)) == 0)
282 		return NULL;
283 
284 	genre = id3_genre_name(id3_field_getstrings(field, 0));
285 	if (genre[0] == '\0')
286 		return NULL;
287 
288 	return (char *)id3_ucs4_utf8duplicate(genre);
289 }
290 
291 static void
292 ip_mad_get_metadata(struct track *t)
293 {
294 	struct id3_file		*file;
295 	struct id3_tag		*tag;
296 	char			*tlen, *val;
297 	const char		*errstr;
298 
299 	if ((file = id3_file_open(t->path, ID3_FILE_MODE_READONLY)) == NULL) {
300 		LOG_ERRX("%s: id3_file_open() failed", t->path);
301 		msg_errx("%s: Cannot open file", t->path);
302 		return;
303 	}
304 
305 	tag = id3_file_tag(file);
306 
307 	t->album = ip_mad_get_id3_frame(tag, ID3_FRAME_ALBUM);
308 	t->albumartist = ip_mad_get_id3_frame(tag, "TPE2");
309 	t->artist = ip_mad_get_id3_frame(tag, ID3_FRAME_ARTIST);
310 	t->comment = ip_mad_get_id3_frame(tag, ID3_FRAME_COMMENT);
311 	t->date = ip_mad_get_id3_frame(tag, ID3_FRAME_YEAR);
312 	t->title = ip_mad_get_id3_frame(tag, ID3_FRAME_TITLE);
313 	t->genre = ip_mad_get_id3_genre(tag);
314 
315 	if ((val = ip_mad_get_id3_frame(tag, "TPOS")) != NULL) {
316 		track_split_tag(val, &t->discnumber, &t->disctotal);
317 		free(val);
318 	}
319 
320 	if ((val = ip_mad_get_id3_frame(tag, ID3_FRAME_TRACK)) != NULL) {
321 		track_split_tag(val, &t->tracknumber, &t->tracktotal);
322 		free(val);
323 	}
324 
325 	if ((tlen = ip_mad_get_id3_frame(tag, "TLEN")) == NULL)
ip_ffmpeg_parse_metadata(struct track * t,AVDictionary * metadata)326 		t->duration = ip_mad_calculate_duration(t->path);
327 	else {
328 		t->duration = strtonum(tlen, 0, UINT_MAX, &errstr);
329 		if (errstr != NULL)
330 			LOG_ERRX("%s: %s: TLEN frame is %s", t->path, tlen,
331 			    errstr);
332 		else
333 			t->duration /= 1000;
334 		free(tlen);
335 	}
336 
337 	if (id3_file_close(file) == -1)
338 		LOG_ERRX("%s: id3_file_close() failed", t->path);
339 }
340 
341 static int
342 ip_mad_get_position(struct track *t, unsigned int *pos)
343 {
344 	struct ip_mad_ipdata *ipd;
345 
346 	ipd = t->ipdata;
347 	*pos = mad_timer_count(ipd->timer, MAD_UNITS_SECONDS);
348 	return 0;
349 }
350 
351 static int
352 ip_mad_open(struct track *t)
353 {
354 	struct ip_mad_ipdata *ipd;
355 
356 	ipd = xmalloc(sizeof *ipd);
357 
358 	if ((ipd->fp = fopen(t->path, "r")) == NULL) {
359 		LOG_ERR("fopen: %s", t->path);
360 		msg_err("%s: Cannot open track", t->path);
361 		free(ipd);
362 		return -1;
363 	}
364 
365 	t->ipdata = ipd;
366 	ipd->buf = xmalloc(IP_MAD_BUFSIZE + MAD_BUFFER_GUARD);
367 	ipd->sampleidx = 0;
368 
369 	mad_stream_init(&ipd->stream);
370 	mad_frame_init(&ipd->frame);
371 	mad_synth_init(&ipd->synth);
372 	mad_timer_reset(&ipd->timer);
373 
374 	if (ip_mad_decode_frame(ipd) != IP_MAD_OK) {
375 		ip_mad_close(t);
376 		return -1;
377 	}
378 	t->format.nbits = 16;
379 	t->format.nchannels = MAD_NCHANNELS(&ipd->frame.header);
380 	t->format.rate = ipd->frame.header.samplerate;
381 
ip_ffmpeg_close(struct track * t)382 	return 0;
383 }
384 
385 static int
386 ip_mad_read(struct track *t, struct sample_buffer *sb)
387 {
388 	struct ip_mad_ipdata	*ipd;
389 	int			 ret;
390 	unsigned short		 i;
391 
392 	ipd = t->ipdata;
393 
ip_ffmpeg_get_metadata(struct track * t)394 	sb->len_s = 0;
395 	while (sb->len_s + t->format.nchannels <= sb->size_s) {
396 		if (ipd->sampleidx == ipd->synth.pcm.length) {
397 			mad_timer_add(&ipd->timer, ipd->frame.header.duration);
398 			ret = ip_mad_decode_frame(ipd);
399 			if (ret == IP_MAD_EOF)
400 				break;
401 			if (ret == IP_MAD_ERROR)
402 				return ret;
403 		}
404 
405 		for (i = 0; i < ipd->synth.pcm.channels; i++)
406 			sb->data2[sb->len_s++] = ip_mad_fixed_to_int(
407 			    ipd->synth.pcm.samples[i][ipd->sampleidx]);
408 
409 		ipd->sampleidx++;
410 	}
411 
412 	sb->len_b = sb->len_s * sb->nbytes;
413 	return sb->len_s != 0;
414 }
415 
416 static void
417 ip_mad_seek(struct track *t, unsigned int seekpos)
418 {
419 	struct ip_mad_ipdata	*ipd;
420 	struct mad_header	 header;
421 	unsigned int		 pos;
422 
423 	ipd = t->ipdata;
424 
425 	pos = mad_timer_count(ipd->timer, MAD_UNITS_SECONDS);
426 	if (pos > seekpos) {
427 		if (fseek(ipd->fp, 0, SEEK_SET) == -1) {
428 			LOG_ERR("fseek: %s", t->path);
429 			msg_err("Cannot seek");
430 			return;
431 		}
ip_ffmpeg_get_position(struct track * t,unsigned int * pos)432 		mad_timer_reset(&ipd->timer);
433 		pos = 0;
434 	}
435 
436 	mad_header_init(&header);
437 
438 	for (;;) {
439 		if (pos >= seekpos)
440 			break;
441 		if (ip_mad_decode_frame_header(ipd->fp, &ipd->stream, &header,
442 		    ipd->buf) != IP_MAD_OK)
443 			break;
ip_ffmpeg_init(void)444 		mad_timer_add(&ipd->timer, header.duration);
445 		pos = mad_timer_count(ipd->timer, MAD_UNITS_SECONDS);
446 	}
447 
448 	mad_header_finish(&header);
449 	mad_frame_mute(&ipd->frame);
450 	mad_synth_mute(&ipd->synth);
451 }
ip_ffmpeg_open(struct track * t)452