/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * liblame_wrapper.cc * * Sat Jul 2 11:11:34 CEST 2005 * Copyright 2005 Bent Bisballe * deva@aasimon.org ****************************************************************************/ /* * This file is part of MIaV. * * MIaV is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * MIaV 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MIaV; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ /* * $Id$ */ /* * $Log$ * Revision 1.2 2005/07/05 23:15:16 deva * *** empty log message *** * * Revision 1.1 2005/07/02 11:39:51 deva * Added some audiocode. * Moved libfame code out of mov_encoder * */ #include #include "liblame_wrapper.h" LibLAMEWrapper::LibLAMEWrapper(Info *i) { info = i; // Init library. if( (gfp = lame_init()) == NULL) { info->error("LAME initialization failed (due to malloc failure!)"); return; } lame_set_in_samplerate(gfp, SAMPLE_RATE); lame_set_out_samplerate(gfp, SAMPLE_RATE); lame_set_num_channels(gfp, CHANNELS); // lame 3.91 dies on quality != 5 lame_set_quality(gfp, 5); // lame 3.91 doesn't work in mono lame_set_mode(gfp, STEREO); lame_set_brate(gfp, 192); lame_set_strict_ISO(gfp, 1); if (lame_init_params(gfp) < 0) { info->error("LAME parameter initialization failed."); return; } lame_init_bitstream(gfp); audio_buffer[0] = new int16_t[AUDIO_BUFFER_SIZE]; audio_buffer[1] = new int16_t[AUDIO_BUFFER_SIZE]; audio_buffer[2] = new int16_t[AUDIO_BUFFER_SIZE]; audio_buffer[3] = new int16_t[AUDIO_BUFFER_SIZE]; // And now for the dv decoder! decoder = NULL; } LibLAMEWrapper::~LibLAMEWrapper() { lame_close(gfp); delete audio_buffer[0]; delete audio_buffer[1]; delete audio_buffer[2]; delete audio_buffer[3]; } Frame *LibLAMEWrapper::encode(Frame *dvframe) { if(!decoder) { decoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE); decoder->quality = DV_QUALITY_BEST; dv_parse_header(decoder, dvframe->data); decoder->system = e_dv_system_625_50; // PAL lines, PAL framerate decoder->sampling = e_dv_sample_422; // 4 bytes y, 2 bytes u, 2 bytes v decoder->std = e_dv_std_iec_61834; decoder->num_dif_seqs = 12; } // See // http://www.koders.com/cpp/fidE614E999154E2B4A813DA272C4421633063C78CA.aspx // line 769 /** * Decode audio using libdv */ // int n, i; // int16_t* s = ( int16_t * ) sound; dv_decode_full_audio( decoder, dvframe->data, audio_buffer ); /* memset(audio_buffer[0], 0, sizeof(audio_buffer[0])); memset(audio_buffer[1], 0, sizeof(audio_buffer[1])); */ /* for ( n = 0; n < SAMPLES; ++n ) for ( i = 0; i < CHANNELS; i++ ) *s++ = audio_buffer[ i ][ n ]; */ /* * input pcm data, output (maybe) mp3 frames. * This routine handles all buffering, resampling and filtering for you. * * The required mp3buf_size can be computed from num_samples, * samplerate and encoding rate, but here is a worst case estimate: * * return code number of bytes output in mp3buffer. can be 0 * if return code = -1: mp3buffer was too small * * mp3buf_size in bytes = 1.25*num_samples + 7200 * * I think a tighter bound could be: (mt, March 2000) * MPEG1: * num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512 * MPEG2: * num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256 * * but test first if you use that! * * set mp3buf_size = 0 and LAME will not check if mp3buf_size is * large enough. * * NOTE: * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels * will be averaged into the L channel before encoding only the L channel * This will overwrite the data in buffer_l[] and buffer_r[]. * */ Frame* audio_frame = new Frame(NULL, (int)(1.25 * SAMPLES + 7200)); const short int *buffer_l = audio_buffer[0]; // PCM data for left channel const short int *buffer_r = audio_buffer[1]; // PCM data for right channel const int nsamples = SAMPLES; // number of samples per channel unsigned char* mp3buf = audio_frame->data; // pointer to encoded MP3 stream const int mp3buf_size = audio_frame->size; // number of valid octets in this int val = lame_encode_buffer(gfp, buffer_l, buffer_r, nsamples, mp3buf, mp3buf_size); if(val < 0) { switch(val) { case -1: // mp3buf was too small info->error("Lame encoding failed, mp3buf was too small."); break; case -2: // malloc() problem info->error("Lame encoding failed, due to malloc() problem."); break; case -3: // lame_init_params() not called info->error("Lame encoding failed, lame_init_params() not called."); break; case -4: // psycho acoustic problems info->error("Lame encoding failed, due to psycho acoustic problems."); break; default: info->error("Lame encoding failed, due to unknown error."); break; } } /* val = lame_encode_flush(gfp, mp3buf, val); if(val < 0) { switch(val) { case -1: // mp3buf was too small info->error("Lame encoding failed (during flush), mp3buf was too small."); break; case -2: // malloc() problem info->error("Lame encoding failed (during flush), due to malloc() problem."); break; case -3: // lame_init_params() not called info->error("Lame encoding failed (during flush), lame_init_params() not called."); break; case -4: // psycho acoustic problems info->error("Lame encoding failed (during flush), due to psycho acoustic problems."); break; default: info->error("Lame encoding failed (during flush), due to unknown error."); break; } } */ audio_frame->size = val; return audio_frame; }