哪位大侠给我上一堂AudioIO控件的使用课。100分不诚敬意。(100分)

  • 主题发起人 主题发起人 jialiang
  • 开始时间 开始时间
J

jialiang

Unregistered / Unconfirmed
GUEST, unregistred user!
就是那个由John Mertus编的,可进行底层音频编程的。
我感到这比mmtools好,就是还不会用。
请那位大侠帮助,
不要告诉我看源代码,看也看不懂。
 
http://www.banasoft.com/AVPhone.htm
 
嫌分少吗?不够可再加,
哪位列些音频编程的技术资料或网站,我也给分啊。
不能浪费啊。
 
到<a href=http://www.vclxx.org>http://www.vclxx.org</a>上面,有很多这方面的例子
和控件的...
 
Jialiang:
到我的网站看看,有音频编程的源代码

Http://person.zy.gz.cn/~bwyclq
 
你最好先熟悉一些音频编码标准,否则就像看天书。
音频函数有多种类型,如MCI、多媒体OLE控制、高级音频等,使用方法都比较简单。
如果想编写一个功能强大的音频处理程序,那就必须使用低级音频函数和多媒体文件I/O来控制音频设备的输入和输出。
因为低级音频函数可直接与音频驱动程序交互,通过窗口消息或回调(CALL BACK)函数来管理音频数据块的记录和播放,控制相当灵活。
 
AudioIO底层音频编程相关简介

waveOutGetNumDevs和waveOutGetDevCaps来获取波形输出设备的个数和能力
waveOutOpen为进行重放操作打开特定的波形设备,一般使用WAVE_MAPPER常数作为设备ID
waveOutPerpareHeader用来在波形重放之前准备好音频数据块
waveOutUnPrepareHeader用来在用完数据块之后清除对波形数据块的准备,必不可少
waveOutWrite用来发送音频数据块
waveOutPause、waveOutRestart和waveOutReset分别用来进行暂停、重新启动和停止播放
waveOutClose用来关闭波形输出设备,以便其他程序可以使用设备

记录数字音频的方法基本同播放过程,不同在于记录期间是不提供诸如暂停和重新开始这样的控制的。
使用到的函数包括:waveInGetDevCaps、waveInOpen、waveInPrepareHeader、waveInUnPrepareHeader、
waveInAddBuffer、waveInReset、waveInStart、waveInStop、waveInClose等。

另注:在使用低级音频函数播放音频时,应用程序必须不断地向设备驱动程序提供数据块,直到播放结束。
WINDOWS 98提供两种方法管理波形重放:一是使用窗口消息管理,二是使用低级回调函数管理。
 
你是说AudioIn和AudioOut的使用吧?
把分给我,我告诉你
 
Zhukewen,我怕你有骗分的动机,贴出来吧,像YB_unique一样大公无私都好啊,要不发至
我的Email:tjl2002@263.net


 
/*
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(&amp;hwavein,WAVE_MAPPER,&amp;waveformat,(UINT)waveInProc,0L,CALLBACK_FUNCTION);
if(result!= MMSYSERR_NOERROR)
{
ShowMessage("不能打开输入设备");
}
WaveInHDR.lpData=(char *)&amp;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,&amp;WaveInHDR,sizeof(WAVEHDR));
waveInAddBuffer(hwavein,&amp;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,&amp;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,&amp;WaveInHDR,sizeof(WAVEHDR));
WaveInHDR.lpData=(char *)&amp;WaveInBuffer[0];
//指向锁定的数据缓冲区的指针
WaveInHDR.dwBufferLength=Buffer_Size*4;
//数据缓冲区的大小
WaveInHDR.dwFlags=0;
waveInPrepareHeader(hwi,&amp;WaveInHDR,sizeof(WAVEHDR));
waveInAddBuffer(hwi,&amp;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(&amp;hwaveout,WAVE_MAPPER,&amp;waveformat,(UINT)waveOutProc,0L,CALLBACK_FUNCTION);
if(result!= MMSYSERR_NOERROR)
{
ShowMessage("不能打开输出设备");
}
WaveOutHDR.lpData=(char *)&amp;WaveOutBuffer[0];
//指向锁定的数据缓冲区的指针
WaveOutHDR.dwBufferLength=Buffer_Size*2;
//数据缓冲区的大小
WaveOutHDR.dwFlags=0;
//提供缓冲区信息的标志
WaveOutHDR.dwLoops=1000;
//循环播放的次数
WaveOutHDR.dwUser=0;
//用户数据
waveOutPrepareHeader(hwaveout,&amp;WaveOutHDR,sizeof(WAVEHDR));
waveOutWrite(hwaveout,&amp;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,&amp;WaveOutHDR,sizeof(WAVEHDR));
WaveOutHDR.lpData=(char *)&amp;WaveOutBuffer[0];
//指向锁定的数据缓冲区的指针
WaveOutHDR.dwBufferLength=Buffer_Size*2;
//数据缓冲区的大小
WaveOutHDR.dwFlags=0;
//提供缓冲区信息的标志
WaveOutHDR.dwLoops=1;
//循环播放的次数
WaveOutHDR.dwUser=0;
//用户数据
waveOutPrepareHeader(hwo,&amp;WaveOutHDR,sizeof(WAVEHDR));
waveOutWrite(hwo,&amp;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,&amp;WaveOutHDR,sizeof(WAVEHDR));
}
//---------------------------------------------------------------------------
 
说明,上面程序用到的p1,p2是我做的一个显示波形的控件,该程序并不是我所写,而是从某一个网站上找到的,具体网址记不清了,希望对你能有所帮助!
 
问一下,WAVEFORMATEX是包含在MMSystem.h文件中的吗?我怎么一使用就报错啊,说是未定义的标志附,我在MSDN里面看到的也是“Header File MMSystem.h”啊,怎么回事哦?
 
typedef struct {
WORD wFormatTag;

WORD nChannels;

DWORD nSamplesPerSec;

DWORD nAvgBytesPerSec;

WORD nBlockAlign;

WORD wBitsPerSample;

WORD cbSize;

} WAVEFORMATEX;
难道是自己在使用中定义的吗?不过我觉得既然在MSDN中描述过了,应该不会让用户自己在使用时定义啊。还有,经常在MSDN上看到的产量标志要使用时都必须自己在程序中定义,怎么回事哦?
 
请问比如要播放一硬盘中的WAVE文件,怎么让该文件读入内存中呢?谢谢
 
后退
顶部