⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audrec.cpp

📁 利用intel dsplib 库函数进行特定2FSK信号(需传导频)解调
💻 CPP
字号:
// AudRec.cpp : implementation file
//


#include "stdafx.h"
#include "AudRec.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CAudRec

CAudRec::CAudRec() : m_nBuffSize(0)
,m_nBuffNum(0)
,m_nDataQueueNum(0)
,m_nDeviceID(0)
,m_szAryInData(NULL)
,m_pAryHdr(NULL)
,m_hRecord(NULL)
,m_funCallBackDataWork(NULL)
,m_hwndParent(NULL)
,m_bSaveFile(FALSE)
,m_bRecording(FALSE)
,m_eStatus(ENUM_STATUS_INVALID)
,m_hWaveFile(NULL)
{
	memset( &m_Format, 0, sizeof(WAVEFORMATEX) );
	ZeroMemory(&m_MMCKInfoParent,sizeof(m_MMCKInfoParent));
	ZeroMemory(&m_MMCKInfoChild,sizeof(m_MMCKInfoChild));
}


CAudRec::~CAudRec()
{
	StopAndFreeAll();
}


BEGIN_MESSAGE_MAP(CAudRec, CWnd)
	//{{AFX_MSG_MAP(CAudRec)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


BOOL CAudRec::PreTranslateMessage(MSG* pMsg) 
{
	if( (pMsg->message >= MM_WOM_OPEN) && (pMsg->message <= MM_MOM_DONE) )
	{
		switch ( pMsg->message )
		{
		case MM_WIM_DATA:
			OnMM_WIM_DATA ( pMsg->wParam, pMsg->lParam );
			break;
		case MM_WIM_CLOSE:
			m_eStatus = ENUM_STATUS_READY;
			m_nDataQueueNum = 0;
			m_bRecording = FALSE;
			break;
		case MM_WOM_DONE:
			break;
		case MM_WOM_CLOSE:
			m_eStatus = ENUM_STATUS_READY;
			m_bRecording = FALSE;
			break;
		case MM_WIM_OPEN:
			break;
		case MM_WOM_OPEN:
			break;
		}
	}
	
	return CWnd::PreTranslateMessage(pMsg);
}


BOOL CAudRec::Record()
{
	if( m_eStatus == ENUM_STATUS_RECORDING )
	{
		TRACE ( "Already Recording ...\n" );
		return TRUE;
	}

	m_bRecording = TRUE;
	MMRESULT  mmReturn = 0;

	if( m_eStatus != ENUM_STATUS_READY )
	{
		AfxMessageBox ( "Class status error" );
		return FALSE;
	}

	SetRecordFormat( m_Format );
	if( !SetRelateParaAfterGetWaveFormat() )
	{
		return FALSE;
	}

	//打开设备
	mmReturn = ::waveInOpen( &m_hRecord, m_nDeviceID, &m_Format, 
		(DWORD)GetSafeHwnd(), NULL, CALLBACK_WINDOW );
	if ( mmReturn )
	{
		waveErrorMsg( mmReturn, "waveInOpen()");
		goto failed;
	}
	else
	{	
		// //设置缓冲区并加入输入队列
		for(UINT i=0; i < m_nBuffNum; i++)
		{
			AddInputBufferToQueue( i );
		}
		
		//开始录音
		mmReturn = ::waveInStart( m_hRecord );
		if ( mmReturn )
		{
			waveErrorMsg( mmReturn, "waveInStart() failed");
			goto failed;
		}
	}
		
	m_eStatus = ENUM_STATUS_RECORDING;

	if( TRUE == m_bSaveFile )
	{
		CreateWaveFile();
	}

	return TRUE;

failed:
	FreeBuffer();
	return FALSE;
}


void CAudRec::Stop()
{
	if ( m_eStatus != ENUM_STATUS_RECORDING )
	{
		return;
	}
	
	if( m_eStatus == ENUM_STATUS_RECORDING )
	{
		SetTimer ( TIMER_EVENT_STOPREC, 1000, NULL );
	}
	
	Invalidate ( TRUE );
	m_eStatus = ENUM_STATUS_STOPING;
}


void CAudRec::StopAndFreeAll()
{
	if ( m_hRecord )
	{
		StopRec();
	}

	FreeBuffer();
}


