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

📄 serialportdlg.cpp

📁 单片机ram下,pcm转换为wav文件,对想了解pcm和wav文件关系的人有用.
💻 CPP
字号:
// SerialPortDlg.cpp : implementation file
//

#include "stdafx.h"
#include "wave.h"
#include "SerialPortDlg.h"

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

#define INDEX_OF_PERSON  1
#define INDEX_OF_COMMAND 1
/////////////////////////////////////////////////////////////////////////////
// CSerialPortDlg dialog

CSerialPortDlg::~CSerialPortDlg()
{
	delete []rcvdArray;
}

CSerialPortDlg::CSerialPortDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSerialPortDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSerialPortDlg)
	m_strReceiveData = _T("");
	m_strSendData = _T("");
	//}}AFX_DATA_INIT
	n_ReceiveLength = 0;
	rcvdArray = new char[2097152];//分配空间2M
	reversed = 0;

	person_index=INDEX_OF_PERSON;
	command_index=INDEX_OF_COMMAND;
	person_index2 = INDEX_OF_PERSON;
	command_index2 = INDEX_OF_COMMAND;
}


void CSerialPortDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSerialPortDlg)
	DDX_Control(pDX, IDC_MSCOMM1, m_ctrlComm);
	DDX_Text(pDX, IDC_EDIT_RECEIVE, m_strReceiveData);
	DDX_Text(pDX, IDC_EDIT_SEND, m_strSendData);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CSerialPortDlg, CDialog)
	//{{AFX_MSG_MAP(CSerialPortDlg)
	ON_BN_CLICKED(IDC_BUTTON_OpenPort, OnBUTTONOpenPort)
	ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnButtonClear)
	ON_BN_CLICKED(IDC_BUTTON_SAVEPCM, OnButtonSavepcm)
	ON_BN_CLICKED(IDC_BUTTON_SAVEWAV, OnButtonSavewav)
	ON_BN_CLICKED(IDC_BUTTON_MANUALSEND, OnButtonManualsend)
	ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_ZANTING, OnButtonZanting)
	ON_BN_CLICKED(IDC_BUTTON_CONTINUE, OnButtonContinue)
	ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
	ON_BN_CLICKED(IDC_BUTTON_RESTART, OnButtonRestart)
	ON_BN_CLICKED(IDC_BUTTON_READFILEBTN, OnButtonReadfilebtn)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSerialPortDlg message handlers

int CSerialPortDlg::DoModal() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CDialog::DoModal();
}

BEGIN_EVENTSINK_MAP(CSerialPortDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CSerialPortDlg)
	ON_EVENT(CSerialPortDlg, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE)
	//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

//SerialPortDIALOG初始化
BOOL CSerialPortDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	n_ReceiveLength = 0;
	reversed = 0;

	
//	person_index=INDEX_OF_PERSON;
//	command_index=INDEX_OF_COMMAND;
//	person_index2 = INDEX_OF_PERSON;
//	command_index2 = INDEX_OF_COMMAND;

	GetModuleFileName(NULL,path.GetBufferSetLength (MAX_PATH+1),MAX_PATH);
	path.ReleaseBuffer ();
	int nPos;
	nPos=path.ReverseFind ('\\');
	path=path.Left (nPos);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

//串口接收数据并显示在编辑框
void CSerialPortDlg::OnComm() 
{
	// TODO: Add your control notification handler code here
	VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
	for(k=0;k<2048;k++)
	{
		rxdata[k] = '0'; 
	}

    CString strtemp;
    if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
    {             ////////以下你可以根据自己的通信协议加入处理代码
        variant_inp=m_ctrlComm.GetInput(); //读缓冲区
        safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
        len=safearray_inp.GetOneDimSize(); //得到有效数据长度
		
        for(k=0;k<len;k++)
		{
            safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
		}

        for(k=0;k<len;k++) //将数组转换为Cstring型变量
        {
            BYTE bt=*(char*)(rxdata + k); //字符型
			*(rcvdArray + n_ReceiveLength + k) = bt;//rxdata[k];
            strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
			if(m_strReceiveData.GetLength() < 1024)
				m_strReceiveData += "*";//strtemp; //加入接收编辑框对应字符串 
			else
				m_strReceiveData = "";
        }
		n_ReceiveLength += len;
    }
    UpdateData(FALSE); //更新编辑框内容
}

