|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
* Blade DLL Interface for LAME.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* Copyright (c) 1999 - 2002 A.L. Faber
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
47f805 |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
47f805 |
* License as published by the Free Software Foundation; either
|
|
Packit |
47f805 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
47f805 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
47f805 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
47f805 |
* Library General Public License for more details.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
47f805 |
* License along with this library; if not, write to the
|
|
Packit |
47f805 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
47f805 |
* Boston, MA 02111-1307, USA.
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <windows.h>
|
|
Packit |
47f805 |
#include <Windef.h>
|
|
Packit |
47f805 |
#include "BladeMP3EncDLL.h"
|
|
Packit |
47f805 |
#include <assert.h>
|
|
Packit |
47f805 |
#include <stdio.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <lame.h>
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef __cplusplus
|
|
Packit |
47f805 |
extern "C" {
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define Min(A, B) ((A) < (B) ? (A) : (B))
|
|
Packit |
47f805 |
#define Max(A, B) ((A) > (B) ? (A) : (B))
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define _RELEASEDEBUG 0
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// lame_enc DLL version number
|
|
Packit |
47f805 |
const BYTE MAJORVERSION = 1;
|
|
Packit |
47f805 |
const BYTE MINORVERSION = 32;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Local variables
|
|
Packit |
47f805 |
static DWORD dwSampleBufferSize=0;
|
|
Packit |
47f805 |
static HMODULE gs_hModule=NULL;
|
|
Packit |
47f805 |
static BOOL gs_bLogFile=FALSE;
|
|
Packit |
47f805 |
static lame_global_flags* gfp_save = NULL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Local function prototypes
|
|
Packit |
47f805 |
static void dump_config( lame_global_flags* gfp );
|
|
Packit |
47f805 |
static void DebugPrintf( const char* pzFormat, ... );
|
|
Packit |
47f805 |
static void DispErr( char const* strErr );
|
|
Packit |
47f805 |
static void PresetOptions( lame_global_flags *gfp, LONG myPreset );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static void DebugPrintf(const char* pzFormat, ...)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
char szBuffer[1024]={'\0',};
|
|
Packit |
47f805 |
char szFileName[MAX_PATH+1]={'\0',};
|
|
Packit |
47f805 |
va_list ap;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get the full module (DLL) file name
|
|
Packit |
47f805 |
GetModuleFileNameA( gs_hModule,
|
|
Packit |
47f805 |
szFileName,
|
|
Packit |
47f805 |
sizeof( szFileName ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// change file name extention
|
|
Packit |
47f805 |
szFileName[ strlen(szFileName) - 3 ] = 't';
|
|
Packit |
47f805 |
szFileName[ strlen(szFileName) - 2 ] = 'x';
|
|
Packit |
47f805 |
szFileName[ strlen(szFileName) - 1 ] = 't';
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// start at beginning of the list
|
|
Packit |
47f805 |
va_start(ap, pzFormat);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// copy it to the string buffer
|
|
Packit |
47f805 |
_vsnprintf(szBuffer, sizeof(szBuffer), pzFormat, ap);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// log it to the file?
|
|
Packit |
47f805 |
if ( gs_bLogFile )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
FILE* fp = NULL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// try to open the log file
|
|
Packit |
47f805 |
fp=fopen( szFileName, "a+" );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// check file open result
|
|
Packit |
47f805 |
if (fp)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// write string to the file
|
|
Packit |
47f805 |
fputs(szBuffer,fp);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// close the file
|
|
Packit |
47f805 |
fclose(fp);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#if defined _DEBUG || defined _RELEASEDEBUG
|
|
Packit |
47f805 |
OutputDebugStringA( szBuffer );
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
va_end(ap);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static void PresetOptions( lame_global_flags *gfp, LONG myPreset )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
switch (myPreset)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/*-1*/case LQP_NOPRESET:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*0*/case LQP_NORMAL_QUALITY:
|
|
Packit |
47f805 |
/* lame_set_quality( gfp, 5 );*/
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*1*/case LQP_LOW_QUALITY:
|
|
Packit |
47f805 |
lame_set_quality( gfp, 9 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*2*/case LQP_HIGH_QUALITY:
|
|
Packit |
47f805 |
lame_set_quality( gfp, 2 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*3*/case LQP_VOICE_QUALITY: // --voice flag for experimental voice mode
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_preset( gfp, 56);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*4*/case LQP_R3MIX: // --R3MIX
|
|
Packit |
47f805 |
lame_set_preset( gfp, R3MIX);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*5*/case LQP_VERYHIGH_QUALITY:
|
|
Packit |
47f805 |
lame_set_quality( gfp, 0 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*6*/case LQP_STANDARD: // --PRESET STANDARD
|
|
Packit |
47f805 |
lame_set_preset( gfp, STANDARD);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*7*/case LQP_FAST_STANDARD: // --PRESET FAST STANDARD
|
|
Packit |
47f805 |
lame_set_preset( gfp, STANDARD_FAST);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*8*/case LQP_EXTREME: // --PRESET EXTREME
|
|
Packit |
47f805 |
lame_set_preset( gfp, EXTREME);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*9*/case LQP_FAST_EXTREME: // --PRESET FAST EXTREME:
|
|
Packit |
47f805 |
lame_set_preset( gfp, EXTREME_FAST);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*10*/case LQP_INSANE: // --PRESET INSANE
|
|
Packit |
47f805 |
lame_set_preset( gfp, INSANE);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*11*/case LQP_ABR: // --PRESET ABR
|
|
Packit |
47f805 |
// handled in beInitStream
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*12*/case LQP_CBR: // --PRESET CBR
|
|
Packit |
47f805 |
// handled in beInitStream
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*13*/case LQP_MEDIUM: // --PRESET MEDIUM
|
|
Packit |
47f805 |
lame_set_preset( gfp, MEDIUM);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*14*/case LQP_FAST_MEDIUM: // --PRESET FAST MEDIUM
|
|
Packit |
47f805 |
lame_set_preset( gfp, MEDIUM_FAST);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*1000*/case LQP_PHONE:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_preset( gfp, 16);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*2000*/case LQP_SW:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_preset( gfp, 24);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*3000*/case LQP_AM:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_preset( gfp, 40);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*4000*/case LQP_FM:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 112);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*5000*/case LQP_VOICE:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_preset( gfp, 56);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*6000*/case LQP_RADIO:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 112);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*7000*/case LQP_TAPE:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 112);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*8000*/case LQP_HIFI:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 160);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*9000*/case LQP_CD:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 192);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*10000*/case LQP_STUDIO:
|
|
Packit |
47f805 |
lame_set_preset( gfp, 256);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int actual_bitrate;
|
|
Packit |
47f805 |
//2001-12-18
|
|
Packit |
47f805 |
BE_CONFIG lameConfig = { 0, };
|
|
Packit |
47f805 |
int nInitReturn = 0;
|
|
Packit |
47f805 |
lame_global_flags* gfp = NULL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Init the global flags structure
|
|
Packit |
47f805 |
gfp = lame_init();
|
|
Packit |
47f805 |
*phbeStream = (HBE_STREAM)gfp;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// clear out structure
|
|
Packit |
47f805 |
memset(&lameConfig,0x00,CURRENT_STRUCT_SIZE);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Check if this is a regular BLADE_ENCODER header
|
|
Packit |
47f805 |
if (pbeConfig->dwConfig!=BE_CONFIG_LAME)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int nCRC=pbeConfig->format.mp3.bCRC;
|
|
Packit |
47f805 |
int nVBR=(nCRC>>12)&0x0F;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Copy parameter from old Blade structure
|
|
Packit |
47f805 |
lameConfig.format.LHV1.dwSampleRate =pbeConfig->format.mp3.dwSampleRate;
|
|
Packit |
47f805 |
//for low bitrates, LAME will automatically downsample for better
|
|
Packit |
47f805 |
//sound quality. Forcing output samplerate = input samplerate is not a good idea
|
|
Packit |
47f805 |
//unless the user specifically requests it:
|
|
Packit |
47f805 |
//lameConfig.format.LHV1.dwReSampleRate=pbeConfig->format.mp3.dwSampleRate;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.nMode =(pbeConfig->format.mp3.byMode&0x0F);
|
|
Packit |
47f805 |
lameConfig.format.LHV1.dwBitrate =pbeConfig->format.mp3.wBitrate;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bPrivate =pbeConfig->format.mp3.bPrivate;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bOriginal =pbeConfig->format.mp3.bOriginal;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bCRC =nCRC&0x01;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bCopyright =pbeConfig->format.mp3.bCopyright;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Fill out the unknowns
|
|
Packit |
47f805 |
lameConfig.format.LHV1.dwStructSize=CURRENT_STRUCT_SIZE;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.dwStructVersion=CURRENT_STRUCT_VERSION;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get VBR setting from fourth nibble
|
|
Packit |
47f805 |
if ( nVBR>0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bWriteVBRHeader = TRUE;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.bEnableVBR = TRUE;
|
|
Packit |
47f805 |
lameConfig.format.LHV1.nVBRQuality = nVBR-1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get Quality from third nibble
|
|
Packit |
47f805 |
lameConfig.format.LHV1.nPreset=((nCRC>>8)&0x0F);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Copy the parameters
|
|
Packit |
47f805 |
memcpy(&lameConfig,pbeConfig,pbeConfig->format.LHV1.dwStructSize);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// --------------- Set arguments to LAME encoder -------------------------
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set input sample frequency
|
|
Packit |
47f805 |
lame_set_in_samplerate( gfp, lameConfig.format.LHV1.dwSampleRate );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// disable INFO/VBR tag by default.
|
|
Packit |
47f805 |
// if this tag is used, the calling program must call beWriteVBRTag()
|
|
Packit |
47f805 |
// after encoding. But the original DLL documentation does not
|
|
Packit |
47f805 |
// require the
|
|
Packit |
47f805 |
// app to call beWriteVBRTag() unless they have specifically
|
|
Packit |
47f805 |
// set LHV1.bWriteVBRHeader=TRUE. Thus the default setting should
|
|
Packit |
47f805 |
// be disabled.
|
|
Packit |
47f805 |
lame_set_bWriteVbrTag( gfp, 0 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//2001-12-18 Dibrom's ABR preset stuff
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(lameConfig.format.LHV1.nPreset == LQP_ABR) // --ALT-PRESET ABR
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
actual_bitrate = lameConfig.format.LHV1.dwVbrAbr_bps / 1000;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// limit range
|
|
Packit |
47f805 |
if( actual_bitrate > 320)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
actual_bitrate = 320;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if( actual_bitrate < 8 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
actual_bitrate = 8;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
lame_set_preset( gfp, actual_bitrate );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// end Dibrom's ABR preset 2001-12-18 ****** START OF CBR
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(lameConfig.format.LHV1.nPreset == LQP_CBR) // --ALT-PRESET CBR
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
actual_bitrate = lameConfig.format.LHV1.dwBitrate;
|
|
Packit |
47f805 |
lame_set_preset(gfp, actual_bitrate);
|
|
Packit |
47f805 |
lame_set_VBR(gfp, vbr_off);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// end Dibrom's CBR preset 2001-12-18
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// The following settings only used when preset is not one of the LAME QUALITY Presets
|
|
Packit |
47f805 |
if ( (int)lameConfig.format.LHV1.nPreset < (int) LQP_STANDARD )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
switch ( lameConfig.format.LHV1.nMode )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case BE_MP3_MODE_STEREO:
|
|
Packit |
47f805 |
lame_set_mode( gfp, STEREO );
|
|
Packit |
47f805 |
lame_set_num_channels( gfp, 2 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case BE_MP3_MODE_JSTEREO:
|
|
Packit |
47f805 |
lame_set_mode( gfp, JOINT_STEREO );
|
|
Packit |
47f805 |
//lame_set_force_ms( gfp, bForceMS ); // no check box to force this?
|
|
Packit |
47f805 |
lame_set_num_channels( gfp, 2 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case BE_MP3_MODE_MONO:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_num_channels( gfp, 1 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case BE_MP3_MODE_DUALCHANNEL:
|
|
Packit |
47f805 |
lame_set_mode( gfp, DUAL_CHANNEL );
|
|
Packit |
47f805 |
lame_set_num_channels( gfp, 2 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DebugPrintf("Invalid lameConfig.format.LHV1.nMode, value is %d\n",lameConfig.format.LHV1.nMode);
|
|
Packit |
47f805 |
return BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bEnableVBR )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/* set VBR quality */
|
|
Packit |
47f805 |
lame_set_VBR_q( gfp, lameConfig.format.LHV1.nVBRQuality );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* select proper VBR method */
|
|
Packit |
47f805 |
switch ( lameConfig.format.LHV1.nVbrMethod)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case VBR_METHOD_NONE:
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_off );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case VBR_METHOD_DEFAULT:
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_default );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case VBR_METHOD_OLD:
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_rh );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case VBR_METHOD_MTRH:
|
|
Packit |
47f805 |
case VBR_METHOD_NEW:
|
|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
* the --vbr-mtrh commandline switch is obsolete.
|
|
Packit |
47f805 |
* now --vbr-mtrh is known as --vbr-new
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_mtrh );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
case VBR_METHOD_ABR:
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_abr );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
/* unsupported VBR method */
|
|
Packit |
47f805 |
assert( FALSE );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/* use CBR encoding method, so turn off VBR */
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_off );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* Set bitrate. (CDex users always specify bitrate=Min bitrate when using VBR) */
|
|
Packit |
47f805 |
lame_set_brate( gfp, lameConfig.format.LHV1.dwBitrate );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* check if we have to use ABR, in order to backwards compatible, this
|
|
Packit |
47f805 |
* condition should still be checked indepedent of the nVbrMethod method
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
if (lameConfig.format.LHV1.dwVbrAbr_bps > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
/* set VBR method to ABR */
|
|
Packit |
47f805 |
lame_set_VBR( gfp, vbr_abr );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* calculate to kbps, round to nearest kbps */
|
|
Packit |
47f805 |
lame_set_VBR_mean_bitrate_kbps( gfp, ( lameConfig.format.LHV1.dwVbrAbr_bps + 500 ) / 1000 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* limit range */
|
|
Packit |
47f805 |
if( lame_get_VBR_mean_bitrate_kbps( gfp ) > 320)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_VBR_mean_bitrate_kbps( gfp, 320 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if( lame_get_VBR_mean_bitrate_kbps( gfp ) < 8 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_VBR_mean_bitrate_kbps( gfp, 8 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// First set all the preset options
|
|
Packit |
47f805 |
if ( LQP_NOPRESET != lameConfig.format.LHV1.nPreset )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
PresetOptions( gfp, lameConfig.format.LHV1.nPreset );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set frequency resampling rate, if specified
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.dwReSampleRate > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_out_samplerate( gfp, lameConfig.format.LHV1.dwReSampleRate );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch ( lameConfig.format.LHV1.nMode )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case BE_MP3_MODE_MONO:
|
|
Packit |
47f805 |
lame_set_mode( gfp, MONO );
|
|
Packit |
47f805 |
lame_set_num_channels( gfp, 1 );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Use strict ISO encoding?
|
|
Packit |
47f805 |
lame_set_strict_ISO( gfp, ( lameConfig.format.LHV1.bStrictIso ) ? 1 : 0 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set copyright flag?
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bCopyright )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_copyright( gfp, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Do we have to tag it as non original
|
|
Packit |
47f805 |
if ( !lameConfig.format.LHV1.bOriginal )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_original( gfp, 0 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_original( gfp, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Add CRC?
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bCRC )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_error_protection( gfp, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_error_protection( gfp, 0 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set private bit?
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bPrivate )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_extension( gfp, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_extension( gfp, 0 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set VBR min bitrate, if specified
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.dwBitrate > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_VBR_min_bitrate_kbps( gfp, lameConfig.format.LHV1.dwBitrate );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set Maxbitrate, if specified
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.dwMaxBitrate > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_VBR_max_bitrate_kbps( gfp, lameConfig.format.LHV1.dwMaxBitrate );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
// Set bit resovoir option
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bNoRes )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_disable_reservoir( gfp,1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// check if the VBR tag is required
|
|
Packit |
47f805 |
if ( lameConfig.format.LHV1.bWriteVBRHeader )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_bWriteVbrTag( gfp, 1 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_bWriteVbrTag( gfp, 0 );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Override Quality setting, use HIGHBYTE = NOT LOWBYTE to be backwards compatible
|
|
Packit |
47f805 |
if ( ( lameConfig.format.LHV1.nQuality & 0xFF ) ==
|
|
Packit |
47f805 |
((~( lameConfig.format.LHV1.nQuality >> 8 )) & 0xFF) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_set_quality( gfp, lameConfig.format.LHV1.nQuality & 0xFF );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( 0 != ( nInitReturn = lame_init_params( gfp ) ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return nInitReturn;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//LAME encoding call will accept any number of samples.
|
|
Packit |
47f805 |
if ( 0 == lame_get_version( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// For MPEG-II, only 576 samples per frame per channel
|
|
Packit |
47f805 |
*dwSamples= 576 * lame_get_num_channels( gfp );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// For MPEG-I, 1152 samples per frame per channel
|
|
Packit |
47f805 |
*dwSamples= 1152 * lame_get_num_channels( gfp );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set the input sample buffer size, so we know what we can expect
|
|
Packit |
47f805 |
dwSampleBufferSize = *dwSamples;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set MP3 buffer size, conservative estimate
|
|
Packit |
47f805 |
*dwBufferSize=(DWORD)( 1.25 * ( *dwSamples / lame_get_num_channels( gfp ) ) + 7200 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// For debugging purposes
|
|
Packit |
47f805 |
dump_config( gfp );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Everything went OK, thus return SUCCESSFUL
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beFlushNoGap(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int nOutputSamples = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Init the global flags structure
|
|
Packit |
47f805 |
nOutputSamples = lame_encode_flush_nogap( gfp, pOutput, LAME_MAXMP3BUFFER );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( nOutputSamples < 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = 0;
|
|
Packit |
47f805 |
return BE_ERR_BUFFER_TOO_SMALL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = nOutputSamples;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int nOutputSamples = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
nOutputSamples = lame_encode_flush( gfp, pOutput, 0 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( nOutputSamples < 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = 0;
|
|
Packit |
47f805 |
return BE_ERR_BUFFER_TOO_SMALL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = nOutputSamples;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beCloseStream(HBE_STREAM hbeStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// lame will be close in VbrWriteTag function
|
|
Packit |
47f805 |
if ( !lame_get_bWriteVbrTag( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// clean up of allocated memory
|
|
Packit |
47f805 |
lame_close( gfp );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
gfp_save = NULL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
gfp_save = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// DeInit encoder
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) VOID beVersion(PBE_VERSION pbeVersion)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// DLL Release date
|
|
Packit |
47f805 |
char lpszDate[20] = { '\0', };
|
|
Packit |
47f805 |
char lpszTemp[5] = { '\0', };
|
|
Packit |
47f805 |
lame_version_t lv = { 0, };
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set DLL interface version
|
|
Packit |
47f805 |
pbeVersion->byDLLMajorVersion=MAJORVERSION;
|
|
Packit |
47f805 |
pbeVersion->byDLLMinorVersion=MINORVERSION;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
get_lame_version_numerical ( &lv );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set Engine version number (Same as Lame version)
|
|
Packit |
47f805 |
pbeVersion->byMajorVersion = (BYTE)lv.major;
|
|
Packit |
47f805 |
pbeVersion->byMinorVersion = (BYTE)lv.minor;
|
|
Packit |
47f805 |
pbeVersion->byAlphaLevel = (BYTE)lv.alpha;
|
|
Packit |
47f805 |
pbeVersion->byBetaLevel = (BYTE)lv.beta;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef MMX_choose_table
|
|
Packit |
47f805 |
pbeVersion->byMMXEnabled=1;
|
|
Packit |
47f805 |
#else
|
|
Packit |
47f805 |
pbeVersion->byMMXEnabled=0;
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
memset( pbeVersion->btReserved, 0, sizeof( pbeVersion->btReserved ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get compilation date
|
|
Packit |
47f805 |
strcpy(lpszDate,__DATE__);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get the first three character, which is the month
|
|
Packit |
47f805 |
strncpy(lpszTemp,lpszDate,3);
|
|
Packit |
47f805 |
lpszTemp[3] = '\0';
|
|
Packit |
47f805 |
pbeVersion->byMonth=1;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set month
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Jan")==0) pbeVersion->byMonth = 1;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Feb")==0) pbeVersion->byMonth = 2;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Mar")==0) pbeVersion->byMonth = 3;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Apr")==0) pbeVersion->byMonth = 4;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"May")==0) pbeVersion->byMonth = 5;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Jun")==0) pbeVersion->byMonth = 6;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Jul")==0) pbeVersion->byMonth = 7;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Aug")==0) pbeVersion->byMonth = 8;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Sep")==0) pbeVersion->byMonth = 9;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Oct")==0) pbeVersion->byMonth = 10;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Nov")==0) pbeVersion->byMonth = 11;
|
|
Packit |
47f805 |
if (strcmp(lpszTemp,"Dec")==0) pbeVersion->byMonth = 12;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get day of month string (char [4..5])
|
|
Packit |
47f805 |
pbeVersion->byDay = (BYTE) atoi( lpszDate + 4 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Get year of compilation date (char [7..10])
|
|
Packit |
47f805 |
pbeVersion->wYear = (WORD) atoi( lpszDate + 7 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
memset( pbeVersion->zHomepage, 0x00, BE_MAX_HOMEPAGE );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
strcpy( pbeVersion->zHomepage, "http://www.mp3dev.org/" );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples,
|
|
Packit |
47f805 |
PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Encode it
|
|
Packit |
47f805 |
int dwSamples;
|
|
Packit |
47f805 |
int nOutputSamples = 0;
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwSamples = nSamples / lame_get_num_channels( gfp );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// old versions of lame_enc.dll required exactly 1152 samples
|
|
Packit |
47f805 |
// and worked even if nSamples accidently set to 2304
|
|
Packit |
47f805 |
// simulate this behavoir:
|
|
Packit |
47f805 |
if ( 1 == lame_get_num_channels( gfp ) && nSamples == 2304)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
dwSamples/= 2;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( 1 == lame_get_num_channels( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
nOutputSamples = lame_encode_buffer(gfp,pSamples,pSamples,dwSamples,pOutput,0);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
nOutputSamples = lame_encode_buffer_interleaved(gfp,pSamples,dwSamples,pOutput,0);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( nOutputSamples < 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput=0;
|
|
Packit |
47f805 |
return BE_ERR_BUFFER_TOO_SMALL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = (DWORD)nOutputSamples;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// accept floating point audio samples, scaled to the range of a signed 16-bit
|
|
Packit |
47f805 |
// integer (within +/- 32768), in non-interleaved channels -- DSPguru, jd
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beEncodeChunkFloatS16NI(HBE_STREAM hbeStream, DWORD nSamples,
|
|
Packit |
47f805 |
PFLOAT buffer_l, PFLOAT buffer_r, PBYTE pOutput, PDWORD pdwOutput)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int nOutputSamples;
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
nOutputSamples = lame_encode_buffer_float(gfp,buffer_l,buffer_r,nSamples,pOutput,0);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( nOutputSamples >= 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput = (DWORD) nOutputSamples;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*pdwOutput=0;
|
|
Packit |
47f805 |
return BE_ERR_BUFFER_TOO_SMALL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static int
|
|
Packit |
47f805 |
maybeSyncWord(FILE* fpStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
unsigned char mp3_frame_header[4];
|
|
Packit |
47f805 |
size_t nbytes = fread(mp3_frame_header, 1, sizeof(mp3_frame_header), fpStream);
|
|
Packit |
47f805 |
if ( nbytes != sizeof(mp3_frame_header) ) {
|
|
Packit |
47f805 |
return -1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( mp3_frame_header[0] != 0xffu ) {
|
|
Packit |
47f805 |
return -1; /* doesn't look like a sync word */
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( (mp3_frame_header[1] & 0xE0u) != 0xE0u ) {
|
|
Packit |
47f805 |
return -1; /* doesn't look like a sync word */
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static int
|
|
Packit |
47f805 |
skipId3v2(FILE * fpStream, size_t lametag_frame_size)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
size_t nbytes;
|
|
Packit |
47f805 |
size_t id3v2TagSize = 0;
|
|
Packit |
47f805 |
unsigned char id3v2Header[10];
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* seek to the beginning of the stream */
|
|
Packit |
47f805 |
if (fseek(fpStream, 0, SEEK_SET) != 0) {
|
|
Packit |
47f805 |
return -2; /* not seekable, abort */
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
/* read 10 bytes in case there's an ID3 version 2 header here */
|
|
Packit |
47f805 |
nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);
|
|
Packit |
47f805 |
if (nbytes != sizeof(id3v2Header)) {
|
|
Packit |
47f805 |
return -3; /* not readable, maybe opened Write-Only */
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
/* does the stream begin with the ID3 version 2 file identifier? */
|
|
Packit |
47f805 |
if (!strncmp((char *) id3v2Header, "ID3", 3)) {
|
|
Packit |
47f805 |
/* the tag size (minus the 10-byte header) is encoded into four
|
|
Packit |
47f805 |
* bytes where the most significant bit is clear in each byte
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)
|
|
Packit |
47f805 |
| ((id3v2Header[7] & 0x7f) << 14)
|
|
Packit |
47f805 |
| ((id3v2Header[8] & 0x7f) << 7)
|
|
Packit |
47f805 |
| (id3v2Header[9] & 0x7f))
|
|
Packit |
47f805 |
+ sizeof id3v2Header;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
/* Seek to the beginning of the audio stream */
|
|
Packit |
47f805 |
if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) {
|
|
Packit |
47f805 |
return -2;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( maybeSyncWord(fpStream) != 0) {
|
|
Packit |
47f805 |
return -1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( fseek(fpStream, id3v2TagSize+lametag_frame_size, SEEK_SET) != 0 ) {
|
|
Packit |
47f805 |
return -2;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
if ( maybeSyncWord(fpStream) != 0) {
|
|
Packit |
47f805 |
return -1;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
/* OK, it seems we found our LAME-Tag/Xing frame again */
|
|
Packit |
47f805 |
/* Seek to the beginning of the audio stream */
|
|
Packit |
47f805 |
if ( fseek(fpStream, id3v2TagSize, SEEK_SET) != 0 ) {
|
|
Packit |
47f805 |
return -2;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static BE_ERR
|
|
Packit |
47f805 |
updateLameTagFrame(lame_global_flags* gfp, FILE* fpStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
size_t n = lame_get_lametag_frame( gfp, 0, 0 ); /* ask for bufer size */
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( n > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
unsigned char* buffer = 0;
|
|
Packit |
47f805 |
size_t m = 1;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( 0 != skipId3v2(fpStream, n) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DispErr( "Error updating LAME-tag frame:\n\n"
|
|
Packit |
47f805 |
"can't locate old frame\n" );
|
|
Packit |
47f805 |
return BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
buffer = (unsigned char*)malloc( n );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( buffer == 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DispErr( "Error updating LAME-tag frame:\n\n"
|
|
Packit |
47f805 |
"can't allocate frame buffer\n" );
|
|
Packit |
47f805 |
return BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* Put it all to disk again */
|
|
Packit |
47f805 |
n = lame_get_lametag_frame( gfp, buffer, n );
|
|
Packit |
47f805 |
if ( n > 0 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m = fwrite( buffer, n, 1, fpStream );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
free( buffer );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( m != 1 )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DispErr( "Error updating LAME-tag frame:\n\n"
|
|
Packit |
47f805 |
"couldn't write frame into file\n" );
|
|
Packit |
47f805 |
return BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beWriteInfoTag( HBE_STREAM hbeStream,
|
|
Packit |
47f805 |
LPCSTR lpszFileName )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
FILE* fpStream = NULL;
|
|
Packit |
47f805 |
BE_ERR beResult = BE_ERR_SUCCESSFUL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
lame_global_flags* gfp = (lame_global_flags*)hbeStream;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ( NULL != gfp )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Do we have to write the VBR tag?
|
|
Packit |
47f805 |
if ( lame_get_bWriteVbrTag( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Try to open the file
|
|
Packit |
47f805 |
fpStream=fopen( lpszFileName, "rb+" );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Check file open result
|
|
Packit |
47f805 |
if ( NULL == fpStream )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
beResult = BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
DispErr( "Error updating LAME-tag frame:\n\n"
|
|
Packit |
47f805 |
"can't open file for reading and writing\n" );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
beResult = updateLameTagFrame( gfp, fpStream );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Close the file stream
|
|
Packit |
47f805 |
fclose( fpStream );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// clean up of allocated memory
|
|
Packit |
47f805 |
lame_close( gfp );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
beResult = BE_ERR_INVALID_FORMAT_PARAMETERS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// return result
|
|
Packit |
47f805 |
return beResult;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// for backwards compatiblity
|
|
Packit |
47f805 |
__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return beWriteInfoTag( (HBE_STREAM)gfp_save, lpszFileName );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
BOOL APIENTRY DllMain(HANDLE hModule,
|
|
Packit |
47f805 |
DWORD ul_reason_for_call,
|
|
Packit |
47f805 |
LPVOID lpReserved)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
(void) lpReserved;
|
|
Packit |
47f805 |
gs_hModule = (HMODULE) hModule;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch( ul_reason_for_call )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case DLL_PROCESS_ATTACH:
|
|
Packit |
47f805 |
// Enable debug/logging?
|
|
Packit |
47f805 |
gs_bLogFile = GetPrivateProfileIntA("Debug","WriteLogFile",gs_bLogFile,"lame_enc.ini");
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case DLL_THREAD_ATTACH:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case DLL_THREAD_DETACH:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
case DLL_PROCESS_DETACH:
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return TRUE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static void dump_config( lame_global_flags* gfp )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DebugPrintf("\n\nLame_enc configuration options:\n");
|
|
Packit |
47f805 |
DebugPrintf("==========================================================\n");
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("version =%d\n",lame_get_version( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Layer =3\n");
|
|
Packit |
47f805 |
DebugPrintf("mode =");
|
|
Packit |
47f805 |
switch ( lame_get_mode( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case STEREO: DebugPrintf( "Stereo\n" ); break;
|
|
Packit |
47f805 |
case JOINT_STEREO: DebugPrintf( "Joint-Stereo\n" ); break;
|
|
Packit |
47f805 |
case DUAL_CHANNEL: DebugPrintf( "Forced Stereo\n" ); break;
|
|
Packit |
47f805 |
case MONO: DebugPrintf( "Mono\n" ); break;
|
|
Packit |
47f805 |
case NOT_SET: /* FALLTROUGH */
|
|
Packit |
47f805 |
default: DebugPrintf( "Error (unknown)\n" ); break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("Input sample rate =%.1f kHz\n", lame_get_in_samplerate( gfp ) /1000.0 );
|
|
Packit |
47f805 |
DebugPrintf("Output sample rate =%.1f kHz\n", lame_get_out_samplerate( gfp ) /1000.0 );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("bitrate =%d kbps\n", lame_get_brate( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Quality Setting =%d\n", lame_get_quality( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("Low pass frequency =%d\n", lame_get_lowpassfreq( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Low pass width =%d\n", lame_get_lowpasswidth( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("High pass frequency =%d\n", lame_get_highpassfreq( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("High pass width =%d\n", lame_get_highpasswidth( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("No short blocks =%d\n", lame_get_no_short_blocks( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Force short blocks =%d\n", lame_get_force_short_blocks( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("de-emphasis =%d\n", lame_get_emphasis( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("private flag =%d\n", lame_get_extension( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("copyright flag =%d\n", lame_get_copyright( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("original flag =%d\n", lame_get_original( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("CRC =%s\n", lame_get_error_protection( gfp ) ? "on" : "off" );
|
|
Packit |
47f805 |
DebugPrintf("Fast mode =%s\n", ( lame_get_quality( gfp ) )? "enabled" : "disabled" );
|
|
Packit |
47f805 |
DebugPrintf("Force mid/side stereo =%s\n", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" );
|
|
Packit |
47f805 |
DebugPrintf("Disable Reservoir =%d\n", lame_get_disable_reservoir( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Allow diff-short =%d\n", lame_get_allow_diff_short( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Interchannel masking =%f\n", lame_get_interChRatio( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Strict ISO Encoding =%s\n", ( lame_get_strict_ISO( gfp ) ) ?"Yes":"No");
|
|
Packit |
47f805 |
DebugPrintf("Scale =%5.2f\n", lame_get_scale( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("VBR =%s, VBR_q =%d, VBR method =",
|
|
Packit |
47f805 |
( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled",
|
|
Packit |
47f805 |
lame_get_VBR_q( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch ( lame_get_VBR( gfp ) )
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case vbr_off: DebugPrintf( "vbr_off\n" ); break;
|
|
Packit |
47f805 |
case vbr_mt : DebugPrintf( "vbr_mt \n" ); break;
|
|
Packit |
47f805 |
case vbr_rh : DebugPrintf( "vbr_rh \n" ); break;
|
|
Packit |
47f805 |
case vbr_mtrh: DebugPrintf( "vbr_mtrh \n" ); break;
|
|
Packit |
47f805 |
case vbr_abr:
|
|
Packit |
47f805 |
DebugPrintf( "vbr_abr (average bitrate %d kbps)\n", lame_get_VBR_mean_bitrate_kbps( gfp ) );
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
DebugPrintf("error, unknown VBR setting\n");
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("Vbr Min bitrate =%d kbps\n", lame_get_VBR_min_bitrate_kbps( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Vbr Max bitrate =%d kbps\n", lame_get_VBR_max_bitrate_kbps( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("Write VBR Header =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No");
|
|
Packit |
47f805 |
DebugPrintf("VBR Hard min =%d\n", lame_get_VBR_hard_min( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("ATH Only =%d\n", lame_get_ATHonly( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH short =%d\n", lame_get_ATHshort( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH no =%d\n", lame_get_noATH( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH type =%d\n", lame_get_ATHtype( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH lower =%f\n", lame_get_ATHlower( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH aa =%d\n", lame_get_athaa_type( gfp ) );
|
|
Packit |
47f805 |
//DebugPrintf("ATH aa loudapprox =%d\n", lame_get_athaa_loudapprox( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("ATH aa sensitivity =%f\n", lame_get_athaa_sensitivity( gfp ) );
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DebugPrintf("Experimental nspsytune =%d\n", lame_get_exp_nspsytune( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Experimental X =%d\n", lame_get_experimentalX( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Experimental Y =%d\n", lame_get_experimentalY( gfp ) );
|
|
Packit |
47f805 |
DebugPrintf("Experimental Z =%d\n", lame_get_experimentalZ( gfp ) );
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
static void DispErr(char const* strErr)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MessageBoxA(NULL,strErr,"LAME_ENC.DLL",MB_OK|MB_ICONHAND);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifdef __cplusplus
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
#endif
|