1 /* mp3enc - encode audio files in MP3 format */
2
3 /*
4 * Command line frontend program
5 *
6 * Copyright (c) 1999 Mark Taylor
7 * 2000 Takehiro TOMIANGA
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
23 */
24
25 /* $Id: main.c,v 1.46 2001/03/11 11:24:25 aleidinger Exp $ */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <assert.h>
33 #include <memory.h>
34 #ifdef HAVE_CONFIG_H
35 # include <config.h>
36 #endif
37
38 /*
39 main.c is example code for how to use libmp3lame.a. To use this library,
40 you only need the library and lame.h. All other .h files are private
41 to the library.
42 */
43 #include "lame.h"
44
45 #include "brhist.h"
46 #include "parse.h"
47 #include "main.h"
48 #include "get_audio.h"
49 #include "timestatus.h"
50
51 /*
52 *
53 * main
54 *
55 * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO
56 * psychoacoustic model.
57 *
58 */
59
60 int
parse_args_from_string(lame_global_flags * const gfp,const char * p)61 parse_args_from_string(lame_global_flags *const gfp, const char *p)
62 {
63 /* Quick & very Dirty */
64 int c = 0, ret;
65 char *f, *q, *r[128];
66
67 if (p == NULL || *p == '\0')
68 return 0;
69
70 f = q = malloc(strlen(p) + 1);
71 strcpy (q, p);
72
73 r[c++] = "lhama";
74 for (;;) {
75 r[c++] = q;
76 while (*q != ' ' && *q != '\0')
77 q++;
78 if (*q == '\0')
79 break;
80 *q++ = '\0';
81 }
82 r[c] = NULL;
83
84 ret = parse_args(gfp, c, r);
85 free(f);
86 return ret;
87 }
88
89 int
main(int argc,char ** argv)90 main(int argc, char **argv)
91 {
92 int i, iread, imp3, ret;
93 short Buffer[2][1152];
94 unsigned char mp3buffer[LAME_MAXMP3BUFFER];
95 FILE *outf;
96 lame_global_flags *gf;
97 static char inPath[] = "-";
98 static char outPath[] = "-";
99 static const char *mode_names[2][4] = {
100 { "stereo", "j-stereo", "dual-ch", "single-ch" },
101 { "stereo", "force-ms", "dual-ch", "single-ch" }
102 };
103
104 /* initialize libmp3lame */
105 input_format = sf_unknown;
106 if (NULL == (gf = lame_init()) ) {
107 fprintf(stderr, "mp3enc: fatal error during initialization\n");
108 return 1;
109 }
110 /*
111 * parse the command line arguments, setting various flags in the
112 * struct 'gf'. If you want to parse your own arguments,
113 * or call libmp3lame from a program which uses a GUI to set arguments,
114 * skip this call and set the values of interest in the gf struct.
115 * (see the file API & lame.h for documentation about these parameters)
116 */
117 parse_args_from_string(gf, getenv("LAMEOPT"));
118 ret = parse_args(gf, argc, argv);
119 if (ret < 0)
120 return ret == -2? 0: 1;
121 if (update_interval < 0.)
122 update_interval = 2.;
123
124 /*
125 * open the wav/aiff/raw pcm or mp3 input file. This call will
126 * open the file, try to parse the headers and
127 * set gf.samplerate, gf.num_channels, gf.num_samples.
128 * if you want to do your own file input, skip this call and set
129 * samplerate, num_channels and num_samples yourself.
130 */
131 init_infile(gf, inPath);
132 if ((outf = init_outfile(outPath, lame_get_decode_only(gf))) == NULL) {
133 fprintf(stderr, "Can't init outfile '%s'\n", outPath);
134 return -42;
135 }
136
137 /*
138 * Now that all the options are set, lame needs to analyze them and
139 * set some more internal options and check for problems
140 */
141 i = lame_init_params(gf);
142 if (i < 0) {
143 if (i == -1)
144 display_bitrates(stderr);
145 fprintf(stderr, "fatal error during initialization\n");
146 return 1;
147 }
148
149 if (silent || gf->VBR == vbr_off)
150 brhist = 0; /* turn off VBR histogram */
151
152 #ifdef BRHIST
153 if (brhist) {
154 if (brhist_init(gf, gf->VBR_min_bitrate_kbps,
155 gf->VBR_max_bitrate_kbps))
156 /* fail to initialize */
157 brhist = 0;
158 } else
159 brhist_init(gf, 128, 128); /* Dirty hack */
160 #endif
161
162
163 #ifdef HAVE_VORBIS
164 if (lame_get_ogg( gf ) ) {
165 lame_encode_ogg_init(gf);
166 gf->VBR = vbr_off; /* ignore lame's various VBR modes */
167 }
168 #endif
169 if (0 == lame_get_decode_only( gf ) && silent < 10 ) {
170 if (0)
171 fprintf(stderr, "Encoding as %g kHz ",
172 1.e-3 * lame_get_out_samplerate( gf ) );
173
174 if (lame_get_ogg(gf)) {
175 if (0)
176 fprintf(stderr, "VBR Ogg Vorbis\n" );
177 } else {
178 const char *appendix = "";
179
180 switch (gf->VBR ) {
181 case vbr_mt:
182 case vbr_rh:
183 case vbr_mtrh:
184 appendix = "ca. ";
185 if (0)
186 fprintf(stderr, "VBR(q=%i)", gf->VBR_q );
187 break;
188 case vbr_abr:
189 if (0)
190 fprintf(stderr, "average %d kbps",
191 gf->VBR_mean_bitrate_kbps);
192 break;
193 default:
194 if (0)
195 fprintf(stderr, "%3d Kb/s", gf->brate);
196 break;
197 }
198 if (0)
199 fprintf(stderr, " %s MPEG-%u%s Layer III (%s%gx) qval=%i\n",
200 mode_names[gf->force_ms][gf->mode],
201 2 - gf->version,
202 lame_get_out_samplerate(gf) < 16000?
203 ".5": "", appendix,
204 0.1 * (int)(10.*gf->compression_ratio + 0.5),
205 lame_get_quality(gf));
206 }
207 fflush(stderr);
208 }
209
210 if (lame_get_decode_only(gf))
211 /* decode an mp3 file to a .wav */
212 if (mp3_delay_set)
213 lame_decoder(gf, outf, mp3_delay, inPath, outPath);
214 else
215 lame_decoder(gf, outf, gf->encoder_delay, inPath, outPath);
216 else {
217 /* encode until we hit eof */
218 do {
219 /* read in 'iread' samples */
220 iread = get_audio(gf, Buffer);
221
222 /* status display */
223 if (!silent)
224 if (update_interval > 0)
225 timestatus_klemm(gf);
226 else {
227 if (0 == gf->frameNum % 50) {
228 #ifdef BRHIST
229 brhist_jump_back();
230 #endif
231 timestatus(lame_get_out_samplerate(gf),
232 gf->frameNum,
233 gf->totalframes,
234 gf->framesize );
235 #ifdef BRHIST
236 if (brhist)
237 brhist_disp(gf);
238 #endif
239 }
240 }
241
242 /* encode */
243 imp3 = lame_encode_buffer(gf, Buffer[0], Buffer[1], iread,
244 mp3buffer, sizeof(mp3buffer));
245
246 /* was our output buffer big enough? */
247 if (imp3 < 0) {
248 if (imp3 == -1)
249 fprintf(stderr, "mp3 buffer is not big enough... \n");
250 else
251 fprintf(stderr, "mp3 internal error: error code=%i\n", imp3);
252 return 1;
253 }
254
255 if (fwrite(mp3buffer, 1, imp3, outf) != imp3) {
256 fprintf(stderr, "Error writing mp3 output \n");
257 return 1;
258 }
259 } while (iread);
260 /* may return one more mp3 frame */
261 imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer));
262 if (imp3 < 0) {
263 if (imp3 == -1)
264 fprintf(stderr, "mp3 buffer is not big enough... \n");
265 else
266 fprintf(stderr, "mp3 internal error: error code=%i\n", imp3);
267 return 1;
268
269 }
270 if (!silent) {
271 #ifdef BRHIST
272 brhist_jump_back();
273 #endif
274 timestatus(lame_get_out_samplerate(gf),
275 gf->frameNum,
276 gf->totalframes,
277 gf->framesize);
278 #ifdef BRHIST
279 if (brhist)
280 brhist_disp(gf);
281 brhist_disp_total(gf);
282 #endif
283 timestatus_finish();
284 }
285
286 fwrite(mp3buffer, 1, imp3, outf);
287 lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */
288 lame_close(gf);
289 fclose(outf);
290 }
291 close_infile();
292 exit(0);
293 return 0;
294 }
295