//打开端口
void CSerialPortDlg::OnBUTTONOpenPort() 
{
	// TODO: Add your control notification handler code here
	m_ctrlComm.SetInBufferSize(1024);
	m_ctrlComm.SetOutBufferSize(1024);
	m_ctrlComm.SetCommPort(4); //选择com4

	if(m_ctrlComm.GetPortOpen())
		m_ctrlComm.SetPortOpen(FALSE);

	
	if( !m_ctrlComm.GetPortOpen())
	{
		m_ctrlComm.SetPortOpen(TRUE);//打开串口
		::AfxMessageBox("串口打开成功!");
	}
	else
		AfxMessageBox("cannot open serial port");

	m_ctrlComm.SetSettings("115200,n,8,1"); //波特率115200,无校验,8个数据位,1个停止位 

	m_ctrlComm.SetInputMode(1); //1:表示以二进制方式检取数据
	m_ctrlComm.SetRThreshold(1); 
	//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
	m_ctrlComm.SetInputLen(0); //设置当前接收区数据长度为0
	m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
}

//清空接收区
void CSerialPortDlg::OnButtonClear() 
{
	// TODO: Add your control notification handler code here
	n_ReceiveLength = 0;
	m_strReceiveData = "";
	reversed = 0;
	UpdateData(FALSE); //更新编辑框内容
	m_ctrlComm.GetInput();
}

//保存为PCM文件
void CSerialPortDlg::OnButtonSavepcm() 
{
	// TODO: Add your control notification handler code here
	if(n_ReceiveLength == 0)
	{
		::AfxMessageBox("尚未接收数据");
		return;
	}
	
	CString ss1,ss2,pcmpath;
    ss1.Format("%d",person_index);
	ss2.Format("%d",command_index);

	//为了让保存wav文件时的文件名同保存pcm文件时的文件名一致
	person_index2 = person_index;
	command_index2 = command_index;

	if(command_index==4){command_index=1;person_index++;}
	else {command_index++;}
    //command_index++;

	CString pcmName = ss1 + "_" + ss2 + ".pcm";
	LPCSTR	lpszPath = "C:\\record\\";
	SetCurrentDirectory( lpszPath );
	static char BASED_CODE szFilter[] = "PCM文件(*.pcm)|*.pcm|所有文件(*.*)|*.*||";

	CFileDialog FileDlg( FALSE, "pcm", pcmName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 szFilter );
	FileDlg.m_ofn.lpstrInitialDir = lpszPath ;

	if( FileDlg.DoModal() ==IDOK )
	{

		CString strFileName = FileDlg.GetFileName();
		CString strFileExt = FileDlg.GetFileExt();
		CString lpstrName =  FileDlg.GetPathName();

		pcmFile.Open(lpstrName, CFile::modeCreate | CFile::modeWrite, NULL);

		//MSB转LSB
		if(0 == reversed)//尚未转成LSB
		{
			for(int i=1;i<n_ReceiveLength;i+=2)
			{
				BYTE temp = *(rcvdArray+i);
				*(rcvdArray+i) = *(rcvdArray+i-1);
				*(rcvdArray+i-1) = temp;
			}
			reversed = 1;
		}

		pcmFile.Write((BYTE *)rcvdArray,n_ReceiveLength);
		pcmFile.Close();
	}



//	pcmpath="C:\\record\\pcm\\boy\\a";
//	CString pcmName = pcmpath + ss1 + "_" + ss2 + ".pcm";
//	pcmFile.Open(pcmName,CFile::modeCreate|CFile::modeWrite,NULL);

}


