http://blog.csdn.net/zjh824/article/details/4017820
修改BSP里声卡驱动WaveMain.cpp里HandleWaveMessage里的消息响应:
case WIDM_OPEN:g_pHWContext->BspOpenRecChanel(TRUE);
case WIDM_CLOSE: g_pHWContext->BspOpenRecChanel(FALSE);
在应用层使用声音输入设备里打开录音通道,
void HardwareContext::BspOpenRecChanel(BOOL bOpen)
{
if(bOpen)
{
IOW_REG_OR(ULONG, &(v_pGpioRegs->gpio[4].paden), GPIO22); //设置GPIO
PIO_OUTPUT_ONE (GPIO, GPIO_GROUP(4), GPIO_INDEX(22));
PIO_OUTPUT_ENABLE (GPIO, GPIO_GROUP(4), GPIO_INDEX(22));
//EnterCriticalSection( &csMutex );
g_oalSysInfo.audioInfo[0].bRecordMic2 = FALSE;
g_oalSysInfo.audioInfo[0].bRecordMic1 = FALSE;
g_oalSysInfo.audioInfo[0].bRecordLineIn = TRUE;
// LeaveCriticalSection( &csMutex );
msWait(20);
}
else
{
IOW_REG_OR(ULONG, &(v_pGpioRegs->gpio[4].paden), GPIO22);
PIO_OUTPUT_ZERO (GPIO, GPIO_GROUP(4), GPIO_INDEX(22));
PIO_OUTPUT_ENABLE (GPIO, GPIO_GROUP(4), GPIO_INDEX(22));
g_oalSysInfo.audioInfo[0].bRecordMic2 = TRUE;
g_oalSysInfo.audioInfo[0].bRecordMic1 = TRUE;
g_oalSysInfo.audioInfo[0].bRecordLineIn = FALSE;
msWait(20);
}
}
//修改声卡寄存器并调节输入增益
void HardwareContext::AudioKickInputDMA()
{
USHORT usRegVal = 0;
AudioPowerInput(TRUE);
if(g_oalSysInfo.audioInfo[0].bRecordMic2)
{
}
else if(g_oalSysInfo.audioInfo[0].bRecordMic1)
{
}
else if(g_oalSysInfo.audioInfo[0].bRecordLineIn)
{
AudioInMute(FALSE);
}
}
BOOL HardwareContext::AudioInMute(BOOL mute)
{
if (mute)
{ // set mute on
WriteAC97Codec( RT_LINE_IN_VOL, (unsigned short) (ac97_regs[RT_LINE_IN_VOL/2] & 0xE808 )); //Disable LineIn to all output Mixer
m_RTCodec5610->Enable_ADC_Input_Source(R_LINE_IN | L_LINE_IN,FALSE); //Disable LineIn to ADC Mixer
}
else
{
// WriteAC97Codec( RT_LINE_IN_VOL, (unsigned short) (ac97_regs[RT_LINE_IN_VOL/2] & 0x6808 ));//Enable LineIn to HP Mixer
WriteAC97Codec( RT_LINE_IN_VOL, (unsigned short) (ac97_regs[RT_LINE_IN_VOL/2] & 0xA000 ));//Enable LineIn to HP Mixer zjhdebug
m_RTCodec5610->Enable_ADC_Input_Source(R_LINE_IN | L_LINE_IN,TRUE); //Enable LineIn to ADC Mixer
}
return TRUE;
}
应用层代码,使用CallBaCK_WINDOW方式。.h文件
- // RecorderDlg.h : header file
- //
- #if !defined(AFX_RECORDERDLG_H__9E12B8F2_2F24_46CE_84C8_6E787E0FA8AB__INCLUDED_)
- #define AFX_RECORDERDLG_H__9E12B8F2_2F24_46CE_84C8_6E787E0FA8AB__INCLUDED_
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
- /
- // CRecorderDlg dialog
- #define MAX_SIZE_INPUT_BUFFER 1024 // 数据块单元大小
- #define RECORDTIME 3000 // 录音时间
- #define MAX_NAMELENGTH 16
- #define MAX_NBEST 8
- #define WM_TIMEUP WM_USER+105 // 自定义消息
- extern "C" __declspec(dllimport) short SR_INITCE(char *RamAddress,long RamSize,char *RomAddress);
- extern "C" __declspec(dllimport) short SR_interfaceCE(char *RamAddress, char *RomAddress,
- short *SpeechBuffer, long SampleAmount,
- char **NameList, short NameAmount,
- short *BestLemma);
- class CRecorderDlg : public CDialog
- {
- // Construction
- public:
- CRecorderDlg(CWnd* pParent = NULL); // standard constructor
- BOOL CheckMic(); // 检查Mic状态
- void SetWaveFormat( WORD wCh = 1 , // 声道数量(单、双)
- DWORD dwSampleRate = 8000, // 采样率
- WORD wBitsPerSample = 16 ); // 采样位数(比特)
- void WriteDatatoFile(); // 把数据写入文件
- void Recognize();
- // Dialog Data
- //{{AFX_DATA(CRecorderDlg)
- enum { IDD = IDD_RECORDER_DIALOG };
- CListCtrl m_cNameList;
- CButton m_bWriteFile;
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CRecorderDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- HICON m_hIcon;
- SHORT m_nInputBuffer[MAX_SIZE_INPUT_BUFFER]; // 系统输入数据缓冲
- DWORD m_dwSavedLength; // 录音数据长度
- PBYTE m_pCurrentData, // 当前系统缓冲中的数据
- m_pSavedData; // 当前自定义缓冲数据
- HWAVEIN m_hWaveIn; // 录音句柄
- HWAVEOUT m_hWaveOut; // 放音句柄
- WAVEHDR m_WaveHeader; // 音频数据头
- WAVEFORMATEX m_WaveFormat; // 音频工作格式
- BOOL m_bEnding, m_bRecording, m_bPlaying; // 当前工作状态
- // Generated message map functions
- //{{AFX_MSG(CRecorderDlg)
- virtual BOOL OnInitDialog();
- afx_msg void OnRecord();
- afx_msg void OnStop();
- afx_msg void OnPlay();
- afx_msg void OnTimer(UINT nIDEvent);
- virtual void OnCancel();
- afx_msg void OnDestroy();
- afx_msg LRESULT OnMM_WIM_OPEN(WPARAM wParam,LPARAM lParam);
- afx_msg LRESULT OnMM_WIM_DATA(WPARAM wParam,LPARAM lParam);
- afx_msg LRESULT OnMM_WIM_CLOSE(WPARAM wParam,LPARAM lParam);
- afx_msg LRESULT OnMM_WOM_OPEN(WPARAM wParam,LPARAM lParam);
- afx_msg LRESULT OnMM_WOM_DONE(WPARAM wParam,LPARAM lParam);
- afx_msg LRESULT OnMM_WOM_CLOSE(WPARAM wParam,LPARAM lParam);
- afx_msg void OnLoad();
- //}}AFX_MSG
- afx_msg LRESULT OnTimeUp(UINT wParam,LONG lParam); // 到达时间限制(响应自定义消息WM_TIMEUP)
- DECLARE_MESSAGE_MAP()
- public:
- void Search();
- char* RomAddress;
- char* RamAddress;
- short Rtn_SR_Init ;
- char **NameList; //输入文件:一句语音、电话本
- short NameAmount;
- unsigned short NEW_NameList[MAX_NAMELENGTH];
- short iBest , RtnFlag , iName ;
- short *BestLemma; //在接口中没有具体定义,实际上就是RamAddress的最前面给出
- long RamSize, RomSize;
- };
- //{{AFX_INSERT_LOCATION}}
- // Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.
- #endif // !defined(AFX_RECORDERDLG_H__9E12B8F2_2F24_46CE_84C8_6E787E0FA8AB__INCLUDED_)
.cpp文件:
- #include "stdafx.h"
- #include "Recorder.h"
- #include "RecorderDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /
- // CRecorderDlg dialog
- CRecorderDlg::CRecorderDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CRecorderDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CRecorderDlg)
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- //设定成员初始变量
- m_pSavedData = NULL;
- m_bRecording = FALSE;
- m_bPlaying = FALSE;
- m_bEnding = FALSE;
- m_dwSavedLength = 0;
- Rtn_SR_Init = -1;
- }
- void CRecorderDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CRecorderDlg)
- DDX_Control(pDX, IDC_NAMELIST, m_cNameList);
- DDX_Control(pDX, IDC_WRITE, m_bWriteFile);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CRecorderDlg, CDialog)
- //{{AFX_MSG_MAP(CRecorderDlg)
- ON_BN_CLICKED(IDC_RECORD, OnRecord)
- ON_BN_CLICKED(IDC_STOP, OnStop)
- ON_BN_CLICKED(IDC_PLAY, OnPlay)
- ON_WM_TIMER()
- ON_WM_DESTROY()
- ON_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN)
- ON_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)
- ON_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)
- ON_MESSAGE(MM_WOM_OPEN,OnMM_WOM_OPEN)
- ON_MESSAGE(MM_WOM_DONE,OnMM_WOM_DONE)
- ON_MESSAGE(MM_WOM_CLOSE,OnMM_WOM_CLOSE)
- ON_BN_CLICKED(IDC_LOAD, OnLoad)
- //}}AFX_MSG_MAP
- ON_MESSAGE(WM_TIMEUP,OnTimeUp)
- END_MESSAGE_MAP()
- /
- // CRecorderDlg message handlers
- BOOL CRecorderDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- CenterWindow(GetDesktopWindow()); // center to the hpc screen
- m_bWriteFile.SetCheck(FALSE);
- m_cNameList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);// | LVS_EX_ONECLICKACTIVATE);
- m_cNameList.InsertColumn(0, _T("Index"), LVCFMT_LEFT, 80);
- m_cNameList.InsertColumn(1, _T("BestLemma"),LVCFMT_LEFT, 120);
- m_cNameList.InsertItem(0, _T("1"));
- m_cNameList.InsertItem(1, _T("2"));
- m_cNameList.InsertItem(2, _T("3"));
- m_cNameList.InsertItem(3, _T("4"));
- m_cNameList.InsertItem(4, _T("5"));
- m_cNameList.InsertItem(5, _T("6"));
- m_cNameList.InsertItem(6, _T("7"));
- m_cNameList.InsertItem(7, _T("8"));
- m_cNameList.InsertItem(8, _T("Confidence"));
- m_cNameList.InsertItem(9, _T("State"));
- m_cNameList.SetItemText(9,1, _T("Ready"));
- // TODO: Add extra initialization here
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CRecorderDlg::OnRecord()
- {
- // TODO: Add your control notification handler code here
- m_bEnding = FALSE;
- if (m_pSavedData)
- {
- free(m_pSavedData);
- m_pSavedData = NULL;
- }
- m_pSavedData = reinterpret_cast<PBYTE>(malloc(1));
- if ( !CheckMic() )
- return;
- SetWaveFormat();
- MMRESULT mmrResult = waveInOpen(&m_hWaveIn,WAVE_MAPPER,
- &m_WaveFormat,(DWORD)this->m_hWnd,
- NULL,CALLBACK_WINDOW);
- if (mmrResult != MMSYSERR_NOERROR)
- {
- MessageBeep(MB_ICONEXCLAMATION);
- AfxMessageBox(CString("不能打开声音设备!"));
- return;
- }
- m_WaveHeader.lpData = (CHAR *)m_nInputBuffer;
- m_WaveHeader.dwBufferLength = MAX_SIZE_INPUT_BUFFER;
- m_WaveHeader.dwBytesRecorded = 0;
- m_WaveHeader.dwUser = 0;
- m_WaveHeader.dwLoops = 1;
- m_WaveHeader.dwFlags = 0;
- m_WaveHeader.lpNext = NULL;
- m_WaveHeader.reserved = 0;
- mmrResult = waveInPrepareHeader(m_hWaveIn, &m_WaveHeader, sizeof(WAVEHDR));
- if( (mmrResult!= MMSYSERR_NOERROR) || ( m_WaveHeader.dwFlags != WHDR_PREPARED) )
- {
- AfxMessageBox(CString("waveInPrepareHeader操作失败!"));
- return;
- }
- mmrResult = waveInAddBuffer(m_hWaveIn, &m_WaveHeader, sizeof(WAVEHDR) );
- if(mmrResult != MMSYSERR_NOERROR)
- {
- AfxMessageBox((CString("waveInAddBuffer操作失败!")));
- return;
- }
- m_bRecording = TRUE ;
- m_bEnding = FALSE ;
- m_dwSavedLength = 0 ;
- mmrResult = waveInStart(m_hWaveIn );
- if (mmrResult != MMSYSERR_NOERROR)
- {
- AfxMessageBox(CString("Cannot Start Wave In !"));
- return;
- }
- }
- void CRecorderDlg::OnStop()
- {
- // TODO: Add your control notification handler code here
- OnTimeUp(NULL, NULL);
- }
- void CRecorderDlg::OnPlay()
- {
- // TODO: Add your control notification handler code here
- if (!m_pSavedData)
- {
- AfxMessageBox(CString("没有录音数据!"));
- return;
- }
- m_bEnding = FALSE;
- if ( m_bPlaying )
- waveOutReset(m_hWaveOut);
- SetWaveFormat();
- MMRESULT mmrResult = waveOutOpen(&m_hWaveOut,WAVE_MAPPER,
- &m_WaveFormat,(DWORD)this->m_hWnd,
- NULL,CALLBACK_WINDOW);
- if ( mmrResult != MMSYSERR_NOERROR )
- {
- MessageBeep(MB_ICONEXCLAMATION);
- AfxMessageBox(CString("音频输出错误!"));
- return;
- }
- }
- void CRecorderDlg::OnTimer(UINT nIDEvent)
- {
- // TODO: Add your message handler code here and/or call default
- PostMessage(WM_TIMEUP);
- CDialog::OnTimer(nIDEvent);
- }
- void CRecorderDlg::OnCancel()
- {
- // TODO: Add extra cleanup here
- CDialog::OnCancel();
- }
- LRESULT CRecorderDlg::OnTimeUp(WPARAM wParam,LPARAM lParam)
- {
- waveInReset(m_hWaveIn);
- m_bRecording = FALSE;
- m_bEnding = TRUE;
- KillTimer(1);
- TRACE(CString("MSG_TIMEUP/n"));
- return 0L;
- }
- void CRecorderDlg::WriteDatatoFile()
- {
- CTime tTime = CTime::GetCurrentTime();
- CString strFileName;
- CString strTime;
- strTime.Format(_T("%d"), tTime.GetMonth());
- strFileName = strTime;
- strTime.Format(_T("%d"), tTime.GetDay());
- strFileName += strTime;
- strTime.Format(_T("%d"), tTime.GetHour());
- strFileName += strTime;
- strTime.Format(_T("%d"), tTime.GetMinute());
- strFileName += strTime;
- //tTime.Format( "%A, %B %d, %Y" );
- strFileName += ".dat";
- strFileName = "..//Recorder//" + strFileName;
- CFile* fSoundFile = NULL;
- TRY
- {
- fSoundFile = new CFile(strFileName, CFile::modeCreate | CFile::modeWrite);
- SHORT nWrittenData;
- PSHORT pShort = (SHORT *)m_pSavedData; // 将系统默认的BYTE变量转为SHORT以便图形输出
- DWORD dwLength = m_dwSavedLength/2; // 由BYTE型长度得到SHORT型长度
- for (DWORD I=0; I<dwLength; I++)
- {
- nWrittenData = pShort[I];
- fSoundFile->Write(&nWrittenData, sizeof(SHORT));
- }
- }
- CATCH(CFileException, pEx)
- pEx->ReportError();
- AND_CATCH(CMemoryException, pEx)
- AfxAbort();
- END_CATCH
- if (fSoundFile)
- {
- fSoundFile->Flush();
- fSoundFile->Close();
- delete fSoundFile;
- fSoundFile = NULL;
- }
- }
- void CRecorderDlg::OnDestroy()
- {
- CDialog::OnDestroy();
- // TODO: Add your message handler code here
- free(m_pSavedData);
- m_pSavedData = NULL;
- }
- /*=====================================================
- 函数名称: ReadNameFile
- 函数功能:
- 输入参数:
- 输出参数:
- ====================================================*/
- void ReadNameFile(FILE *fp_Name, char **NameList, short NameAmount)
- {
- short iName;
- short Temp;
- fscanf(fp_Name,"%d/n", &Temp);
- for(iName=0; iName<NameAmount; iName++)
- {
- NameList[iName] = (char*)malloc(sizeof(char)*(2*MAX_NAMELENGTH+1));
- }
- for(iName=0; iName<NameAmount; iName++)
- {
- fscanf(fp_Name,"%s/n",NameList[iName]);
- }
- return;
- }
- void FileMatchRom(char *RomAddress, FILE *fp_Rom)
- {
- long FileLength_BYTE;
- short *RomFile;
- RomFile = (short*)(RomAddress);
- fseek(fp_Rom, 0, SEEK_END);
- FileLength_BYTE = ftell(fp_Rom);
- fseek(fp_Rom, 0, SEEK_SET);
- fread(RomFile, 2, (FileLength_BYTE/2), fp_Rom);
- return;
- }
- void CRecorderDlg::Recognize()
- {
- char* RomAddress;
- char* RamAddress;
- short Rtn_SR_Init = -1;
- char **NameList; //输入文件:一句语音、电话本
- short NameAmount;
- unsigned short NEW_NameList[MAX_NAMELENGTH];
- short iBest = 0, RtnFlag = 0, iName = 0;
- short *BestLemma; //在接口中没有具体定义,实际上就是RamAddress的最前面给出
- long RamSize, RomSize;
- FILE *fp_Name;
- FILE *fp_Rom;
- // char NameFile[100] = "//Recorder//FileIO//NameList.txt";
- char NameFile[100] = "//Datastorage//Recorder//FileIO//NameList.txt";
- char RomFile[100] = "//Datastorage//Recorder//FileIO//Rom_B03.bin"; //Table、Model、NetStuff合并成一个文件
- //0418194332 0418194336 0418194341 0418194350 0418194355 0418194359 0418194403 0418194408
- //0418194412 0418194416 0418194454 0418194458 0418194503 0418194507 0418194512 0418194517 0418194521
- fp_Name = fopen(NameFile,"r");
- fscanf(fp_Name, "%d", &NameAmount);
- NameList = (char**)malloc(sizeof(char*)*NameAmount);
- ReadNameFile(fp_Name, NameList, NameAmount);
- fclose(fp_Name);
- RamSize = 500*1024; //系统供给的地址空间,保证RAM和ROM的首地址和连续的空间长度
- RomSize = 300*1024;
- RamAddress = (char*)malloc(sizeof(char)*RamSize);
- RomAddress = (char*)malloc(sizeof(char)*RomSize);
- BestLemma = (short*)(RamAddress);
- long TickCount = 0 ;
- //==========================================================================================
- // MyPrintf(_T("File Match Rom&Ram..."));
- m_cNameList.SetItemText(9,1, _T("File Match Rom&Ram..."));
- fp_Rom = fopen(RomFile,"rb");
- if(!fp_Rom)
- {
- OutputDebugString(_T("/r/nfailed open the rom file/r/n"));
- return;
- }
- FileMatchRom(RomAddress, fp_Rom);
- fclose(fp_Rom);
- // MyPrintf(_T("Rom&Ram Checking..."));
- m_cNameList.SetItemText(9,1, _T("Rom&Ram Checking..."));
- Rtn_SR_Init = SR_INITCE(RamAddress, RamSize, RomAddress);
- if(Rtn_SR_Init == 1)
- {
- // MyPrintf(_T("ROM中的数据错误"));
- AfxMessageBox(_T("ROM中的数据错误"));
- return ;
- }
- else if(Rtn_SR_Init == 2)
- {
- // MyPrintf(_T("RAM分配资源不足"));
- AfxMessageBox(_T("RAM分配资源不足"));
- return ;
- }
- // else
- // AfxMessageBox(_T("MESSAGE:Rom&Ram Checked OK!"));
- // MyPrintf(_T("Utterance Processing..."));
- m_cNameList.SetItemText(9,1, _T("Utterance Processing..."));
- long dwStartTime = GetTickCount();
- //测试该函数的运行时间
- RtnFlag = SR_interfaceCE(RamAddress, RomAddress, (SHORT *)m_pSavedData, m_dwSavedLength/2, NameList, NameAmount, BestLemma);
- long dwFinishTime = GetTickCount();
- TickCount = TickCount + dwFinishTime - dwStartTime;
- // MyPrintf(_T("BestLemma List"));
- if(RtnFlag == 0)
- AfxMessageBox(_T("Speech Data Lacked!"));
- else
- {
- for(iBest=0; iBest<MAX_NBEST; iBest++)
- {
- CString str;
- MultiByteToWideChar(CP_ACP, 0, NameList[BestLemma[iBest]], -1, NEW_NameList, MAX_NAMELENGTH);
- str.Format(_T("%d: %s"), BestLemma[iBest], NEW_NameList);
- m_cNameList.SetItemText(iBest, 1, str.GetBuffer(100));
- }
- char temp[50];
- wsprintf((LPTSTR)temp,_T("CONFIDENCE:%d!"), RtnFlag);
- // MyPrintf((LPTSTR)temp);
- m_cNameList.SetItemText(8, 1, (LPTSTR)temp);
- // if(RtnFlag>0 && RtnFlag<25)
- // MyPrintf(_T("SYSTEM SUGGESTION: Trustless Result!"));
- // else
- // if(RtnFlag>50)
- // MyPrintf(_T("SYSTEM SUGGESTION: Trusty Result!"));
- // else
- // MyPrintf(_T("SYSTEM SUGGESTION: Try Again Suggested!"));
- }
- // free(SpeechBuf);
- CString str;
- str.Format(_T("Done.Cost %d ms."), (int)(TickCount));
- m_cNameList.SetItemText(9,1, str);
- // AfxMessageBox(str);
- //===========================================================================================
- free(RamAddress);
- free(RomAddress);
- return ;
- }
- BOOL CRecorderDlg::CheckMic()
- {
- MMRESULT mmrResult;
- mmrResult = waveInGetNumDevs();
- if (mmrResult == 0)
- {
- AfxMessageBox(CString("未检测到声音设备!"));
- return FALSE;
- }
- WAVEINCAPS m_WaveInDevCaps;
- mmrResult = waveInGetDevCaps (0, &m_WaveInDevCaps, sizeof(WAVEINCAPS));
- if ( mmrResult != MMSYSERR_NOERROR)
- {
- AfxMessageBox(CString("声卡类型不可知!"));
- return FALSE;
- }
- return TRUE;
- }
- /
- //
- // 函数名: SetWaveFormat()
- // 返回值: 无
- // 功能: 设定数据采集时的编码方法、采样率等格式。
- // 注释: 无
- //
- /
- void CRecorderDlg::SetWaveFormat(WORD wCh, DWORD dwSampleRate, WORD wBitsPerSample)
- {
- m_WaveFormat.wFormatTag = WAVE_FORMAT_PCM; // PCM编码格式
- m_WaveFormat.nChannels = wCh; // 默认为1
- m_WaveFormat.nSamplesPerSec = dwSampleRate; // 采样率
- m_WaveFormat.nAvgBytesPerSec = dwSampleRate * wCh * wBitsPerSample/8; // 标准计算公式
- m_WaveFormat.nBlockAlign = wCh * wBitsPerSample/8; // 标准计算公式
- m_WaveFormat.wBitsPerSample = wBitsPerSample; // 默认为16比特
- m_WaveFormat.cbSize = 0; // 保留
- }
- /
- //
- // 函数名: OnMM_WIM_OPEN()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WIM_OPEN的响应。
- // 注释: 当声音设备被打开时发送此消息。
- //
- /
- LRESULT CRecorderDlg::OnMM_WIM_OPEN(WPARAM wParam, LPARAM lParam)
- {
- m_bRecording=TRUE;
- GetDlgItem(IDC_RECORD)->EnableWindow(FALSE);
- GetDlgItem(IDC_STOP)->EnableWindow(TRUE);
- SetTimer(1, RECORDTIME, NULL);
- TRACE(CString("MM_WIM_OPEN/n"));
- return 0L;
- }
- /
- //
- // 函数名: OnMM_WIM_DATA()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WIM_DATA的响应。
- // 注释: 当系统缓冲已满,或者waveInReset函数被调用时,发送此消息。
- //
- /
- LRESULT CRecorderDlg::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam)
- {
- PBYTE m_pCurrentData = (PBYTE)realloc(m_pSavedData,
- m_dwSavedLength + ((PWAVEHDR) lParam)->dwBytesRecorded) ;
- if (!m_pCurrentData)
- {
- waveInClose (m_hWaveIn) ;
- MessageBeep (MB_ICONEXCLAMATION) ;
- AfxMessageBox(CString("内存分配失败。请调低采样率,或检查可用的系统内存。"));
- CDialog::OnCancel();
- }
- m_pSavedData = m_pCurrentData ;
- CopyMemory(m_pSavedData + m_dwSavedLength, ((PWAVEHDR) lParam)->lpData,
- ((PWAVEHDR) lParam)->dwBytesRecorded) ;
- m_dwSavedLength += ((PWAVEHDR) lParam)->dwBytesRecorded;
- if (m_bEnding)
- {
- waveInClose (m_hWaveIn);
- return 1L;
- }
- waveInAddBuffer (m_hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ;
- return 0L;
- }
- /
- //
- // 函数名: OnMM_WIM_CLOSE()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WIM_CLOSE的响应。
- // 注释: 音频设备被关闭时,发送此消息。发送此消息后,音频设备句柄
- // 将不再有效。
- //
- /
- LRESULT CRecorderDlg::OnMM_WIM_CLOSE(WPARAM wParam, LPARAM lParam)
- {
- TRACE(CString("MM_WIM_CLOSE/n"));
- if ( m_dwSavedLength==0 )
- return 1L;
- waveInUnprepareHeader(m_hWaveIn, &m_WaveHeader, sizeof (WAVEHDR)) ;
- m_bRecording = FALSE ;
- // 在这里做识别
- // Recognize();
- Search();
- if (m_bWriteFile.GetCheck())
- WriteDatatoFile();
- GetDlgItem(IDC_RECORD)->EnableWindow(TRUE);
- GetDlgItem(IDC_STOP)->EnableWindow(FALSE);
- // AfxMessageBox(CString("录音完毕"));
- return 0L;
- }
- /
- //
- // 函数名: OnMM_WOM_OPEN()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WOM_OPEN的响应。
- // 注释: 音频设备被打开时,发送此消息。
- //
- /
- LRESULT CRecorderDlg::OnMM_WOM_OPEN(WPARAM wParam, LPARAM lParam)
- {
- TRACE(CString("MM_WOM_OPEN /n"));
- GetDlgItem(IDC_PLAY)->EnableWindow(FALSE);
- m_WaveHeader.lpData = (LPSTR)m_pSavedData ;
- m_WaveHeader.dwBufferLength = m_dwSavedLength ;
- m_WaveHeader.dwBytesRecorded = 0 ;
- m_WaveHeader.dwUser = 0 ;
- m_WaveHeader.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
- m_WaveHeader.dwLoops = 1;
- m_WaveHeader.lpNext = NULL ;
- m_WaveHeader.reserved = 0 ;
- waveOutPrepareHeader (m_hWaveOut, &m_WaveHeader, sizeof (WAVEHDR)) ;
- waveOutWrite (m_hWaveOut, &m_WaveHeader, sizeof (WAVEHDR)) ;
- m_bEnding = FALSE ;
- m_bPlaying = TRUE ;
- return 0L;
- }
- /
- //
- // 函数名: OnMM_WOM_DONE()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WOM_DONE的响应。
- // 注释: 当放音结束,或者waveOutReset函数被调用时,发送此消息
- //
- /
- LRESULT CRecorderDlg::OnMM_WOM_DONE(WPARAM wParam, LPARAM lParam)
- {
- TRACE(CString("MM_WOM_DONE/n"));
- waveOutUnprepareHeader (m_hWaveOut, &m_WaveHeader, sizeof (WAVEHDR)) ;
- waveOutClose (m_hWaveOut) ;
- m_bPlaying = FALSE ;
- return 0L;
- }
- /
- //
- // 函数名: OnMM_WOM_CLOSE()
- // 返回值: 无
- // 功能: 重载对系统消息MM_WOM_CLOSE的响应。
- // 注释: 音频设备被关闭时,发送此消息。发送此消息后,音频设备句柄
- // 将不再有效。
- //
- /
- LRESULT CRecorderDlg::OnMM_WOM_CLOSE(WPARAM wParam, LPARAM lParam)
- {
- TRACE(CString("MM_WOM_CLOSE/n"));
- m_bEnding = TRUE ;
- m_bPlaying = FALSE ;
- GetDlgItem(IDC_PLAY)->EnableWindow(TRUE);
- AfxMessageBox(CString("放音完毕"));
- return 0L;
- }
- void CRecorderDlg::OnLoad()
- {
- // TODO: Add your control notification handler code here
- Rtn_SR_Init = -1;
- iBest = 0, RtnFlag = 0, iName = 0;
- HANDLE hDev;
- hDev = CreateFile(TEXT("FME1:"), GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, 0, 0);
- CloseHandle(hDev);
- FILE *fp_Name;
- FILE *fp_Rom;
- // char NameFile[100] = "//Recorder//FileIO//NameList.txt";
- char NameFile[100] = "//Datastorage//Recorder//FileIO//NameList.txt";
- char RomFile[100] = "//Datastorage//Recorder//FileIO//Rom_B03.bin"; //Table、Model、NetStuff合并成一个文件
- //0418194332 0418194336 0418194341 0418194350 0418194355 0418194359 0418194403 0418194408
- //0418194412 0418194416 0418194454 0418194458 0418194503 0418194507 0418194512 0418194517 0418194521
- fp_Name = fopen(NameFile,"r");
- fscanf(fp_Name, "%d", &NameAmount);
- NameList = (char**)malloc(sizeof(char*)*NameAmount);
- ReadNameFile(fp_Name, NameList, NameAmount);
- fclose(fp_Name);
- RamSize = 500*1024; //系统供给的地址空间,保证RAM和ROM的首地址和连续的空间长度
- RomSize = 300*1024;
- RamAddress = (char*)malloc(sizeof(char)*RamSize);
- RomAddress = (char*)malloc(sizeof(char)*RomSize);
- BestLemma = (short*)(RamAddress);
- long TickCount = 0 ;
- //==========================================================================================
- // MyPrintf(_T("File Match Rom&Ram..."));
- m_cNameList.SetItemText(9,1, _T("File Match Rom&Ram..."));
- fp_Rom = fopen(RomFile,"rb");
- if(!fp_Rom)
- {
- OutputDebugString(_T("/r/nfailed open the rom file/r/n"));
- return;
- }
- FileMatchRom(RomAddress, fp_Rom);
- fclose(fp_Rom);
- // MyPrintf(_T("Rom&Ram Checking..."));
- m_cNameList.SetItemText(9,1, _T("Rom&Ram Checking..."));
- Rtn_SR_Init = SR_INITCE(RamAddress, RamSize, RomAddress);
- if(Rtn_SR_Init == 1)
- {
- // MyPrintf(_T("ROM中的数据错误"));
- AfxMessageBox(_T("ROM中的数据错误"));
- return ;
- }
- else if(Rtn_SR_Init == 2)
- {
- // MyPrintf(_T("RAM分配资源不足"));
- AfxMessageBox(_T("RAM分配资源不足"));
- return ;
- }
- m_cNameList.SetItemText(9,1, _T("Load OK..."));
- }
- void CRecorderDlg::Search()
- {
- m_cNameList.SetItemText(9,1, _T("Utterance Processing..."));
- long TickCount = 0 ;
- long dwStartTime = GetTickCount();
- //测试该函数的运行时间
- RtnFlag = SR_interfaceCE(RamAddress, RomAddress, (SHORT *)m_pSavedData, m_dwSavedLength/2, NameList, NameAmount, BestLemma);
- long dwFinishTime = GetTickCount();
- TickCount = TickCount + dwFinishTime - dwStartTime;
- // MyPrintf(_T("BestLemma List"));
- if(RtnFlag == 0)
- AfxMessageBox(_T("Speech Data Lacked!"));
- else
- {
- for(iBest=0; iBest<MAX_NBEST; iBest++)
- {
- CString str;
- MultiByteToWideChar(CP_ACP, 0, NameList[BestLemma[iBest]], -1, NEW_NameList, MAX_NAMELENGTH);
- str.Format(_T("%d: %s"), BestLemma[iBest], NEW_NameList);
- m_cNameList.SetItemText(iBest, 1, str.GetBuffer(100));
- }
- char temp[50];
- wsprintf((LPTSTR)temp,_T("CONFIDENCE:%d!"), RtnFlag);
- // MyPrintf((LPTSTR)temp);
- m_cNameList.SetItemText(8, 1, (LPTSTR)temp);
- // if(RtnFlag>0 && RtnFlag<25)
- // MyPrintf(_T("SYSTEM SUGGESTION: Trustless Result!"));
- // else
- // if(RtnFlag>50)
- // MyPrintf(_T("SYSTEM SUGGESTION: Trusty Result!"));
- // else
- // MyPrintf(_T("SYSTEM SUGGESTION: Try Again Suggested!"));
- }
- // free(SpeechBuf);
- CString str;
- str.Format(_T("Done.Cost %d ms."), (int)(TickCount));
- m_cNameList.SetItemText(9,1, str);
- }