void CAudRec::StopRec()
{
	if ( !m_hRecord )
	{
		return;
	}

	if ( m_eStatus != ENUM_STATUS_RECORDING && m_eStatus != ENUM_STATUS_STOPING )
	{
		return;
	}

	MMRESULT mmReturn = 0;
	mmReturn = ::waveInReset ( m_hRecord );
	if ( mmReturn )
	{	
		waveErrorMsg ( mmReturn, "waveInReset() failed" );	
	}

	//关键,给线程退出时间
	::Sleep ( 10 );

	::mmioAscend( m_hWaveFile, &m_MMCKInfoChild, 0 );
	::mmioAscend( m_hWaveFile, &m_MMCKInfoParent, 0 );
	::mmioClose( m_hWaveFile, 0 );
	m_hWaveFile = NULL;

	mmReturn = ::waveInClose ( m_hRecord );
	m_hRecord = NULL;

	if( mmReturn ) 
	{	
		waveErrorMsg ( mmReturn, "waveInClose() failed" );
	}
}


/////////////////////////////////////////////////////////////////////////////
// CAudRec message handlers

BOOL CAudRec::Create(HWND hwndParent, LPRECT lpRect)
{
	LPCTSTR lpszClassName = AfxRegisterWndClass( 
		0,
		LoadCursor(AfxGetInstanceHandle(), IDC_ARROW),
		NULL,
		NULL);

	CRect rc(0, 0, 0, 0);
	if( lpRect )
	{
		rc = *lpRect;
	}

	if( !CreateEx( 0, lpszClassName, "", WS_CHILD | WS_TABSTOP,
		rc.left, rc.top, rc.Width(), rc.Height(),
		hwndParent, NULL, NULL) )
	{
		AfxMessageBox("Creat the Record Wnd failed!");
		return FALSE;
	}

	if( lpRect )
	{
		ShowWindow( SW_SHOW );
	}
	else
	{
		ShowWindow( SW_HIDE );
	}

	//GetClientRect ( &m_rcClient );	
	return TRUE;
}

/*
CAudRec m_rec;

WAVEFORMATEX wf;
wf.ss = 11025
wf.bits = 16
CALLBACK rr(dd,dd);
{

}

CRect rc
m_rec.init( wf, true, 2034, 0, this->getsafehandle(), &rc, rr)

mrec.record(
m_.stop
*/

BOOL CAudRec::Init( WAVEFORMATEX sRecordFormat, 
				BOOL IsSaveFile, 
				UINT nBuffSize, 
				UINT nDeviceID,
				HWND hwndParent,
				LPRECT lpRect,
				CALLBACK_DATAWORK proc_CallBack_DataWork
				)
{
	SetDeviceID( nDeviceID );

	m_nBuffSize = nBuffSize;
	m_bSaveFile = IsSaveFile;
	m_hwndParent = hwndParent;
	m_rcClient = lpRect;
	m_funCallBackDataWork = proc_CallBack_DataWork;

	memcpy(&m_Format, &sRecordFormat, sizeof(WAVEFORMATEX) );

	// 创建窗口用来接收消息
	if ( !Create ( m_hwndParent, m_rcClient ) )
	{
		AfxMessageBox("failed in Init to Create child windows for get message!");
	}
	
	m_eStatus = ENUM_STATUS_READY;

	return TRUE;
}


VOID CAudRec::SetDeviceID(UINT uDeviceID)
{
	StopAndFreeAll ();
	m_nDeviceID = uDeviceID;
}


void CAudRec::waveErrorMsg(MMRESULT result, LPCTSTR addstr)
{
	char errorbuffer[100];

	waveInGetErrorText ( result, errorbuffer, 100 );

	CString csMsg;
	csMsg.Format ( "WAVEIN:%x:%s %s", result, errorbuffer, addstr );
	AfxMessageBox ( csMsg );
}


