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 + -
显示快捷键?