69,371
社区成员
发帖
与我相关
我的任务
分享
#include "stdafx.h"
//#include "mmsystem.h"
#include "WaveInRecorder.h"
#include "stdlib.h"
#include "RecorderError.h"
#include "Logs.h"
//#pragma comment(lib,"winmm.lib")
WaveInRecorder::WaveInRecorder()
{
LOG_DUG("WaveInRecorder");
m_bRecording = ivFalse;
m_hSaveFile = NULL;
m_hWaveIn = NULL;
ZeroMemory(&m_WaveFormatEx,sizeof(m_WaveFormatEx));//清零
ZeroMemory( m_pBuffer,RECORD_BUFFER_NUM * sizeof( m_pBuffer[0] ) );
ZeroMemory( m_pWaveHdr,RECORD_BUFFER_NUM * sizeof( m_pWaveHdr[0] ) );
}
WaveInRecorder::~WaveInRecorder()
{
CleanAllBuffer();
}
// 创建录音句柄
ivInt32 ivCall WaveInRecorder::create ()//初始化protected对象
{
ivInt32 ret;
ret = ERR_OK;
//默认录音格式:16k16bit
m_WaveFormatEx.wFormatTag = 1;
m_WaveFormatEx.nChannels = 1;
m_WaveFormatEx.wBitsPerSample = 16;
m_WaveFormatEx.nSamplesPerSec = 16000;
m_WaveFormatEx.nBlockAlign = m_WaveFormatEx.nChannels * m_WaveFormatEx.wBitsPerSample / 8;
m_WaveFormatEx.nAvgBytesPerSec = m_WaveFormatEx.nSamplesPerSec * m_WaveFormatEx.nBlockAlign;
m_WaveFormatEx.cbSize = 0;
ivInt32 n = waveInGetNumDevs();
if (n < 1)
{
ret = ERR_WAVEIN_ENUM_DEVICES;
goto END_create;
}
END_create:
// call back error
if (ERR_OK != ret)
{
CleanAllBuffer();
if(m_hWaveIn != NULL)
{
waveInReset(m_hWaveIn);
waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
}
SendErrMsg(ret);
}
else
{
m_Status = IDLE;
}
return ret;
}
// 启动录音
ivInt32 ivCall WaveInRecorder::start()
{
ivInt32 ret;
MMRESULT result_open;
MMRESULT result_start;
m_BufferSize=640;
ret = ERR_OK;
if (result_open = waveInOpen(&m_hWaveIn, WAVE_MAPPER, &m_WaveFormatEx, (DWORD)waveInProc, (DWORD_PTR)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR )
{
ret = ERR_WAVEIN_OPEN_DEVICE;
goto END_start;
}
for (ivInt32 i = 0; i < RECORD_BUFFER_NUM; i++)
{
m_pBuffer[i]=new BYTE[m_BufferSize];
if(m_pBuffer[i] == NULL)
{
goto END_start;
}
ZeroMemory( m_pBuffer[i], m_BufferSize );
//allocate memory for wave header
m_pWaveHdr[i]=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
if(m_pWaveHdr[i] == NULL )
{
ret = ERR_WAVEIN_CREATE_BUFFER;
goto END_start;
}
ZeroMemory(m_pWaveHdr[i],sizeof(WAVEHDR));
m_pWaveHdr[i]->lpData = (LPSTR)m_pBuffer[i];
m_pWaveHdr[i]->dwBufferLength = m_BufferSize;
m_pWaveHdr[i]->dwBytesRecorded = 0;
m_pWaveHdr[i]->dwUser = 0;
m_pWaveHdr[i]->dwFlags = 0;
m_pWaveHdr[i]->dwLoops = 1;
m_pWaveHdr[i]->lpNext = NULL;
m_pWaveHdr[i]->reserved = 0;
MMRESULT res = waveInPrepareHeader(m_hWaveIn,m_pWaveHdr[i],sizeof(WAVEHDR));
if (res != MMSYSERR_NOERROR)
{
ret = ERR_WAVEIN_PREPARE_BUFFER;
goto END_start;
}
// Add the buffers
res = waveInAddBuffer (m_hWaveIn, m_pWaveHdr[i], sizeof (WAVEHDR)) ;
if (res != MMSYSERR_NOERROR)
{
ret = ERR_WAVEIN_ADD_BUFFER;
goto END_start;
}
}
result_start = waveInStart(m_hWaveIn);
if (result_start != MMSYSERR_NOERROR)
{
ret = ERR_WAVEIN_START;
goto END_start;
}
END_start:
// call back error
if (ERR_OK != ret)
{
CleanAllBuffer();
if(m_hWaveIn != NULL)
{
waveInReset(m_hWaveIn);
waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
}
SendErrMsg(ret);
}
else
{
m_Status = RUNNING;
}
return ret;
}
// 停止录音
ivInt32 ivCall WaveInRecorder::stop()
{
ivInt32 ret;
MMRESULT result;
ret = ERR_OK;
m_bRecording = ivFalse;
waveInReset(m_hWaveIn);
//注意:WIM_DATA中不能调用waveInUnprepareHeader,否则会产生死锁
for (ivInt32 i = 0; i < RECORD_BUFFER_NUM; i++)
{
result = waveInUnprepareHeader (m_hWaveIn, m_pWaveHdr[i], sizeof (WAVEHDR)) ;
if (result != MMSYSERR_NOERROR)
{
ret = ERR_WAVEIN_UNPREPARE_BUFFER;
goto END_stop;
}
}
END_stop:
// call back error
if (ERR_OK != ret)
{
CleanAllBuffer();
SendErrMsg(ret);
}
else
{
m_Status = IDLE;
}
return ret;
}
// 释放录音句柄
ivInt32 ivCall WaveInRecorder::release()
{
ivInt32 ret;
ret = ERR_OK;
MMRESULT result;
result = waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
if (result != MMSYSERR_NOERROR)
{
ret = ERR_WAVEIN_CLOSE;
goto END_release;
}
END_release:
if (ERR_OK != ret)
{
CleanAllBuffer();
if(m_hWaveIn != NULL)
{
waveInReset(m_hWaveIn);
waveInClose(m_hWaveIn);
m_hWaveIn = NULL;
}
SendErrMsg(ret);
}
else
{
m_Status = IDLE;
}
return ret;
}
// 判断是否正在录音
ivBool ivCall WaveInRecorder::isRunning()
{
ivBool ret;
//状态初始化
ret = ivFalse;
if( m_Status == RUNNING)
{
ret=ivTrue;
}
return ret;
}
// 修改参数
ivInt32 ivCall WaveInRecorder::setParam(ivInt32 paramKey, ivStr paramValue)
{
ivInt32 ret;
ret = 0;
return ret;
}
// 获取参数
ivStr ivCall WaveInRecorder::getParam(ivInt32 paramKey)
{
ivStr ret;
ret = 0;
return ret;
}
static void CALLBACK waveInProc(HWAVEIN hWi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
if (NULL == dwInstance)
{
LOG_ERR("WaveInProc | null instance error.");
return;
}
WaveInRecorder*pWRec=(WaveInRecorder*)dwInstance;
if(uMsg==WIM_DATA)
{
pWRec->OnWIM_DATA(dwParam1,dwParam2);
}
if(uMsg==WIM_OPEN)
{
pWRec->OnWIM_OPEN(dwParam1,dwParam2);
}
}
void WaveInRecorder::OnWIM_CLOSE(WPARAM wParam, LPARAM lParam)
{
if(m_hSaveFile != NULL)
{
CloseHandle(m_hSaveFile);
m_hSaveFile = NULL;
}
}
void ivCall WaveInRecorder::OnWIM_DATA(WPARAM wParam, LPARAM lParam)
{
if (m_bRecording == ivFalse)
return;
DWORD dwBytesRecorded = ((PWAVEHDR)wParam)->dwBytesRecorded;
ivPByte audioData;
ivInt32 dataLen;
audioData=(LPBYTE)((PWAVEHDR)wParam)->lpData;
//DWORD dwBytesRecorded = ((PWAVEHDR)dwParam1)->dwBytesRecorded;
dataLen=((PWAVEHDR)wParam)->dwBytesRecorded;
SendReuslt(audioData,dataLen);
if(m_bRecording == ivTrue)
{
MMRESULT ret = waveInAddBuffer(m_hWaveIn, (PWAVEHDR) wParam, sizeof (WAVEHDR));
if (ret != MMSYSERR_NOERROR)
{}
}
}
void WaveInRecorder::OnWIM_OPEN(WPARAM wParam, LPARAM lParam)
{
m_bRecording = ivTrue;
}
// 设置录音数据回调
ivInt32 ivCall WaveInRecorder::setRecordResultCallback(RecordResultCallback callback)
{
ivInt32 ret;
ret = 0;
onRecordResult = callback;
return ret;
}
void WaveInRecorder::SendReuslt(ivPByte audioData, ivInt32 dataLen)
{
if (NULL != onRecordResult)
{
onRecordResult(audioData,dataLen);
}
}
// 设置录音出错回调
ivInt32 ivCall WaveInRecorder::setRecordErrorCallback(RecordErrorCallback callback)
{
ivInt32 ret;
ret = 0;
onRecordError = callback;
return ret;
}
// 发送出错消息
void WaveInRecorder::SendErrMsg(ivInt32 errorCode)
{
if (NULL != onRecordError)
{
onRecordError(errorCode);
}
}
ivInt32 ivCall WaveInRecorder::CleanAllBuffer()
{
ivInt32 ret;
ret = 0;
for (ivInt32 i = 0; i < RECORD_BUFFER_NUM; i++)
{
if (m_pBuffer[i] != NULL)
{
delete[] m_pBuffer[i];
m_pBuffer[i] = NULL;
}
if (m_pWaveHdr[i] != NULL)
{
free(m_pWaveHdr[i]);
m_pWaveHdr[i] = NULL;
}
}
return ret;
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RecorderTest
{
public partial class Form1 : Form
{
private const string TAG = "Form1";
public Form1()
{
InitializeComponent();
// UI同步
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
// mic.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
// mic.Image = Image.FromFile(Application.StartupPath + @"\res\imgs\mic.png");
initRecorder();
}
//初始化
private void initRecorder()
{
Logs.d(TAG, "initRecorder | enter.");
AudioRecorder.initRecorder(1);
// 录音数据回调
AudioRecorder.RecordResultCallback recorderListener = new AudioRecorder.RecordResultCallback(onAudioGet);
AudioRecorder.setRecordResultListener(recorderListener);
// 录音出错回调
AudioRecorder.RecordErrorCallback errorListener = new AudioRecorder.RecordErrorCallback(onRecordError);
AudioRecorder.setRecordErrorListener(errorListener);
}
//逆初始化
private void uninitRecorder()
{
Logs.d(TAG, "uninitRecorder | enter.");
AudioRecorder.uninitRecorder();
}
private void RecordInit_Click(object sender, EventArgs e)
{
}
//开始按钮
private void RecordStart_Click(object sender, EventArgs e)
{
Logs.d(TAG, "RecordStart_Click | enter.");
AudioRecorder.startRecord();
// Trace.TraceInformation("test");
Logs.d(TAG, "RecordStart_Click | leave.");
}
//结束按钮
private void RecordStop_Click(object sender, EventArgs e)
{
Logs.d(TAG, "RecordStop_Click | enter.");
AudioRecorder.stopRecord();
Logs.d(TAG, "RecordStop_Click | leave.");
}
/// <summary>
/// 写录音文件
/// </summary>
/// <param name="audioData"></param>
/// <param name="dataLen"></param>
/// <returns></returns>
public int onAudioGet(IntPtr audioData, int dataLen)
{
Logs.d(TAG, "onAudioGet | enter. data_len=" + dataLen);
int ret = 0;
// 实现
try
{
const string FILE_NAME = @"lib\record.pcm";
if (!File.Exists(FILE_NAME))
{
// 创建文件
// Trace.TraceInformation("test。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");
FileStream newfs = File.Create(FILE_NAME);
newfs.Close();
}
if (audioData != IntPtr.Zero && dataLen > 0)
{
byte[] dataBytes = new byte[dataLen];
Marshal.Copy(audioData, dataBytes, 0, dataLen);
if (dataBytes != null)
{
// 写文件
FileStream fs = new FileStream(FILE_NAME, FileMode.Append, FileAccess.Write);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(dataBytes, 0, dataLen);
bw.Flush();
bw.Close();
fs.Close();
}
}
}
catch(Exception e)
{
Logs.e(TAG, e.ToString());
}
Logs.d(TAG, "onAudioGet | leave");
return ret;
}
/// <summary>
/// 输出Log信息
/// </summary>
/// <param name="errorCode"></param>
/// <returns></returns>
public int onRecordError(int errorCode)
{
Logs.d(TAG, "onRecordError | enter.");
int ret = 0;
// 实现
try
{
MessageBox.Show("错误代码:" + errorCode, "ERROR");
}
catch (Exception e)
{
Logs.e(TAG, e.ToString());
}
Logs.d(TAG, "onRecordError | leave");
return ret;
}
}
}