/*
wave文件格式:
waveformat.wBitsPerSample=16;
//量化位数
waveformat.wFormatTag=WAVE_FORMAT_PCM;
//采样数据格式,目前只能用PCM格式
waveformat.nChannels=2;
//通道数目(1或2)
waveformat.nSamplesPerSec=11025;
//采样速率
waveformat.nAvgBytesPerSec=11025;
//每秒采样得到的数据 nSamplesPerSec*nChannels*wBitPerSample/8
waveformat.nBlockAlign=4;
//记录区块对齐的单位。此值为nChannels*wBitsPerSample/8
8位量化 Buffer为 unsigned char *;0对应着负满幅值,128对应着零电平,255对应着正满幅值;
单声道(waveformat.nChannels=1)时,一个字节对应一次采样数据;
双声道(waveformat.nChannels=2)时,两个字节对应一次采样数据;
前一个字节为左声道采样数据;
后一个字节为右声道采样数据;
16位量化 Buffer为 shot int * -32768对应着负满幅值,0对应着零电平,32767对应着正满幅值。
单声道(waveformat.nChannels=1)时,两个字节对应一次采样数据;
双声道(waveformat.nChannels=2)时,四个字节对应一次采样数据;
前两个字节为左声道采样数据;
后两个字节为右声道采样数据;
*/
//---------------------------------------------------------------------------
#include <vcl.h>
#include <mmsystem.h>
#include <winuser.h>
#include <stdio.h>
#include <math.h>
#pragma hdrstop
#include "wavein.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "YePlot"
#pragma resource "*.dfm"
#define Buffer_Size 5000
TForm1 *Form1;
WAVEFORMATEX waveformat;
HWAVEIN hwavein;
HWAVEOUT hwaveout;
WAVEHDR WaveInHDR,WaveOutHDR;
short WaveInBuffer[Buffer_Size];
short WaveOutBuffer[Buffer_Size];
MMRESULT result;
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
void CALLBACK waveOutProc(HWAVEIN hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
BOOL Stop=false;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender) //Wave In
{
Stop=false;
waveformat.wBitsPerSample=16;
//量化位数
waveformat.wFormatTag=WAVE_FORMAT_PCM;
//采样数据格式,目前只能用PCM格式
waveformat.nChannels=2;
//通道数目(1或2)
waveformat.nSamplesPerSec=100025;
//采样速率
waveformat.nAvgBytesPerSec=100025;
//每秒采样得到的数据 nSamplesPerSec*nChannels*wBitPerSample/8
waveformat.nBlockAlign=4;
//记录区块对齐的单位。此值为nChannels*wBitsPerSample/8
result=waveInOpen(&hwavein,WAVE_MAPPER,&waveformat,(UINT)waveInProc,0L,CALLBACK_FUNCTION);
if(result!= MMSYSERR_NOERROR)
{
ShowMessage("不能打开输入设备");
}
WaveInHDR.lpData=(char *)&WaveInBuffer[0];
//指向锁定的数据缓冲区的指针
WaveInHDR.dwBufferLength=Buffer_Size*4;
//数据缓冲区的大小
WaveInHDR.dwFlags=0;
//提供缓冲区信息的标志
WaveInHDR.dwLoops=0;
//循环播放的次数
WaveInHDR.dwUser=0;
//用户数据
WaveInHDR.lpNext=0;
//reserved;
must be zero
WaveInHDR.reserved=0;
//reserved;
must be zero
waveInPrepareHeader(hwavein,&WaveInHDR,sizeof(WAVEHDR));
waveInAddBuffer(hwavein,&WaveInHDR,sizeof(WAVEHDR));
result=waveInStart(hwavein);
if(result!= MMSYSERR_NOERROR)
{
ShowMessage("不能打开输入设备");
ShowMessage(IntToStr(result));
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender) //Stop
{
Stop=true;
Sleep(50);
Timer1->Enabled=false;
result=waveInStop(hwavein);
if(result!=MMSYSERR_NOERROR)
{
ShowMessage("Stop Error.");
}
result=waveInReset(hwavein);
if(result!=MMSYSERR_NOERROR)
{
ShowMessage("Reset Error.");
}
result=waveInClose(hwavein);
if(result!=MMSYSERR_NOERROR)
{
ShowMessage("Close Error.");
ShowMessage(IntToStr(result));
}
waveInUnprepareHeader(hwavein,&WaveInHDR,sizeof(WAVEHDR));
}
//---------------------------------------------------------------------------
void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
if(uMsg!=MM_WIM_DATA||Stop==true) //等待缓冲区处理完毕,才可以调用waveInReset.
{
Form1->Timer1->Enabled=false;
return;
}
Form1->Timer1->Enabled=true;
waveInUnprepareHeader(hwi,&WaveInHDR,sizeof(WAVEHDR));
WaveInHDR.lpData=(char *)&WaveInBuffer[0];
//指向锁定的数据缓冲区的指针
WaveInHDR.dwBufferLength=Buffer_Size*4;
//数据缓冲区的大小
WaveInHDR.dwFlags=0;
waveInPrepareHeader(hwi,&WaveInHDR,sizeof(WAVEHDR));
waveInAddBuffer(hwi,&WaveInHDR,sizeof(WAVEHDR));
}
void __fastcall TForm1::Button3Click(TObject *Sender) //Wave Out
{
Timer1->Enabled=false;
Stop=false;
waveformat.wBitsPerSample=16;
//量化位数
waveformat.wFormatTag=WAVE_FORMAT_PCM;
//采样数据格式,目前只能用PCM格式
waveformat.nChannels=1;
//通道数目(1或2)
waveformat.nSamplesPerSec=11025;
//采样速率
waveformat.nAvgBytesPerSec=11025;
//每秒采样得到的数据
waveformat.nBlockAlign=2;
//记录区块对齐的单位。此值为nChannels*wBitsPerSample/8
/* init the sound Ouutput buffer with a Sine signal*/
for (int i=0;
i<1000;i++)
WaveOutBuffer=(SHORT)(10000.0*sin(i*2*3.1415926535897*5/1000));
result=waveOutOpen(&hwaveout,WAVE_MAPPER,&waveformat,(UINT)waveOutProc,0L,CALLBACK_FUNCTION);
if(result!= MMSYSERR_NOERROR)
{
ShowMessage("不能打开输出设备");
}
WaveOutHDR.lpData=(char *)&WaveOutBuffer[0];
//指向锁定的数据缓冲区的指针
WaveOutHDR.dwBufferLength=Buffer_Size*2;
//数据缓冲区的大小
WaveOutHDR.dwFlags=0;
//提供缓冲区信息的标志
WaveOutHDR.dwLoops=1000;
//循环播放的次数
WaveOutHDR.dwUser=0;
//用户数据
waveOutPrepareHeader(hwaveout,&WaveOutHDR,sizeof(WAVEHDR));
waveOutWrite(hwaveout,&WaveOutHDR,sizeof(WAVEHDR));
// waveOutRestart(hwaveout);
}
//---------------------------------------------------------------------------
void CALLBACK waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
if(uMsg!=MM_WOM_DONE||Stop==true) //等待缓冲区处理完毕,才可以调用waveOutReset.
{
return;
}
waveOutUnprepareHeader(hwo,&WaveOutHDR,sizeof(WAVEHDR));
WaveOutHDR.lpData=(char *)&WaveOutBuffer[0];
//指向锁定的数据缓冲区的指针
WaveOutHDR.dwBufferLength=Buffer_Size*2;
//数据缓冲区的大小
WaveOutHDR.dwFlags=0;
//提供缓冲区信息的标志
WaveOutHDR.dwLoops=1;
//循环播放的次数
WaveOutHDR.dwUser=0;
//用户数据
waveOutPrepareHeader(hwo,&WaveOutHDR,sizeof(WAVEHDR));
waveOutWrite(hwo,&WaveOutHDR,sizeof(WAVEHDR));
// waveOutRestart(hwo);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
p1->XAutoScale=true;
// p1->YAutoScale=true;
p2->XAutoScale=true;
// p2->YAutoScale=true;
Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
float *x=(float *)calloc(2048,sizeof(float));
float *y=(float *)calloc(2048,sizeof(float));
for (int i=0;i<2048;i++)
x=i;
int k=0;
for (int i=0;i<4096;i+=2)
{
y[k]=WaveInBuffer;
k++;
}
p1->SetChannelData(x,y,2048,"第一声道",0);
k=0;
for (int i=0;i<4096;i+=2)
{
y[k]=WaveInBuffer[i+1];
k++;
}
p2->SetChannelData(x,y,2048,"第二声道",0);
delete x;
delete y;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender) //Wave out stop.
{
Stop=true;
waveOutPause(hwaveout);
waveOutReset(hwaveout);
waveOutClose(hwaveout);
waveOutUnprepareHeader(hwaveout,&WaveOutHDR,sizeof(WAVEHDR));
}
//---------------------------------------------------------------------------