/* parse_args() Parse the command line arguments */ void parse_args(int argc, char **argv, twolame_options * encopts ) { int ch=0; // process args struct option longopts[] = { // Input { "raw-input", no_argument, NULL, 'r' }, { "byte-swap", no_argument, NULL, 'x' }, { "samplerate", required_argument, NULL, 's' }, { "channels", required_argument, NULL, 'N' }, { "swap-channels", no_argument, NULL, 'g' }, { "scale", required_argument, NULL, 1000 }, { "scale-l", required_argument, NULL, 1001 }, { "scale-r", required_argument, NULL, 1002 }, // Output { "mode", required_argument, NULL, 'm' }, { "downmix", no_argument, NULL, 'a' }, { "bitrate", required_argument, NULL, 'b' }, { "psyc-mode", required_argument, NULL, 'P' }, { "vbr", no_argument, NULL, 'v' }, { "vbr-level", required_argument, NULL, 'V' }, { "max-bitrate", required_argument, NULL, 'B' }, { "ath", required_argument, NULL, 'l' }, { "quick", required_argument, NULL, 'q' }, { "single-frame", no_argument, NULL, 'S' }, // Misc { "copyright", no_argument, NULL, 'c' }, { "non-original", no_argument, NULL, 'o' }, { "original", no_argument, NULL, 1003 }, { "protect", no_argument, NULL, 'p' }, { "padding", no_argument, NULL, 'd' }, { "reserve-bits", required_argument, NULL, 'R' }, { "deemphasis", required_argument, NULL, 'e' }, { "energy", no_argument, NULL, 'E' }, // Verbosity { "talkativity", required_argument, NULL, 't' }, { "quiet", no_argument, NULL, 1004 }, { "brief", no_argument, NULL, 1005 }, { "verbose", no_argument, NULL, 1006 }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; // Create a short options structure from the long one char* shortopts = build_shortopt_string( longopts ); //printf("shortopts: %s\n", shortopts); while( (ch = getopt_long( argc, argv, shortopts, longopts, NULL )) != -1) { switch(ch) { // Input case 'r': sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16; break; case 'x': byteswap = TRUE; break; case 's': twolame_set_out_samplerate(encopts, atoi(optarg)); sfinfo.samplerate = atoi(optarg); break; case 'N': sfinfo.channels = atoi(optarg); break; case 'g': channelswap = TRUE; break; case 1000: // --scale twolame_set_scale( encopts, atof(optarg) ); break; case 1001: // --scale-l twolame_set_scale_left( encopts, atof(optarg) ); break; case 1002: // --scale-r twolame_set_scale_right( encopts, atof(optarg) ); break; // Output case 'm': if (*optarg == 's') { twolame_set_mode(encopts, TWOLAME_STEREO); } else if (*optarg == 'd') { twolame_set_mode(encopts, TWOLAME_DUAL_CHANNEL); } else if (*optarg == 'j') { twolame_set_mode(encopts, TWOLAME_JOINT_STEREO); } else if (*optarg == 'm') { twolame_set_mode(encopts, TWOLAME_MONO); } else if (*optarg == 'a') { twolame_set_mode(encopts, TWOLAME_AUTO_MODE); } else { fprintf(stderr, "Error: mode must be a/s/d/j/m not '%s'\n\n", optarg); usage_long(); } break; case 'a': // downmix twolame_set_mode(encopts, TWOLAME_MONO); break; case 'b': twolame_set_bitrate(encopts, atoi(optarg)); break; case 'P': twolame_set_psymodel(encopts, atoi(optarg)); break; case 'v': twolame_set_VBR(encopts, TRUE); break; case 'V': twolame_set_VBR(encopts, TRUE); twolame_set_VBR_level(encopts, atof(optarg)); break; case 'B': twolame_set_VBR_max_bitrate_kbps(encopts, atoi(optarg)); break; case 'l': twolame_set_ATH_level(encopts, atof(optarg)); break; case 'q': twolame_set_quick_mode(encopts, TRUE); twolame_set_quick_count(encopts, atoi(optarg)); break; case 'S': single_frame_mode = TRUE; break; // Miscellaneous case 'c': twolame_set_copyright(encopts, TRUE); break; case 'o': // --non-original twolame_set_original(encopts, FALSE); break; case 1003: // --original twolame_set_original(encopts, TRUE); break; case 'p': twolame_set_error_protection(encopts, TRUE); break; case 'd': twolame_set_padding(encopts, TWOLAME_PAD_ALL); break; case 'R': twolame_set_num_ancillary_bits(encopts, atoi(optarg)); break; case 'e': if (*optarg == 'n') twolame_set_emphasis(encopts, TWOLAME_EMPHASIS_N); else if (*optarg == '5') twolame_set_emphasis(encopts, TWOLAME_EMPHASIS_5); else if (*optarg == 'c') twolame_set_emphasis(encopts, TWOLAME_EMPHASIS_C); else { fprintf(stderr, "Error: emphasis must be n/5/c not '%s'\n\n", optarg); usage_long(); } break; case 'E': twolame_set_energy_levels(encopts, TRUE); break; // Verbosity case 't': twolame_set_verbosity(encopts, atoi(optarg)); break; case 1004: // --quiet twolame_set_verbosity(encopts, 0); break; case 1005: // --brief twolame_set_verbosity(encopts, 1); break; case 1006: // --verbose twolame_set_verbosity(encopts, 4); break; case 'h': usage_long(); break; default: usage_short(); break; } } // Look for the input and output file names argc -= optind; argv += optind; while( argc ) { if (inputfilename[0] == '\0') strncpy(inputfilename, *argv, MAX_NAME_SIZE); else if (outputfilename[0] == '\0') strncpy(outputfilename, *argv, MAX_NAME_SIZE); else { fprintf(stderr, "excess argument: %s\n", *argv); usage_short(); } argv++; argc--; } // Check that we now have input and output file names ok if ( inputfilename[0] == '\0') { fprintf(stderr, "Missing input filename.\n"); usage_short(); } if ( outputfilename[0] == '\0' && strcmp(inputfilename, "-")!=0 ) { // Create output filename from the inputfilename // and change the suffix new_extension( inputfilename, OUTPUT_SUFFIX, outputfilename ); } if ( outputfilename[0] == '\0') { fprintf(stderr, "Missing output filename.\n"); usage_short(); } }
int twolame_init_params (twolame_options *glopts) { if (glopts->twolame_init) { fprintf(stderr,"Already called twolame_init_params() once.\n"); return 1; } // Check the number of channels if (glopts->num_channels != 1 && glopts->num_channels != 2) { fprintf(stderr,"twolame_init_params(): must specify number of channels in input samples using twolame_set_num_channels().\n"); return -1; } // If not output samplerate has been set, then set it to the input sample rate if (glopts->samplerate_out < 1) { glopts->samplerate_out = glopts->samplerate_in; } // If the MPEG version has not been set, then choose automatically if (glopts->version == -1) { // Get the MPEG version for the chosen samplerate glopts->version = twolame_get_version_for_samplerate( glopts->samplerate_out ); if (glopts->version < 0) { fprintf(stdout,"twolame_init_params(): invalid samplerate: %i\n", glopts->samplerate_out ); return -1; } else if (glopts->verbosity>=3) { fprintf(stderr, "Chosen version '%s' for samplerate of %d Hz.\n", twolame_mpeg_version_name(glopts->version), glopts->samplerate_out); } } // Choose mode (if none chosen) if (glopts->mode == TWOLAME_AUTO_MODE) { if (glopts->num_channels == 2) glopts->mode = TWOLAME_STEREO; else glopts->mode = TWOLAME_MONO; if (glopts->verbosity>=3) { fprintf(stderr, "Chosen mode to be '%s' because of %d input channels.\n", twolame_get_mode_name(glopts), glopts->num_channels); } } // Choose the bitrate (if none chosen) if (glopts->bitrate <= 0) { if (glopts->mode == TWOLAME_MONO) { switch(glopts->samplerate_out) { case 48000: glopts->bitrate = 96; break; // (LAME=64) case 44100: glopts->bitrate = 96; break; // (LAME=64) case 32000: glopts->bitrate = 80; break; // (LAME=48) case 24000: glopts->bitrate = 48; break; // (LAME=32) case 22050: glopts->bitrate = 48; break; // (LAME=32) case 16000: glopts->bitrate = 32; break; // (LAME=24) } } else { switch(glopts->samplerate_out) { case 48000: glopts->bitrate = 192; break; // (LAME=128) case 44100: glopts->bitrate = 192; break; // (LAME=128) case 32000: glopts->bitrate = 160; break; // (LAME=96) case 24000: glopts->bitrate = 96; break; // (LAME=64) case 22050: glopts->bitrate = 96; break; // (LAME=64) case 16000: glopts->bitrate = 64; break; // (LAME=48) } } if (glopts->verbosity>=3) { fprintf(stderr, "Chosen bitrate of %dkbps for samplerate of %d Hz.\n", glopts->bitrate, glopts->samplerate_out); } } /* Can't do DAB and energylevel extensions at the same time Because both of them think they're the only ones inserting information into the ancillary section of the frame */ if (glopts->do_dab && glopts->do_energy_levels) { fprintf(stderr,"Can't do DAB and Energy Levels at the same time\n"); return -1; } /* Check that if we're doing energy levels, that there's enough space to put the information */ if (glopts->do_energy_levels) { if ((glopts->mode==TWOLAME_MONO)&&(glopts->num_ancillary_bits<16)) { fprintf(stderr,"Too few ancillary bits: %i<16\n",glopts->num_ancillary_bits); glopts->num_ancillary_bits = 16; } if ((glopts->mode!=TWOLAME_MONO)&&(glopts->num_ancillary_bits<40)) { fprintf(stderr,"Too few ancillary bits: %i<40\n",glopts->num_ancillary_bits); glopts->num_ancillary_bits = 40; } } /* * MFC Feb 2003: in VBR mode, joint * stereo doesn't make any sense at * the moment, as there are no noisy * subbands according to * bits_for_nonoise in vbr mode */ if (glopts->vbr && glopts->mode==TWOLAME_JOINT_STEREO) { // force stereo mode twolame_set_mode(glopts, TWOLAME_STEREO); } /* don't use padding for VBR */ if (glopts->vbr) { twolame_set_padding(glopts, FALSE); } //MFC FIX: Need to cross validate the number of ancillary_bits // with the energylevel setting. // // energylevel: // MFC FIX: This option must be mutually exclusive with the // reservebits(-R) option *UNLESS * the number // of explicitly reserved bits > 5 bytes. // If energy information is required, see if we're in MONO mode in // which case, we only need 16 bits of ancillary data if (glopts->do_energy_levels) { if (glopts->mode==TWOLAME_MONO) { // only 2 bytes needed for energy level for mono channel twolame_set_num_ancillary_bits(glopts, 16); } else { // 5 bytes for the stereo energy info twolame_set_num_ancillary_bits(glopts, 40); } } // build mpeg header from parameters if (init_header_info( glopts )<0) { return -1; } // load the alloc tables and do some other stuff if (init_frame_info( glopts )<0) { return -1; } // initialise bitrate allocation if (init_bit_allocation( glopts )<0) { return -1; } // Check input samplerate is same as output samplerate if (glopts->samplerate_out != glopts->samplerate_in) { fprintf(stderr,"twolame_init_params(): sorry, twolame doesn't support resampling (yet).\n"); return -1; } // Initialise interal variables glopts->samples_in_buffer = 0; glopts->psycount = 0; glopts->crc = 0; // Allocate memory to larger buffers glopts->subband = (subband_t *) twolame_malloc (sizeof (subband_t), "subband"); glopts->j_sample = (jsb_sample_t *) twolame_malloc (sizeof (jsb_sample_t), "j_sample"); glopts->sb_sample = (sb_sample_t *) twolame_malloc (sizeof (sb_sample_t), "sb_sample"); // clear buffers memset ((char *) glopts->buffer, 0, sizeof(glopts->buffer)); memset ((char *) glopts->bit_alloc, 0, sizeof (glopts->bit_alloc)); memset ((char *) glopts->scfsi, 0, sizeof (glopts->scfsi)); memset ((char *) glopts->scalar, 0, sizeof (glopts->scalar)); memset ((char *) glopts->j_scale, 0, sizeof (glopts->j_scale)); memset ((char *) glopts->smrdef, 0, sizeof (glopts->smrdef)); memset ((char *) glopts->smr, 0, sizeof (glopts->smr)); memset ((char *) glopts->max_sc, 0, sizeof (glopts->max_sc)); // Initialise subband windowfilter if (init_subband(&glopts->smem)<0) { return -1; } // All initalised now :) glopts->twolame_init++; return(0); }