LRESULT CAudRec::OnMM_WIM_DATA ( WPARAM wParam, LPARAM lParam )
{
	MMRESULT mmReturn = 0;

	LPWAVEHDR pHdr = (LPWAVEHDR) lParam;
	ASSERT ( pHdr );

	mmReturn = ::waveInUnprepareHeader( m_hRecord, pHdr, sizeof(WAVEHDR));
	if( mmReturn )
	{
		waveErrorMsg ( mmReturn, "waveInUnprepareHeader() failed" );
		return -1L;
	}

	if( m_eStatus == ENUM_STATUS_RECORDING )
	{
		if( TRUE == m_bSaveFile )
		{
			UINT length = ::mmioWrite( m_hWaveFile, (CHAR*)pHdr->lpData, pHdr->dwBytesRecorded );
			if( length != pHdr->dwBytesRecorded )
			{
				Stop();
				m_nDataQueueNum --;
				AfxMessageBox ( "Write file failed" );
				return -1L;
			}
		}

		if( m_funCallBackDataWork )
		{
			m_funCallBackDataWork( (UCHAR*)pHdr->lpData, pHdr->dwBytesRecorded);
		}

		mmReturn = ::waveInPrepareHeader( m_hRecord, pHdr, sizeof(WAVEHDR) );
		
		if ( mmReturn )
		{
			waveErrorMsg( mmReturn, "waveInPrepareHeader() failed in OnMM_WIM_DATA" );
		}
		else
		{
			mmReturn = ::waveInAddBuffer( m_hRecord, pHdr, sizeof(WAVEHDR) );
			if ( mmReturn )
			{
				waveErrorMsg( mmReturn, "waveInAddBuffer() failed in OnMM_WIM_DATA");
			}
			else
			{
				return 0L; 
			}
		}
	}
	else
	{
		if ( m_nDataQueueNum == 1 )
		{
			StopRec();
		}
		else
		{
			m_nDataQueueNum--;
		}
	}

	return 0L;
}


BOOL CAudRec::AddInputBufferToQueue(INT nIndex)
{
	ASSERT( (UINT(nIndex) >= 0) && (UINT(nIndex) < m_nBuffNum) );
	ASSERT( m_szAryInData[nIndex] );

	MMRESULT mmReturn = 0;

	LPWAVEHDR pHdr = m_pAryHdr[nIndex];
	ZeroMemory( pHdr, sizeof(WAVEHDR) );
	pHdr->lpData = (char*)m_szAryInData[nIndex];
	pHdr->dwBufferLength = m_nBuffSize;

	mmReturn = ::waveInPrepareHeader( m_hRecord, pHdr, sizeof(WAVEHDR) );
	if ( mmReturn )
	{
		waveErrorMsg ( mmReturn, "AddInputBufferToQueue Failed");
		return FALSE;
	}

	mmReturn = ::waveInAddBuffer( m_hRecord, pHdr, sizeof(WAVEHDR) );
	if ( mmReturn )
	{
		waveErrorMsg ( mmReturn, "waveInAddBuffer() failed");
		return FALSE;
	}
	
	m_nDataQueueNum++;

	return TRUE;
}


BOOL CAudRec::AllocateBuffer(UINT dwBufferSize)
{
	m_nBuffSize = dwBufferSize;

	ASSERT ( m_nBuffNum > 0 );
	m_szAryInData = new char*[m_nBuffNum];
	m_pAryHdr = new WAVEHDR*[m_nBuffNum];

	if ( !m_szAryInData )
	{
		::AfxThrowMemoryException();
		return FALSE;
	}

	memset( m_szAryInData, 0, sizeof(char*) * m_nBuffNum );
	memset( m_pAryHdr, 0, sizeof(WAVEHDR*) * m_nBuffNum );

	for ( UINT i=0; i < m_nBuffNum; i++ )
	{
		
		m_szAryInData[i] = new char[m_nBuffSize];
		m_pAryHdr[i] = new WAVEHDR;
		if ( !m_szAryInData[i] || !m_pAryHdr[i] )
		{
			::AfxThrowMemoryException ();
			return FALSE;
		}

		TRACE( "Alloc m_nBuffNum = %d\n", i);

		memset ( m_szAryInData[i], 0, m_nBuffSize );
		memset ( m_pAryHdr[i], 0, sizeof(WAVEHDR) );
	}
	
	return TRUE;
}


void CAudRec::FreeBuffer()
{
	if ( m_szAryInData )
	{
		for ( UINT i=0; i < m_nBuffNum; i++ )
		{
			if ( m_szAryInData[i] )
				delete[] m_szAryInData[i];
			TRACE( "Delete m_nBuffNum = %d\n", i);
		}
		memset ( m_szAryInData, 0, sizeof(char*)*m_nBuffNum );
		delete[] m_szAryInData;
		m_szAryInData = NULL;
	}

	if ( m_pAryHdr )
	{
		for ( UINT i=0; i < m_nBuffNum; i++ )
		{
			if ( m_pAryHdr[i] )
				delete[] m_pAryHdr[i];
		}
		memset ( m_pAryHdr, 0, sizeof(WAVEHDR*)*m_nBuffNum );
		delete[] m_pAryHdr;
		m_pAryHdr = NULL;
	}
}


