?? blademp3encdll.c
字號:
/* * Blade DLL Interface for LAME. * * Copyright (c) 1999 A.L. Faber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include "BladeMP3EncDLL.h"#include <assert.h>#include "version.h" #include "VbrTag.h" #include "lame.h"/*#include "get_audio.h"#include "globalflags.h"#include "machine.h"#include "util.h"*/#ifdef _DEBUG #define _DEBUGDLL 1#endifconst int MAJORVERSION=1;const int MINORVERSION=11;const int CURRENT_STRUCT_VERSION=1;const int CURRENT_STRUCT_SIZE=sizeof(BE_CONFIG);// Local variablesstatic int nPsychoModel=2;static BOOL bFirstFrame=TRUE;static DWORD dwSampleBufferSize=0;#ifdef _DEBUGDLLvoid dump_config( char *inPath, char *outPath);#endiflame_global_flags gf;static void InitParams(){ bFirstFrame=TRUE; lame_init(&gf);}__declspec(dllexport) BE_ERR beInitStream(PBE_CONFIG pbeConfig, PDWORD dwSamples, PDWORD dwBufferSize, PHBE_STREAM phbeStream){ int nDllArgC=0; BE_CONFIG lameConfig; InitParams(); // clear out structure memset(&lameConfig,0x00,CURRENT_STRUCT_SIZE); // Check if this is a regular BLADE_ENCODER header if (pbeConfig->dwConfig!=BE_CONFIG_LAME) { int nCRC=pbeConfig->format.mp3.bCRC; int nVBR=(nCRC>>12)&0x0F; // Copy parameter from old Blade structure lameConfig.format.LHV1.dwSampleRate =pbeConfig->format.mp3.dwSampleRate; //for low bitrates, LAME will automatically downsample for better //sound quality. Forcing output samplerate = input samplerate is not a good idea //unless the user specifically requests it: //lameConfig.format.LHV1.dwReSampleRate=pbeConfig->format.mp3.dwSampleRate; lameConfig.format.LHV1.nMode =(pbeConfig->format.mp3.byMode&0x0F); lameConfig.format.LHV1.dwBitrate =pbeConfig->format.mp3.wBitrate; lameConfig.format.LHV1.bPrivate =pbeConfig->format.mp3.bPrivate; lameConfig.format.LHV1.bOriginal =pbeConfig->format.mp3.bOriginal; lameConfig.format.LHV1.bCRC =nCRC&0x01; lameConfig.format.LHV1.bCopyright =pbeConfig->format.mp3.bCopyright; // Fill out the unknowns lameConfig.format.LHV1.dwStructSize=CURRENT_STRUCT_VERSION; lameConfig.format.LHV1.dwStructVersion=CURRENT_STRUCT_SIZE; // Get VBR setting from fourth nibble if (nVBR>0) { lameConfig.format.LHV1.bWriteVBRHeader=TRUE; lameConfig.format.LHV1.bEnableVBR=TRUE; lameConfig.format.LHV1.nVBRQuality=nVBR-1; } // Get Quality from third nibble lameConfig.format.LHV1.nQuality=(MPEG_QUALITY)((nCRC>>8)&0x0F); } else { // Copy the parameters memcpy(&lameConfig,pbeConfig,pbeConfig->format.LHV1.dwStructSize); } // Not used, always assign stream 1 *phbeStream=1; // --------------- Set arguments to LAME encoder ------------------------- // Set zero argument, the filename //strcpy(DllArgV[nDllArgC++],"LameDLLEncoder"); switch (lameConfig.format.LHV1.nMode) { case BE_MP3_MODE_STEREO: gf.mode=0; gf.mode_fixed=1; /* dont allow LAME to change the mode */ gf.num_channels=2; break; case BE_MP3_MODE_JSTEREO: gf.mode=1; gf.mode_fixed=1; gf.num_channels=2; break; case BE_MP3_MODE_MONO: gf.mode=3; gf.mode_fixed=1; gf.num_channels=1; break; case BE_MP3_MODE_DUALCHANNEL: gf.force_ms=1; gf.mode=1; gf.mode_fixed=1; gf.num_channels=2; break; default: { char lpszError[255]; sprintf(lpszError,"Invalid lameConfig.format.LHV1.nMode, value is %d\n",lameConfig.format.LHV1.nMode); OutputDebugString(lpszError); return BE_ERR_INVALID_FORMAT_PARAMETERS; } } switch (lameConfig.format.LHV1.nQuality) { case NORMAL_QUALITY: // Nothing special break; case LOW_QUALITY: // -f flag gf.quality=9; break; case HIGH_QUALITY: // -h flag for high qualtiy gf.quality=2; break; case VOICE_QUALITY: // --voice flag for experimental voice mode gf.lowpassfreq=12000; gf.VBR_max_bitrate_kbps=160; gf.no_short_blocks=1; break; } if (lameConfig.format.LHV1.bEnableVBR) { // 0=no vbr 1..10 is VBR quality setting -1 gf.VBR=1; gf.VBR_q=lameConfig.format.LHV1.nVBRQuality; if (lameConfig.format.LHV1.bWriteVBRHeader==TRUE) { gf.bWriteVbrTag=TRUE; } else { gf.bWriteVbrTag=FALSE; } } // Set frequency gf.in_samplerate=lameConfig.format.LHV1.dwSampleRate; // Set frequency resampling rate, if specified if (lameConfig.format.LHV1.dwReSampleRate>0) gf.out_samplerate=lameConfig.format.LHV1.dwReSampleRate; // Set bitrate. (CDex users always specify bitrate=Min bitrate when using VBR) gf.brate=lameConfig.format.LHV1.dwBitrate; gf.VBR_min_bitrate_kbps=gf.brate; // Set Maxbitrate, if specified if (lameConfig.format.LHV1.dwMaxBitrate>0) gf.VBR_max_bitrate_kbps=lameConfig.format.LHV1.dwMaxBitrate; // Set copyright flag? if (lameConfig.format.LHV1.bCopyright) gf.copyright=1; // Do we have to tag it as non original if (!lameConfig.format.LHV1.bOriginal) { gf.original=0; } else { gf.original=1; } // Add CRC? if (lameConfig.format.LHV1.bCRC) { gf.error_protection=1; } else { gf.error_protection=0; } gf.silent=1; /* disable status ouput */ // Set private bit? if (lameConfig.format.LHV1.bPrivate) { gf.extension = 1; } else { gf.extension = 0; } lame_init_params(&gf); //LAME encoding call will accept any number of samples. *dwSamples=1152*gf.num_channels; // Set the input sample buffer size, so we know what we can expect dwSampleBufferSize=*dwSamples; // Set MP3 buffer size // conservative estimate *dwBufferSize=1.25*(*dwSamples/gf.num_channels) + 7200;#ifdef _DEBUGDLL dump_config(gf.inPath,gf.outPath);#endif // Everything went OK, thus return SUCCESSFUL return BE_ERR_SUCCESSFUL;}__declspec(dllexport) BE_ERR beDeinitStream(HBE_STREAM hbeStream, PBYTE pOutput, PDWORD pdwOutput){ *pdwOutput = lame_encode_finish(&gf,pOutput,0); if (*pdwOutput<0) { *pdwOutput=0; return BE_ERR_BUFFER_TOO_SMALL; } return BE_ERR_SUCCESSFUL;}__declspec(dllexport) BE_ERR beCloseStream(HBE_STREAM hbeStream){ // DeInit encoder// return DeInitEncoder(); return BE_ERR_SUCCESSFUL;}__declspec(dllexport) VOID beVersion(PBE_VERSION pbeVersion){ // DLL Release date char lpszDate[20]; char lpszTemp[5]; // Set DLL interface version pbeVersion->byDLLMajorVersion=MAJORVERSION; pbeVersion->byDLLMinorVersion=MINORVERSION; // Set Engine version number (Same as Lame version) pbeVersion->byMajorVersion=LAME_MAJOR_VERSION; pbeVersion->byMinorVersion=LAME_MINOR_VERSION; // Get compilation date strcpy(lpszDate,__DATE__); // Get the first three character, which is the month strncpy(lpszTemp,lpszDate,3); lpszTemp[3]='\0'; pbeVersion->byMonth=1; // Set month if (strcmp(lpszTemp,"Jan")==0) pbeVersion->byMonth=1; if (strcmp(lpszTemp,"Feb")==0) pbeVersion->byMonth=2; if (strcmp(lpszTemp,"Mar")==0) pbeVersion->byMonth=3; if (strcmp(lpszTemp,"Apr")==0) pbeVersion->byMonth=4; if (strcmp(lpszTemp,"May")==0) pbeVersion->byMonth=5; if (strcmp(lpszTemp,"Jun")==0) pbeVersion->byMonth=6; if (strcmp(lpszTemp,"Jul")==0) pbeVersion->byMonth=7; if (strcmp(lpszTemp,"Aug")==0) pbeVersion->byMonth=8; if (strcmp(lpszTemp,"Sep")==0) pbeVersion->byMonth=9; if (strcmp(lpszTemp,"Oct")==0) pbeVersion->byMonth=10; if (strcmp(lpszTemp,"Nov")==0) pbeVersion->byMonth=11; if (strcmp(lpszTemp,"Dec")==0) pbeVersion->byMonth=12; // Get day of month string (char [4..5]) pbeVersion->byDay=atoi(lpszDate+4); // Get year of compilation date (char [7..10]) pbeVersion->wYear=atoi(lpszDate+7); memset(pbeVersion->zHomepage,0x00,BE_MAX_HOMEPAGE); strcpy(pbeVersion->zHomepage,"http://www.sulaco.org/mp3/");}__declspec(dllexport) BE_ERR beEncodeChunk(HBE_STREAM hbeStream, DWORD nSamples, PSHORT pSamples, PBYTE pOutput, PDWORD pdwOutput){ // Encode it int dwSamples; dwSamples=nSamples/gf.num_channels; // old versions of lame_enc.dll required exactly 1152 samples // and worked even if nSamples accidently set to 2304 // simulate this behavoir: if (gf.num_channels==1 && nSamples == 2304) dwSamples/=2; *pdwOutput=lame_encode_buffer_interleaved(&gf,pSamples,dwSamples,pOutput,0); if (*pdwOutput<0) { *pdwOutput=0; return BE_ERR_BUFFER_TOO_SMALL; } return BE_ERR_SUCCESSFUL;}__declspec(dllexport) BE_ERR beWriteVBRHeader(LPCSTR lpszFileName){ if (gf.bWriteVbrTag) { // Calculate relative quality of VBR stream // 0=best, 100=worst int nQuality=gf.VBR_q*100/9; // Write Xing header again return PutVbrTag(&gf,(LPSTR)lpszFileName,nQuality); } return BE_ERR_INVALID_FORMAT_PARAMETERS;}BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ switch( ul_reason_for_call ) { case DLL_PROCESS_ATTACH:#ifdef _DEBUGDLL OutputDebugString("Attach Process \n");#endif break; case DLL_THREAD_ATTACH:#ifdef _DEBUGDLL OutputDebugString("Attach Thread \n");#endif break; case DLL_THREAD_DETACH:#ifdef _DEBUGDLL OutputDebugString("Detach Thread \n");#endif break; case DLL_PROCESS_DETACH:#ifdef _DEBUGDLL OutputDebugString("Detach Process \n");#endif break; } return TRUE;}#ifdef _DEBUGDLLvoid dump_config( char *inPath, char *outPath){ char strTmp[255]; OutputDebugString("Encoding configuration:\n"); sprintf(strTmp,"Write VBR Header=%s\n",(gf.bWriteVbrTag)?"Yes":"No"); OutputDebugString(strTmp); sprintf(strTmp,"version=%d\n",gf.version); OutputDebugString(strTmp); sprintf(strTmp,"Layer=3 mode=%d \n",gf.mode); OutputDebugString(strTmp); sprintf(strTmp,"samp frq=%.1f kHz total bitrate=%d kbps\n",gf.in_samplerate/1000.0); OutputDebugString(strTmp); sprintf(strTmp,"de-emph=%d c/right=%d orig=%d errprot=%s\n",gf.emphasis, gf.copyright, gf.original,((gf.error_protection) ? "on" : "off")); OutputDebugString(strTmp);// sprintf(strTmp,"16 Khz cut off is %s\n",(0)?"enabled":"disabled");// OutputDebugString(strTmp); sprintf(strTmp,"Fast mode is %s\n",(gf.quality==9)?"enabled":"disabled"); OutputDebugString(strTmp); sprintf(strTmp,"Force ms %s\n",(gf.force_ms)?"enabled":"disabled"); OutputDebugString(strTmp);// sprintf(strTmp,"GPsycho acoustic model is %s\n",(gpsycho)?"enabled":"disabled");// OutputDebugString(strTmp); sprintf(strTmp,"VRB is %s, VBR_q value is %d\n",(gf.VBR)?"enabled":"disabled",gf.VBR_q); OutputDebugString(strTmp); sprintf(strTmp,"input file: '%s' output file: '%s'\n", inPath, outPath); OutputDebugString(strTmp);// sprintf(strTmp,"Voice mode %s\n",(voice_mode)?"enabled":"disabled");// OutputDebugString(strTmp); sprintf(strTmp,"Encoding as %.1f kHz %d kbps MPEG-%d LayerIII file\n",gf.out_samplerate/1000.0,gf.brate,gf.mode,3 - gf.version); OutputDebugString(strTmp);}void DispErr(LPSTR strErr){ MessageBox(NULL,strErr,"",MB_OK);}#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -