voicecmddlg.cpp
来自「wince平台下的一个录音机」· C++ 代码 · 共 412 行
CPP
412 行
// VoiceCmdDlg.cpp : implementation file
//
#include "stdafx.h"
#include "VoiceCmd.h"
#include "VoiceCmdDlg.h"
#include "recwav.h"
//use cfg decoder
//#include "asrice.h"
//use lvi decoder
//#include "asr_api.h"
//#include "namedb.h"
//online version for PDA decoder:input one piece of wav, recognize it right now
///#ifdef ONLINE_VER
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//#ifdef _DEBUG
int g_display_time_cost = 0;
#ifndef ENGLISH
#define TEXT_VOICE_CMD_TITLE L"语音导航"
#define TEXT_MIC_BUTTON_OFF L"请点击这里或按功能键"
#define TEXT_MIC_BUTTON_PROC L"搜索中..."
#define TEXT_MIC_BUTTON_SPK L"请说出命令..."
#define TEXT_CMD_LIST L"命令列表"
#define TEXT_REC L"WAV"
#define TEXT_TIME_COST L"ASR"
#define TEXT_SPK_AGN L"请再说一遍"
#define TEXT_TIME_UNIT L"秒"
#else
#define TEXT_MIC_BUTTON_OFF L"Push to talk"
#define TEXT_MIC_BUTTON_PROC L"Searching ..."
#define TEXT_MIC_BUTTON_SPK L"Pls speak ..."
#define TEXT_TIME_COST L"Time cost"
#define TEXT_SPK_AGN L"Pls speak agn"
#define TEXT_TIME_UNIT L"s"
#endif
int stack_num = 800;
int topn = 3;
char file_wave[MAX_FILE_LEN];// = "\\veldasoft\\CFG\\vcmd.wav";
char file_wave_prefix[MAX_FILE_LEN] = "vcmd"; // = "\\veldasoft\\CFG\\vcmd.wav";
char path_wave[MAX_FILE_LEN] = "\\wav";
// flag for seperate command name and command
const char CMD_SEPERATE_FLAG = '\t';
#define MAX_CMD_EXE_LEN 256
#define MAX_CMD_NAME_LEN 50
#define MAX_CMD_NUM 1024
int volum_pos = 0;
int MAX_REC_DURATION = 3000;
int TIMER_DURATION = 500;
// the exe file of commands
char cmd_exe_buf[MAX_CMD_NUM][MAX_CMD_EXE_LEN];
// the names of commands
char cmd_name_buf[MAX_CMD_NUM][MAX_CMD_NAME_LEN];
int non_sil_cnt = 0;
int sil_cnt = 0;
/*
int max_sil_time = 800; //ms
int min_non_sil_time = 150; //ms
int max_non_sil_time = 2000; //ms
int rec_time_out = 2500; //ms
*/
int max_sil_time = 500; //ms
int min_non_sil_time = 150; //ms
int max_non_sil_time = 1500; //ms
int rec_time_out = 5000; //ms
// recording duration
int n_rec_dur = 0; //ms
int n_rec_start = 0;
int n_rec_stop = 0;
BOOL exec(LPCWSTR lpApplicationName, LPCWSTR lpCommandLine)
{
return CreateProcess(lpApplicationName,
lpCommandLine, NULL, NULL, FALSE,
0, NULL, NULL, NULL,
NULL);
}
// 默认的配置
int launchProgram_default(const char *asr_result)
{
return 0;
}
// 启动应用程序
int launchProgram(const char *asr_result)
{
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CVoiceCmdDlg dialog
CVoiceCmdDlg::CVoiceCmdDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVoiceCmdDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVoiceCmdDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
enableSilDetect = true;
useTimeAsFileName = true;
//enableSilDetect = false;
}
void CVoiceCmdDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVoiceCmdDlg)
DDX_Control(pDX, IDC_PROGRESS, m_ctlVolum);
DDX_Control(pDX, IDC_CMD_LIST, m_ctlCmdList);
DDX_Control(pDX, IDC_LIST_CONTACT, m_ctlListContact);
DDX_Control(pDX, IDC_LIST_INFO, m_ctlListInfo);
DDX_Control(pDX, IDC_LIST_ASR, m_ctlListASR);
DDX_Control(pDX, IDC_MIC_ONOFF, m_mic);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVoiceCmdDlg, CDialog)
//{{AFX_MSG_MAP(CVoiceCmdDlg)
ON_BN_CLICKED(IDC_MIC_ONOFF, OnMicOnoff)
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVoiceCmdDlg message handlers
BOOL CVoiceCmdDlg::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
SetWindowText(TEXT_VOICE_CMD_TITLE);
CenterWindow(GetDesktopWindow()); // center to the hpc screen
// TODO: Add extra initialization here
m_mic.SetWindowText(TEXT_MIC_BUTTON_OFF);
m_ctlCmdList.SetWindowText(TEXT_CMD_LIST);
m_ctlVolum.SetRange( 0, MAX_REC_DURATION/TIMER_DURATION);
m_ctlVolum.SetPos(0);
updateNameList();
OnMicOnoff();
TCHAR *psz_exe=NULL;
TCHAR psz_filename[256];
//BYTE vk;
if( GetModuleFileName(NULL, psz_filename, 255) )
{
TCHAR *p;
p = psz_filename;
while( p )
{
p = wcsstr(p, L"\\");
if( p )
{
psz_exe = p+1;
}
p ++;
}
}
/*
vk = SHGetAppKeyAssoc(psz_exe);
if( vk )
{
//SHORT GetAsyncKeyState(int vKey); for determinate the state of the key is up or down
//AfxMessageBox(L"map to a key:0002");
SHSetAppKeyWndAssoc(vk, this->GetSafeHwnd());
if( !RegisterHotKey(this->GetSafeHwnd(), 0x0012, MOD_KEYUP, vk) )
{
AfxMessageBox(L"RegisterHotKey(HOTKEY_DIAL failed)");
}
}
*/
return TRUE; // return TRUE unless you set the focus to a control
}
void CVoiceCmdDlg::OnMicOnoff(void)
{
non_sil_cnt = 0;
sil_cnt = 0;
if( micIsOff() )
{
//TCHAR szWindowName[] = L"Voice Commander" ;
HWND hWnd = NULL;
MessageBeep(0xFFFFFFFF);
if( useTimeAsFileName )
{
SYSTEMTIME systemTime;
LPSYSTEMTIME lpSystemTime = &systemTime;
//make file directory
//_mkdir(path_wave);
GetSystemTime( lpSystemTime );
sprintf(file_wave, "%s\\%s_%4d%02d%02d_%02d%02d%02d.wav",
path_wave, file_wave_prefix,
lpSystemTime->wYear, lpSystemTime->wMonth, lpSystemTime->wDay,
lpSystemTime->wHour, lpSystemTime->wMinute, lpSystemTime->wSecond);
}
//m_ctlListASR.ResetContent();
//m_ctlListInfo.ResetContent();
m_ctlListASR.ResetContent();
m_mic.SetWindowText(TEXT_MIC_BUTTON_SPK);
hWnd = this->GetSafeHwnd();
waveInit(hWnd,WAVE_FORMAT_PCM,1, REC_WAVE_FREQ, REC_WAVE_BIT, file_wave);
m_nTimer = SetTimer(1, TIMER_DURATION, 0);
n_rec_start = GetTickCount();
}else{
m_mic.EnableWindow(FALSE);
m_mic.SetWindowText(TEXT_MIC_BUTTON_PROC);
if( -1 == waveCloseBuf() )
{
AfxMessageBox(L"Error: no enough space for writing wave file!");
return;
}
m_ctlVolum.SetPos(0);
KillTimer(m_nTimer);
volum_pos = 0;
n_rec_stop = GetTickCount();
#ifndef _DEBUG
remove(file_wave);
#endif
m_mic.EnableWindow(TRUE);
m_mic.SetWindowText(TEXT_MIC_BUTTON_OFF);
}
}
void CVoiceCmdDlg::OnTimer(UINT nIDEvent)
{
volum_pos ++;
m_ctlVolum.SetPos(volum_pos);
if( volum_pos > MAX_REC_DURATION/TIMER_DURATION )
{
OnMicOnoff();
}
CDialog::OnTimer(nIDEvent);
}
LRESULT CVoiceCmdDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
switch (message)
{
#if 1
case WM_KEYDOWN:
//AfxMessageBox(L"Key down");
//sndPlaySound(pszSound, SND_FILENAME|SND_ASYNC);
//OnMicOnoff();
break;
case WM_KEYUP:
//AfxMessageBox(L"Key up");
//sndPlaySound(pszSound, SND_FILENAME|SND_ASYNC);
OnMicOnoff();
break;
case WM_HOTKEY:
//AfxMessageBox(L"HotKey");
//sndPlaySound(pszSound, SND_FILENAME|SND_ASYNC);
break;
#endif
case WIM_DATA:
if( enableSilDetect )
{
if( isSilWav(((WAVEHDR *)lParam)->lpData, ((WAVEHDR *)lParam)->dwBytesRecorded) )
{
sil_cnt ++;
int contd_sil_time;
int non_sil_time;
contd_sil_time = (int)((float)REC_BUFSIZE/(float)REC_WAVE_FREQ * 1000.0)
* sil_cnt;
non_sil_time = (int)((float)REC_BUFSIZE/(float)REC_WAVE_FREQ * 1000.0)
* non_sil_cnt;
// 如果sil太长,而且已经录到足够长的语音(non-sil), 当作录音结束
if( contd_sil_time > max_sil_time && non_sil_time > min_non_sil_time )
{
OnMicOnoff();
}else if( non_sil_time > max_non_sil_time )
{
// 如果non-sil太长,可能是用户环境太吵, 提示用户到安静的地方
//AfxMessageBox(ENV_TOO_NOISE);
OnMicOnoff();
}else if( contd_sil_time > rec_time_out )
{
// 如果sil超过timeout, 当作录音结束
OnMicOnoff();
}
}else{
non_sil_cnt ++;
sil_cnt = 0;
}
}
waveProcBuf((WAVEHDR *)lParam);
break;
default:
break;
}
return CDialog::DefWindowProc(message, wParam, lParam);
}
BOOL CVoiceCmdDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::OnNotify(wParam, lParam, pResult);
}
BOOL CVoiceCmdDlg::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// TODO: Add your specialized code here and/or call the base class
return CDialog::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
BOOL CVoiceCmdDlg::DestroyWindow(void)
{
// TODO: Add your specialized code here and/or call the base class
if( micIsOn() )
{
waveCloseBuf();
}
return CDialog::DestroyWindow();
}
// update command list in the listbox
int CVoiceCmdDlg::updateNameList(void)
{
return 0;
}
void CVoiceCmdDlg::OnOptions(void)
{
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?