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