void CAudRec::OnTimer(UINT nIDEvent) 
{
	switch( nIDEvent )
	{
	case TIMER_EVENT_STOPREC:
		KillTimer( nIDEvent );
		StopRec();
		break;
	}

	CWnd::OnTimer(nIDEvent);
}


void CAudRec::SetRecordFormat(WAVEFORMATEX sFormat)
{
	memset ( &m_Format, 0, sizeof(WAVEFORMATEX) );

	m_Format.cbSize = sFormat.cbSize;
	m_Format.nAvgBytesPerSec = sFormat.nAvgBytesPerSec;
	m_Format.nBlockAlign = sFormat.nBlockAlign;
	m_Format.nChannels = sFormat.nChannels;
	m_Format.nSamplesPerSec = sFormat.nSamplesPerSec;
	m_Format.wBitsPerSample = sFormat.wBitsPerSample;
	m_Format.wFormatTag = sFormat.wFormatTag;
}


BOOL CAudRec::SetRelateParaAfterGetWaveFormat()
{
	FreeBuffer();

	m_nBuffNum = (UINT)( m_Format.nChannels + m_Format.wBitsPerSample/8
		+ m_Format.nSamplesPerSec/11025 );

	if ( !AllocateBuffer( m_nBuffSize ) )
	{
		AfxMessageBox("Failed in SetRecordFormat AllocateBuffer!");
		return FALSE;
	}

	return TRUE;
}

UINT CAudRec::GetWaveInCount()
{
	return waveInGetNumDevs();
}

void CAudRec::CreateWaveFile()
{
	INT nPos;
	CHAR buffer[20];
	CTime t = CTime::GetCurrentTime();
	
	nPos = sprintf( buffer, "%d", t.GetYear() );
	nPos += sprintf( buffer + nPos, "%d", t.GetMonth() );
	nPos += sprintf( buffer + nPos, "%d", t.GetDay() );
	nPos += sprintf( buffer + nPos, "%d", t.GetHour() );
	nPos += sprintf( buffer + nPos, "%d", t.GetMinute() );
	nPos += sprintf( buffer + nPos, "%d", t.GetSecond() );

	strcat( buffer, ".wav");

	// if existing the same file, delete it
	::mmioOpen ( (LPTSTR)buffer, NULL, MMIO_DELETE ); 

	m_hWaveFile = ::mmioOpen( buffer, NULL, MMIO_CREATE|MMIO_WRITE|MMIO_EXCLUSIVE|MMIO_ALLOCBUF  ); 
	if( NULL == m_hWaveFile )
	{
		AfxMessageBox("can not create the wave file!");
	}

	WAVEFORMATEX wfx = m_Format;

	ZeroMemory ( &m_MMCKInfoParent, sizeof(MMCKINFO) );
	m_MMCKInfoParent.fccType = mmioFOURCC('W','A','V','E');
	
	MMRESULT mmResult = ::mmioCreateChunk( m_hWaveFile,&m_MMCKInfoParent, MMIO_CREATERIFF);
	
	ZeroMemory ( &m_MMCKInfoChild, sizeof(MMCKINFO) );
	m_MMCKInfoChild.ckid = mmioFOURCC('f','m','t',' ');
	m_MMCKInfoChild.cksize = sizeof(WAVEFORMATEX) + wfx.cbSize;

	mmResult = ::mmioCreateChunk(m_hWaveFile, &m_MMCKInfoChild, 0);	
	mmResult = ::mmioWrite(m_hWaveFile, (char*)&wfx, sizeof(WAVEFORMATEX) + wfx.cbSize); 	
	mmResult = ::mmioAscend(m_hWaveFile, &m_MMCKInfoChild, 0);
	
	m_MMCKInfoChild.ckid = mmioFOURCC('d', 'a', 't', 'a');
	mmResult = ::mmioCreateChunk ( m_hWaveFile, &m_MMCKInfoChild, 0 );
}

UINT CAudRec::GetBuffSize()
{
	return m_nBuffSize;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -