📄 (old)adoencogg.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////////
//
// 文件名称:AdoEncMp3.cpp
//
// 文件功能:Mp3音频编码库实现文件(采用开源代码实现)
//
// 作 者:黄建峰
//
// 创建日期:2004-7-5
//
// 最后修改:
//
// 版权所有:星辉时代
//
//////////////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include <time.h>
#include <io.h>
#include "lame.h"
//#include "get_audio.h"
#include "../include/AdoEncMp3.h"
#define PCMBUFLEN (1024*256) //Pcm数据输入缓冲长度
typedef struct
{
lame_global_flags Mp3EncInfo;//mp3编码器信息结构
//数据缓冲管理定义
LPMP3ENCCALLBACK lpCallBack;//数据压缩回调
LPBYTE lpPcmData;//Pcm数据缓冲
INT nPcmDataLen;//Pcm数据缓冲长度
//编码控制管理定义
CRITICAL_SECTION CriSection;//临界区管理
HANDLE hEncEvent; //事件管理对象
HANDLE hEncThread; //编码线程句柄
BOOL bExit;
}
MP3ENCINFO,*LPMP3ENCINFO;
//编码压缩线程
DWORD WINAPI ThreadEnc(LPVOID lpEncHandle);
//读取PCM音频数据
INT APIENTRY ReadPcmData(HANDLE hEncIns,LPBYTE lpData,INT nDataLen);
///////////////////////////////////////////////////////////////////////
//
// 函数名 : InitMp3Enc
// 功能描述 : 初始化Mp3编码器
// 参数 : INT nChanl; Mp3音频流压缩通数(1-2),需要和原始音频数据一致
// 参数 : INT nFreq; Mp3音频流压缩帧率(22050,44100,48000),需要和原始音频数据一致
// 参数 : INT nLeave; Mp3音频流压缩质量等级(1-10),
// 1的质量最高数据量也最大,10等级最低数据量最小
// 参数 : LPDATACALLBACK lpCallBack; 压缩数据回调函数指针
//
// 返回值 : 成功后返回Mp3编码器实例句柄,否则返回NULL
//
///////////////////////////////////////////////////////////////////////
HANDLE APIENTRY InitMp3Enc(INT nChanl,INT nFreq,INT nLeave,LPMP3ENCCALLBACK lpCallBack)
{
LPMP3ENCINFO lpMp3Enc = NULL;
DWORD dwThread = 0;
INT nRet = 0;
//分配压缩对象
lpMp3Enc=new MP3ENCINFO;
if(!lpMp3Enc) return NULL;
//得到音频信息
ZeroMemory(lpMp3Enc,sizeof(MP3ENCINFO));
// lpMp3Enc->fLeave = float(nLeave*0.1);
lpMp3Enc->lpPcmData = new BYTE[PCMBUFLEN];
lpMp3Enc->lpCallBack = lpCallBack;
//创建事件和临界管理对象
InitializeCriticalSection(&lpMp3Enc->CriSection);
lpMp3Enc->hEncEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
//初始化Mp3编码器
// lame_init(&lpMp3Enc->Mp3EncInfo,nFreq,nChanl,16,nLeave);
//创建编码线程
lpMp3Enc->hEncThread=CreateThread(NULL,NULL,ThreadEnc,lpMp3Enc,0,&dwThread);
return HANDLE(lpMp3Enc);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : StartMp3Enc
// 功能描述 : 开始编码
// 参数 : HANDLE hEncIns;Ogg编码器实例句柄
// 返回值 : APIENTRY
//
///////////////////////////////////////////////////////////////////////
BOOL APIENTRY StartMp3Enc(HANDLE hEncIns)
{
LPMP3ENCINFO lpMp3Enc = (LPMP3ENCINFO)hEncIns;
return SetEvent(lpMp3Enc->hEncEvent);
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : WritePcmData
// 功能描述 : 写入原始Pcm数据
// 参数 : HANDLE hEncIns;Ogg编码器实例句柄
// 参数 : LPBYTE lpPcmData;Pcm数据缓冲
// 参数 : UINT nPcmData;Pcm数据缓冲长度
// 返回值 : 返回写入的数据长度
//
///////////////////////////////////////////////////////////////////////
INT APIENTRY Mp3EncWritePcm(HANDLE hEncIns,LPBYTE lpPcmData,INT nPcmDataLen)
{
LPMP3ENCINFO lpMp3Enc = (LPMP3ENCINFO)hEncIns;
INT nLeftSpace = 0;//PCm缓冲剩余空间
INT nRealWrite = 0;//实际写入长度
READ_DATA:
EnterCriticalSection(&lpMp3Enc->CriSection);
//检查剩余空间
nLeftSpace=PCMBUFLEN-lpMp3Enc->nPcmDataLen;
if(!nLeftSpace)
{
LeaveCriticalSection(&lpMp3Enc->CriSection);
Sleep(150);
goto READ_DATA;
}
//拷贝
nRealWrite=min(nLeftSpace,nPcmDataLen);
CopyMemory(lpMp3Enc->lpPcmData+lpMp3Enc->nPcmDataLen,lpPcmData,nRealWrite);
lpMp3Enc->nPcmDataLen+=nRealWrite;
LeaveCriticalSection(&lpMp3Enc->CriSection);
return nRealWrite;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : StopEnc
// 功能描述 : 停止编码
// 参数 : HANDLE hEncIns;Ogg编码器实例句柄
// 返回值 : APIENTRY
//
///////////////////////////////////////////////////////////////////////
BOOL APIENTRY StopMp3Enc(HANDLE hEncIns)
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : FreeAdoEnc
// 功能描述 : 释放关闭Ogg编码器
// 参数 : HANDLE hEncIns
// 返回值 : VOID APIENTRY
//
///////////////////////////////////////////////////////////////////////
VOID APIENTRY FreeMp3Enc(HANDLE hEncIns)
{
LPMP3ENCINFO lpMp3Enc = (LPMP3ENCINFO)(hEncIns);
INT nleftMp3Frame = 0;
char szMp3buffer[LAME_MAXMP3BUFFER];
INT nRet = 0;
if(lpMp3Enc)
{
//关闭编码线程
TerminateThread(lpMp3Enc->hEncThread,0);
lpMp3Enc->bExit = TRUE;
Sleep(100);
//刷新Mp3内部缓冲
nleftMp3Frame=lame_encode_finish(&lpMp3Enc->Mp3EncInfo,szMp3buffer,(int)sizeof(szMp3buffer)); /* may return one more mp3 frame */
//清除缓冲
DeleteCriticalSection(&lpMp3Enc->CriSection);
CloseHandle(lpMp3Enc->hEncEvent);
delete []lpMp3Enc->lpPcmData;
delete lpMp3Enc;
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : AdoEncCmd
// 功能描述 : 扩充功能函数
// 参数 : INT nCmd ;扩充功能定义
// 参数 : WPARAM wParam ;附加参数1
// 参数 : LPARAM lParam ;附加参数2
// 返回值 : INT APIENTRY ;处理结果
//
///////////////////////////////////////////////////////////////////////
INT APIENTRY AdoMp3Cmd(INT nCmd,WPARAM wParam,LPARAM lParam)
{
return 1;
}
//内部函数
///////////////////////////////////////////////////////////////////////
//
// 函数名 : ThreadEnc
// 功能描述 : 编码压缩线程
// 参数 : LPVOID lpEncHandle
// 返回值 : ULONG APIENTRY
//
///////////////////////////////////////////////////////////////////////
DWORD WINAPI ThreadEnc(LPVOID lpEncHandle)
{
LPMP3ENCINFO lpMp3Enc = NULL;
INT nReadBytes = 0;//返回读取数据长度
short int Buffer[2][1152] = {0};
char Mp3buffer[LAME_MAXMP3BUFFER];
INT nRet = 0;
INT nEos = 0;
INT i = 0;
lpMp3Enc=(LPMP3ENCINFO)lpEncHandle;
if(!lpMp3Enc) return 1;
//等待编码开始
WaitForSingleObject(lpMp3Enc->hEncEvent,INFINITE);
//初始化编码器内部信息
lame_init_params(&lpMp3Enc->Mp3EncInfo);
//开始编码
while(!nEos)
{
// nReadBytes = lame_readframe(NULL,Buffer); //读取wav数据
nReadBytes = lame_readframe(lpMp3Enc,Buffer); //读取wav数据
if(!nReadBytes)
{
Sleep(30); //没有数据,则等待30毫秒
continue;
}
else {
nRet = lame_encode_buffer(&lpMp3Enc->Mp3EncInfo,Buffer[0],Buffer[1],nReadBytes,
Mp3buffer,(int)sizeof(Mp3buffer));
}
}
return 0;
}
///////////////////////////////////////////////////////////////////////
//
// 函数名 : APIENTRY ReadPcmData
// 功能描述 :
// 参数 : HANDLE hEncIns
// 参数 : LPBYTE lpData(OUt);Pcm数据缓冲
// 参数 : INT nDataLen(IN);Pcm数据缓冲长度
// 返回值 : INT
//
///////////////////////////////////////////////////////////////////////
INT APIENTRY ReadPcmData(HANDLE hEncIns,LPBYTE lpData,INT nDataLen)
{
LPMP3ENCINFO lpMp3Enc = (LPMP3ENCINFO)(hEncIns);
INT nReadlen = 0;
INT nMovePos = 0;//移动数据量
nReadlen=min(lpMp3Enc->nPcmDataLen,nDataLen);
if(nReadlen<1) return 0;
//读取Pcm数据
EnterCriticalSection(&lpMp3Enc->CriSection);
CopyMemory(lpData,lpMp3Enc->lpPcmData,nReadlen);
nMovePos=lpMp3Enc->nPcmDataLen-nReadlen;
LeaveCriticalSection(&lpMp3Enc->CriSection);
//检查Pcm缓冲区是否还有剩余数据,如有则需要移动缓冲数据
EnterCriticalSection(&lpMp3Enc->CriSection);
if(nMovePos)
{
CopyMemory(lpMp3Enc->lpPcmData,lpMp3Enc->lpPcmData+nReadlen,nMovePos);
}
//wsprintf(szBuff,"readLen=%d,PcmLen=%d,nMovePos=%d\r\n",nReadlen,lpMp3Enc->nPcmDataLen,nMovePos);
//_lwrite(hLog,szBuff,lstrlen(szBuff));
lpMp3Enc->nPcmDataLen=lpMp3Enc->nPcmDataLen-nReadlen;
LeaveCriticalSection(&lpMp3Enc->CriSection);
return nReadlen;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -