📄 wavedlg.cpp
字号:
// waveDlg.cpp : implementation file
//
#include "stdafx.h"
#include "wave.h"
#include "waveDlg.h"
#include "stdio.h"
#include <mmsystem.h>
#include <stdio.h>
#include "math.h"
//////////////////////////////////////////
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr
#define FT_FWD 1
#define FT_BACK -1
//#define EXIT_SUCCESS 1//注意需要重新定义
//#define EXIT_FAILURE -1
#define DEFAULT_LENGTH 256
#define DEFAULT_SHIFT 128
#define DEFAULT_MULTIPLE 0.950//1.0
#define DEFAULT_SMOOTHING 0.95
#ifndef PI
#define PI 3.1415926535897932384626434
#endif
#define DPI 0.31830988618379067154 /* 1.0 / PI */
#define SQRT2 1.41421356237309504880 /* sqrt(2.0) */
#define SQRTD2 0.70710678118654752440 /* sqrt(0.5) */
#define E 2.7182818284590452354 /* base of natural log */
#define LOG10E 0.43429448190325182765 /* log10(e) */
#define LN10 2.30258509299404568402 /* ln(10.0) */
#define TRUE 1
#define FALSE 0
///////////////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
long sample;
int channel;
int isPlayEnd;
static short *pSpeech;
static long nDataSize;
WAVDATATYPE DecSampleData[2048];
unsigned long totBlock;
static unsigned long num;
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()
/////////////////////////////////////////////////////////////////////////////
// CWaveDlg dialog
CWaveDlg::CWaveDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWaveDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CWaveDlg)
// 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 CWaveDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWaveDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CWaveDlg, CDialog)
//{{AFX_MSG_MAP(CWaveDlg)
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_denoise, Ondenoise)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWaveDlg message handlers
BOOL CWaveDlg::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 CWaveDlg::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 CWaveDlg::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 CWaveDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//static int ReadInWavFile(char* in_waveFile)
void GetInfo_Play( char * in_waveFile,WAVEFORMATEX* pFormat, long *sample,int *channel)
{
FILE *fp;
WAVEFORMATEX_MY wav_struct;
if ((fp = fopen(in_waveFile, "rb")) == NULL)
{
AfxMessageBox("cannot open this wavefile\n",MB_OK,0);
}
num=0;
isPlayEnd = 0;
int cc_place = 40;
long isDataChunk;
fseek(fp,36,SEEK_SET);
fread(&isDataChunk, sizeof(long), 1, fp);
/*不同的wave文件,fmt格式的长度是不同的*/
if (isDataChunk != 1635017060)
cc_place = 54;
fseek(fp,20,SEEK_SET);
/* 读取格式信息*/
fread(&wav_struct,sizeof(WAVEFORMATEX_MY),1,fp);
pFormat->wFormatTag = 1;
*channel=pFormat->nChannels = wav_struct.nChannels;
*sample=pFormat->nSamplesPerSec = wav_struct.nSamplesPerSec;
pFormat->nAvgBytesPerSec =wav_struct.nAvgBytesPerSec;
pFormat->nBlockAlign =wav_struct.nBlockAlign;
pFormat->wBitsPerSample = wav_struct.wBitsPerSample/*16*/;
pFormat->cbSize = 0;
fseek(fp, cc_place, SEEK_SET);
/*读取实际音频数据的长度*/
fread(&nDataSize, sizeof(long), 1, fp);
//nDataSize = nDataSize/(pFormat->wBitsPerSample/8);
//nDataSize = nDataSize/(pFormat->wBitsPerSample/16);
totBlock=nDataSize/1024/(*channel);
pSpeech = new short[nDataSize];
fread(pSpeech, sizeof(short), nDataSize, fp);
fclose(fp);
}
void CWaveDlg::Onopen()
{
// TODO: Add your control notification handler code here
char fileFilter[50];
CString fileTitle;
strcpy(fileFilter,"Wave Files (*.wav)|*.wav");
CFileDialog fileOpenDlg(TRUE,"wav","*.wav",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,fileFilter);
if (fileOpenDlg.DoModal() == IDOK)
{
fileNameIn = fileOpenDlg.GetPathName();
strcpy(fileFilter,fileNameIn);
fileTitle = fileOpenDlg.GetFileTitle();
m_inputEdit = fileNameIn;
GetInfo_Play(fileFilter,&pFormat,&sample,&channel);
}
}
void GetData(WAVDATATYPE * DecSampleData)
{
int ch;
int i;
num++;
if(num==totBlock)
isPlayEnd=1;
for(ch=0;ch<channel;ch++)
for(i=0;i<1024;i++)
*DecSampleData++=*pSpeech++;
}
void CWaveDlg::Onplay()
{
// TODO: Add your control notification handler code here
int j;
if(m_inputEdit.IsEmpty())
{
MessageBox("please select the input file!");
return;
}
m_inputEdit.Empty();
isFirstPlay = 1;
// isPlayEnd = 0;
GetData(DecSampleData);
if( waveOutOpen((LPHWAVEOUT)&hWaveOut,
0L,//WAVE_MAPPER,
(LPWAVEFORMATEX)&pFormat,
//NULL,
(DWORD)m_hWnd,
0L,
//WAVE_FORMAT_QUERY))
CALLBACK_WINDOW ))
isFirstPlay = 0;
playedBlockNum = 0;
//为了适应不同长度音乐的播放,playBufNum必须有不同的值
if (totBlock<50)
playBufNum = (int)(totBlock/2);
else
if (totBlock<1000)
playBufNum = 50;
else
if (totBlock<10000)
playBufNum = 100;
else
playBufNum = 150;
int curbuf=-1;
do
{
curbuf ++;
//给lpData分配内存并封锁内存
hData=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,channel*1024*sizeof(WAVDATATYPE));
if(!hData)
{
AfxMessageBox("out of memory",MB_OK,0);
break;// return 1;
}
if((lpData[curbuf]=(HPSTR)GlobalLock(hData))==NULL)
{
AfxMessageBox("Failed to lock memory for data chunk",MB_OK,0);
GlobalFree(hData);
break; //return 1;
}
GetData((WAVDATATYPE*)lpData[curbuf]);
//如果音乐长度没有缓冲区长
if (curbuf==(playBufNum-1)||isPlayEnd)
{
curbuf++;
for(j=0;j<curbuf;j++)
{
//给lpWaveHdr分配内存并封锁内存
hWaveHdr=GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE,(DWORD)sizeof(WAVEHDR));
if(hWaveHdr==NULL)
{
GlobalUnlock((HANDLE)lpData[j]);
GlobalFree((HANDLE)lpData[j]);
AfxMessageBox("Not enough memory for header",MB_OK,0);
break; //return 1;
}
lpWaveHdr[j]=(LPWAVEHDR)GlobalLock(hWaveHdr);
if(lpWaveHdr[j]==NULL)
{
GlobalUnlock((HANDLE)lpData[j]);
GlobalFree((HANDLE)lpData[j]);
GlobalFree(hWaveHdr);
AfxMessageBox("Failed to lock memory for header",MB_OK,0);
break; //return 1;
}
lpWaveHdr[j]->lpData=lpData[j];
lpWaveHdr[j]->dwBufferLength=channel*1024*sizeof(WAVDATATYPE);
lpWaveHdr[j]->dwFlags=0l;
lpWaveHdr[j]->dwLoops=0l;
waveOutPrepareHeader(hWaveOut,lpWaveHdr[j],sizeof(WAVEHDR));
wResult=waveOutWrite(hWaveOut,lpWaveHdr[j],sizeof(WAVEHDR));
if(wResult!=0)
{
waveOutUnprepareHeader(hWaveOut,lpWaveHdr[j],sizeof(WAVEHDR));
GlobalUnlock((HANDLE)lpData[j]);
GlobalFree((HANDLE)lpData[j]);
AfxMessageBox("Fail to write block to device",MB_OK,0);
break; //return 1;
}
}//for(j=;j<playBufNum
}//if block==curbuf
}while(curbuf<playBufNum);
}
LRESULT CWaveDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
LPWAVEHDR pWaveHdrOut;
//static long count=0;
static int count=0;
int buffnum=0;
switch (message)
{
case MM_WOM_DONE:
if (isPlayEnd==1)
{
waveOutReset((HWAVEOUT) wParam);
waveOutClose((HWAVEOUT)wParam);
return CDialog::WindowProc(message,wParam,lParam);
}
if (isPlayEnd==0)
{
count = 0;
pWaveHdrOut=(LPWAVEHDR)lParam;
waveOutUnprepareHeader((HWAVEOUT)wParam,
pWaveHdrOut,sizeof(WAVEHDR));
GlobalUnlock(pWaveHdrOut);
GetData((WAVDATATYPE*)(pWaveHdrOut->lpData));
waveOutPrepareHeader((HWAVEOUT)wParam,pWaveHdrOut,sizeof(WAVEHDR));
wResult=waveOutWrite((HWAVEOUT)wParam,pWaveHdrOut,sizeof(WAVEHDR));
if(wResult!=0)
{
waveOutUnprepareHeader((HWAVEOUT) wParam,
pWaveHdrOut,sizeof(WAVEHDR));
GlobalUnlock((HANDLE)(pWaveHdrOut->lpData));
GlobalFree((HANDLE)(pWaveHdrOut->lpData));
MessageBox("Fail to write block to device'wproc'");
return CDialog::WindowProc(message,wParam,lParam);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -