1159b3361Sopenharmony_ci/* 2159b3361Sopenharmony_ci* Blade DLL Interface for LAME. 3159b3361Sopenharmony_ci* 4159b3361Sopenharmony_ci* Copyright (c) 1999 - 2002 A.L. Faber 5159b3361Sopenharmony_ci* 6159b3361Sopenharmony_ci* This library is free software; you can redistribute it and/or 7159b3361Sopenharmony_ci* modify it under the terms of the GNU Library General Public 8159b3361Sopenharmony_ci* License as published by the Free Software Foundation; either 9159b3361Sopenharmony_ci* version 2 of the License, or (at your option) any later version. 10159b3361Sopenharmony_ci* 11159b3361Sopenharmony_ci* This library is distributed in the hope that it will be useful, 12159b3361Sopenharmony_ci* but WITHOUT ANY WARRANTY; without even the implied warranty of 13159b3361Sopenharmony_ci* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14159b3361Sopenharmony_ci* Library General Public License for more details. 15159b3361Sopenharmony_ci* 16159b3361Sopenharmony_ci* You should have received a copy of the GNU Library General Public 17159b3361Sopenharmony_ci* License along with this library; if not, write to the 18159b3361Sopenharmony_ci* Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19159b3361Sopenharmony_ci* Boston, MA 02111-1307, USA. 20159b3361Sopenharmony_ci*/ 21159b3361Sopenharmony_ci 22159b3361Sopenharmony_ci#include <windows.h> 23159b3361Sopenharmony_ci#include <Windef.h> 24159b3361Sopenharmony_ci#include "BladeMP3EncDLL.h" 25159b3361Sopenharmony_ci#include <assert.h> 26159b3361Sopenharmony_ci#include <stdio.h> 27159b3361Sopenharmony_ci 28159b3361Sopenharmony_ci#include <lame.h> 29159b3361Sopenharmony_ci 30159b3361Sopenharmony_ci#ifdef __cplusplus 31159b3361Sopenharmony_ciextern "C" { 32159b3361Sopenharmony_ci#endif 33159b3361Sopenharmony_ci 34159b3361Sopenharmony_ci#define Min(A, B) ((A) < (B) ? (A) : (B)) 35159b3361Sopenharmony_ci#define Max(A, B) ((A) > (B) ? (A) : (B)) 36159b3361Sopenharmony_ci 37159b3361Sopenharmony_ci#define _RELEASEDEBUG 0 38159b3361Sopenharmony_ci 39159b3361Sopenharmony_ci// lame_enc DLL version number 40159b3361Sopenharmony_ciconst BYTE MAJORVERSION = 1; 41159b3361Sopenharmony_ciconst BYTE MINORVERSION = 32; 42159b3361Sopenharmony_ci 43159b3361Sopenharmony_ci 44159b3361Sopenharmony_ci// Local variables 45159b3361Sopenharmony_cistatic DWORD dwSampleBufferSize=0; 46159b3361Sopenharmony_cistatic HMODULE gs_hModule=NULL; 47159b3361Sopenharmony_cistatic BOOL gs_bLogFile=FALSE; 48159b3361Sopenharmony_cistatic lame_global_flags* gfp_save = NULL; 49159b3361Sopenharmony_ci 50159b3361Sopenharmony_ci// Local function prototypes 51159b3361Sopenharmony_cistatic void dump_config( lame_global_flags* gfp ); 52159b3361Sopenharmony_cistatic void DebugPrintf( const char* pzFormat, ... ); 53159b3361Sopenharmony_cistatic void DispErr( char const* strErr ); 54159b3361Sopenharmony_cistatic void PresetOptions( lame_global_flags *gfp, LONG myPreset ); 55159b3361Sopenharmony_ci 56159b3361Sopenharmony_ci 57159b3361Sopenharmony_cistatic void DebugPrintf(const char* pzFormat, ...) 58159b3361Sopenharmony_ci{ 59159b3361Sopenharmony_ci char szBuffer[1024]={'\0',}; 60159b3361Sopenharmony_ci char szFileName[MAX_PATH+1]={'\0',}; 61159b3361Sopenharmony_ci va_list ap; 62159b3361Sopenharmony_ci 63159b3361Sopenharmony_ci // Get the full module (DLL) file name 64159b3361Sopenharmony_ci GetModuleFileNameA( gs_hModule, 65159b3361Sopenharmony_ci szFileName, 66159b3361Sopenharmony_ci sizeof( szFileName ) ); 67159b3361Sopenharmony_ci 68159b3361Sopenharmony_ci // change file name extention 69159b3361Sopenharmony_ci szFileName[ strlen(szFileName) - 3 ] = 't'; 70159b3361Sopenharmony_ci szFileName[ strlen(szFileName) - 2 ] = 'x'; 71159b3361Sopenharmony_ci szFileName[ strlen(szFileName) - 1 ] = 't'; 72159b3361Sopenharmony_ci 73159b3361Sopenharmony_ci // start at beginning of the list 74159b3361Sopenharmony_ci va_start(ap, pzFormat); 75159b3361Sopenharmony_ci 76159b3361Sopenharmony_ci // copy it to the string buffer 77159b3361Sopenharmony_ci _vsnprintf(szBuffer, sizeof(szBuffer), pzFormat, ap); 78159b3361Sopenharmony_ci 79159b3361Sopenharmony_ci // log it to the file? 80159b3361Sopenharmony_ci if ( gs_bLogFile ) 81159b3361Sopenharmony_ci { 82159b3361Sopenharmony_ci FILE* fp = NULL; 83159b3361Sopenharmony_ci 84159b3361Sopenharmony_ci // try to open the log file 85159b3361Sopenharmony_ci fp=fopen( szFileName, "a+" ); 86159b3361Sopenharmony_ci 87159b3361Sopenharmony_ci // check file open result 88159b3361Sopenharmony_ci if (fp) 89159b3361Sopenharmony_ci { 90159b3361Sopenharmony_ci // write string to the file 91159b3361Sopenharmony_ci fputs(szBuffer,fp); 92159b3361Sopenharmony_ci 93159b3361Sopenharmony_ci // close the file 94159b3361Sopenharmony_ci fclose(fp); 95159b3361Sopenharmony_ci } 96159b3361Sopenharmony_ci } 97159b3361Sopenharmony_ci 98159b3361Sopenharmony_ci#if defined _DEBUG || defined _RELEASEDEBUG 99159b3361Sopenharmony_ci OutputDebugStringA( szBuffer ); 100159b3361Sopenharmony_ci#endif 101159b3361Sopenharmony_ci 102159b3361Sopenharmony_ci va_end(ap); 103159b3361Sopenharmony_ci} 104159b3361Sopenharmony_ci 105159b3361Sopenharmony_ci 106159b3361Sopenharmony_cistatic void PresetOptions( lame_global_flags *gfp, LONG myPreset ) 107159b3361Sopenharmony_ci{ 108159b3361Sopenharmony_ci switch (myPreset) 109159b3361Sopenharmony_ci { 110159b3361Sopenharmony_ci /*-1*/case LQP_NOPRESET: 111159b3361Sopenharmony_ci break; 112159b3361Sopenharmony_ci 113159b3361Sopenharmony_ci /*0*/case LQP_NORMAL_QUALITY: 114159b3361Sopenharmony_ci /* lame_set_quality( gfp, 5 );*/ 115159b3361Sopenharmony_ci break; 116159b3361Sopenharmony_ci 117159b3361Sopenharmony_ci /*1*/case LQP_LOW_QUALITY: 118159b3361Sopenharmony_ci lame_set_quality( gfp, 9 ); 119159b3361Sopenharmony_ci break; 120159b3361Sopenharmony_ci 121159b3361Sopenharmony_ci /*2*/case LQP_HIGH_QUALITY: 122159b3361Sopenharmony_ci lame_set_quality( gfp, 2 ); 123159b3361Sopenharmony_ci break; 124159b3361Sopenharmony_ci 125159b3361Sopenharmony_ci /*3*/case LQP_VOICE_QUALITY: // --voice flag for experimental voice mode 126159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 127159b3361Sopenharmony_ci lame_set_preset( gfp, 56); 128159b3361Sopenharmony_ci break; 129159b3361Sopenharmony_ci 130159b3361Sopenharmony_ci /*4*/case LQP_R3MIX: // --R3MIX 131159b3361Sopenharmony_ci lame_set_preset( gfp, R3MIX); 132159b3361Sopenharmony_ci break; 133159b3361Sopenharmony_ci 134159b3361Sopenharmony_ci /*5*/case LQP_VERYHIGH_QUALITY: 135159b3361Sopenharmony_ci lame_set_quality( gfp, 0 ); 136159b3361Sopenharmony_ci break; 137159b3361Sopenharmony_ci 138159b3361Sopenharmony_ci /*6*/case LQP_STANDARD: // --PRESET STANDARD 139159b3361Sopenharmony_ci lame_set_preset( gfp, STANDARD); 140159b3361Sopenharmony_ci break; 141159b3361Sopenharmony_ci 142159b3361Sopenharmony_ci /*7*/case LQP_FAST_STANDARD: // --PRESET FAST STANDARD 143159b3361Sopenharmony_ci lame_set_preset( gfp, STANDARD_FAST); 144159b3361Sopenharmony_ci break; 145159b3361Sopenharmony_ci 146159b3361Sopenharmony_ci /*8*/case LQP_EXTREME: // --PRESET EXTREME 147159b3361Sopenharmony_ci lame_set_preset( gfp, EXTREME); 148159b3361Sopenharmony_ci break; 149159b3361Sopenharmony_ci 150159b3361Sopenharmony_ci /*9*/case LQP_FAST_EXTREME: // --PRESET FAST EXTREME: 151159b3361Sopenharmony_ci lame_set_preset( gfp, EXTREME_FAST); 152159b3361Sopenharmony_ci break; 153159b3361Sopenharmony_ci 154159b3361Sopenharmony_ci /*10*/case LQP_INSANE: // --PRESET INSANE 155159b3361Sopenharmony_ci lame_set_preset( gfp, INSANE); 156159b3361Sopenharmony_ci break; 157159b3361Sopenharmony_ci 158159b3361Sopenharmony_ci /*11*/case LQP_ABR: // --PRESET ABR 159159b3361Sopenharmony_ci // handled in beInitStream 160159b3361Sopenharmony_ci break; 161159b3361Sopenharmony_ci 162159b3361Sopenharmony_ci /*12*/case LQP_CBR: // --PRESET CBR 163159b3361Sopenharmony_ci // handled in beInitStream 164159b3361Sopenharmony_ci break; 165159b3361Sopenharmony_ci 166159b3361Sopenharmony_ci /*13*/case LQP_MEDIUM: // --PRESET MEDIUM 167159b3361Sopenharmony_ci lame_set_preset( gfp, MEDIUM); 168159b3361Sopenharmony_ci break; 169159b3361Sopenharmony_ci 170159b3361Sopenharmony_ci /*14*/case LQP_FAST_MEDIUM: // --PRESET FAST MEDIUM 171159b3361Sopenharmony_ci lame_set_preset( gfp, MEDIUM_FAST); 172159b3361Sopenharmony_ci break; 173159b3361Sopenharmony_ci 174159b3361Sopenharmony_ci /*1000*/case LQP_PHONE: 175159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 176159b3361Sopenharmony_ci lame_set_preset( gfp, 16); 177159b3361Sopenharmony_ci break; 178159b3361Sopenharmony_ci 179159b3361Sopenharmony_ci /*2000*/case LQP_SW: 180159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 181159b3361Sopenharmony_ci lame_set_preset( gfp, 24); 182159b3361Sopenharmony_ci break; 183159b3361Sopenharmony_ci 184159b3361Sopenharmony_ci /*3000*/case LQP_AM: 185159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 186159b3361Sopenharmony_ci lame_set_preset( gfp, 40); 187159b3361Sopenharmony_ci break; 188159b3361Sopenharmony_ci 189159b3361Sopenharmony_ci /*4000*/case LQP_FM: 190159b3361Sopenharmony_ci lame_set_preset( gfp, 112); 191159b3361Sopenharmony_ci break; 192159b3361Sopenharmony_ci 193159b3361Sopenharmony_ci /*5000*/case LQP_VOICE: 194159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 195159b3361Sopenharmony_ci lame_set_preset( gfp, 56); 196159b3361Sopenharmony_ci break; 197159b3361Sopenharmony_ci 198159b3361Sopenharmony_ci /*6000*/case LQP_RADIO: 199159b3361Sopenharmony_ci lame_set_preset( gfp, 112); 200159b3361Sopenharmony_ci break; 201159b3361Sopenharmony_ci 202159b3361Sopenharmony_ci /*7000*/case LQP_TAPE: 203159b3361Sopenharmony_ci lame_set_preset( gfp, 112); 204159b3361Sopenharmony_ci break; 205159b3361Sopenharmony_ci 206159b3361Sopenharmony_ci /*8000*/case LQP_HIFI: 207159b3361Sopenharmony_ci lame_set_preset( gfp, 160); 208159b3361Sopenharmony_ci break; 209159b3361Sopenharmony_ci 210159b3361Sopenharmony_ci /*9000*/case LQP_CD: 211159b3361Sopenharmony_ci lame_set_preset( gfp, 192); 212159b3361Sopenharmony_ci break; 213159b3361Sopenharmony_ci 214159b3361Sopenharmony_ci /*10000*/case LQP_STUDIO: 215159b3361Sopenharmony_ci lame_set_preset( gfp, 256); 216159b3361Sopenharmony_ci break; 217159b3361Sopenharmony_ci 218159b3361Sopenharmony_ci } 219159b3361Sopenharmony_ci} 220159b3361Sopenharmony_ci 221159b3361Sopenharmony_ci 222159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream) 223159b3361Sopenharmony_ci{ 224159b3361Sopenharmony_ci int actual_bitrate; 225159b3361Sopenharmony_ci //2001-12-18 226159b3361Sopenharmony_ci BE_CONFIG lameConfig = { 0, }; 227159b3361Sopenharmony_ci int nInitReturn = 0; 228159b3361Sopenharmony_ci lame_global_flags* gfp = NULL; 229159b3361Sopenharmony_ci 230159b3361Sopenharmony_ci // Init the global flags structure 231159b3361Sopenharmony_ci gfp = lame_init(); 232159b3361Sopenharmony_ci *phbeStream = (HBE_STREAM)gfp; 233159b3361Sopenharmony_ci 234159b3361Sopenharmony_ci // clear out structure 235159b3361Sopenharmony_ci memset(&lameConfig,0x00,CURRENT_STRUCT_SIZE); 236159b3361Sopenharmony_ci 237159b3361Sopenharmony_ci // Check if this is a regular BLADE_ENCODER header 238159b3361Sopenharmony_ci if (pbeConfig->dwConfig!=BE_CONFIG_LAME) 239159b3361Sopenharmony_ci { 240159b3361Sopenharmony_ci int nCRC=pbeConfig->format.mp3.bCRC; 241159b3361Sopenharmony_ci int nVBR=(nCRC>>12)&0x0F; 242159b3361Sopenharmony_ci 243159b3361Sopenharmony_ci // Copy parameter from old Blade structure 244159b3361Sopenharmony_ci lameConfig.format.LHV1.dwSampleRate =pbeConfig->format.mp3.dwSampleRate; 245159b3361Sopenharmony_ci //for low bitrates, LAME will automatically downsample for better 246159b3361Sopenharmony_ci //sound quality. Forcing output samplerate = input samplerate is not a good idea 247159b3361Sopenharmony_ci //unless the user specifically requests it: 248159b3361Sopenharmony_ci //lameConfig.format.LHV1.dwReSampleRate=pbeConfig->format.mp3.dwSampleRate; 249159b3361Sopenharmony_ci lameConfig.format.LHV1.nMode =(pbeConfig->format.mp3.byMode&0x0F); 250159b3361Sopenharmony_ci lameConfig.format.LHV1.dwBitrate =pbeConfig->format.mp3.wBitrate; 251159b3361Sopenharmony_ci lameConfig.format.LHV1.bPrivate =pbeConfig->format.mp3.bPrivate; 252159b3361Sopenharmony_ci lameConfig.format.LHV1.bOriginal =pbeConfig->format.mp3.bOriginal; 253159b3361Sopenharmony_ci lameConfig.format.LHV1.bCRC =nCRC&0x01; 254159b3361Sopenharmony_ci lameConfig.format.LHV1.bCopyright =pbeConfig->format.mp3.bCopyright; 255159b3361Sopenharmony_ci 256159b3361Sopenharmony_ci // Fill out the unknowns 257159b3361Sopenharmony_ci lameConfig.format.LHV1.dwStructSize=CURRENT_STRUCT_SIZE; 258159b3361Sopenharmony_ci lameConfig.format.LHV1.dwStructVersion=CURRENT_STRUCT_VERSION; 259159b3361Sopenharmony_ci 260159b3361Sopenharmony_ci // Get VBR setting from fourth nibble 261159b3361Sopenharmony_ci if ( nVBR>0 ) 262159b3361Sopenharmony_ci { 263159b3361Sopenharmony_ci lameConfig.format.LHV1.bWriteVBRHeader = TRUE; 264159b3361Sopenharmony_ci lameConfig.format.LHV1.bEnableVBR = TRUE; 265159b3361Sopenharmony_ci lameConfig.format.LHV1.nVBRQuality = nVBR-1; 266159b3361Sopenharmony_ci } 267159b3361Sopenharmony_ci 268159b3361Sopenharmony_ci // Get Quality from third nibble 269159b3361Sopenharmony_ci lameConfig.format.LHV1.nPreset=((nCRC>>8)&0x0F); 270159b3361Sopenharmony_ci 271159b3361Sopenharmony_ci } 272159b3361Sopenharmony_ci else 273159b3361Sopenharmony_ci { 274159b3361Sopenharmony_ci // Copy the parameters 275159b3361Sopenharmony_ci memcpy(&lameConfig,pbeConfig,pbeConfig->format.LHV1.dwStructSize); 276159b3361Sopenharmony_ci } 277159b3361Sopenharmony_ci 278159b3361Sopenharmony_ci // --------------- Set arguments to LAME encoder ------------------------- 279159b3361Sopenharmony_ci 280159b3361Sopenharmony_ci // Set input sample frequency 281159b3361Sopenharmony_ci lame_set_in_samplerate( gfp, lameConfig.format.LHV1.dwSampleRate ); 282159b3361Sopenharmony_ci 283159b3361Sopenharmony_ci // disable INFO/VBR tag by default. 284159b3361Sopenharmony_ci // if this tag is used, the calling program must call beWriteVBRTag() 285159b3361Sopenharmony_ci // after encoding. But the original DLL documentation does not 286159b3361Sopenharmony_ci // require the 287159b3361Sopenharmony_ci // app to call beWriteVBRTag() unless they have specifically 288159b3361Sopenharmony_ci // set LHV1.bWriteVBRHeader=TRUE. Thus the default setting should 289159b3361Sopenharmony_ci // be disabled. 290159b3361Sopenharmony_ci lame_set_bWriteVbrTag( gfp, 0 ); 291159b3361Sopenharmony_ci 292159b3361Sopenharmony_ci //2001-12-18 Dibrom's ABR preset stuff 293159b3361Sopenharmony_ci 294159b3361Sopenharmony_ci if(lameConfig.format.LHV1.nPreset == LQP_ABR) // --ALT-PRESET ABR 295159b3361Sopenharmony_ci { 296159b3361Sopenharmony_ci actual_bitrate = lameConfig.format.LHV1.dwVbrAbr_bps / 1000; 297159b3361Sopenharmony_ci 298159b3361Sopenharmony_ci // limit range 299159b3361Sopenharmony_ci if( actual_bitrate > 320) 300159b3361Sopenharmony_ci { 301159b3361Sopenharmony_ci actual_bitrate = 320; 302159b3361Sopenharmony_ci } 303159b3361Sopenharmony_ci 304159b3361Sopenharmony_ci if( actual_bitrate < 8 ) 305159b3361Sopenharmony_ci { 306159b3361Sopenharmony_ci actual_bitrate = 8; 307159b3361Sopenharmony_ci } 308159b3361Sopenharmony_ci 309159b3361Sopenharmony_ci lame_set_preset( gfp, actual_bitrate ); 310159b3361Sopenharmony_ci } 311159b3361Sopenharmony_ci 312159b3361Sopenharmony_ci // end Dibrom's ABR preset 2001-12-18 ****** START OF CBR 313159b3361Sopenharmony_ci 314159b3361Sopenharmony_ci if(lameConfig.format.LHV1.nPreset == LQP_CBR) // --ALT-PRESET CBR 315159b3361Sopenharmony_ci { 316159b3361Sopenharmony_ci actual_bitrate = lameConfig.format.LHV1.dwBitrate; 317159b3361Sopenharmony_ci lame_set_preset(gfp, actual_bitrate); 318159b3361Sopenharmony_ci lame_set_VBR(gfp, vbr_off); 319159b3361Sopenharmony_ci } 320159b3361Sopenharmony_ci 321159b3361Sopenharmony_ci // end Dibrom's CBR preset 2001-12-18 322159b3361Sopenharmony_ci 323159b3361Sopenharmony_ci // The following settings only used when preset is not one of the LAME QUALITY Presets 324159b3361Sopenharmony_ci if ( (int)lameConfig.format.LHV1.nPreset < (int) LQP_STANDARD ) 325159b3361Sopenharmony_ci { 326159b3361Sopenharmony_ci switch ( lameConfig.format.LHV1.nMode ) 327159b3361Sopenharmony_ci { 328159b3361Sopenharmony_ci case BE_MP3_MODE_STEREO: 329159b3361Sopenharmony_ci lame_set_mode( gfp, STEREO ); 330159b3361Sopenharmony_ci lame_set_num_channels( gfp, 2 ); 331159b3361Sopenharmony_ci break; 332159b3361Sopenharmony_ci case BE_MP3_MODE_JSTEREO: 333159b3361Sopenharmony_ci lame_set_mode( gfp, JOINT_STEREO ); 334159b3361Sopenharmony_ci //lame_set_force_ms( gfp, bForceMS ); // no check box to force this? 335159b3361Sopenharmony_ci lame_set_num_channels( gfp, 2 ); 336159b3361Sopenharmony_ci break; 337159b3361Sopenharmony_ci case BE_MP3_MODE_MONO: 338159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 339159b3361Sopenharmony_ci lame_set_num_channels( gfp, 1 ); 340159b3361Sopenharmony_ci break; 341159b3361Sopenharmony_ci case BE_MP3_MODE_DUALCHANNEL: 342159b3361Sopenharmony_ci lame_set_mode( gfp, DUAL_CHANNEL ); 343159b3361Sopenharmony_ci lame_set_num_channels( gfp, 2 ); 344159b3361Sopenharmony_ci break; 345159b3361Sopenharmony_ci default: 346159b3361Sopenharmony_ci { 347159b3361Sopenharmony_ci DebugPrintf("Invalid lameConfig.format.LHV1.nMode, value is %d\n",lameConfig.format.LHV1.nMode); 348159b3361Sopenharmony_ci return BE_ERR_INVALID_FORMAT_PARAMETERS; 349159b3361Sopenharmony_ci } 350159b3361Sopenharmony_ci } 351159b3361Sopenharmony_ci 352159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bEnableVBR ) 353159b3361Sopenharmony_ci { 354159b3361Sopenharmony_ci /* set VBR quality */ 355159b3361Sopenharmony_ci lame_set_VBR_q( gfp, lameConfig.format.LHV1.nVBRQuality ); 356159b3361Sopenharmony_ci 357159b3361Sopenharmony_ci /* select proper VBR method */ 358159b3361Sopenharmony_ci switch ( lameConfig.format.LHV1.nVbrMethod) 359159b3361Sopenharmony_ci { 360159b3361Sopenharmony_ci case VBR_METHOD_NONE: 361159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_off ); 362159b3361Sopenharmony_ci break; 363159b3361Sopenharmony_ci 364159b3361Sopenharmony_ci case VBR_METHOD_DEFAULT: 365159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_default ); 366159b3361Sopenharmony_ci break; 367159b3361Sopenharmony_ci 368159b3361Sopenharmony_ci case VBR_METHOD_OLD: 369159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_rh ); 370159b3361Sopenharmony_ci break; 371159b3361Sopenharmony_ci 372159b3361Sopenharmony_ci case VBR_METHOD_MTRH: 373159b3361Sopenharmony_ci case VBR_METHOD_NEW: 374159b3361Sopenharmony_ci /* 375159b3361Sopenharmony_ci * the --vbr-mtrh commandline switch is obsolete. 376159b3361Sopenharmony_ci * now --vbr-mtrh is known as --vbr-new 377159b3361Sopenharmony_ci */ 378159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_mtrh ); 379159b3361Sopenharmony_ci break; 380159b3361Sopenharmony_ci 381159b3361Sopenharmony_ci case VBR_METHOD_ABR: 382159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_abr ); 383159b3361Sopenharmony_ci break; 384159b3361Sopenharmony_ci 385159b3361Sopenharmony_ci default: 386159b3361Sopenharmony_ci /* unsupported VBR method */ 387159b3361Sopenharmony_ci assert( FALSE ); 388159b3361Sopenharmony_ci } 389159b3361Sopenharmony_ci } 390159b3361Sopenharmony_ci else 391159b3361Sopenharmony_ci { 392159b3361Sopenharmony_ci /* use CBR encoding method, so turn off VBR */ 393159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_off ); 394159b3361Sopenharmony_ci } 395159b3361Sopenharmony_ci 396159b3361Sopenharmony_ci /* Set bitrate. (CDex users always specify bitrate=Min bitrate when using VBR) */ 397159b3361Sopenharmony_ci lame_set_brate( gfp, lameConfig.format.LHV1.dwBitrate ); 398159b3361Sopenharmony_ci 399159b3361Sopenharmony_ci /* check if we have to use ABR, in order to backwards compatible, this 400159b3361Sopenharmony_ci * condition should still be checked indepedent of the nVbrMethod method 401159b3361Sopenharmony_ci */ 402159b3361Sopenharmony_ci if (lameConfig.format.LHV1.dwVbrAbr_bps > 0 ) 403159b3361Sopenharmony_ci { 404159b3361Sopenharmony_ci /* set VBR method to ABR */ 405159b3361Sopenharmony_ci lame_set_VBR( gfp, vbr_abr ); 406159b3361Sopenharmony_ci 407159b3361Sopenharmony_ci /* calculate to kbps, round to nearest kbps */ 408159b3361Sopenharmony_ci lame_set_VBR_mean_bitrate_kbps( gfp, ( lameConfig.format.LHV1.dwVbrAbr_bps + 500 ) / 1000 ); 409159b3361Sopenharmony_ci 410159b3361Sopenharmony_ci /* limit range */ 411159b3361Sopenharmony_ci if( lame_get_VBR_mean_bitrate_kbps( gfp ) > 320) 412159b3361Sopenharmony_ci { 413159b3361Sopenharmony_ci lame_set_VBR_mean_bitrate_kbps( gfp, 320 ); 414159b3361Sopenharmony_ci } 415159b3361Sopenharmony_ci 416159b3361Sopenharmony_ci if( lame_get_VBR_mean_bitrate_kbps( gfp ) < 8 ) 417159b3361Sopenharmony_ci { 418159b3361Sopenharmony_ci lame_set_VBR_mean_bitrate_kbps( gfp, 8 ); 419159b3361Sopenharmony_ci } 420159b3361Sopenharmony_ci } 421159b3361Sopenharmony_ci 422159b3361Sopenharmony_ci } 423159b3361Sopenharmony_ci 424159b3361Sopenharmony_ci // First set all the preset options 425159b3361Sopenharmony_ci if ( LQP_NOPRESET != lameConfig.format.LHV1.nPreset ) 426159b3361Sopenharmony_ci { 427159b3361Sopenharmony_ci PresetOptions( gfp, lameConfig.format.LHV1.nPreset ); 428159b3361Sopenharmony_ci } 429159b3361Sopenharmony_ci 430159b3361Sopenharmony_ci 431159b3361Sopenharmony_ci // Set frequency resampling rate, if specified 432159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.dwReSampleRate > 0 ) 433159b3361Sopenharmony_ci { 434159b3361Sopenharmony_ci lame_set_out_samplerate( gfp, lameConfig.format.LHV1.dwReSampleRate ); 435159b3361Sopenharmony_ci } 436159b3361Sopenharmony_ci 437159b3361Sopenharmony_ci 438159b3361Sopenharmony_ci switch ( lameConfig.format.LHV1.nMode ) 439159b3361Sopenharmony_ci { 440159b3361Sopenharmony_ci case BE_MP3_MODE_MONO: 441159b3361Sopenharmony_ci lame_set_mode( gfp, MONO ); 442159b3361Sopenharmony_ci lame_set_num_channels( gfp, 1 ); 443159b3361Sopenharmony_ci break; 444159b3361Sopenharmony_ci 445159b3361Sopenharmony_ci default: 446159b3361Sopenharmony_ci break; 447159b3361Sopenharmony_ci } 448159b3361Sopenharmony_ci 449159b3361Sopenharmony_ci 450159b3361Sopenharmony_ci // Use strict ISO encoding? 451159b3361Sopenharmony_ci lame_set_strict_ISO( gfp, ( lameConfig.format.LHV1.bStrictIso ) ? 1 : 0 ); 452159b3361Sopenharmony_ci 453159b3361Sopenharmony_ci // Set copyright flag? 454159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bCopyright ) 455159b3361Sopenharmony_ci { 456159b3361Sopenharmony_ci lame_set_copyright( gfp, 1 ); 457159b3361Sopenharmony_ci } 458159b3361Sopenharmony_ci 459159b3361Sopenharmony_ci // Do we have to tag it as non original 460159b3361Sopenharmony_ci if ( !lameConfig.format.LHV1.bOriginal ) 461159b3361Sopenharmony_ci { 462159b3361Sopenharmony_ci lame_set_original( gfp, 0 ); 463159b3361Sopenharmony_ci } 464159b3361Sopenharmony_ci else 465159b3361Sopenharmony_ci { 466159b3361Sopenharmony_ci lame_set_original( gfp, 1 ); 467159b3361Sopenharmony_ci } 468159b3361Sopenharmony_ci 469159b3361Sopenharmony_ci // Add CRC? 470159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bCRC ) 471159b3361Sopenharmony_ci { 472159b3361Sopenharmony_ci lame_set_error_protection( gfp, 1 ); 473159b3361Sopenharmony_ci } 474159b3361Sopenharmony_ci else 475159b3361Sopenharmony_ci { 476159b3361Sopenharmony_ci lame_set_error_protection( gfp, 0 ); 477159b3361Sopenharmony_ci } 478159b3361Sopenharmony_ci 479159b3361Sopenharmony_ci // Set private bit? 480159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bPrivate ) 481159b3361Sopenharmony_ci { 482159b3361Sopenharmony_ci lame_set_extension( gfp, 1 ); 483159b3361Sopenharmony_ci } 484159b3361Sopenharmony_ci else 485159b3361Sopenharmony_ci { 486159b3361Sopenharmony_ci lame_set_extension( gfp, 0 ); 487159b3361Sopenharmony_ci } 488159b3361Sopenharmony_ci 489159b3361Sopenharmony_ci 490159b3361Sopenharmony_ci // Set VBR min bitrate, if specified 491159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.dwBitrate > 0 ) 492159b3361Sopenharmony_ci { 493159b3361Sopenharmony_ci lame_set_VBR_min_bitrate_kbps( gfp, lameConfig.format.LHV1.dwBitrate ); 494159b3361Sopenharmony_ci } 495159b3361Sopenharmony_ci 496159b3361Sopenharmony_ci // Set Maxbitrate, if specified 497159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.dwMaxBitrate > 0 ) 498159b3361Sopenharmony_ci { 499159b3361Sopenharmony_ci lame_set_VBR_max_bitrate_kbps( gfp, lameConfig.format.LHV1.dwMaxBitrate ); 500159b3361Sopenharmony_ci } 501159b3361Sopenharmony_ci // Set bit resovoir option 502159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bNoRes ) 503159b3361Sopenharmony_ci { 504159b3361Sopenharmony_ci lame_set_disable_reservoir( gfp,1 ); 505159b3361Sopenharmony_ci } 506159b3361Sopenharmony_ci 507159b3361Sopenharmony_ci // check if the VBR tag is required 508159b3361Sopenharmony_ci if ( lameConfig.format.LHV1.bWriteVBRHeader ) 509159b3361Sopenharmony_ci { 510159b3361Sopenharmony_ci lame_set_bWriteVbrTag( gfp, 1 ); 511159b3361Sopenharmony_ci } 512159b3361Sopenharmony_ci else 513159b3361Sopenharmony_ci { 514159b3361Sopenharmony_ci lame_set_bWriteVbrTag( gfp, 0 ); 515159b3361Sopenharmony_ci } 516159b3361Sopenharmony_ci 517159b3361Sopenharmony_ci // Override Quality setting, use HIGHBYTE = NOT LOWBYTE to be backwards compatible 518159b3361Sopenharmony_ci if ( ( lameConfig.format.LHV1.nQuality & 0xFF ) == 519159b3361Sopenharmony_ci ((~( lameConfig.format.LHV1.nQuality >> 8 )) & 0xFF) ) 520159b3361Sopenharmony_ci { 521159b3361Sopenharmony_ci lame_set_quality( gfp, lameConfig.format.LHV1.nQuality & 0xFF ); 522159b3361Sopenharmony_ci } 523159b3361Sopenharmony_ci 524159b3361Sopenharmony_ci if ( 0 != ( nInitReturn = lame_init_params( gfp ) ) ) 525159b3361Sopenharmony_ci { 526159b3361Sopenharmony_ci return nInitReturn; 527159b3361Sopenharmony_ci } 528159b3361Sopenharmony_ci 529159b3361Sopenharmony_ci //LAME encoding call will accept any number of samples. 530159b3361Sopenharmony_ci if ( 0 == lame_get_version( gfp ) ) 531159b3361Sopenharmony_ci { 532159b3361Sopenharmony_ci // For MPEG-II, only 576 samples per frame per channel 533159b3361Sopenharmony_ci *dwSamples= 576 * lame_get_num_channels( gfp ); 534159b3361Sopenharmony_ci } 535159b3361Sopenharmony_ci else 536159b3361Sopenharmony_ci { 537159b3361Sopenharmony_ci // For MPEG-I, 1152 samples per frame per channel 538159b3361Sopenharmony_ci *dwSamples= 1152 * lame_get_num_channels( gfp ); 539159b3361Sopenharmony_ci } 540159b3361Sopenharmony_ci 541159b3361Sopenharmony_ci // Set the input sample buffer size, so we know what we can expect 542159b3361Sopenharmony_ci dwSampleBufferSize = *dwSamples; 543159b3361Sopenharmony_ci 544159b3361Sopenharmony_ci // Set MP3 buffer size, conservative estimate 545159b3361Sopenharmony_ci *dwBufferSize=(DWORD)( 1.25 * ( *dwSamples / lame_get_num_channels( gfp ) ) + 7200 ); 546159b3361Sopenharmony_ci 547159b3361Sopenharmony_ci // For debugging purposes 548159b3361Sopenharmony_ci dump_config( gfp ); 549159b3361Sopenharmony_ci 550159b3361Sopenharmony_ci // Everything went OK, thus return SUCCESSFUL 551159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 552159b3361Sopenharmony_ci} 553159b3361Sopenharmony_ci 554159b3361Sopenharmony_ci 555159b3361Sopenharmony_ci 556159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput) 557159b3361Sopenharmony_ci{ 558159b3361Sopenharmony_ci int nOutputSamples = 0; 559159b3361Sopenharmony_ci 560159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 561159b3361Sopenharmony_ci 562159b3361Sopenharmony_ci // Init the global flags structure 563159b3361Sopenharmony_ci nOutputSamples = lame_encode_flush_nogap( gfp, pOutput, LAME_MAXMP3BUFFER ); 564159b3361Sopenharmony_ci 565159b3361Sopenharmony_ci if ( nOutputSamples < 0 ) 566159b3361Sopenharmony_ci { 567159b3361Sopenharmony_ci *pdwOutput = 0; 568159b3361Sopenharmony_ci return BE_ERR_BUFFER_TOO_SMALL; 569159b3361Sopenharmony_ci } 570159b3361Sopenharmony_ci else 571159b3361Sopenharmony_ci { 572159b3361Sopenharmony_ci *pdwOutput = nOutputSamples; 573159b3361Sopenharmony_ci } 574159b3361Sopenharmony_ci 575159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 576159b3361Sopenharmony_ci} 577159b3361Sopenharmony_ci 578159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput) 579159b3361Sopenharmony_ci{ 580159b3361Sopenharmony_ci int nOutputSamples = 0; 581159b3361Sopenharmony_ci 582159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 583159b3361Sopenharmony_ci 584159b3361Sopenharmony_ci nOutputSamples = lame_encode_flush( gfp, pOutput, 0 ); 585159b3361Sopenharmony_ci 586159b3361Sopenharmony_ci if ( nOutputSamples < 0 ) 587159b3361Sopenharmony_ci { 588159b3361Sopenharmony_ci *pdwOutput = 0; 589159b3361Sopenharmony_ci return BE_ERR_BUFFER_TOO_SMALL; 590159b3361Sopenharmony_ci } 591159b3361Sopenharmony_ci else 592159b3361Sopenharmony_ci { 593159b3361Sopenharmony_ci *pdwOutput = nOutputSamples; 594159b3361Sopenharmony_ci } 595159b3361Sopenharmony_ci 596159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 597159b3361Sopenharmony_ci} 598159b3361Sopenharmony_ci 599159b3361Sopenharmony_ci 600159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beCloseStream(HBE_STREAM hbeStream) 601159b3361Sopenharmony_ci{ 602159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 603159b3361Sopenharmony_ci 604159b3361Sopenharmony_ci // lame will be close in VbrWriteTag function 605159b3361Sopenharmony_ci if ( !lame_get_bWriteVbrTag( gfp ) ) 606159b3361Sopenharmony_ci { 607159b3361Sopenharmony_ci // clean up of allocated memory 608159b3361Sopenharmony_ci lame_close( gfp ); 609159b3361Sopenharmony_ci 610159b3361Sopenharmony_ci gfp_save = NULL; 611159b3361Sopenharmony_ci } 612159b3361Sopenharmony_ci else 613159b3361Sopenharmony_ci { 614159b3361Sopenharmony_ci gfp_save = (lame_global_flags*)hbeStream; 615159b3361Sopenharmony_ci } 616159b3361Sopenharmony_ci 617159b3361Sopenharmony_ci // DeInit encoder 618159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 619159b3361Sopenharmony_ci} 620159b3361Sopenharmony_ci 621159b3361Sopenharmony_ci 622159b3361Sopenharmony_ci 623159b3361Sopenharmony_ci__declspec(dllexport) VOID beVersion(PBE_VERSION pbeVersion) 624159b3361Sopenharmony_ci{ 625159b3361Sopenharmony_ci // DLL Release date 626159b3361Sopenharmony_ci char lpszDate[20] = { '\0', }; 627159b3361Sopenharmony_ci char lpszTemp[5] = { '\0', }; 628159b3361Sopenharmony_ci lame_version_t lv = { 0, }; 629159b3361Sopenharmony_ci 630159b3361Sopenharmony_ci 631159b3361Sopenharmony_ci // Set DLL interface version 632159b3361Sopenharmony_ci pbeVersion->byDLLMajorVersion=MAJORVERSION; 633159b3361Sopenharmony_ci pbeVersion->byDLLMinorVersion=MINORVERSION; 634159b3361Sopenharmony_ci 635159b3361Sopenharmony_ci get_lame_version_numerical ( &lv ); 636159b3361Sopenharmony_ci 637159b3361Sopenharmony_ci // Set Engine version number (Same as Lame version) 638159b3361Sopenharmony_ci pbeVersion->byMajorVersion = (BYTE)lv.major; 639159b3361Sopenharmony_ci pbeVersion->byMinorVersion = (BYTE)lv.minor; 640159b3361Sopenharmony_ci pbeVersion->byAlphaLevel = (BYTE)lv.alpha; 641159b3361Sopenharmony_ci pbeVersion->byBetaLevel = (BYTE)lv.beta; 642159b3361Sopenharmony_ci 643159b3361Sopenharmony_ci#ifdef MMX_choose_table 644159b3361Sopenharmony_ci pbeVersion->byMMXEnabled=1; 645159b3361Sopenharmony_ci#else 646159b3361Sopenharmony_ci pbeVersion->byMMXEnabled=0; 647159b3361Sopenharmony_ci#endif 648159b3361Sopenharmony_ci 649159b3361Sopenharmony_ci memset( pbeVersion->btReserved, 0, sizeof( pbeVersion->btReserved ) ); 650159b3361Sopenharmony_ci 651159b3361Sopenharmony_ci // Get compilation date 652159b3361Sopenharmony_ci strcpy(lpszDate,__DATE__); 653159b3361Sopenharmony_ci 654159b3361Sopenharmony_ci // Get the first three character, which is the month 655159b3361Sopenharmony_ci strncpy(lpszTemp,lpszDate,3); 656159b3361Sopenharmony_ci lpszTemp[3] = '\0'; 657159b3361Sopenharmony_ci pbeVersion->byMonth=1; 658159b3361Sopenharmony_ci 659159b3361Sopenharmony_ci // Set month 660159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Jan")==0) pbeVersion->byMonth = 1; 661159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Feb")==0) pbeVersion->byMonth = 2; 662159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Mar")==0) pbeVersion->byMonth = 3; 663159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Apr")==0) pbeVersion->byMonth = 4; 664159b3361Sopenharmony_ci if (strcmp(lpszTemp,"May")==0) pbeVersion->byMonth = 5; 665159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Jun")==0) pbeVersion->byMonth = 6; 666159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Jul")==0) pbeVersion->byMonth = 7; 667159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Aug")==0) pbeVersion->byMonth = 8; 668159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Sep")==0) pbeVersion->byMonth = 9; 669159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Oct")==0) pbeVersion->byMonth = 10; 670159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Nov")==0) pbeVersion->byMonth = 11; 671159b3361Sopenharmony_ci if (strcmp(lpszTemp,"Dec")==0) pbeVersion->byMonth = 12; 672159b3361Sopenharmony_ci 673159b3361Sopenharmony_ci // Get day of month string (char [4..5]) 674159b3361Sopenharmony_ci pbeVersion->byDay = (BYTE) atoi( lpszDate + 4 ); 675159b3361Sopenharmony_ci 676159b3361Sopenharmony_ci // Get year of compilation date (char [7..10]) 677159b3361Sopenharmony_ci pbeVersion->wYear = (WORD) atoi( lpszDate + 7 ); 678159b3361Sopenharmony_ci 679159b3361Sopenharmony_ci memset( pbeVersion->zHomepage, 0x00, BE_MAX_HOMEPAGE ); 680159b3361Sopenharmony_ci 681159b3361Sopenharmony_ci strcpy( pbeVersion->zHomepage, "https://lame.sourceforge.io/" ); 682159b3361Sopenharmony_ci} 683159b3361Sopenharmony_ci 684159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, 685159b3361Sopenharmony_ci PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput) 686159b3361Sopenharmony_ci{ 687159b3361Sopenharmony_ci // Encode it 688159b3361Sopenharmony_ci int dwSamples; 689159b3361Sopenharmony_ci int nOutputSamples = 0; 690159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 691159b3361Sopenharmony_ci 692159b3361Sopenharmony_ci dwSamples = nSamples / lame_get_num_channels( gfp ); 693159b3361Sopenharmony_ci 694159b3361Sopenharmony_ci // old versions of lame_enc.dll required exactly 1152 samples 695159b3361Sopenharmony_ci // and worked even if nSamples accidently set to 2304 696159b3361Sopenharmony_ci // simulate this behavoir: 697159b3361Sopenharmony_ci if ( 1 == lame_get_num_channels( gfp ) && nSamples == 2304) 698159b3361Sopenharmony_ci { 699159b3361Sopenharmony_ci dwSamples/= 2; 700159b3361Sopenharmony_ci } 701159b3361Sopenharmony_ci 702159b3361Sopenharmony_ci 703159b3361Sopenharmony_ci if ( 1 == lame_get_num_channels( gfp ) ) 704159b3361Sopenharmony_ci { 705159b3361Sopenharmony_ci nOutputSamples = lame_encode_buffer(gfp,pSamples,pSamples,dwSamples,pOutput,0); 706159b3361Sopenharmony_ci } 707159b3361Sopenharmony_ci else 708159b3361Sopenharmony_ci { 709159b3361Sopenharmony_ci nOutputSamples = lame_encode_buffer_interleaved(gfp,pSamples,dwSamples,pOutput,0); 710159b3361Sopenharmony_ci } 711159b3361Sopenharmony_ci 712159b3361Sopenharmony_ci 713159b3361Sopenharmony_ci if ( nOutputSamples < 0 ) 714159b3361Sopenharmony_ci { 715159b3361Sopenharmony_ci *pdwOutput=0; 716159b3361Sopenharmony_ci return BE_ERR_BUFFER_TOO_SMALL; 717159b3361Sopenharmony_ci } 718159b3361Sopenharmony_ci else 719159b3361Sopenharmony_ci { 720159b3361Sopenharmony_ci *pdwOutput = (DWORD)nOutputSamples; 721159b3361Sopenharmony_ci } 722159b3361Sopenharmony_ci 723159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 724159b3361Sopenharmony_ci} 725159b3361Sopenharmony_ci 726159b3361Sopenharmony_ci 727159b3361Sopenharmony_ci// accept floating point audio samples, scaled to the range of a signed 16-bit 728159b3361Sopenharmony_ci// integer (within +/- 32768), in non-interleaved channels -- DSPguru, jd 729159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples, 730159b3361Sopenharmony_ci PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput) 731159b3361Sopenharmony_ci{ 732159b3361Sopenharmony_ci int nOutputSamples; 733159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 734159b3361Sopenharmony_ci 735159b3361Sopenharmony_ci nOutputSamples = lame_encode_buffer_float(gfp,buffer_l,buffer_r,nSamples,pOutput,0); 736159b3361Sopenharmony_ci 737159b3361Sopenharmony_ci if ( nOutputSamples >= 0 ) 738159b3361Sopenharmony_ci { 739159b3361Sopenharmony_ci *pdwOutput = (DWORD) nOutputSamples; 740159b3361Sopenharmony_ci } 741159b3361Sopenharmony_ci else 742159b3361Sopenharmony_ci { 743159b3361Sopenharmony_ci *pdwOutput=0; 744159b3361Sopenharmony_ci return BE_ERR_BUFFER_TOO_SMALL; 745159b3361Sopenharmony_ci } 746159b3361Sopenharmony_ci 747159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 748159b3361Sopenharmony_ci} 749159b3361Sopenharmony_ci 750159b3361Sopenharmony_cistatic int 751159b3361Sopenharmony_cimaybeSyncWord(FILE* fpStream) 752159b3361Sopenharmony_ci{ 753159b3361Sopenharmony_ci unsigned char mp3_frame_header[4]; 754159b3361Sopenharmony_ci size_t nbytes = fread(mp3_frame_header, 1, sizeof(mp3_frame_header), fpStream); 755159b3361Sopenharmony_ci if ( nbytes != sizeof(mp3_frame_header) ) { 756159b3361Sopenharmony_ci return -1; 757159b3361Sopenharmony_ci } 758159b3361Sopenharmony_ci if ( mp3_frame_header[0] != 0xffu ) { 759159b3361Sopenharmony_ci return -1; /* doesn't look like a sync word */ 760159b3361Sopenharmony_ci } 761159b3361Sopenharmony_ci if ( (mp3_frame_header[1] & 0xE0u) != 0xE0u ) { 762159b3361Sopenharmony_ci return -1; /* doesn't look like a sync word */ 763159b3361Sopenharmony_ci } 764159b3361Sopenharmony_ci return 0; 765159b3361Sopenharmony_ci} 766159b3361Sopenharmony_ci 767159b3361Sopenharmony_cistatic int 768159b3361Sopenharmony_ciskipId3v2(FILE * fpStream, size_t lametag_frame_size) 769159b3361Sopenharmony_ci{ 770159b3361Sopenharmony_ci size_t nbytes; 771159b3361Sopenharmony_ci size_t id3v2TagSize = 0; 772159b3361Sopenharmony_ci unsigned char id3v2Header[10]; 773159b3361Sopenharmony_ci 774159b3361Sopenharmony_ci /* seek to the beginning of the stream */ 775159b3361Sopenharmony_ci if (fseek(fpStream, 0, SEEK_SET) != 0) { 776159b3361Sopenharmony_ci return -2; /* not seekable, abort */ 777159b3361Sopenharmony_ci } 778159b3361Sopenharmony_ci /* read 10 bytes in case there's an ID3 version 2 header here */ 779159b3361Sopenharmony_ci nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream); 780159b3361Sopenharmony_ci if (nbytes != sizeof(id3v2Header)) { 781159b3361Sopenharmony_ci return -3; /* not readable, maybe opened Write-Only */ 782159b3361Sopenharmony_ci } 783159b3361Sopenharmony_ci /* does the stream begin with the ID3 version 2 file identifier? */ 784159b3361Sopenharmony_ci if (!strncmp((char *) id3v2Header, "ID3", 3)) { 785159b3361Sopenharmony_ci /* the tag size (minus the 10-byte header) is encoded into four 786159b3361Sopenharmony_ci * bytes where the most significant bit is clear in each byte 787159b3361Sopenharmony_ci */ 788159b3361Sopenharmony_ci id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21) 789159b3361Sopenharmony_ci | ((id3v2Header[7] & 0x7f) << 14) 790159b3361Sopenharmony_ci | ((id3v2Header[8] & 0x7f) << 7) 791159b3361Sopenharmony_ci | (id3v2Header[9] & 0x7f)) 792159b3361Sopenharmony_ci + sizeof id3v2Header; 793159b3361Sopenharmony_ci } 794159b3361Sopenharmony_ci /* Seek to the beginning of the audio stream */ 795159b3361Sopenharmony_ci if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) { 796159b3361Sopenharmony_ci return -2; 797159b3361Sopenharmony_ci } 798159b3361Sopenharmony_ci if ( maybeSyncWord(fpStream) != 0) { 799159b3361Sopenharmony_ci return -1; 800159b3361Sopenharmony_ci } 801159b3361Sopenharmony_ci if ( fseek(fpStream, id3v2TagSize+lametag_frame_size, SEEK_SET) != 0 ) { 802159b3361Sopenharmony_ci return -2; 803159b3361Sopenharmony_ci } 804159b3361Sopenharmony_ci if ( maybeSyncWord(fpStream) != 0) { 805159b3361Sopenharmony_ci return -1; 806159b3361Sopenharmony_ci } 807159b3361Sopenharmony_ci /* OK, it seems we found our LAME-Tag/Xing frame again */ 808159b3361Sopenharmony_ci /* Seek to the beginning of the audio stream */ 809159b3361Sopenharmony_ci if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) { 810159b3361Sopenharmony_ci return -2; 811159b3361Sopenharmony_ci } 812159b3361Sopenharmony_ci return 0; 813159b3361Sopenharmony_ci} 814159b3361Sopenharmony_ci 815159b3361Sopenharmony_cistatic BE_ERR 816159b3361Sopenharmony_ciupdateLameTagFrame(lame_global_flags* gfp, FILE* fpStream) 817159b3361Sopenharmony_ci{ 818159b3361Sopenharmony_ci size_t n = lame_get_lametag_frame( gfp, 0, 0 ); /* ask for bufer size */ 819159b3361Sopenharmony_ci 820159b3361Sopenharmony_ci if ( n > 0 ) 821159b3361Sopenharmony_ci { 822159b3361Sopenharmony_ci unsigned char* buffer = 0; 823159b3361Sopenharmony_ci size_t m = 1; 824159b3361Sopenharmony_ci 825159b3361Sopenharmony_ci if ( 0 != skipId3v2(fpStream, n) ) 826159b3361Sopenharmony_ci { 827159b3361Sopenharmony_ci DispErr( "Error updating LAME-tag frame:\n\n" 828159b3361Sopenharmony_ci "can't locate old frame\n" ); 829159b3361Sopenharmony_ci return BE_ERR_INVALID_FORMAT_PARAMETERS; 830159b3361Sopenharmony_ci } 831159b3361Sopenharmony_ci 832159b3361Sopenharmony_ci buffer = (unsigned char*)malloc( n ); 833159b3361Sopenharmony_ci 834159b3361Sopenharmony_ci if ( buffer == 0 ) 835159b3361Sopenharmony_ci { 836159b3361Sopenharmony_ci DispErr( "Error updating LAME-tag frame:\n\n" 837159b3361Sopenharmony_ci "can't allocate frame buffer\n" ); 838159b3361Sopenharmony_ci return BE_ERR_INVALID_FORMAT_PARAMETERS; 839159b3361Sopenharmony_ci } 840159b3361Sopenharmony_ci 841159b3361Sopenharmony_ci /* Put it all to disk again */ 842159b3361Sopenharmony_ci n = lame_get_lametag_frame( gfp, buffer, n ); 843159b3361Sopenharmony_ci if ( n > 0 ) 844159b3361Sopenharmony_ci { 845159b3361Sopenharmony_ci m = fwrite( buffer, n, 1, fpStream ); 846159b3361Sopenharmony_ci } 847159b3361Sopenharmony_ci free( buffer ); 848159b3361Sopenharmony_ci 849159b3361Sopenharmony_ci if ( m != 1 ) 850159b3361Sopenharmony_ci { 851159b3361Sopenharmony_ci DispErr( "Error updating LAME-tag frame:\n\n" 852159b3361Sopenharmony_ci "couldn't write frame into file\n" ); 853159b3361Sopenharmony_ci return BE_ERR_INVALID_FORMAT_PARAMETERS; 854159b3361Sopenharmony_ci } 855159b3361Sopenharmony_ci } 856159b3361Sopenharmony_ci return BE_ERR_SUCCESSFUL; 857159b3361Sopenharmony_ci} 858159b3361Sopenharmony_ci 859159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beWriteInfoTag( HBE_STREAM hbeStream, 860159b3361Sopenharmony_ci LPCSTR lpszFileName ) 861159b3361Sopenharmony_ci{ 862159b3361Sopenharmony_ci FILE* fpStream = NULL; 863159b3361Sopenharmony_ci BE_ERR beResult = BE_ERR_SUCCESSFUL; 864159b3361Sopenharmony_ci 865159b3361Sopenharmony_ci lame_global_flags* gfp = (lame_global_flags*)hbeStream; 866159b3361Sopenharmony_ci 867159b3361Sopenharmony_ci if ( NULL != gfp ) 868159b3361Sopenharmony_ci { 869159b3361Sopenharmony_ci // Do we have to write the VBR tag? 870159b3361Sopenharmony_ci if ( lame_get_bWriteVbrTag( gfp ) ) 871159b3361Sopenharmony_ci { 872159b3361Sopenharmony_ci // Try to open the file 873159b3361Sopenharmony_ci fpStream=fopen( lpszFileName, "rb+" ); 874159b3361Sopenharmony_ci 875159b3361Sopenharmony_ci // Check file open result 876159b3361Sopenharmony_ci if ( NULL == fpStream ) 877159b3361Sopenharmony_ci { 878159b3361Sopenharmony_ci beResult = BE_ERR_INVALID_FORMAT_PARAMETERS; 879159b3361Sopenharmony_ci DispErr( "Error updating LAME-tag frame:\n\n" 880159b3361Sopenharmony_ci "can't open file for reading and writing\n" ); 881159b3361Sopenharmony_ci } 882159b3361Sopenharmony_ci else 883159b3361Sopenharmony_ci { 884159b3361Sopenharmony_ci beResult = updateLameTagFrame( gfp, fpStream ); 885159b3361Sopenharmony_ci 886159b3361Sopenharmony_ci // Close the file stream 887159b3361Sopenharmony_ci fclose( fpStream ); 888159b3361Sopenharmony_ci } 889159b3361Sopenharmony_ci } 890159b3361Sopenharmony_ci 891159b3361Sopenharmony_ci // clean up of allocated memory 892159b3361Sopenharmony_ci lame_close( gfp ); 893159b3361Sopenharmony_ci } 894159b3361Sopenharmony_ci else 895159b3361Sopenharmony_ci { 896159b3361Sopenharmony_ci beResult = BE_ERR_INVALID_FORMAT_PARAMETERS; 897159b3361Sopenharmony_ci } 898159b3361Sopenharmony_ci 899159b3361Sopenharmony_ci // return result 900159b3361Sopenharmony_ci return beResult; 901159b3361Sopenharmony_ci} 902159b3361Sopenharmony_ci 903159b3361Sopenharmony_ci// for backwards compatiblity 904159b3361Sopenharmony_ci__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName) 905159b3361Sopenharmony_ci{ 906159b3361Sopenharmony_ci return beWriteInfoTag( (HBE_STREAM)gfp_save, lpszFileName ); 907159b3361Sopenharmony_ci} 908159b3361Sopenharmony_ci 909159b3361Sopenharmony_ci 910159b3361Sopenharmony_ciBOOL APIENTRY DllMain(HANDLE hModule, 911159b3361Sopenharmony_ci DWORD ul_reason_for_call, 912159b3361Sopenharmony_ci LPVOID lpReserved) 913159b3361Sopenharmony_ci{ 914159b3361Sopenharmony_ci (void) lpReserved; 915159b3361Sopenharmony_ci gs_hModule = (HMODULE) hModule; 916159b3361Sopenharmony_ci 917159b3361Sopenharmony_ci switch( ul_reason_for_call ) 918159b3361Sopenharmony_ci { 919159b3361Sopenharmony_ci case DLL_PROCESS_ATTACH: 920159b3361Sopenharmony_ci // Enable debug/logging? 921159b3361Sopenharmony_ci gs_bLogFile = GetPrivateProfileIntA("Debug","WriteLogFile",gs_bLogFile,"lame_enc.ini"); 922159b3361Sopenharmony_ci break; 923159b3361Sopenharmony_ci case DLL_THREAD_ATTACH: 924159b3361Sopenharmony_ci break; 925159b3361Sopenharmony_ci case DLL_THREAD_DETACH: 926159b3361Sopenharmony_ci break; 927159b3361Sopenharmony_ci case DLL_PROCESS_DETACH: 928159b3361Sopenharmony_ci break; 929159b3361Sopenharmony_ci } 930159b3361Sopenharmony_ci return TRUE; 931159b3361Sopenharmony_ci} 932159b3361Sopenharmony_ci 933159b3361Sopenharmony_ci 934159b3361Sopenharmony_cistatic void dump_config( lame_global_flags* gfp ) 935159b3361Sopenharmony_ci{ 936159b3361Sopenharmony_ci DebugPrintf("\n\nLame_enc configuration options:\n"); 937159b3361Sopenharmony_ci DebugPrintf("==========================================================\n"); 938159b3361Sopenharmony_ci 939159b3361Sopenharmony_ci DebugPrintf("version =%d\n",lame_get_version( gfp ) ); 940159b3361Sopenharmony_ci DebugPrintf("Layer =3\n"); 941159b3361Sopenharmony_ci DebugPrintf("mode ="); 942159b3361Sopenharmony_ci switch ( lame_get_mode( gfp ) ) 943159b3361Sopenharmony_ci { 944159b3361Sopenharmony_ci case STEREO: DebugPrintf( "Stereo\n" ); break; 945159b3361Sopenharmony_ci case JOINT_STEREO: DebugPrintf( "Joint-Stereo\n" ); break; 946159b3361Sopenharmony_ci case DUAL_CHANNEL: DebugPrintf( "Forced Stereo\n" ); break; 947159b3361Sopenharmony_ci case MONO: DebugPrintf( "Mono\n" ); break; 948159b3361Sopenharmony_ci case NOT_SET: /* FALLTROUGH */ 949159b3361Sopenharmony_ci default: DebugPrintf( "Error (unknown)\n" ); break; 950159b3361Sopenharmony_ci } 951159b3361Sopenharmony_ci 952159b3361Sopenharmony_ci DebugPrintf("Input sample rate =%.1f kHz\n", lame_get_in_samplerate( gfp ) /1000.0 ); 953159b3361Sopenharmony_ci DebugPrintf("Output sample rate =%.1f kHz\n", lame_get_out_samplerate( gfp ) /1000.0 ); 954159b3361Sopenharmony_ci 955159b3361Sopenharmony_ci DebugPrintf("bitrate =%d kbps\n", lame_get_brate( gfp ) ); 956159b3361Sopenharmony_ci DebugPrintf("Quality Setting =%d\n", lame_get_quality( gfp ) ); 957159b3361Sopenharmony_ci 958159b3361Sopenharmony_ci DebugPrintf("Low pass frequency =%d\n", lame_get_lowpassfreq( gfp ) ); 959159b3361Sopenharmony_ci DebugPrintf("Low pass width =%d\n", lame_get_lowpasswidth( gfp ) ); 960159b3361Sopenharmony_ci 961159b3361Sopenharmony_ci DebugPrintf("High pass frequency =%d\n", lame_get_highpassfreq( gfp ) ); 962159b3361Sopenharmony_ci DebugPrintf("High pass width =%d\n", lame_get_highpasswidth( gfp ) ); 963159b3361Sopenharmony_ci 964159b3361Sopenharmony_ci DebugPrintf("No short blocks =%d\n", lame_get_no_short_blocks( gfp ) ); 965159b3361Sopenharmony_ci DebugPrintf("Force short blocks =%d\n", lame_get_force_short_blocks( gfp ) ); 966159b3361Sopenharmony_ci 967159b3361Sopenharmony_ci DebugPrintf("de-emphasis =%d\n", lame_get_emphasis( gfp ) ); 968159b3361Sopenharmony_ci DebugPrintf("private flag =%d\n", lame_get_extension( gfp ) ); 969159b3361Sopenharmony_ci 970159b3361Sopenharmony_ci DebugPrintf("copyright flag =%d\n", lame_get_copyright( gfp ) ); 971159b3361Sopenharmony_ci DebugPrintf("original flag =%d\n", lame_get_original( gfp ) ); 972159b3361Sopenharmony_ci DebugPrintf("CRC =%s\n", lame_get_error_protection( gfp ) ? "on" : "off" ); 973159b3361Sopenharmony_ci DebugPrintf("Fast mode =%s\n", ( lame_get_quality( gfp ) )? "enabled" : "disabled" ); 974159b3361Sopenharmony_ci DebugPrintf("Force mid/side stereo =%s\n", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" ); 975159b3361Sopenharmony_ci DebugPrintf("Disable Reservoir =%d\n", lame_get_disable_reservoir( gfp ) ); 976159b3361Sopenharmony_ci DebugPrintf("Allow diff-short =%d\n", lame_get_allow_diff_short( gfp ) ); 977159b3361Sopenharmony_ci DebugPrintf("Interchannel masking =%f\n", lame_get_interChRatio( gfp ) ); 978159b3361Sopenharmony_ci DebugPrintf("Strict ISO Encoding =%s\n", ( lame_get_strict_ISO( gfp ) ) ?"Yes":"No"); 979159b3361Sopenharmony_ci DebugPrintf("Scale =%5.2f\n", lame_get_scale( gfp ) ); 980159b3361Sopenharmony_ci 981159b3361Sopenharmony_ci DebugPrintf("VBR =%s, VBR_q =%d, VBR method =", 982159b3361Sopenharmony_ci ( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled", 983159b3361Sopenharmony_ci lame_get_VBR_q( gfp ) ); 984159b3361Sopenharmony_ci 985159b3361Sopenharmony_ci switch ( lame_get_VBR( gfp ) ) 986159b3361Sopenharmony_ci { 987159b3361Sopenharmony_ci case vbr_off: DebugPrintf( "vbr_off\n" ); break; 988159b3361Sopenharmony_ci case vbr_mt : DebugPrintf( "vbr_mt \n" ); break; 989159b3361Sopenharmony_ci case vbr_rh : DebugPrintf( "vbr_rh \n" ); break; 990159b3361Sopenharmony_ci case vbr_mtrh: DebugPrintf( "vbr_mtrh \n" ); break; 991159b3361Sopenharmony_ci case vbr_abr: 992159b3361Sopenharmony_ci DebugPrintf( "vbr_abr (average bitrate %d kbps)\n", lame_get_VBR_mean_bitrate_kbps( gfp ) ); 993159b3361Sopenharmony_ci break; 994159b3361Sopenharmony_ci default: 995159b3361Sopenharmony_ci DebugPrintf("error, unknown VBR setting\n"); 996159b3361Sopenharmony_ci break; 997159b3361Sopenharmony_ci } 998159b3361Sopenharmony_ci 999159b3361Sopenharmony_ci DebugPrintf("Vbr Min bitrate =%d kbps\n", lame_get_VBR_min_bitrate_kbps( gfp ) ); 1000159b3361Sopenharmony_ci DebugPrintf("Vbr Max bitrate =%d kbps\n", lame_get_VBR_max_bitrate_kbps( gfp ) ); 1001159b3361Sopenharmony_ci 1002159b3361Sopenharmony_ci DebugPrintf("Write VBR Header =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No"); 1003159b3361Sopenharmony_ci DebugPrintf("VBR Hard min =%d\n", lame_get_VBR_hard_min( gfp ) ); 1004159b3361Sopenharmony_ci 1005159b3361Sopenharmony_ci DebugPrintf("ATH Only =%d\n", lame_get_ATHonly( gfp ) ); 1006159b3361Sopenharmony_ci DebugPrintf("ATH short =%d\n", lame_get_ATHshort( gfp ) ); 1007159b3361Sopenharmony_ci DebugPrintf("ATH no =%d\n", lame_get_noATH( gfp ) ); 1008159b3361Sopenharmony_ci DebugPrintf("ATH type =%d\n", lame_get_ATHtype( gfp ) ); 1009159b3361Sopenharmony_ci DebugPrintf("ATH lower =%f\n", lame_get_ATHlower( gfp ) ); 1010159b3361Sopenharmony_ci DebugPrintf("ATH aa =%d\n", lame_get_athaa_type( gfp ) ); 1011159b3361Sopenharmony_ci //DebugPrintf("ATH aa loudapprox =%d\n", lame_get_athaa_loudapprox( gfp ) ); 1012159b3361Sopenharmony_ci DebugPrintf("ATH aa sensitivity =%f\n", lame_get_athaa_sensitivity( gfp ) ); 1013159b3361Sopenharmony_ci 1014159b3361Sopenharmony_ci DebugPrintf("Experimental nspsytune =%d\n", lame_get_exp_nspsytune( gfp ) ); 1015159b3361Sopenharmony_ci DebugPrintf("Experimental X =%d\n", lame_get_experimentalX( gfp ) ); 1016159b3361Sopenharmony_ci DebugPrintf("Experimental Y =%d\n", lame_get_experimentalY( gfp ) ); 1017159b3361Sopenharmony_ci DebugPrintf("Experimental Z =%d\n", lame_get_experimentalZ( gfp ) ); 1018159b3361Sopenharmony_ci} 1019159b3361Sopenharmony_ci 1020159b3361Sopenharmony_ci 1021159b3361Sopenharmony_cistatic void DispErr(char const* strErr) 1022159b3361Sopenharmony_ci{ 1023159b3361Sopenharmony_ci MessageBoxA(NULL,strErr,"LAME_ENC.DLL",MB_OK|MB_ICONHAND); 1024159b3361Sopenharmony_ci} 1025159b3361Sopenharmony_ci 1026159b3361Sopenharmony_ci#ifdef __cplusplus 1027159b3361Sopenharmony_ci} 1028159b3361Sopenharmony_ci#endif 1029