/* -*- 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.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. lamegf = lame_init(); if(!lamegf) { info->error("LAME initialization failed (due to malloc failure!)"); } lame_init_params(lamegf); decoder = NULL; audio_buffer[0] = new int16_t[AUDIO_BUFFER_SIZE]; audio_buffer[1] = new int16_t[AUDIO_BUFFER_SIZE]; } LibLAMEWrapper::~LibLAMEWrapper() { delete audio_buffer[0]; delete audio_buffer[1]; } 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 ); /* 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: * * 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[0]; // 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(lamegf, 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; } } return audio_frame; }