wavein uMsg=WIM_DATA 之后获取录音数据,但是之后不能回调

anhuiyuhu 2013-07-18 11:24:25
现在可以获取录音数据,但是回调没反映,直接内存报错。
每次执行到 uMsg 之后,就直接跳出了。后面就没有执行了。怀疑是不是 WIM_DATA子函数有问题。或者就是回调SendResult 出错。求解答。麻烦各位了。十分感谢

#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;
}




...全文
176 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
whoopeeman 2016-03-28
  • 打赏
  • 举报
回复
LZ可在?能否有源码共享?
whoopeeman 2016-03-23
  • 打赏
  • 举报
回复
你好!请问你的源码可以发出来参考一下吗?
anhuiyuhu 2013-07-18
  • 打赏
  • 举报
回复
下面是 我的form1.cs 文件。其中有 获取录音函数onAudioGet
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;
        }

    }
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