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

📄 sndprodlg.cpp

📁 一个能在Windows CE下运行的G723音频压缩算法的实现,可配置
💻 CPP
字号:
// sndproDlg.cpp : implementation file
//

#include "stdafx.h"
#include "sndpro.h"
#include "sndproDlg.h"
#include <mmsystem.h>


#define SAMPLE_RATE      8000
#define OUT_BUFFER_SIZE  9600  // 20 frame
#define RCD_BUFFER_SIZE  9600  // 20 frame

HWAVEIN      hWaveRcd;
HWAVEOUT     hWaveOut;
PBYTE        pBuffer,pBufferRcd;
PWAVEHDR     pWaveHdr,pWaveHdrRcd;
WAVEFORMATEX waveformat,waveformatRcd ;
FILE         *fp_out,*fp_rcd;

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSndproDlg dialog

CSndproDlg::CSndproDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSndproDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSndproDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSndproDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSndproDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSndproDlg, CDialog)
	//{{AFX_MSG_MAP(CSndproDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_Open, OnOpen)
	ON_BN_CLICKED(IDC_Play, OnPlay)
	ON_BN_CLICKED(IDC_Close, OnClose)
	ON_BN_CLICKED(IDC_OpenRcd, OnOpenRcd)
	ON_BN_CLICKED(IDC_Record, OnRecord)
	ON_BN_CLICKED(IDC_CloseRcd, OnCloseRcd)
	ON_BN_CLICKED(IDC_Stop, OnStop)
	ON_BN_CLICKED(IDC_StopRcd, OnStopRcd)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSndproDlg message handlers

BOOL CSndproDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSndproDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CSndproDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CSndproDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CSndproDlg::OnOpen() 
{
	char msg[150];
	fp_out = fopen("f2.pcm", "rb");
	if(fp_out == NULL) MessageBox (TEXT("fopen error!"));

	// Allocate memory for headers and buffers
    pWaveHdr = (struct wavehdr_tag *)malloc (sizeof (WAVEHDR));
	pBuffer  = (unsigned char *)malloc (OUT_BUFFER_SIZE) ;
	if (!pWaveHdr || !pBuffer)
	{
		if (!pWaveHdr) free (pWaveHdr) ;
		if (!pBuffer)  free (pBuffer) ;
		MessageBeep (MB_ICONEXCLAMATION) ;
		MessageBox (TEXT ("Error allocating memory!")) ;
		return;
	}

	// Open waveform audio for output
	waveformat.wFormatTag      = WAVE_FORMAT_PCM ;
    waveformat.nChannels       = 1 ;
    waveformat.nSamplesPerSec  = SAMPLE_RATE ;
    waveformat.nAvgBytesPerSec = SAMPLE_RATE*2 ;
    waveformat.nBlockAlign     = 2 ;
    waveformat.wBitsPerSample  = 16;
    waveformat.cbSize          = 0 ;
    
	// Open wave device for output
	MMRESULT ret = waveOutOpen (&hWaveOut, WAVE_MAPPER, &waveformat,
		NULL, NULL, CALLBACK_NULL);     
    if ( ret != MMSYSERR_NOERROR )
	{
		free (pWaveHdr);
        free (pBuffer);

		waveOutGetErrorText(ret, msg, 140);
		hWaveOut = NULL;
        MessageBeep (MB_ICONEXCLAMATION);
        MessageBox (TEXT (msg));
		return;
    }

	GetDlgItem(IDC_Open)->EnableWindow(false);
	GetDlgItem(IDC_Play)->EnableWindow(true);
	GetDlgItem(IDC_Close)->EnableWindow(true);
}


void CSndproDlg::OnPlay() 
{
//	GetDlgItem(IDC_Stop)->EnableWindow(true);

	if(feof(fp_out)) fseek(fp_out,0,SEEK_SET);
	do 
	{	
		if(FillBuffer()!=0) break;
		else
		{
		    // Set up headers and prepare them
			pWaveHdr->lpData          = (char *)pBuffer ;
		    pWaveHdr->dwBufferLength  = OUT_BUFFER_SIZE ;
			pWaveHdr->dwBytesRecorded = 0 ;
			pWaveHdr->dwUser          = 0 ;
			pWaveHdr->dwFlags         = 0 ;
			pWaveHdr->dwLoops         = 1 ;
			pWaveHdr->lpNext          = NULL ;
			pWaveHdr->reserved        = 0 ;
                    
			waveOutPrepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR));
			int ret=waveOutWrite (hWaveOut, pWaveHdr, sizeof (WAVEHDR));
			Sleep(650);
//			if(ret==MMSYSERR_NOERROR)
//			{
//				while (pWaveHdr->dwFlags==0) Sleep(100);
//			}
			waveInUnprepareHeader (hWaveRcd, pWaveHdrRcd, sizeof (WAVEHDR)) ;
//			else 
//			{
//				CString sttr;
//				sttr.Format("%d",ret);
//				MessageBox(sttr);
//				break;
//			}
		}
	}while(!feof(fp_out));
}

void CSndproDlg::OnStop() 
{
    waveOutPause (hWaveOut) ;
    waveOutReset (hWaveOut) ;
}