//保存为wav文件
void CSerialPortDlg::OnButtonSavewav() 
{
	// TODO: Add your control notification handler code here
	if(n_ReceiveLength == 0)
	{
		::AfxMessageBox("尚未接收数据");
		return ;
	}

	CString ss1,ss2,pcmpath;
    ss1.Format("%d",person_index2);
	ss2.Format("%d",command_index2);

	CString waveName = ss1 + "_" + ss2 + ".wav";
	LPCSTR	lpszPath = "C:\\record\\";
	SetCurrentDirectory( lpszPath );
	static char BASED_CODE szFilter[] = "WAVE文件(*.wav)|*.wav|所有文件(*.*)|*.*||";

	CFileDialog FileDlg( FALSE, "wav", waveName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 szFilter );
	FileDlg.m_ofn.lpstrInitialDir = lpszPath ;

	if( FileDlg.DoModal() ==IDOK )
	{
		CString strFileName = FileDlg.GetFileName();
		CString strFileExt = FileDlg.GetFileExt();
		CString lpstrName =  FileDlg.GetPathName();

		waveFile.Open(lpstrName,CFile::modeCreate|CFile::modeWrite,NULL);

		//加wav头
		char RIFF[4] = {'R','I','F','F'};
		int size = n_ReceiveLength + 36;
		char WAVE[4] = {'W','A','V','E'};
		char fmt[4] = {'f','m','t',' '};
		int size1 = 16;
		short audioFormat = 1;
		short channels = 1;
		int sampleRate = 8000;
		int byteRate = 16000;
		short blockAlign = 2;
		short bitPerSample = 16;
		char data[4] = {'d','a','t','a'};
		int size2 = n_ReceiveLength;

		char head[44];
		::memcpy(head,RIFF,4);
		::memcpy(head+4,&size,4);
		::memcpy(head+8,WAVE,4);
		::memcpy(head+12,fmt,4);
		::memcpy(head+16,&size1,4);
		::memcpy(head+20,&audioFormat,2);
		::memcpy(head+22,&channels,2);
		::memcpy(head+24,&sampleRate,4);
		::memcpy(head+28,&byteRate,4);
		::memcpy(head+32,&blockAlign,2);
		::memcpy(head+34,&bitPerSample,2);
		::memcpy(head+36,data,4);
		::memcpy(head+40,&size2,4);

		waveFile.SeekToBegin();
		waveFile.Write((char*)head,44);

		//MSB转LSB
		if(0 == reversed)//尚未转成LSB
		{
			for(int i=1;i<n_ReceiveLength;i+=2)
			{
				BYTE temp = *(rcvdArray+i);
				*(rcvdArray+i) = *(rcvdArray+i-1);
				*(rcvdArray+i-1) = temp;
			}
			reversed = 1;
		}

		waveFile.Write((char*)rcvdArray,n_ReceiveLength);
		waveFile.Close();
	}

	//清空接收数据
	n_ReceiveLength = 0;
	m_strReceiveData = "";
	reversed = 0;
	UpdateData(FALSE); //更新编辑框内容
	m_ctrlComm.GetInput();

}

//发送编辑框里的内容
void CSerialPortDlg::OnButtonManualsend() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE); //读取编辑框内容
	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

//读文件发送文件内容并显示在发送框
void CSerialPortDlg::OnButtonReadfilebtn() 
{
	// TODO: Add your control notification handler code here
	LPCSTR	lpszPath = "C:\\";
	SetCurrentDirectory( lpszPath );
	static char BASED_CODE szFilter[] = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*||";

	CFileDialog FileDlg( TRUE,  NULL,  NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		 szFilter );
	FileDlg.m_ofn.lpstrInitialDir = lpszPath ;

	if( FileDlg.DoModal() ==IDOK )
	{

		CString strFileName = FileDlg.GetFileName( );
		CString strFileExt = FileDlg.GetFileExt( );
		CString lpstrName =  FileDlg.GetPathName( );

		CFile f;
		CString str;
		f.Open(lpstrName, CFile::modeRead);
		
		int length = f.GetLength();
		TCHAR* pBuff = new TCHAR[length+1];
		f.Read(pBuff,length);
		pBuff[length] = '\0';//pBuff结束符标志

		m_strSendData = pBuff;//用于编辑框显示文本
		UpdateData(FALSE);
		f.Close();
		pBuff = NULL;
		CSerialPortDlg::OnButtonManualsend();
	}
}


//录音开始
void CSerialPortDlg::OnButtonStart() 
{
	// TODO: Add your control notification handler code here
	m_ctrlComm.SetInBufferCount(0);
	m_strSendData = "000000000000000000000000000000";//30个0
	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

//录音暂停
void CSerialPortDlg::OnButtonZanting() 
{
	// TODO: Add your control notification handler code here
	m_strSendData = "111111111111111111111111111111";//30个1
	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

//录音继续
void CSerialPortDlg::OnButtonContinue() 
{
	// TODO: Add your control notification handler code here
//	m_strSendData = "10";
//	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

//录音停止
void CSerialPortDlg::OnButtonStop() 
{
	// TODO: Add your control notification handler code here
//	m_strSendData = "11";
//	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

//FPGA重新启动
void CSerialPortDlg::OnButtonRestart() 
{
	// TODO: Add your control notification handler code here
//	m_strSendData = "111";
//	m_ctrlComm.SetOutput(COleVariant(m_strSendData));//发送数据
}

⌨️ 快捷键说明

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