1159b3361Sopenharmony_ci/** 2159b3361Sopenharmony_ci * 3159b3361Sopenharmony_ci * Lame ACM wrapper, encode/decode MP3 based RIFF/AVI files in MS Windows 4159b3361Sopenharmony_ci * 5159b3361Sopenharmony_ci * Copyright (c) 2002 Steve Lhomme <steve.lhomme at free.fr> 6159b3361Sopenharmony_ci * 7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or 8159b3361Sopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either 10159b3361Sopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11159b3361Sopenharmony_ci * 12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful, 13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15159b3361Sopenharmony_ci * Lesser General Public License for more details. 16159b3361Sopenharmony_ci * 17159b3361Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18159b3361Sopenharmony_ci * License along with this library; if not, write to the Free Software 19159b3361Sopenharmony_ci * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20159b3361Sopenharmony_ci * 21159b3361Sopenharmony_ci */ 22159b3361Sopenharmony_ci 23159b3361Sopenharmony_ci/*! 24159b3361Sopenharmony_ci \author Steve Lhomme 25159b3361Sopenharmony_ci \version \$Id$ 26159b3361Sopenharmony_ci*/ 27159b3361Sopenharmony_ci 28159b3361Sopenharmony_ci#if !defined(STRICT) 29159b3361Sopenharmony_ci#define STRICT 30159b3361Sopenharmony_ci#endif // STRICT 31159b3361Sopenharmony_ci 32159b3361Sopenharmony_ci#include <assert.h> 33159b3361Sopenharmony_ci#include <windows.h> 34159b3361Sopenharmony_ci 35159b3361Sopenharmony_ci#include "adebug.h" 36159b3361Sopenharmony_ci 37159b3361Sopenharmony_ci#include "ACMStream.h" 38159b3361Sopenharmony_ci 39159b3361Sopenharmony_ci#include <lame.h> 40159b3361Sopenharmony_ci 41159b3361Sopenharmony_ci// static methods 42159b3361Sopenharmony_ci 43159b3361Sopenharmony_ciACMStream * ACMStream::Create() 44159b3361Sopenharmony_ci{ 45159b3361Sopenharmony_ci ACMStream * Result; 46159b3361Sopenharmony_ci 47159b3361Sopenharmony_ci Result = new ACMStream; 48159b3361Sopenharmony_ci 49159b3361Sopenharmony_ci return Result; 50159b3361Sopenharmony_ci} 51159b3361Sopenharmony_ci 52159b3361Sopenharmony_ciconst bool ACMStream::Erase(const ACMStream * a_ACMStream) 53159b3361Sopenharmony_ci{ 54159b3361Sopenharmony_ci delete a_ACMStream; 55159b3361Sopenharmony_ci return true; 56159b3361Sopenharmony_ci} 57159b3361Sopenharmony_ci 58159b3361Sopenharmony_ci// class methods 59159b3361Sopenharmony_ci 60159b3361Sopenharmony_ciACMStream::ACMStream() : 61159b3361Sopenharmony_ci m_WorkingBufferUseSize(0), 62159b3361Sopenharmony_ci gfp(NULL) 63159b3361Sopenharmony_ci{ 64159b3361Sopenharmony_ci /// \todo get the debug level from the registry 65159b3361Sopenharmony_cimy_debug = new ADbg(DEBUG_LEVEL_CREATION); 66159b3361Sopenharmony_ci if (my_debug != NULL) { 67159b3361Sopenharmony_ci unsigned char DebugFileName[512]; 68159b3361Sopenharmony_ci 69159b3361Sopenharmony_ci my_debug->setPrefix("LAMEstream"); /// \todo get it from the registry 70159b3361Sopenharmony_cimy_debug->setIncludeTime(true); /// \todo get it from the registry 71159b3361Sopenharmony_ci 72159b3361Sopenharmony_ci// Check in the registry if we have to Output Debug information 73159b3361Sopenharmony_ciDebugFileName[0] = '\0'; 74159b3361Sopenharmony_ci 75159b3361Sopenharmony_ci HKEY OssKey; 76159b3361Sopenharmony_ci if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\MUKOLI", 0, KEY_READ , &OssKey ) == ERROR_SUCCESS) { 77159b3361Sopenharmony_ci DWORD DataType; 78159b3361Sopenharmony_ci DWORD DebugFileNameSize = 512; 79159b3361Sopenharmony_ci if (RegQueryValueEx( OssKey, "DebugFile", NULL, &DataType, DebugFileName, &DebugFileNameSize ) == ERROR_SUCCESS) { 80159b3361Sopenharmony_ci if (DataType == REG_SZ) { 81159b3361Sopenharmony_ci my_debug->setUseFile(true); 82159b3361Sopenharmony_ci my_debug->setDebugFile((char *)DebugFileName); 83159b3361Sopenharmony_ci my_debug->OutPut("Debug file is %s",(char *)DebugFileName); 84159b3361Sopenharmony_ci } 85159b3361Sopenharmony_ci } 86159b3361Sopenharmony_ci } 87159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_START, "ACMStream Creation (0X%08X)",this); 88159b3361Sopenharmony_ci } 89159b3361Sopenharmony_ci else { 90159b3361Sopenharmony_ci ADbg debug; 91159b3361Sopenharmony_ci debug.OutPut("ACMStream::ACMACMStream : Impossible to create my_debug"); 92159b3361Sopenharmony_ci } 93159b3361Sopenharmony_ci 94159b3361Sopenharmony_ci} 95159b3361Sopenharmony_ci 96159b3361Sopenharmony_ciACMStream::~ACMStream() 97159b3361Sopenharmony_ci{ 98159b3361Sopenharmony_ci // release memory - encoding is finished 99159b3361Sopenharmony_ci if (gfp) lame_close( gfp ); 100159b3361Sopenharmony_ci 101159b3361Sopenharmony_ci if (my_debug != NULL) 102159b3361Sopenharmony_ci { 103159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_START, "ACMStream Deletion (0X%08X)",this); 104159b3361Sopenharmony_ci delete my_debug; 105159b3361Sopenharmony_ci } 106159b3361Sopenharmony_ci} 107159b3361Sopenharmony_ci 108159b3361Sopenharmony_cibool ACMStream::init(const int nSamplesPerSec, const int nOutputSamplesPerSec, const int nChannels, const int nAvgBytesPerSec, const vbr_mode mode) 109159b3361Sopenharmony_ci{ 110159b3361Sopenharmony_ci bool bResult = false; 111159b3361Sopenharmony_ci 112159b3361Sopenharmony_ci my_SamplesPerSec = nSamplesPerSec; 113159b3361Sopenharmony_ci my_OutBytesPerSec = nOutputSamplesPerSec; 114159b3361Sopenharmony_ci my_Channels = nChannels; 115159b3361Sopenharmony_ci my_AvgBytesPerSec = nAvgBytesPerSec; 116159b3361Sopenharmony_ci my_VBRMode = mode; 117159b3361Sopenharmony_ci 118159b3361Sopenharmony_ci bResult = true; 119159b3361Sopenharmony_ci 120159b3361Sopenharmony_ci return bResult; 121159b3361Sopenharmony_ci 122159b3361Sopenharmony_ci} 123159b3361Sopenharmony_ci 124159b3361Sopenharmony_cibool ACMStream::open(const AEncodeProperties & the_Properties) 125159b3361Sopenharmony_ci{ 126159b3361Sopenharmony_ci bool bResult = false; 127159b3361Sopenharmony_ci 128159b3361Sopenharmony_ci // Init the MP3 Stream 129159b3361Sopenharmony_ci // Init the global flags structure 130159b3361Sopenharmony_ci gfp = lame_init(); 131159b3361Sopenharmony_ci 132159b3361Sopenharmony_ci // Set input sample frequency 133159b3361Sopenharmony_ci lame_set_in_samplerate( gfp, my_SamplesPerSec ); 134159b3361Sopenharmony_ci 135159b3361Sopenharmony_ci // Set output sample frequency 136159b3361Sopenharmony_ci lame_set_out_samplerate( gfp, my_OutBytesPerSec ); 137159b3361Sopenharmony_ci 138159b3361Sopenharmony_ci lame_set_num_channels( gfp, my_Channels ); 139159b3361Sopenharmony_ci if (my_Channels == 1) 140159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 141159b3361Sopenharmony_ci else 142159b3361Sopenharmony_ci lame_set_mode( gfp, (MPEG_mode_e)the_Properties.GetChannelModeValue()) ; /// \todo Get the mode from the default configuration 143159b3361Sopenharmony_ci 144159b3361Sopenharmony_ci// lame_set_VBR( gfp, vbr_off ); /// \note VBR not supported for the moment 145159b3361Sopenharmony_ci lame_set_VBR( gfp, my_VBRMode ); /// \note VBR not supported for the moment 146159b3361Sopenharmony_ci 147159b3361Sopenharmony_ci if (my_VBRMode == vbr_abr) 148159b3361Sopenharmony_ci { 149159b3361Sopenharmony_ci lame_set_VBR_q( gfp, 1 ); 150159b3361Sopenharmony_ci 151159b3361Sopenharmony_ci lame_set_VBR_mean_bitrate_kbps( gfp, (my_AvgBytesPerSec * 8 + 500) / 1000 ); 152159b3361Sopenharmony_ci 153159b3361Sopenharmony_ci if (24000 > lame_get_in_samplerate( gfp )) 154159b3361Sopenharmony_ci { 155159b3361Sopenharmony_ci // For MPEG-II 156159b3361Sopenharmony_ci lame_set_VBR_min_bitrate_kbps( gfp, 8); 157159b3361Sopenharmony_ci 158159b3361Sopenharmony_ci lame_set_VBR_max_bitrate_kbps( gfp, 160); 159159b3361Sopenharmony_ci } 160159b3361Sopenharmony_ci else 161159b3361Sopenharmony_ci { 162159b3361Sopenharmony_ci // For MPEG-I 163159b3361Sopenharmony_ci lame_set_VBR_min_bitrate_kbps( gfp, 32); 164159b3361Sopenharmony_ci 165159b3361Sopenharmony_ci lame_set_VBR_max_bitrate_kbps( gfp, 320); 166159b3361Sopenharmony_ci } 167159b3361Sopenharmony_ci } 168159b3361Sopenharmony_ci 169159b3361Sopenharmony_ci // Set bitrate 170159b3361Sopenharmony_ci lame_set_brate( gfp, my_AvgBytesPerSec * 8 / 1000 ); 171159b3361Sopenharmony_ci 172159b3361Sopenharmony_ci /// \todo Get the mode from the default configuration 173159b3361Sopenharmony_ci // Set copyright flag? 174159b3361Sopenharmony_ci lame_set_copyright( gfp, the_Properties.GetCopyrightMode()?1:0 ); 175159b3361Sopenharmony_ci // Do we have to tag it as non original 176159b3361Sopenharmony_ci lame_set_original( gfp, the_Properties.GetOriginalMode()?1:0 ); 177159b3361Sopenharmony_ci // Add CRC? 178159b3361Sopenharmony_ci lame_set_error_protection( gfp, the_Properties.GetCRCMode()?1:0 ); 179159b3361Sopenharmony_ci // Set private bit? 180159b3361Sopenharmony_ci lame_set_extension( gfp, the_Properties.GetPrivateMode()?1:0 ); 181159b3361Sopenharmony_ci // INFO tag support not possible in ACM - it requires rewinding 182159b3361Sopenharmony_ci // output stream to the beginning after encoding is finished. 183159b3361Sopenharmony_ci lame_set_bWriteVbrTag( gfp, 0 ); 184159b3361Sopenharmony_ci 185159b3361Sopenharmony_ci if (0 == lame_init_params( gfp )) 186159b3361Sopenharmony_ci { 187159b3361Sopenharmony_ci //LAME encoding call will accept any number of samples. 188159b3361Sopenharmony_ci if ( 0 == lame_get_version( gfp ) ) 189159b3361Sopenharmony_ci { 190159b3361Sopenharmony_ci // For MPEG-II, only 576 samples per frame per channel 191159b3361Sopenharmony_ci my_SamplesPerBlock = 576 * lame_get_num_channels( gfp ); 192159b3361Sopenharmony_ci } 193159b3361Sopenharmony_ci else 194159b3361Sopenharmony_ci { 195159b3361Sopenharmony_ci // For MPEG-I, 1152 samples per frame per channel 196159b3361Sopenharmony_ci my_SamplesPerBlock = 1152 * lame_get_num_channels( gfp ); 197159b3361Sopenharmony_ci } 198159b3361Sopenharmony_ci } 199159b3361Sopenharmony_ci 200159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "version =%d",lame_get_version( gfp ) ); 201159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Layer =3"); 202159b3361Sopenharmony_ci switch ( lame_get_mode( gfp ) ) 203159b3361Sopenharmony_ci { 204159b3361Sopenharmony_ci case STEREO: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "mode =Stereo" ); break; 205159b3361Sopenharmony_ci case JOINT_STEREO: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "mode =Joint-Stereo" ); break; 206159b3361Sopenharmony_ci case DUAL_CHANNEL: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "mode =Forced Stereo" ); break; 207159b3361Sopenharmony_ci case MONO: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "mode =Mono" ); break; 208159b3361Sopenharmony_ci case NOT_SET: /* FALLTROUGH */ 209159b3361Sopenharmony_ci default: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "mode =Error (unknown)" ); break; 210159b3361Sopenharmony_ci } 211159b3361Sopenharmony_ci 212159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "sampling frequency =%.1f kHz", lame_get_in_samplerate( gfp ) /1000.0 ); 213159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "bitrate =%d kbps", lame_get_brate( gfp ) ); 214159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Min bitrate =%d kbps", lame_get_VBR_min_bitrate_kbps( gfp ) ); 215159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Max bitrate =%d kbps", lame_get_VBR_max_bitrate_kbps( gfp ) ); 216159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Quality Setting =%d", lame_get_quality( gfp ) ); 217159b3361Sopenharmony_ci 218159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass frequency =%d", lame_get_lowpassfreq( gfp ) ); 219159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass width =%d", lame_get_lowpasswidth( gfp ) ); 220159b3361Sopenharmony_ci 221159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass frequency =%d", lame_get_highpassfreq( gfp ) ); 222159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass width =%d", lame_get_highpasswidth( gfp ) ); 223159b3361Sopenharmony_ci 224159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "No Short Blocks =%d", lame_get_no_short_blocks( gfp ) ); 225159b3361Sopenharmony_ci 226159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "de-emphasis =%d", lame_get_emphasis( gfp ) ); 227159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "private flag =%d", lame_get_extension( gfp ) ); 228159b3361Sopenharmony_ci 229159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "copyright flag =%d", lame_get_copyright( gfp ) ); 230159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "original flag =%d", lame_get_original( gfp ) ); 231159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "CRC =%s", lame_get_error_protection( gfp ) ? "on" : "off" ); 232159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Fast mode =%s", ( lame_get_quality( gfp ) )? "enabled" : "disabled" ); 233159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Force mid/side stereo =%s", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" ); 234159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Disable Resorvoir =%d", lame_get_disable_reservoir( gfp ) ); 235159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "VBR =%s, VBR_q =%d, VBR method =", 236159b3361Sopenharmony_ci ( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled", 237159b3361Sopenharmony_ci lame_get_VBR_q( gfp ) ); 238159b3361Sopenharmony_ci 239159b3361Sopenharmony_ci switch ( lame_get_VBR( gfp ) ) 240159b3361Sopenharmony_ci { 241159b3361Sopenharmony_ci case vbr_off: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "vbr_off" ); break; 242159b3361Sopenharmony_ci case vbr_mt : my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "vbr_mt" ); break; 243159b3361Sopenharmony_ci case vbr_rh : my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "vbr_rh" ); break; 244159b3361Sopenharmony_ci case vbr_mtrh: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "vbr_mtrh" ); break; 245159b3361Sopenharmony_ci case vbr_abr: 246159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "vbr_abr (average bitrate %d kbps)", lame_get_VBR_mean_bitrate_kbps( gfp ) ); 247159b3361Sopenharmony_ci break; 248159b3361Sopenharmony_ci default: 249159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "error, unknown VBR setting"); 250159b3361Sopenharmony_ci break; 251159b3361Sopenharmony_ci } 252159b3361Sopenharmony_ci 253159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Write VBR Header =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No"); 254159b3361Sopenharmony_ci 255159b3361Sopenharmony_ci#ifdef FROM_DLL 256159b3361Sopenharmony_cibeConfig.format.LHV1.dwReSampleRate = my_OutBytesPerSec; // force the user resampling 257159b3361Sopenharmony_ci#endif // FROM_DLL 258159b3361Sopenharmony_ci 259159b3361Sopenharmony_ci bResult = true; 260159b3361Sopenharmony_ci 261159b3361Sopenharmony_ci return bResult; 262159b3361Sopenharmony_ci} 263159b3361Sopenharmony_ci 264159b3361Sopenharmony_cibool ACMStream::close(LPBYTE pOutputBuffer, DWORD *pOutputSize) 265159b3361Sopenharmony_ci{ 266159b3361Sopenharmony_ci 267159b3361Sopenharmony_cibool bResult = false; 268159b3361Sopenharmony_ci 269159b3361Sopenharmony_ci int nOutputSamples = 0; 270159b3361Sopenharmony_ci 271159b3361Sopenharmony_ci nOutputSamples = lame_encode_flush( gfp, pOutputBuffer, 0 ); 272159b3361Sopenharmony_ci 273159b3361Sopenharmony_ci if ( nOutputSamples < 0 ) 274159b3361Sopenharmony_ci { 275159b3361Sopenharmony_ci // BUFFER_TOO_SMALL 276159b3361Sopenharmony_ci*pOutputSize = 0; 277159b3361Sopenharmony_ci } 278159b3361Sopenharmony_ci else 279159b3361Sopenharmony_ci{ 280159b3361Sopenharmony_ci *pOutputSize = nOutputSamples; 281159b3361Sopenharmony_ci 282159b3361Sopenharmony_ci bResult = true; 283159b3361Sopenharmony_ci } 284159b3361Sopenharmony_ci 285159b3361Sopenharmony_ci // lame will be closed in destructor 286159b3361Sopenharmony_ci //lame_close( gfp ); 287159b3361Sopenharmony_ci 288159b3361Sopenharmony_ci return bResult; 289159b3361Sopenharmony_ci} 290159b3361Sopenharmony_ci 291159b3361Sopenharmony_ciDWORD ACMStream::GetOutputSizeForInput(const DWORD the_SrcLength) const 292159b3361Sopenharmony_ci{ 293159b3361Sopenharmony_ci/* double OutputInputRatio; 294159b3361Sopenharmony_ci 295159b3361Sopenharmony_ci if (my_VBRMode == vbr_off) 296159b3361Sopenharmony_ci OutputInputRatio = double(my_AvgBytesPerSec) / double(my_OutBytesPerSec * 2); 297159b3361Sopenharmony_ci else // reserve the space for 320 kbps 298159b3361Sopenharmony_ci OutputInputRatio = 40000.0 / double(my_OutBytesPerSec * 2); 299159b3361Sopenharmony_ci 300159b3361Sopenharmony_ci OutputInputRatio *= 1.15; // allow 15% more*/ 301159b3361Sopenharmony_ci 302159b3361Sopenharmony_ci DWORD Result; 303159b3361Sopenharmony_ci 304159b3361Sopenharmony_ci// Result = DWORD(double(the_SrcLength) * OutputInputRatio); 305159b3361Sopenharmony_ci Result = DWORD(1.25*the_SrcLength + 7200); 306159b3361Sopenharmony_ci 307159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "Result = %d",Result); 308159b3361Sopenharmony_ci 309159b3361Sopenharmony_ci return Result; 310159b3361Sopenharmony_ci} 311159b3361Sopenharmony_ci 312159b3361Sopenharmony_cibool ACMStream::ConvertBuffer(LPACMDRVSTREAMHEADER a_StreamHeader) 313159b3361Sopenharmony_ci{ 314159b3361Sopenharmony_ci bool result; 315159b3361Sopenharmony_ci 316159b3361Sopenharmony_ciif (my_debug != NULL) 317159b3361Sopenharmony_ci{ 318159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "enter ACMStream::ConvertBuffer"); 319159b3361Sopenharmony_ci} 320159b3361Sopenharmony_ci 321159b3361Sopenharmony_ci DWORD InSize = a_StreamHeader->cbSrcLength / 2, OutSize = a_StreamHeader->cbDstLength; // 2 for 8<->16 bits 322159b3361Sopenharmony_ci 323159b3361Sopenharmony_ci// Encode it 324159b3361Sopenharmony_ciint dwSamples; 325159b3361Sopenharmony_ci int nOutputSamples = 0; 326159b3361Sopenharmony_ci 327159b3361Sopenharmony_ci dwSamples = InSize / lame_get_num_channels( gfp ); 328159b3361Sopenharmony_ci 329159b3361Sopenharmony_ci if ( 1 == lame_get_num_channels( gfp ) ) 330159b3361Sopenharmony_ci { 331159b3361Sopenharmony_ci nOutputSamples = lame_encode_buffer(gfp,(PSHORT)a_StreamHeader->pbSrc,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength); 332159b3361Sopenharmony_ci } 333159b3361Sopenharmony_ci else 334159b3361Sopenharmony_ci { 335159b3361Sopenharmony_ci nOutputSamples = lame_encode_buffer_interleaved(gfp,(PSHORT)a_StreamHeader->pbSrc,dwSamples,a_StreamHeader->pbDst,a_StreamHeader->cbDstLength); 336159b3361Sopenharmony_ci } 337159b3361Sopenharmony_ci 338159b3361Sopenharmony_ci a_StreamHeader->cbSrcLengthUsed = a_StreamHeader->cbSrcLength; 339159b3361Sopenharmony_ci a_StreamHeader->cbDstLengthUsed = nOutputSamples; 340159b3361Sopenharmony_ci 341159b3361Sopenharmony_ci result = a_StreamHeader->cbDstLengthUsed <= a_StreamHeader->cbDstLength; 342159b3361Sopenharmony_ci 343159b3361Sopenharmony_ci my_debug->OutPut(DEBUG_LEVEL_FUNC_CODE, "UsedSize = %d / EncodedSize = %d, result = %d (%d <= %d)", InSize, OutSize, result, a_StreamHeader->cbDstLengthUsed, a_StreamHeader->cbDstLength); 344159b3361Sopenharmony_ci 345159b3361Sopenharmony_ciif (my_debug != NULL) 346159b3361Sopenharmony_ci{ 347159b3361Sopenharmony_cimy_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "ACMStream::ConvertBuffer result = %d (0x%02X 0x%02X)",result,a_StreamHeader->pbDst[0],a_StreamHeader->pbDst[1]); 348159b3361Sopenharmony_ci} 349159b3361Sopenharmony_ci 350159b3361Sopenharmony_ci return result; 351159b3361Sopenharmony_ci} 352159b3361Sopenharmony_ci 353159b3361Sopenharmony_ci/* map frequency to a valid MP3 sample frequency 354159b3361Sopenharmony_ci * 355159b3361Sopenharmony_ci * Robert Hegemann 2000-07-01 356159b3361Sopenharmony_ci */ 357159b3361Sopenharmony_cistatic int 358159b3361Sopenharmony_cimap2MP3Frequency(int freq) 359159b3361Sopenharmony_ci{ 360159b3361Sopenharmony_ci if (freq <= 8000) 361159b3361Sopenharmony_ci return 8000; 362159b3361Sopenharmony_ci if (freq <= 11025) 363159b3361Sopenharmony_ci return 11025; 364159b3361Sopenharmony_ci if (freq <= 12000) 365159b3361Sopenharmony_ci return 12000; 366159b3361Sopenharmony_ci if (freq <= 16000) 367159b3361Sopenharmony_ci return 16000; 368159b3361Sopenharmony_ci if (freq <= 22050) 369159b3361Sopenharmony_ci return 22050; 370159b3361Sopenharmony_ci if (freq <= 24000) 371159b3361Sopenharmony_ci return 24000; 372159b3361Sopenharmony_ci if (freq <= 32000) 373159b3361Sopenharmony_ci return 32000; 374159b3361Sopenharmony_ci if (freq <= 44100) 375159b3361Sopenharmony_ci return 44100; 376159b3361Sopenharmony_ci 377159b3361Sopenharmony_ci return 48000; 378159b3361Sopenharmony_ci} 379159b3361Sopenharmony_ci 380159b3361Sopenharmony_ci 381159b3361Sopenharmony_ciunsigned int ACMStream::GetOutputSampleRate(int samples_per_sec, int bitrate, int channels) 382159b3361Sopenharmony_ci{ 383159b3361Sopenharmony_ci if (bitrate==0) 384159b3361Sopenharmony_ci bitrate = (64000*channels)/8; 385159b3361Sopenharmony_ci 386159b3361Sopenharmony_ci /// \todo pass through the same LAME routine 387159b3361Sopenharmony_ci unsigned int OutputFrequency; 388159b3361Sopenharmony_ci double compression_ratio = double(samples_per_sec * 16 * channels / (bitrate * 8)); 389159b3361Sopenharmony_ci if (compression_ratio > 13.) 390159b3361Sopenharmony_ci OutputFrequency = map2MP3Frequency( (10. * bitrate * 8) / (16 * channels)); 391159b3361Sopenharmony_ci else 392159b3361Sopenharmony_ci OutputFrequency = map2MP3Frequency( 0.97 * samples_per_sec ); 393159b3361Sopenharmony_ci 394159b3361Sopenharmony_ci return OutputFrequency; 395159b3361Sopenharmony_ci 396159b3361Sopenharmony_ci} 397159b3361Sopenharmony_ci 398