void CSndproDlg::OnClose() 
{
	fclose(fp_out);

    waveOutReset (hWaveOut) ;
	waveOutUnprepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
    waveOutClose (hWaveOut) ;
	if(pWaveHdr) free (pWaveHdr) ;
    if(pBuffer) free (pBuffer) ;

	GetDlgItem(IDC_Open)->EnableWindow(true);
	GetDlgItem(IDC_Play)->EnableWindow(false);
	GetDlgItem(IDC_Stop)->EnableWindow(false);
	GetDlgItem(IDC_Close)->EnableWindow(false);
}


void CSndproDlg::OnOpenRcd() 
{
	char msg[150];

	fp_rcd = fopen("f2.pcm", "wb");
	if(fp_rcd == NULL) MessageBox (TEXT("fopen error!"));

	// Allocate memory for headers and buffers
    pWaveHdrRcd = (struct wavehdr_tag *)malloc (sizeof (WAVEHDR));
	pBufferRcd  = (unsigned char *)malloc (RCD_BUFFER_SIZE) ;
	if (!pWaveHdrRcd || !pBufferRcd)
	{
		if (!pWaveHdrRcd) free (pWaveHdrRcd) ;
		if (!pBufferRcd)  free (pBufferRcd) ;
		MessageBeep (MB_ICONEXCLAMATION) ;
		MessageBox (TEXT ("Error allocating memory!")) ;
		return;
	}

	// Open waveform audio for record
	waveformatRcd.wFormatTag      = WAVE_FORMAT_PCM ;
    waveformatRcd.nChannels       = 1 ;
    waveformatRcd.nSamplesPerSec  = SAMPLE_RATE ;
    waveformatRcd.nAvgBytesPerSec = SAMPLE_RATE*2 ;
    waveformatRcd.nBlockAlign     = 2 ;
    waveformatRcd.wBitsPerSample  = 16;
    waveformatRcd.cbSize          = 0 ;
    
	// Open wave device for record
	MMRESULT ret = waveInOpen (&hWaveRcd, WAVE_MAPPER, &waveformatRcd,
		NULL, NULL, CALLBACK_NULL);     
    if ( ret != MMSYSERR_NOERROR )
	{
		free (pWaveHdrRcd);
        free (pBufferRcd);

		waveInGetErrorText(ret, msg, 140);
		hWaveRcd = NULL;
        MessageBeep (MB_ICONEXCLAMATION);
        MessageBox (TEXT (msg));
		return;
    }

	GetDlgItem(IDC_OpenRcd)->EnableWindow(false);
	GetDlgItem(IDC_Record)->EnableWindow(true);
	GetDlgItem(IDC_CloseRcd)->EnableWindow(true);
	
}


void CSndproDlg::OnRecord() 
{
	int a=10;
	while(a--)
	{	
		// Set up headers and prepare them
		pWaveHdrRcd->lpData          = (char *)pBufferRcd ;
	    pWaveHdrRcd->dwBufferLength  = RCD_BUFFER_SIZE ;
		pWaveHdrRcd->dwBytesRecorded = RCD_BUFFER_SIZE ;
		pWaveHdrRcd->dwUser          = 0 ;
		pWaveHdrRcd->dwFlags         = 0 ;
		pWaveHdrRcd->dwLoops         = 1 ;
		pWaveHdrRcd->lpNext          = NULL ;
		pWaveHdrRcd->reserved        = 0 ;
                    
	    waveInPrepareHeader (hWaveRcd, pWaveHdrRcd, sizeof (WAVEHDR));
		int ret=waveInAddBuffer(hWaveRcd, pWaveHdrRcd, sizeof (WAVEHDR));
		waveInStart(hWaveRcd);
		Sleep(650);
//		if(ret==MMSYSERR_NOERROR)
//		{
//			while (pWaveHdr->dwFlags==0) Sleep(10);
//		}
		PullBuffer();
		waveInUnprepareHeader (hWaveRcd, pWaveHdrRcd, sizeof (WAVEHDR)) ;
	}
}

void CSndproDlg::OnCloseRcd() 
{
	fclose(fp_rcd);

    waveInStop (hWaveRcd) ;
	waveInUnprepareHeader (hWaveRcd, pWaveHdrRcd, sizeof (WAVEHDR)) ;
    waveInClose (hWaveRcd) ;
	if(pWaveHdrRcd) free (pWaveHdrRcd) ;
    if(pBufferRcd) free (pBufferRcd) ;

	GetDlgItem(IDC_OpenRcd)->EnableWindow(true);
	GetDlgItem(IDC_Record)->EnableWindow(false);
	GetDlgItem(IDC_CloseRcd)->EnableWindow(false);
}

void CSndproDlg::OnStopRcd() 
{
    waveInStop (hWaveRcd) ;
//  waveInReset (hWaveRcd) ;
}

int CSndproDlg::FillBuffer()
{
	int ret;
	
	memset(pBuffer,0,OUT_BUFFER_SIZE);
	ret = fread(pBuffer, sizeof(unsigned char), OUT_BUFFER_SIZE, fp_out);
	if(ret != OUT_BUFFER_SIZE) return 1;
	else return 0;
}

int CSndproDlg::PullBuffer()
{
	int ret=0;
	ret = fwrite(pBufferRcd, sizeof(unsigned char), RCD_BUFFER_SIZE, fp_rcd);
	if(ret != RCD_BUFFER_SIZE)	 return 1;
	return 0;
}


⌨️ 快捷键说明

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