1 /*
2 * Command line frontend program
3 *
4 * Copyright (c) 1999 Mark Taylor
5 * 2000 Takehiro TOMINAGA
6 * 2010-2017 Robert Hegemann
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 */
23
24 /* $Id$ */
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #include <assert.h>
31 #include <stdio.h>
32
33 #ifdef STDC_HEADERS
34 # include <stdlib.h>
35 # include <string.h>
36 #else
37 # ifndef HAVE_STRCHR
38 # define strchr index
39 # define strrchr rindex
40 # endif
41 char *strchr(), *strrchr();
42 # ifndef HAVE_MEMCPY
43 # define memcpy(d, s, n) bcopy ((s), (d), (n))
44 # define memmove(d, s, n) bcopy ((s), (d), (n))
45 # endif
46 #endif
47
48 #ifdef HAVE_FCNTL_H
49 # include <fcntl.h>
50 #endif
51
52 #ifdef __sun__
53 /* woraround for SunOS 4.x, it has SEEK_* defined here */
54 #include <unistd.h>
55 #endif
56
57 #if defined(_WIN32)
58 # include <windows.h>
59 #endif
60
61
62 /*
63 main.c is example code for how to use libmp3lame.a. To use this library,
64 you only need the library and lame.h. All other .h files are private
65 to the library.
66 */
67 #include "lame.h"
68
69 #include "console.h"
70 #include "parse.h"
71 #include "main.h"
72 #include "get_audio.h"
73 #include "timestatus.h"
74
75 /* PLL 14/04/2000 */
76 #if macintosh
77 #include <console.h>
78 #endif
79
80 #ifdef WITH_DMALLOC
81 #include <dmalloc.h>
82 #endif
83
84
85
86
87 /************************************************************************
88 *
89 * main
90 *
91 * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
92 * psychoacoustic model.
93 *
94 ************************************************************************/
95
96
97 static FILE *
init_files(lame_global_flags * gf, char const *inPath, char const *outPath)98 init_files(lame_global_flags * gf, char const *inPath, char const *outPath)
99 {
100 FILE *outf;
101 /* Mostly it is not useful to use the same input and output name.
102 This test is very easy and buggy and don't recognize different names
103 assigning the same file
104 */
105 if (0 != strcmp("-", outPath) && 0 == strcmp(inPath, outPath)) {
106 error_printf("Input file and Output file are the same. Abort.\n");
107 return NULL;
108 }
109
110 /* open the wav/aiff/raw pcm or mp3 input file. This call will
111 * open the file, try to parse the headers and
112 * set gf.samplerate, gf.num_channels, gf.num_samples.
113 * if you want to do your own file input, skip this call and set
114 * samplerate, num_channels and num_samples yourself.
115 */
116 if (init_infile(gf, inPath) < 0) {
117 error_printf("Can't init infile '%s'\n", inPath);
118 return NULL;
119 }
120 if ((outf = init_outfile(outPath, lame_get_decode_only(gf))) == NULL) {
121 error_printf("Can't init outfile '%s'\n", outPath);
122 return NULL;
123 }
124
125 return outf;
126 }
127
128
129 static void
printInputFormat(lame_t gfp)130 printInputFormat(lame_t gfp)
131 {
132 int const v_main = 2 - lame_get_version(gfp);
133 char const *v_ex = lame_get_out_samplerate(gfp) < 16000 ? ".5" : "";
134 switch (global_reader.input_format) {
135 case sf_mp123: /* FIXME: !!! */
136 break;
137 case sf_mp3:
138 console_printf("MPEG-%u%s Layer %s", v_main, v_ex, "III");
139 break;
140 case sf_mp2:
141 console_printf("MPEG-%u%s Layer %s", v_main, v_ex, "II");
142 break;
143 case sf_mp1:
144 console_printf("MPEG-%u%s Layer %s", v_main, v_ex, "I");
145 break;
146 case sf_raw:
147 console_printf("raw PCM data");
148 break;
149 case sf_wave:
150 console_printf("Microsoft WAVE");
151 break;
152 case sf_aiff:
153 console_printf("SGI/Apple AIFF");
154 break;
155 default:
156 console_printf("unknown");
157 break;
158 }
159 }
160
161 /* the simple lame decoder */
162 /* After calling lame_init(), lame_init_params() and
163 * init_infile(), call this routine to read the input MP3 file
164 * and output .wav data to the specified file pointer*/
165 /* lame_decoder will ignore the first 528 samples, since these samples
166 * represent the mpglib delay (and are all 0). skip = number of additional
167 * samples to skip, to (for example) compensate for the encoder delay */
168
169 static int
lame_decoder_loop(lame_t gfp, FILE * outf, char *inPath, char *outPath)170 lame_decoder_loop(lame_t gfp, FILE * outf, char *inPath, char *outPath)
171 {
172 short int Buffer[2][1152];
173 int i, iread;
174 double wavsize;
175 int tmp_num_channels = lame_get_num_channels(gfp);
176 int skip_start = samples_to_skip_at_start();
177 int skip_end = samples_to_skip_at_end();
178 DecoderProgress dp = 0;
179
180 if (!(tmp_num_channels >= 1 && tmp_num_channels <= 2)) {
181 error_printf("Internal error. Aborting.");
182 return -1;
183 }
184
185 if (global_ui_config.silent < 9) {
186 console_printf("\rinput: %s%s(%g kHz, %i channel%s, ",
187 strcmp(inPath, "-") ? inPath : "<stdin>",
188 strlen(inPath) > 26 ? "\n\t" : " ",
189 lame_get_in_samplerate(gfp) / 1.e3,
190 tmp_num_channels, tmp_num_channels != 1 ? "s" : "");
191
192 printInputFormat(gfp);
193
194 console_printf(")\noutput: %s%s(16 bit, Microsoft WAVE)\n",
195 strcmp(outPath, "-") ? outPath : "<stdout>",
196 strlen(outPath) > 45 ? "\n\t" : " ");
197
198 if (skip_start > 0)
199 console_printf("skipping initial %i samples (encoder+decoder delay)\n", skip_start);
200 if (skip_end > 0)
201 console_printf("skipping final %i samples (encoder padding-decoder delay)\n", skip_end);
202
203 switch (global_reader.input_format) {
204 case sf_mp3:
205 case sf_mp2:
206 case sf_mp1:
207 dp = decoder_progress_init(lame_get_num_samples(gfp),
208 global_decoder.mp3input_data.framesize);
209 break;
210 case sf_raw:
211 case sf_wave:
212 case sf_aiff:
213 default:
214 dp = decoder_progress_init(lame_get_num_samples(gfp),
215 lame_get_in_samplerate(gfp) < 32000 ? 576 : 1152);
216 break;
217 }
218 }
219
220 if (0 == global_decoder.disable_wav_header)
221 WriteWaveHeader(outf, 0x7FFFFFFF, lame_get_in_samplerate(gfp), tmp_num_channels, 16);
222 /* unknown size, so write maximum 32 bit signed value */
223
224 wavsize = 0;
225 do {
226 iread = get_audio16(gfp, Buffer); /* read in 'iread' samples */
227 if (iread >= 0) {
228 wavsize += iread;
229 if (dp != 0) {
230 decoder_progress(dp, &global_decoder.mp3input_data, iread);
231 }
232 put_audio16(outf, Buffer, iread, tmp_num_channels);
233 }
234 } while (iread > 0);
235
236 i = (16 / 8) * tmp_num_channels;
237 assert(i > 0);
238 if (wavsize <= 0) {
239 if (global_ui_config.silent < 10)
240 error_printf("WAVE file contains 0 PCM samples\n");
241 wavsize = 0;
242 }
243 else if (wavsize > 0xFFFFFFD0 / i) {
244 if (global_ui_config.silent < 10)
245 error_printf("Very huge WAVE file, can't set filesize accordingly\n");
246 wavsize = 0xFFFFFFD0;
247 }
248 else {
249 wavsize *= i;
250 }
251 /* if outf is seekable, rewind and adjust length */
252 if (!global_decoder.disable_wav_header && strcmp("-", outPath)
253 && !fseek(outf, 0l, SEEK_SET))
254 WriteWaveHeader(outf, (int) wavsize, lame_get_in_samplerate(gfp), tmp_num_channels, 16);
255
256 if (dp != 0)
257 decoder_progress_finish(dp);
258 return 0;
259 }
260
261 static int
lame_decoder(lame_t gfp, FILE * outf, char *inPath, char *outPath)262 lame_decoder(lame_t gfp, FILE * outf, char *inPath, char *outPath)
263 {
264 int ret;
265
266 ret = lame_decoder_loop(gfp, outf, inPath, outPath);
267 fclose(outf); /* close the output file */
268 close_infile(); /* close the input file */
269 return ret;
270 }
271
272
273 static void
print_trailing_info(lame_global_flags * gf)274 print_trailing_info(lame_global_flags * gf)
275 {
276 if (lame_get_findReplayGain(gf)) {
277 int RadioGain = lame_get_RadioGain(gf);
278 console_printf("ReplayGain: %s%.1fdB\n", RadioGain > 0 ? "+" : "",
279 ((float) RadioGain) / 10.0);
280 if (RadioGain > 0x1FE || RadioGain < -0x1FE)
281 error_printf
282 ("WARNING: ReplayGain exceeds the -51dB to +51dB range. Such a result is too\n"
283 " high to be stored in the header.\n");
284 }
285
286 /* if (the user requested printing info about clipping) and (decoding
287 on the fly has actually been performed) */
288 if (global_ui_config.print_clipping_info && lame_get_decode_on_the_fly(gf)) {
289 float noclipGainChange = (float) lame_get_noclipGainChange(gf) / 10.0f;
290 float noclipScale = lame_get_noclipScale(gf);
291
292 if (noclipGainChange > 0.0) { /* clipping occurs */
293 console_printf
294 ("WARNING: clipping occurs at the current gain. Set your decoder to decrease\n"
295 " the gain by at least %.1fdB or encode again ", noclipGainChange);
296
297 /* advice the user on the scale factor */
298 if (noclipScale > 0) {
299 console_printf("using --scale %.2f\n", noclipScale * lame_get_scale(gf));
300 console_printf(" or less (the value under --scale is approximate).\n");
301 }
302 else {
303 /* the user specified his own scale factor. We could suggest
304 * the scale factor of (32767.0/gfp->PeakSample)*(gfp->scale)
305 * but it's usually very inaccurate. So we'd rather advice him to
306 * disable scaling first and see our suggestion on the scale factor then. */
307 console_printf("using --scale <arg>\n"
308 " (For a suggestion on the optimal value of <arg> encode\n"
309 " with --scale 1 first)\n");
310 }
311
312 }
313 else { /* no clipping */
314 if (noclipGainChange > -0.1)
315 console_printf
316 ("\nThe waveform does not clip and is less than 0.1dB away from full scale.\n");
317 else
318 console_printf
319 ("\nThe waveform does not clip and is at least %.1fdB away from full scale.\n",
320 -noclipGainChange);
321 }
322 }
323
324 }
325
326
327 static int
write_xing_frame(lame_global_flags * gf, FILE * outf, size_t offset)328 write_xing_frame(lame_global_flags * gf, FILE * outf, size_t offset)
329 {
330 unsigned char mp3buffer[LAME_MAXMP3BUFFER];
331 size_t imp3, owrite;
332
333 imp3 = lame_get_lametag_frame(gf, mp3buffer, sizeof(mp3buffer));
334 if (imp3 == 0) {
335 return 0; /* nothing to do */
336 }
337 if (global_ui_config.silent <= 0) {
338 console_printf("Writing LAME Tag...");
339 }
340 if (imp3 > sizeof(mp3buffer)) {
341 error_printf
342 ("Error writing LAME-tag frame: buffer too small: buffer size=%d frame size=%d\n",
343 sizeof(mp3buffer), imp3);
344 return -1;
345 }
346 assert( offset <= LONG_MAX );
347 if (fseek(outf, (long) offset, SEEK_SET) != 0) {
348 error_printf("fatal error: can't update LAME-tag frame!\n");
349 return -1;
350 }
351 owrite = fwrite(mp3buffer, 1, imp3, outf);
352 if (owrite != imp3) {
353 error_printf("Error writing LAME-tag \n");
354 return -1;
355 }
356 if (global_ui_config.silent <= 0) {
357 console_printf("done\n");
358 }
359 assert( imp3 <= INT_MAX );
360 return (int) imp3;
361 }
362
363
364 static int
write_id3v1_tag(lame_t gf, FILE * outf)365 write_id3v1_tag(lame_t gf, FILE * outf)
366 {
367 unsigned char mp3buffer[128];
368 size_t imp3, owrite;
369
370 imp3 = lame_get_id3v1_tag(gf, mp3buffer, sizeof(mp3buffer));
371 if (imp3 == 0) {
372 return 0;
373 }
374 if (imp3 > sizeof(mp3buffer)) {
375 error_printf("Error writing ID3v1 tag: buffer too small: buffer size=%d ID3v1 size=%d\n",
376 sizeof(mp3buffer), imp3);
377 return 0; /* not critical */
378 }
379 owrite = fwrite(mp3buffer, 1, imp3, outf);
380 if (owrite != imp3) {
381 error_printf("Error writing ID3v1 tag \n");
382 return 1;
383 }
384 return 0;
385 }
386
387
388 static int
lame_encoder_loop(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath)389 lame_encoder_loop(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath)
390 {
391 unsigned char mp3buffer[LAME_MAXMP3BUFFER];
392 int Buffer[2][1152];
393 int iread, imp3, owrite, in_limit=0;
394 size_t id3v2_size;
395
396 encoder_progress_begin(gf, inPath, outPath);
397
398 id3v2_size = lame_get_id3v2_tag(gf, 0, 0);
399 if (id3v2_size > 0) {
400 unsigned char *id3v2tag = malloc(id3v2_size);
401 if (id3v2tag != 0) {
402 size_t n_bytes = lame_get_id3v2_tag(gf, id3v2tag, id3v2_size);
403 size_t written = fwrite(id3v2tag, 1, n_bytes, outf);
404 free(id3v2tag);
405 if (written != n_bytes) {
406 encoder_progress_end(gf);
407 error_printf("Error writing ID3v2 tag \n");
408 return 1;
409 }
410 }
411 }
412 else {
413 unsigned char* id3v2tag = getOldTag(gf);
414 id3v2_size = sizeOfOldTag(gf);
415 if ( id3v2_size > 0 ) {
416 size_t owrite = fwrite(id3v2tag, 1, id3v2_size, outf);
417 if (owrite != id3v2_size) {
418 encoder_progress_end(gf);
419 error_printf("Error writing ID3v2 tag \n");
420 return 1;
421 }
422 }
423 }
424 if (global_writer.flush_write == 1) {
425 fflush(outf);
426 }
427
428 /* do not feed more than in_limit PCM samples in one encode call
429 otherwise the mp3buffer is likely too small
430 */
431 in_limit = lame_get_maximum_number_of_samples(gf, sizeof(mp3buffer));
432 if (in_limit < 1)
433 in_limit = 1;
434
435 /* encode until we hit eof */
436 do {
437 /* read in 'iread' samples */
438 iread = get_audio(gf, Buffer);
439
440 if (iread >= 0) {
441 const int* buffer_l = Buffer[0];
442 const int* buffer_r = Buffer[1];
443 int rest = iread;
444 do {
445 int const chunk = rest < in_limit ? rest : in_limit;
446 encoder_progress(gf);
447
448 /* encode */
449
450 imp3 = lame_encode_buffer_int(gf, buffer_l, buffer_r, chunk,
451 mp3buffer, sizeof(mp3buffer));
452 buffer_l += chunk;
453 buffer_r += chunk;
454 rest -= chunk;
455
456 /* was our output buffer big enough? */
457 if (imp3 < 0) {
458 if (imp3 == -1)
459 error_printf("mp3 buffer is not big enough... \n");
460 else
461 error_printf("mp3 internal error: error code=%i\n", imp3);
462 return 1;
463 }
464 owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
465 if (owrite != imp3) {
466 error_printf("Error writing mp3 output \n");
467 return 1;
468 }
469 } while (rest > 0);
470 }
471 if (global_writer.flush_write == 1) {
472 fflush(outf);
473 }
474 } while (iread > 0);
475
476 if (nogap)
477 imp3 = lame_encode_flush_nogap(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */
478 else
479 imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); /* may return one more mp3 frame */
480
481 if (imp3 < 0) {
482 if (imp3 == -1)
483 error_printf("mp3 buffer is not big enough... \n");
484 else
485 error_printf("mp3 internal error: error code=%i\n", imp3);
486 return 1;
487
488 }
489
490 encoder_progress_end(gf);
491
492 owrite = (int) fwrite(mp3buffer, 1, imp3, outf);
493 if (owrite != imp3) {
494 error_printf("Error writing mp3 output \n");
495 return 1;
496 }
497 if (global_writer.flush_write == 1) {
498 fflush(outf);
499 }
500 imp3 = write_id3v1_tag(gf, outf);
501 if (global_writer.flush_write == 1) {
502 fflush(outf);
503 }
504 if (imp3) {
505 return 1;
506 }
507 write_xing_frame(gf, outf, id3v2_size);
508 if (global_writer.flush_write == 1) {
509 fflush(outf);
510 }
511 if (global_ui_config.silent <= 0) {
512 print_trailing_info(gf);
513 }
514 return 0;
515 }
516
517
518 static int
lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath)519 lame_encoder(lame_global_flags * gf, FILE * outf, int nogap, char *inPath, char *outPath)
520 {
521 int ret;
522
523 ret = lame_encoder_loop(gf, outf, nogap, inPath, outPath);
524 fclose(outf); /* close the output file */
525 close_infile(); /* close the input file */
526 return ret;
527 }
528
529
530 int
lame_main(lame_t gf, int argc, char **argv)531 lame_main(lame_t gf, int argc, char **argv)
532 {
533 char inPath[PATH_MAX + 1];
534 char outPath[PATH_MAX + 1];
535 char nogapdir[PATH_MAX + 1];
536 /* support for "nogap" encoding of up to 200 .wav files */
537 #define MAX_NOGAP 200
538 int nogapout = 0;
539 int max_nogap = MAX_NOGAP;
540 char nogap_inPath_[MAX_NOGAP][PATH_MAX + 1];
541 char *nogap_inPath[MAX_NOGAP];
542 char nogap_outPath_[MAX_NOGAP][PATH_MAX + 1];
543 char *nogap_outPath[MAX_NOGAP];
544
545 int ret;
546 int i;
547 FILE *outf = NULL;
548
549 lame_set_msgf(gf, &frontend_msgf);
550 lame_set_errorf(gf, &frontend_errorf);
551 lame_set_debugf(gf, &frontend_debugf);
552 if (argc <= 1) {
553 usage(stderr, argv[0]); /* no command-line args, print usage, exit */
554 return 1;
555 }
556
557 memset(inPath, 0, sizeof(inPath));
558 memset(nogap_inPath_, 0, sizeof(nogap_inPath_));
559 for (i = 0; i < MAX_NOGAP; ++i) {
560 nogap_inPath[i] = &nogap_inPath_[i][0];
561 }
562 memset(nogap_outPath_, 0, sizeof(nogap_outPath_));
563 for (i = 0; i < MAX_NOGAP; ++i) {
564 nogap_outPath[i] = &nogap_outPath_[i][0];
565 }
566
567 /* parse the command line arguments, setting various flags in the
568 * struct 'gf'. If you want to parse your own arguments,
569 * or call libmp3lame from a program which uses a GUI to set arguments,
570 * skip this call and set the values of interest in the gf struct.
571 * (see the file API and lame.h for documentation about these parameters)
572 */
573 ret = parse_args(gf, argc, argv, inPath, outPath, nogap_inPath, &max_nogap);
574 if (ret < 0) {
575 return ret == -2 ? 0 : 1;
576 }
577 if (global_ui_config.update_interval < 0.)
578 global_ui_config.update_interval = 2.;
579
580 if (outPath[0] != '\0' && max_nogap > 0) {
581 strncpy(nogapdir, outPath, PATH_MAX + 1);
582 nogapdir[PATH_MAX] = '\0';
583 nogapout = 1;
584 }
585
586 /* initialize input file. This also sets samplerate and as much
587 other data on the input file as available in the headers */
588 if (max_nogap > 0) {
589 /* for nogap encoding of multiple input files, it is not possible to
590 * specify the output file name, only an optional output directory. */
591 for (i = 0; i < max_nogap; ++i) {
592 char const* outdir = nogapout ? nogapdir : "";
593 if (generateOutPath(nogap_inPath[i], outdir, ".mp3", nogap_outPath[i]) != 0) {
594 error_printf("processing nogap file %d: %s\n", i+1, nogap_inPath[i]);
595 return -1;
596 }
597 }
598 outf = init_files(gf, nogap_inPath[0], nogap_outPath[0]);
599 }
600 else {
601 outf = init_files(gf, inPath, outPath);
602 }
603 if (outf == NULL) {
604 close_infile();
605 return -1;
606 }
607 /* turn off automatic writing of ID3 tag data into mp3 stream
608 * we have to call it before 'lame_init_params', because that
609 * function would spit out ID3v2 tag data.
610 */
611 lame_set_write_id3tag_automatic(gf, 0);
612
613 /* Now that all the options are set, lame needs to analyze them and
614 * set some more internal options and check for problems
615 */
616 ret = lame_init_params(gf);
617 if (ret < 0) {
618 if (ret == -1) {
619 display_bitrates(stderr);
620 }
621 error_printf("fatal error during initialization\n");
622 fclose(outf);
623 close_infile();
624 return ret;
625 }
626
627 if (global_ui_config.silent > 0) {
628 global_ui_config.brhist = 0; /* turn off VBR histogram */
629 }
630
631 if (lame_get_decode_only(gf)) {
632 /* decode an mp3 file to a .wav */
633 ret = lame_decoder(gf, outf, inPath, outPath);
634 }
635 else if (max_nogap == 0) {
636 /* encode a single input file */
637 ret = lame_encoder(gf, outf, 0, inPath, outPath);
638 }
639 else {
640 /* encode multiple input files using nogap option */
641 for (i = 0; i < max_nogap; ++i) {
642 int use_flush_nogap = (i != (max_nogap - 1));
643 if (i > 0) {
644 /* note: if init_files changes anything, like
645 samplerate, num_channels, etc, we are screwed */
646 outf = init_files(gf, nogap_inPath[i], nogap_outPath[i]);
647 if (outf == NULL) {
648 close_infile();
649 return -1;
650 }
651 /* reinitialize bitstream for next encoding. this is normally done
652 * by lame_init_params(), but we cannot call that routine twice */
653 lame_init_bitstream(gf);
654 }
655 lame_set_nogap_total(gf, max_nogap);
656 lame_set_nogap_currentindex(gf, i);
657 ret = lame_encoder(gf, outf, use_flush_nogap, nogap_inPath[i], nogap_outPath[i]);
658 }
659 }
660 return ret;
661 }
662