ref: 930efe67e81635e632f1e6f93e1c56499c79a55f
dir: /sys/src/cmd/audio/mp3enc/main.c/
/* mp3enc - encode audio files in MP3 format */ /* * Command line frontend program * * Copyright (c) 1999 Mark Taylor * 2000 Takehiro TOMIANGA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: main.c,v 1.46 2001/03/11 11:24:25 aleidinger Exp $ */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <assert.h> #include <memory.h> #ifdef HAVE_CONFIG_H # include <config.h> #endif /* main.c is example code for how to use libmp3lame.a. To use this library, you only need the library and lame.h. All other .h files are private to the library. */ #include "lame.h" #include "brhist.h" #include "parse.h" #include "main.h" #include "get_audio.h" #include "timestatus.h" /* * * main * * PURPOSE: MPEG-1,2 Layer III encoder with GPSYCHO * psychoacoustic model. * */ int parse_args_from_string(lame_global_flags *const gfp, const char *p) { /* Quick & very Dirty */ int c = 0, ret; char *f, *q, *r[128]; if (p == NULL || *p == '\0') return 0; f = q = malloc(strlen(p) + 1); strcpy (q, p); r[c++] = "lhama"; for (;;) { r[c++] = q; while (*q != ' ' && *q != '\0') q++; if (*q == '\0') break; *q++ = '\0'; } r[c] = NULL; ret = parse_args(gfp, c, r); free(f); return ret; } int main(int argc, char **argv) { int i, iread, imp3, ret; short Buffer[2][1152]; unsigned char mp3buffer[LAME_MAXMP3BUFFER]; FILE *outf; lame_global_flags *gf; static char inPath[] = "-"; static char outPath[] = "-"; static const char *mode_names[2][4] = { { "stereo", "j-stereo", "dual-ch", "single-ch" }, { "stereo", "force-ms", "dual-ch", "single-ch" } }; /* initialize libmp3lame */ input_format = sf_unknown; if (NULL == (gf = lame_init()) ) { fprintf(stderr, "mp3enc: fatal error during initialization\n"); return 1; } /* * parse the command line arguments, setting various flags in the * struct 'gf'. If you want to parse your own arguments, * or call libmp3lame from a program which uses a GUI to set arguments, * skip this call and set the values of interest in the gf struct. * (see the file API & lame.h for documentation about these parameters) */ parse_args_from_string(gf, getenv("LAMEOPT")); ret = parse_args(gf, argc, argv); if (ret < 0) return ret == -2? 0: 1; if (update_interval < 0.) update_interval = 2.; /* * open the wav/aiff/raw pcm or mp3 input file. This call will * open the file, try to parse the headers and * set gf.samplerate, gf.num_channels, gf.num_samples. * if you want to do your own file input, skip this call and set * samplerate, num_channels and num_samples yourself. */ init_infile(gf, inPath); if ((outf = init_outfile(outPath, lame_get_decode_only(gf))) == NULL) { fprintf(stderr, "Can't init outfile '%s'\n", outPath); return -42; } /* * Now that all the options are set, lame needs to analyze them and * set some more internal options and check for problems */ i = lame_init_params(gf); if (i < 0) { if (i == -1) display_bitrates(stderr); fprintf(stderr, "fatal error during initialization\n"); return 1; } if (silent || gf->VBR == vbr_off) brhist = 0; /* turn off VBR histogram */ #ifdef BRHIST if (brhist) { if (brhist_init(gf, gf->VBR_min_bitrate_kbps, gf->VBR_max_bitrate_kbps)) /* fail to initialize */ brhist = 0; } else brhist_init(gf, 128, 128); /* Dirty hack */ #endif #ifdef HAVE_VORBIS if (lame_get_ogg( gf ) ) { lame_encode_ogg_init(gf); gf->VBR = vbr_off; /* ignore lame's various VBR modes */ } #endif if (0 == lame_get_decode_only( gf ) && silent < 10 ) { if (0) fprintf(stderr, "Encoding as %g kHz ", 1.e-3 * lame_get_out_samplerate( gf ) ); if (lame_get_ogg(gf)) { if (0) fprintf(stderr, "VBR Ogg Vorbis\n" ); } else { const char *appendix = ""; switch (gf->VBR ) { case vbr_mt: case vbr_rh: case vbr_mtrh: appendix = "ca. "; if (0) fprintf(stderr, "VBR(q=%i)", gf->VBR_q ); break; case vbr_abr: if (0) fprintf(stderr, "average %d kbps", gf->VBR_mean_bitrate_kbps); break; default: if (0) fprintf(stderr, "%3d Kb/s", gf->brate); break; } if (0) fprintf(stderr, " %s MPEG-%u%s Layer III (%s%gx) qval=%i\n", mode_names[gf->force_ms][gf->mode], 2 - gf->version, lame_get_out_samplerate(gf) < 16000? ".5": "", appendix, 0.1 * (int)(10.*gf->compression_ratio + 0.5), lame_get_quality(gf)); } fflush(stderr); } if (lame_get_decode_only(gf)) /* decode an mp3 file to a .wav */ if (mp3_delay_set) lame_decoder(gf, outf, mp3_delay, inPath, outPath); else lame_decoder(gf, outf, gf->encoder_delay, inPath, outPath); else { /* encode until we hit eof */ do { /* read in 'iread' samples */ iread = get_audio(gf, Buffer); /* status display */ if (!silent) if (update_interval > 0) timestatus_klemm(gf); else { if (0 == gf->frameNum % 50) { #ifdef BRHIST brhist_jump_back(); #endif timestatus(lame_get_out_samplerate(gf), gf->frameNum, gf->totalframes, gf->framesize ); #ifdef BRHIST if (brhist) brhist_disp(gf); #endif } } /* encode */ imp3 = lame_encode_buffer(gf, Buffer[0], Buffer[1], iread, mp3buffer, sizeof(mp3buffer)); /* was our output buffer big enough? */ if (imp3 < 0) { if (imp3 == -1) fprintf(stderr, "mp3 buffer is not big enough... \n"); else fprintf(stderr, "mp3 internal error: error code=%i\n", imp3); return 1; } if (fwrite(mp3buffer, 1, imp3, outf) != imp3) { fprintf(stderr, "Error writing mp3 output \n"); return 1; } } while (iread); /* may return one more mp3 frame */ imp3 = lame_encode_flush(gf, mp3buffer, sizeof(mp3buffer)); if (imp3 < 0) { if (imp3 == -1) fprintf(stderr, "mp3 buffer is not big enough... \n"); else fprintf(stderr, "mp3 internal error: error code=%i\n", imp3); return 1; } if (!silent) { #ifdef BRHIST brhist_jump_back(); #endif timestatus(lame_get_out_samplerate(gf), gf->frameNum, gf->totalframes, gf->framesize); #ifdef BRHIST if (brhist) brhist_disp(gf); brhist_disp_total(gf); #endif timestatus_finish(); } fwrite(mp3buffer, 1, imp3, outf); lame_mp3_tags_fid(gf, outf); /* add VBR tags to mp3 file */ lame_close(gf); fclose(outf); } close_infile(); return 0; }