Example #1
0
int
main(int argc, char **argv)
{
	twolame_options *encopts = NULL;
	audioin_t		*inputfile = NULL;
	FILE			*outputfile = NULL;
	short int		*pcmaudio = NULL;
	unsigned int	frame_count = 0;
	unsigned int	total_frames = 0;
	unsigned int	frame_len = 0;
	unsigned int	total_bytes = 0;
	unsigned char	*mp2buffer = NULL;
	int				samples_read = 0;
	int				mp2fill_size = 0;
	int				audioReadSize = 0;


	// Allocate memory for the PCM audio data
	if ((pcmaudio = (short int *) calloc(AUDIO_BUF_SIZE, sizeof(short int))) == NULL) {
		fprintf(stderr, "Error: pcmaudio memory allocation failed\n");
		exit(ERR_MEM_ALLOC);
	}
	
	// Allocate memory for the encoded MP2 audio data
	if ((mp2buffer = (unsigned char *) calloc(MP2_BUF_SIZE, sizeof(unsigned char))) == NULL) {
		fprintf(stderr, "Error: mp2buffer memory allocation failed\n");
		exit(ERR_MEM_ALLOC);
	}
	
	// Initialise Encoder Options Structure 
	encopts = twolame_init();
	if (encopts == NULL) {
		fprintf(stderr, "Error: initializing libtwolame encoder failed.\n");
		exit(ERR_MEM_ALLOC);
	}

	
	// Get options and parameters from the command line
	parse_args(argc, argv, encopts);

	// Display the filenames
	print_filenames( twolame_get_verbosity(encopts) );

	// Open the input file
	if (use_raw) {
		// use raw input handler
		inputfile = open_audioin_raw( inputfilename, &sfinfo, sample_size );
	} else {
		// use libsndfile
		inputfile = open_audioin_sndfile( inputfilename, &sfinfo );
	}
	
	// Display input information
	if (twolame_get_verbosity(encopts)>1) {
		inputfile->print_info( inputfile );
	}
	
	// Use information from input file to configure libtwolame 
	twolame_set_num_channels( encopts, sfinfo.channels );
	twolame_set_in_samplerate( encopts, sfinfo.samplerate );

		
	// Open the output file
	outputfile = open_output_file( outputfilename );

	// initialise twolame with this set of options
	if (twolame_init_params( encopts ) != 0) {
		fprintf(stderr, "Error: configuring libtwolame encoder failed.\n");
		exit(ERR_INVALID_PARAM);
	}

	// display encoder settings
	twolame_print_config( encopts );


	// Only encode a single frame of mpeg audio ?
	if (single_frame_mode) audioReadSize = TWOLAME_SAMPLES_PER_FRAME;
	else audioReadSize = AUDIO_BUF_SIZE;

	// Calculate the size and number of frames we are going to encode
	frame_len = twolame_get_framelength( encopts );
	if (sfinfo.frames) total_frames = sfinfo.frames / TWOLAME_SAMPLES_PER_FRAME;


	// Now do the reading/encoding/writing
	while ((samples_read = inputfile->read( inputfile, pcmaudio, audioReadSize )) > 0) {
		int bytes_out = 0;
		
		// Force byte swapping if requested
		if (byteswap) {
			int i;
			for (i = 0; i<samples_read; i++) {
				short tmp = pcmaudio[i];
				char *src = (char*)&tmp;
				char *dst = (char*)&pcmaudio[i];
				dst[0] = src[1];
				dst[1] = src[0];
			}
		}

		// Calculate the number of samples we have (per channel)
		samples_read /= sfinfo.channels;

		// Do swapping of left and right channels if requested
		if (channelswap && sfinfo.channels == 2) {
			int i;
			for(i=0; i<samples_read; i++) {
				short tmp = pcmaudio[(2*i)];
				pcmaudio[(2*i)] = pcmaudio[(2*i)+1];
				pcmaudio[(2*i)+1] = tmp;
			}
		}
		
		// Encode the audio to MP2
		mp2fill_size = twolame_encode_buffer_interleaved( encopts, pcmaudio, samples_read, mp2buffer, MP2_BUF_SIZE);
		
		// Stop if we don't have any bytes (probably don't have enough audio for a full frame of mpeg audio)
		if (mp2fill_size==0) break;
		if (mp2fill_size<0) {
			fprintf(stderr,"error while encoding audio: %d\n", mp2fill_size);
			exit(ERR_ENCODING);
		}

		// Check that a whole number of frame was written
		//if (mp2fill_size % frame_len != 0) {
		//	  fprintf(stderr,"error while encoding audio: non-whole number of frames written\n");
		//	  exit(ERR_ENCODING);
		//}

		// Write the encoded audio out
		bytes_out = fwrite(mp2buffer, sizeof(unsigned char), mp2fill_size, outputfile);
		if (bytes_out != mp2fill_size) {
			perror("error while writing to output file");
			exit(ERR_WRITING_OUTPUT);
		}
		total_bytes += bytes_out;
		
		// Only single frame ?
		if (single_frame_mode) break;
		

		// Display Progress
		frame_count += (mp2fill_size / frame_len);
		if (twolame_get_verbosity(encopts)>0) {
			fprintf(stderr, "\rEncoding frame: %i", frame_count );
			if (total_frames) {
				fprintf(stderr, "/%i (%i%%)", total_frames, (frame_count*100)/total_frames);
			}
			fflush(stderr);
		}
	}

	// Was there an error reading the audio?
	if (inputfile->error_str( inputfile )) {
		fprintf(stderr, "Error reading from input file: %s\n", inputfile->error_str(inputfile) );
	}

	//
	// flush any remaining audio. (don't send any new audio data) There
	// should only ever be a max of 1 frame on a flush. There may be zero
	// frames if the audio data was an exact multiple of 1152
	//
	mp2fill_size = twolame_encode_flush( encopts, mp2buffer, MP2_BUF_SIZE);
	if (mp2fill_size>0) {
		frame_count++;
		int bytes_out = fwrite(mp2buffer, sizeof(unsigned char), mp2fill_size, outputfile);
		if (bytes_out<=0) {
			perror("error while writing to output file");
			exit(ERR_WRITING_OUTPUT);
		}
		total_bytes += bytes_out;
	}
	
	if (twolame_get_verbosity(encopts)>1) {
		char* filesize = format_filesize_string( total_bytes );
		fprintf(stderr, "\nEncoding Finished.\n");
		fprintf(stderr, "Total bytes written: %s.\n",filesize);
		free(filesize);
	}

	// Close input and output streams
	inputfile->close( inputfile );
	fclose( outputfile );

	// Close the libtwolame encoder
	twolame_close(&encopts);
	
	
	// Free up memory
	free(pcmaudio);
	free(mp2buffer);

	return (ERR_NO_ERROR);
}
Example #2
0
static int OpenEncoder( vlc_object_t *p_this )
{
    encoder_t *p_enc = (encoder_t *)p_this;
    encoder_sys_t *p_sys;
    int i_frequency;

    if( p_enc->fmt_out.i_codec != VLC_CODEC_MP2 &&
        p_enc->fmt_out.i_codec != VLC_CODEC_MPGA &&
        p_enc->fmt_out.i_codec != VLC_FOURCC( 'm', 'p', '2', 'a' ) &&
        !p_enc->b_force )
    {
        return VLC_EGENERIC;
    }

    if( p_enc->fmt_in.audio.i_channels > 2 )
    {
        msg_Err( p_enc, "doesn't support > 2 channels" );
        return VLC_EGENERIC;
    }

    for ( i_frequency = 0; i_frequency < 6; i_frequency++ )
    {
        if ( p_enc->fmt_out.audio.i_rate == mpa_freq_tab[i_frequency] )
            break;
    }
    if ( i_frequency == 6 )
    {
        msg_Err( p_enc, "MPEG audio doesn't support frequency=%d",
                 p_enc->fmt_out.audio.i_rate );
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
        return VLC_ENOMEM;
    p_enc->p_sys = p_sys;

    p_enc->fmt_in.i_codec = VLC_CODEC_S16N;

    p_enc->fmt_out.i_cat = AUDIO_ES;
    p_enc->fmt_out.i_codec = VLC_CODEC_MPGA;

    config_ChainParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );

    p_sys->p_twolame = twolame_init();

    /* Set options */
    twolame_set_in_samplerate( p_sys->p_twolame, p_enc->fmt_out.audio.i_rate );
    twolame_set_out_samplerate( p_sys->p_twolame, p_enc->fmt_out.audio.i_rate );

    if( var_GetBool( p_enc, ENC_CFG_PREFIX "vbr" ) )
    {
        float f_quality = var_GetFloat( p_enc, ENC_CFG_PREFIX "quality" );
        if ( f_quality > 50.0 ) f_quality = 50.0;
        if ( f_quality < 0.0 ) f_quality = 0.0;
        twolame_set_VBR( p_sys->p_twolame, 1 );
        twolame_set_VBR_q( p_sys->p_twolame, f_quality );
    }
    else
    {
        int i;
        for ( i = 1; i < 14; i++ )
        {
            if ( p_enc->fmt_out.i_bitrate / 1000
                  <= mpa_bitrate_tab[i_frequency / 3][i] )
                break;
        }
        if ( p_enc->fmt_out.i_bitrate / 1000
              != mpa_bitrate_tab[i_frequency / 3][i] )
        {
            msg_Warn( p_enc, "MPEG audio doesn't support bitrate=%d, using %d",
                      p_enc->fmt_out.i_bitrate,
                      mpa_bitrate_tab[i_frequency / 3][i] * 1000 );
            p_enc->fmt_out.i_bitrate = mpa_bitrate_tab[i_frequency / 3][i]
                                        * 1000;
        }

        twolame_set_bitrate( p_sys->p_twolame,
                             p_enc->fmt_out.i_bitrate / 1000 );
    }

    if ( p_enc->fmt_in.audio.i_channels == 1 )
    {
        twolame_set_num_channels( p_sys->p_twolame, 1 );
        twolame_set_mode( p_sys->p_twolame, TWOLAME_MONO );
    }
    else
    {
        twolame_set_num_channels( p_sys->p_twolame, 2 );
        switch( var_GetInteger( p_enc, ENC_CFG_PREFIX "mode" ) )
        {
        case 1:
            twolame_set_mode( p_sys->p_twolame, TWOLAME_DUAL_CHANNEL );
            break;
        case 2:
            twolame_set_mode( p_sys->p_twolame, TWOLAME_JOINT_STEREO );
            break;
        case 0:
        default:
            twolame_set_mode( p_sys->p_twolame, TWOLAME_STEREO );
            break;
        }
    }

    twolame_set_psymodel( p_sys->p_twolame,
                          var_GetInteger( p_enc, ENC_CFG_PREFIX "psy" ) );

    if ( twolame_init_params( p_sys->p_twolame ) )
    {
        msg_Err( p_enc, "twolame initialization failed" );
        return -VLC_EGENERIC;
    }

    p_enc->pf_encode_audio = Encode;

    p_sys->i_nb_samples = 0;

    return VLC_SUCCESS;
}
Example #3
0
int mpae_init_twolame(audio_encoder_t *encoder)
{
	int mode;
	mpae_twolame_ctx *ctx = NULL;

	if(encoder->params.channels == 1)
	{
		mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_twolame, 1 audio channel, forcing mono mode\n");
		mode = TWOLAME_MONO;
	}
	else if(encoder->params.channels == 2)
	{
		if(! strcasecmp(param_mode, "dual"))
			mode = TWOLAME_DUAL_CHANNEL;
		else if(! strcasecmp(param_mode, "jstereo"))
			mode = TWOLAME_JOINT_STEREO;
		else if(! strcasecmp(param_mode, "stereo"))
			mode = TWOLAME_STEREO;
		else
		{
			mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, unknown mode %s, exiting\n", param_mode);
		}
	}
	else
		mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, Twolame can't encode > 2 channels, exiting\n");

	ctx = calloc(1, sizeof(mpae_twolame_ctx));
	if(ctx == NULL)
	{
		mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_twolame_ctx));
		return 0;
	}

	ctx->twolame_ctx = twolame_init();
	if(ctx->twolame_ctx == NULL)
	{
		mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't initial parameters from libtwolame, exiting\n");
		free(ctx);
		return 0;
	}
	ctx->vbr = 0;

	if(twolame_set_num_channels(ctx->twolame_ctx, encoder->params.channels) != 0)
		return 0;
	if(twolame_set_mode(ctx->twolame_ctx, mode) != 0)
		return 0;

	if(twolame_set_in_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0)
		return 0;

	if(twolame_set_out_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0)
		return 0;

	if(encoder->params.sample_rate < 32000)
		twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG2);
	else
		twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG1);

	if(twolame_set_psymodel(ctx->twolame_ctx, param_psy) != 0)
		return 0;

	if(twolame_set_bitrate(ctx->twolame_ctx, param_bitrate) != 0)
		return 0;

	if(param_errprot)
		if(twolame_set_error_protection(ctx->twolame_ctx, TRUE) != 0)
			return 0;

	if(param_vbr != 0)
	{
		if(twolame_set_VBR(ctx->twolame_ctx, TRUE) != 0)
			return 0;
		if(twolame_set_VBR_q(ctx->twolame_ctx, param_vbr) != 0)
			return 0;
		if(twolame_set_padding(ctx->twolame_ctx, FALSE) != 0)
			return 0;
		if(param_maxvbr)
		{
			if(twolame_set_VBR_max_bitrate_kbps(ctx->twolame_ctx, param_maxvbr) != 0)
				return 0;
		}
		ctx->vbr = 1;
	}

	if(twolame_set_verbosity(ctx->twolame_ctx, param_debug) != 0)
		return 0;

	if(twolame_init_params(ctx->twolame_ctx) != 0)
		return 0;

	encoder->params.bitrate = param_bitrate * 1000;
	encoder->params.samples_per_frame = 1152;
	encoder->priv = ctx;
	encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels;

	encoder->bind = bind_twolame;
	encoder->get_frame_size = get_frame_size;
	encoder->encode = encode_twolame;
	encoder->close = close_twolame;

	return 1;
}