1 // ------------------------------------------------------------------------
2 // audioio-mp3.cpp: Interface for mp3 decoders and encoders that support
3 // input/output using standard streams. Defaults to
4 // mpg123 and lame.
5 // Copyright (C) 1999-2006,2008,2009,2015 Kai Vehmanen
6 // Note! Routines for parsing mp3 header information were taken from XMMS
7 // 1.2.5's mpg123 plugin. Improvements to parsing logic were
8 // contributed by Julian Dobson.
9 //
10 // Attributes:
11 // eca-style-version: 3 (see Ecasound Programmer's Guide)
12 //
13 // References:
14 // http://www.mp3-tech.org/programmer/frame_header.html
15 // http://www.mpg123.de/
16 //
17 // This program is free software; you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation; either version 2 of the License, or
20 // (at your option) any later version.
21 //
22 // This program is distributed in the hope that it will be useful,
23 // but WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 // GNU General Public License for more details.
26 //
27 // You should have received a copy of the GNU General Public License
28 // along with this program; if not, write to the Free Software
29 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 // ------------------------------------------------------------------------
31
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include <string>
37 #include <cmath>
38 #include <cstring>
39 #include <cstdlib> /* atol() */
40
41 #include <signal.h>
42 #include <unistd.h> /* stat() */
43 #include <sys/stat.h> /* stat() */
44 #include <sys/wait.h>
45
46 #include <kvu_inttypes.h>
47 #include <kvu_message_item.h>
48 #include <kvu_numtostr.h>
49
50 #include "audioio-mp3.h"
51 #include "audioio-mp3_impl.h"
52 #include "samplebuffer.h"
53 #include "audioio.h"
54
55 #include "eca-logger.h"
56
57 const char *default_input_cmd = "mpg123 --stereo -q -s -k %o %f";
58 const char *default_output_cmd = "lame -b %B -s %S -r --big-endian -S - %f";
59 const long int default_output_bitrate = 128000;
60
61 std::string MP3FILE::conf_input_cmd = std::string(default_input_cmd);
62 std::string MP3FILE::conf_output_cmd = std::string(default_output_cmd);
63
64 long int MP3FILE::conf_default_output_bitrate = default_output_bitrate;
65
set_input_cmd(const std::string & value)66 void MP3FILE::set_input_cmd(const std::string& value) { MP3FILE::conf_input_cmd = value; }
set_output_cmd(const std::string & value)67 void MP3FILE::set_output_cmd(const std::string& value) { MP3FILE::conf_output_cmd = value; }
68
69 /***************************************************************
70 * Routines for parsing mp3 header information. Taken from XMMS
71 * 1.2.5's mpg123 plugin.
72 **************************************************************/
73
74 #define MAXFRAMESIZE 1792
75 #define MPG_MD_STEREO 0
76 #define MPG_MD_JOINT_STEREO 1
77 #define MPG_MD_DUAL_CHANNEL 2
78 #define MPG_MD_MONO 3
79
80 int tabsel_123[2][3][16] =
81 {
82 {
83 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
84 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
85 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
86
87 {
88 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
89 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
90 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}}
91 };
92
93 long mpg123_freqs[9] =
94 {44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
95
96 struct frame
97 {
98 int stereo;
99 int jsbound;
100 int single;
101 int II_sblimit;
102 int down_sample_sblimit;
103 int lsf;
104 int mpeg25;
105 int down_sample;
106 int header_change;
107 int lay;
108 int error_protection;
109 int bitrate_index;
110 int sampling_frequency;
111 int padding;
112 int extension;
113 int mode;
114 int mode_ext;
115 int copyright;
116 int original;
117 int emphasis;
118 int framesize; /* computed framesize */
119 };
120
mpg123_head_check(unsigned long head)121 static bool mpg123_head_check(unsigned long head)
122 {
123 /* ref: http://www.mp3-tech.org/programmer/frame_header.html */
124
125 /* frame sync must be 0xffe (11bits) */
126 if ((head & 0xffe00000) != 0xffe00000) return false;
127 /* layer must be non-null (2bits) */
128 if (!((head >> 17) & 3)) return false;
129 /* invalid bitrate index: all-ones (4bit) */
130 if (((head >> 12) & 0xf) == 0xf) return false;
131 /* invalid bitrate index: null (4bit) */
132 if (!((head >> 12) & 0xf)) return false;
133 /* invalid srate index: all-ones (2bit) */
134 if (((head >> 10) & 0x3) == 0x3) return false;
135 #if 0
136 /* invalid: mpeg2/2.5, layer I, protection bit off */
137 if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1) return false;
138 /* - mpeg version 1, CRC protection bit */
139 if ((head & 0xffff0000) == 0xfffe0000) return false;
140 #endif
141
142 return true;
143 }
144
mpg123_compute_bpf(struct frame * fr)145 static double mpg123_compute_bpf(struct frame *fr)
146 {
147 double bpf;
148
149 switch (fr->lay)
150 {
151 case 1:
152 bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
153 bpf *= 12000.0 * 4.0;
154 bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
155 break;
156 case 2:
157 case 3:
158 bpf = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index];
159 bpf *= 144000;
160 bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
161 break;
162 default:
163 bpf = 1.0;
164 }
165
166 return bpf;
167 }
168
mpg123_compute_tpf(struct frame * fr)169 static double mpg123_compute_tpf(struct frame *fr)
170 {
171 static int bs[4] =
172 {0, 384, 1152, 1152};
173 double tpf;
174
175 tpf = (double) bs[fr->lay];
176 tpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
177 return tpf;
178 }
179
180 /*
181 * the code a header and write the information
182 * into the frame structure
183 */
mpg123_decode_header(struct frame * fr,unsigned long newhead)184 static bool mpg123_decode_header(struct frame *fr, unsigned long newhead)
185 {
186 if (newhead & (1 << 20))
187 {
188 fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1;
189 fr->mpeg25 = 0;
190 }
191 else
192 {
193 fr->lsf = 1;
194 fr->mpeg25 = 1;
195 }
196 fr->lay = 4 - ((newhead >> 17) & 3);
197 if (fr->mpeg25)
198 {
199 fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3);
200 }
201 else
202 fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3);
203 fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1;
204
205 if (fr->mpeg25) /* allow Bitrate change for 2.5 ... */
206 fr->bitrate_index = ((newhead >> 12) & 0xf);
207
208 fr->bitrate_index = ((newhead >> 12) & 0xf);
209 fr->padding = ((newhead >> 9) & 0x1);
210 fr->extension = ((newhead >> 8) & 0x1);
211 fr->mode = ((newhead >> 6) & 0x3);
212 fr->mode_ext = ((newhead >> 4) & 0x3);
213 fr->copyright = ((newhead >> 3) & 0x1);
214 fr->original = ((newhead >> 2) & 0x1);
215 fr->emphasis = newhead & 0x3;
216
217 fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
218
219 if (!fr->bitrate_index) {
220 ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid bitrate!");
221 return false;
222 }
223
224 int ssize = 0;
225 switch (fr->lay)
226 {
227 case 1:
228 // fr->do_layer = mpg123_do_layer1;
229 // mpg123_init_layer2();
230 fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
231 fr->framesize /= mpg123_freqs[fr->sampling_frequency];
232 fr->framesize = ((fr->framesize + fr->padding) << 2) - 4;
233 break;
234 case 2:
235 // fr->do_layer = mpg123_do_layer2;
236 // mpg123_init_layer2();
237 fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
238 fr->framesize /= mpg123_freqs[fr->sampling_frequency];
239 fr->framesize += fr->padding - 4;
240 break;
241 case 3:
242 // fr->do_layer = mpg123_do_layer3;
243 if (fr->lsf)
244 ssize = (fr->stereo == 1) ? 9 : 17;
245 else
246 ssize = (fr->stereo == 1) ? 17 : 32;
247 if (fr->error_protection)
248 ssize += 2;
249 fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
250 fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
251 fr->framesize = fr->framesize + fr->padding - 4;
252 break;
253 default:
254 return false;
255 }
256
257 if(fr->framesize > MAXFRAMESIZE) {
258 ECA_LOG_MSG(ECA_LOGGER::errors, "Invalid framesize!");
259 return false;
260 }
261
262 return true;
263 }
264
265 /* not used anymore, kaiv 2005/03 */
266 #if 0
267 static uint32_t convert_to_header(uint8_t * buf)
268 {
269
270 return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
271 }
272 #endif
273
mpg123_detect_by_content(const char * filename,struct frame * frp)274 static bool mpg123_detect_by_content(const char* filename, struct frame* frp)
275 {
276 FILE *file;
277 uint8_t tmp[4]; /* room for the 32bit head */
278 uint32_t head = 0;
279 bool data_left = true;
280 bool header_found = false;
281 size_t offset = 0;
282
283 if((file = std::fopen(filename, "rb")) == NULL) {
284 ECA_LOG_MSG(ECA_LOGGER::errors, string("Unable to open file ") + filename + ".");
285 data_left = false;
286 }
287 /* search for headers in the first 262kB of data */
288 while(data_left == true && offset < (1<<18)) {
289 /* octet-by-octet search */
290 if (std::fread(tmp, 1, 1, file) != 1) {
291 ECA_LOG_MSG(ECA_LOGGER::errors, "End of mp3 file, no valid header data found.");
292 data_left = false;
293 break;
294 }
295
296 head <<= 8;
297 head |= tmp[0];
298 offset += 1;
299
300 if (offset > 3) {
301 /* verify the header and if ok, fetch mp3 parameters and store
302 them to 'frp' */
303 if (mpg123_head_check(head) && mpg123_decode_header(frp, head)) {
304 if (header_found == true) {
305 /* two headers found, stop searching */
306 data_left = false;
307 }
308 else {
309 /* after the first header is found, skip to the next
310 valid frame to verify that the first frame is not
311 dummy frame (id3 or something similar) */
312 if (std::fseek(file, frp->framesize, SEEK_CUR) != 0) {
313 data_left = false;
314 }
315 header_found = true;
316 }
317 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found mp3 header at offset " +
318 kvu_numtostr(static_cast<int>(offset - 4)));
319 }
320 }
321 }
322
323 return header_found;
324 }
325
326 /***************************************************************
327 * MP3FILE specific parts.
328 **************************************************************/
329
MP3FILE(const std::string & name)330 MP3FILE::MP3FILE(const std::string& name)
331 : finished_rep(false),
332 triggered_rep(false)
333 {
334 set_label(name);
335 filedes_rep = -1;
336 filehandle_rep = 0;
337 mono_input_rep = false;
338 pcm_rep = 1;
339 bitrate_rep = MP3FILE::conf_default_output_bitrate;
340 }
341
~MP3FILE(void)342 MP3FILE::~MP3FILE(void)
343 {
344 /* see notes in stop_io() */
345 clean_child(io_mode() == io_read ? true : false);
346 if (is_open() == true) {
347 close();
348 }
349 }
350
open(void)351 void MP3FILE::open(void) throw(AUDIO_IO::SETUP_ERROR &)
352 {
353 if (io_mode() == io_read) {
354 /* decoder supports: fixed channel count and sample format,
355 sample rate set by parsing mp3 header */
356 get_mp3_params(label());
357 }
358 else {
359 /* encoder supports: srate configurable, fixed channel
360 count and sample format */
361 set_channels(2);
362 set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le);
363
364 /* note: 'lame' command-line syntax, and default related to them,
365 * have changed slightly in lame 3.98, so we need this hack
366 * to support both old and new versions. In the past,
367 * Ecasound wrote little-endian samples and used lame
368 * option "-x". Newer lame versions (3.97) introduced
369 * "--litle-endian" and "--big-endian", but these were
370 * buggy still in 3.97 (fixed in 3.98). And with 3.98,
371 * additional options (e.g. "-r") need to be passed, or
372 * otherwise lame will exit with an error.
373 *
374 * In addition to above problems, we also need to remember
375 * people updating to a newer Ecasound, but who do not update
376 * their custom 'lame' launch commands in
377 * ~/.ecasound/ecasoundrc (ecasound must continue to output
378 * little-endian samples by default).
379 */
380 if (MP3FILE::conf_output_cmd.find("lame ") != std::string::npos &&
381 MP3FILE::conf_output_cmd.find(" --big-endian ") != std::string::npos) {
382 set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_be);
383 }
384 }
385
386 triggered_rep = false;
387
388 AUDIO_IO::open();
389 }
390
close(void)391 void MP3FILE::close(void)
392 {
393 if (pid_of_child() > 0) {
394 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + ".");
395 /* note: mp3 input/output can handle SIGTERM */
396 clean_child(true);
397 triggered_rep = false;
398 }
399
400 AUDIO_IO::close();
401 }
402
process_mono_fix(char * target_buffer,long int bytes)403 void MP3FILE::process_mono_fix(char* target_buffer, long int bytes) {
404 for(long int n = 0; n < bytes;) {
405 target_buffer[n + 2] = target_buffer[n];
406 target_buffer[n + 3] = target_buffer[n + 1];
407 n += 4;
408 }
409 }
410
read_samples(void * target_buffer,long int samples)411 long int MP3FILE::read_samples(void* target_buffer, long int samples)
412 {
413 if (triggered_rep != true) {
414 ECA_LOG_MSG(ECA_LOGGER::info, "WARNING: triggering an external program in real-time context");
415 triggered_rep = true;
416 fork_input_process();
417 }
418
419 bytes_rep = std::fread(target_buffer, 1, frame_size() * samples, filehandle_rep);
420 if (bytes_rep < samples * frame_size() || bytes_rep == 0) {
421 if (position_in_samples() == 0)
422 ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_input_cmd + "\". Please check your ~/.ecasound/ecasoundrc.");
423 finished_rep = true;
424 triggered_rep = false;
425 }
426 else
427 finished_rep = false;
428
429 last_position_rep += (bytes_rep / frame_size());
430
431 return bytes_rep / frame_size();
432 }
433
write_samples(void * target_buffer,long int samples)434 void MP3FILE::write_samples(void* target_buffer, long int samples)
435 {
436 if (triggered_rep != true) {
437 triggered_rep = true;
438 fork_output_process();
439 }
440
441 if (wait_for_child() != true) {
442 finished_rep = true;
443 triggered_rep = false;
444 ECA_LOG_MSG(ECA_LOGGER::errors, "Attempt to write after child process has terminated.");
445 }
446 else {
447 bytes_rep = ::write(filedes_rep, target_buffer, frame_size() * samples);
448
449 if (bytes_rep < frame_size() * samples) {
450 if (position_in_samples() == 0)
451 ECA_LOG_MSG(ECA_LOGGER::errors, "Can't start process \"" + MP3FILE::conf_output_cmd + "\". Please check your ~/.ecasound/ecasoundrc.");
452 else
453 ECA_LOG_MSG(ECA_LOGGER::errors,
454 "Error in writing to child process (to write "
455 + kvu_numtostr(frame_size() * samples)
456 + ", result "
457 + kvu_numtostr(bytes_rep)
458 + ").");
459
460 finished_rep = true;
461 }
462 else
463 finished_rep = false;
464 }
465 }
466
seek_position(SAMPLE_SPECS::sample_pos_t pos)467 SAMPLE_SPECS::sample_pos_t MP3FILE::seek_position(SAMPLE_SPECS::sample_pos_t pos)
468 {
469 finished_rep = false;
470 if (triggered_rep == true &&
471 last_position_rep != pos) {
472 if (is_open() == true) {
473 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Cleaning child process pid=" + kvu_numtostr(pid_of_child()) + ".");
474 clean_child(true);
475 triggered_rep = false;
476 }
477 }
478 return pos;
479 }
480
set_parameter(int param,std::string value)481 void MP3FILE::set_parameter(int param, std::string value)
482 {
483 switch (param) {
484 case 1:
485 set_label(value);
486 break;
487
488 case 2:
489 long int numvalue = atol(value.c_str());
490 if (numvalue > 0)
491 bitrate_rep = numvalue;
492 else
493 bitrate_rep = MP3FILE::conf_default_output_bitrate;
494 break;
495 }
496 }
497
get_parameter(int param) const498 std::string MP3FILE::get_parameter(int param) const
499 {
500 switch (param) {
501 case 1:
502 return label();
503
504 case 2:
505 return kvu_numtostr(bitrate_rep);
506 }
507 return "";
508 }
509
get_mp3_params(const std::string & fname)510 void MP3FILE::get_mp3_params(const std::string& fname) throw(AUDIO_IO::SETUP_ERROR&)
511 {
512 std::string urlprefix;
513 struct frame fr = { 0 };
514
515 if (mpg123_detect_by_content(fname.c_str(), &fr) != true) {
516 /* not a file, next search for an URL */
517 size_t offset = fname.find_first_of("://");
518 if (offset == std::string::npos) {
519 throw(SETUP_ERROR(SETUP_ERROR::io_mode, "AUDIOIO-MP3: Can't open " + label() + " for reading."));
520 }
521 else {
522 urlprefix = std::string(fname, 0, offset);
523 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Found url; protocol '" + urlprefix + "'.");
524 }
525 }
526 else {
527 /* file size */
528 struct stat buf;
529 ::stat(fname.c_str(), &buf);
530 double fsize = (double)buf.st_size;
531 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total file size (bytes): " + kvu_numtostr(fsize));
532
533 /* bitrate */
534 double bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] * 1000;
535 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Bitrate (bits/s): " + kvu_numtostr(bitrate));
536
537 /* sample freq */
538 double sfreq = mpg123_freqs[fr.sampling_frequency];
539 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Sampling frequncy (Hz): " + kvu_numtostr(sfreq));
540 set_samples_per_second(static_cast<SAMPLE_SPECS::sample_rate_t>(sfreq));
541
542 /* channels */
543 // notice! mpg123 always outputs 16bit samples, stereo
544 mono_input_rep = (fr.mode == MPG_MD_MONO) ? true : false;
545
546 /* temporal length */
547 long int numframes = static_cast<long int>((fsize / mpg123_compute_bpf(&fr)));
548 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (frames): " + kvu_numtostr(numframes));
549 double tpf = mpg123_compute_tpf(&fr);
550 set_length_in_seconds(tpf * numframes);
551 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Total length (seconds): " + kvu_numtostr(length_in_seconds()));
552
553 /* set pcm per frame value */
554 static int bs[4] = {0, 384, 1152, 1152};
555 pcm_rep = bs[fr.lay];
556 ECA_LOG_MSG(ECA_LOGGER::user_objects, "Pcm per mp3 frames: " + kvu_numtostr(pcm_rep));
557 }
558
559 /* sample format (this comes from mpg123) */
560 set_channels(2);
561 set_sample_format(ECA_AUDIO_FORMAT::sfmt_s16_le);
562 }
563
start_io(void)564 void MP3FILE::start_io(void)
565 {
566 if (triggered_rep != true) {
567 if (io_mode() == io_read)
568 fork_input_process();
569 else
570 fork_output_process();
571
572 triggered_rep = true;
573 }
574 }
575
stop_io(void)576 void MP3FILE::stop_io(void)
577 {
578 if (triggered_rep == true) {
579 /* note: it's safe to send a SIGTERM if the client is
580 * an input and we know its PID (otherwise
581 * cleanup will still work but will take more time, which
582 * is nasty if we are in a middle of a seek */
583 if (io_mode() == io_read)
584 clean_child(true);
585 else
586 clean_child(false);
587
588 triggered_rep = false;
589 }
590 }
591
fork_input_process(void)592 void MP3FILE::fork_input_process(void)
593 {
594 std::string cmd = MP3FILE::conf_input_cmd;
595 if (cmd.find("%o") != std::string::npos) {
596 cmd.replace(cmd.find("%o"), 2, kvu_numtostr((long)(position_in_samples() / pcm_rep)));
597 }
598 last_position_rep = position_in_samples();
599 ECA_LOG_MSG(ECA_LOGGER::user_objects, "" + cmd);
600 set_fork_command(cmd);
601 set_fork_file_name(label());
602
603 set_fork_bits(bits());
604 set_fork_channels(channels());
605 set_fork_sample_rate(samples_per_second()); /* for old mpg123 */
606
607 fork_child_for_read();
608 if (child_fork_succeeded() == true) {
609
610 /* NOTE: the file description will be closed by
611 * AUDIO_IO_FORKED_STREAM::clean_child() */
612 filedes_rep = file_descriptor();
613 filehandle_rep = fdopen(filedes_rep, "r"); /* not part of <cstdio> */
614 if (filehandle_rep == 0) {
615 finished_rep = true;
616 triggered_rep = false;
617 }
618 }
619 }
620
fork_output_process(void)621 void MP3FILE::fork_output_process(void)
622 {
623 ECA_LOG_MSG(ECA_LOGGER::info, "Starting to encode " + label() + " with lame.");
624 last_position_rep = position_in_samples();
625 std::string cmd = MP3FILE::conf_output_cmd;
626 if (cmd.find("%B") != std::string::npos) {
627 cmd.replace(cmd.find("%B"), 2, kvu_numtostr((long int)(bitrate_rep / 1000)));
628 }
629
630 set_fork_command(cmd);
631
632 set_fork_file_name(label());
633 set_fork_bits(bits());
634 set_fork_channels(channels());
635
636 set_fork_sample_rate(samples_per_second());
637 fork_child_for_write();
638 if (child_fork_succeeded() == true) {
639 filedes_rep = file_descriptor();
640 }
641 }
642