//record 录音
namespace record{
/* ****************API函数声明区***************** */
::Winmm := ..raw.loadDll("Winmm.dll");
var waveInOpenA = Winmm.api("waveInOpen","INT(pointer& phwi,INT uDeviceID,struct pwfx,POINTER dwCallback,INT dwCallbackInstance,INT fdwOpen)");
var waveInGetIDA = Winmm.api("waveInGetID","INT(pointer hwi,pointer& lpuDeviceID)")
var waveInGetDevCapsA = Winmm.api("waveInGetDevCapsA","INT(INT uDeviceID,struct& pwic,INT cbwic)");
var waveInGetErrorTextA = Winmm.api("waveInGetErrorTextA","INT(INT mmrError,string &pszText,INT cchText)")
//var waveInPrepareHeader = Winmm.api("waveInPrepareHeader","INT(pointer hwi, struct& pwh,INT cbwh);");
//var waveInUnprepareHeader = Winmm.api("waveInUnprepareHeader","INT(pointer hwi, struct& pwh,INT cbwh);");
//var waveInAddBuffer = Winmm.api("waveInAddBuffer","INT(pointer hwi, struct& pwh,INT cbwh);");
/* ****************结构体定义区***************** */
class WAVEINCAPS{
WORD wMid; //驱动程序标识
WORD wPid; //产品标识
INT vDriverVersion;//驱动程序版本号
BYTE szPname[32];//制造商名称
INT dwFormats; //支持格式
WORD wChannels; //声道
WORD wReserved1; //保留参数
}
//缓存结构
class LPWAVEHDR {
pointer lpData; //指向波形数据缓冲区
INT dwBufferLength;//波形数据缓冲区的长度
INT dwBytesRecorded;//若首部用于输入, 指出缓冲区中的数据量
INT dwUser;//指定用户的32位数据
INT dwFlags;//缓冲区标志
INT dwLoops;//循环播放次数, 仅用于输出缓冲区
pointer lpNext;//保留
INT reserved; //保留
};
//采集音频的格式,结构体
class WAVEFORMATEX{
WORD wFormatTag; //声音格式为PCM
WORD nChannels; //采样声道数,1声道
INT nSamplesPerSec; //采样率,22050次/秒
INT nAvgBytesPerSec; //每秒的数据率,就是每秒能采集多少字节的数据,字节数=声道数*取样率*比特率/8
WORD nBlockAlign; //指定块对齐(每个样本的字节数), 块对齐是数据的最小单位=声道数*比特率/8
WORD wBitsPerSample; //采样位数.wFormatTag为WAVE_FORMAT_PCM时,为8或者16,采样大小(字节), 每个样本的量化位数
WORD cbSize;//wFormatTag为WAVE_FORMAT_PCM时,忽略此参数
}
/* ****************函数声明区***************** */
//返回系统中就绪的波形声音输入设备的数量
waveInGetNumDevs = function(){
return Winmm.waveInGetNumDevs();
}
//检查指定波形输入设备的特性
waveInGetDevCaps = function(uDeviceID){
return waveInGetDevCapsA(uDeviceID,WAVEINCAPS(),..raw.sizeof(WAVEINCAPS()));
}
//加入到准备的录音缓冲区中
waveInPrepareHeader = function(hWaveIn,pwh,cbwh){
..console.log("准备缓冲区...")
return Winmm.waveInPrepareHeader(hWaveIn,pwh,cbwh);
}
waveInUnprepareHeader = function(hWaveIn,pwh,cbwh){
..console.log("清空缓冲区...")
return Winmm.waveInUnprepareHeader(hWaveIn,pwh,cbwh);
}
//将缓冲区发送给设备,若缓冲区填满,则不起作用。
waveInAddBuffer = function(hWaveIn,pwh,cbwh){
..console.log("将缓冲区加入音频输入设备...")
return Winmm.waveInAddBuffer(hWaveIn,pwh,cbwh);
}
//检索由给定错误号标识的错误的文本描述。
waveInGetErrorText = function(mmrError){
//INT mmrError, 代码编号
//ustring pszText, 缓冲区
//INT cchText, 缓冲区大小 文本的长度一般不超过 MAXERRORLENGTH = 128; 如果缓冲区太小, 文本会被截断
var pszText = ..raw.buffer(128);
return waveInGetErrorTextA(mmrError,pszText,128);
}
//函数获取给定波形音频输入设备的设备标识符。
waveInGetID = function(hWaveIn,lpuDeviceID){
//hWaveIn, 待获取输入设备的句柄
//lpuDeviceID, 用于接收声音设备ID
return waveInGetIDA(hWaveIn,lpuDeviceID);
}
//打开指定的音频输入设备,进行录音
waveInOpen = function(uDeviceID,nChannels,nSamplesPerSec,wBitsPerSample){
waveFormat = WAVEFORMATEX();
waveFormat.wFormatTag = 0x1/*_WAVE_FORMAT_PCM*/;
waveFormat.nChannels = nChannels;//声道数
waveFormat.nSamplesPerSec = nSamplesPerSec;//取样率
waveFormat.wBitsPerSample = wBitsPerSample;//比特率
waveFormat.nAvgBytesPerSec = nChannels * nSamplesPerSec * wBitsPerSample / 8;//传输速率
waveFormat.nBlockAlign = nChannels * wBitsPerSample / 8;//块对齐
fun_c = ..raw.tostdcall(
function(hWaveIn,uMsg,dwInstance,dwParam1,dwParam2){
select(uMsg) {
case 958/*WIM_OPEN*/ {
..console.log("WIM_OPEN","3.>音频设备已经打开...")
}
case 960/*WIM_DATA*/ {
Param = ..raw.convert(dwParam1,LPWAVEHDRS)
..console.log(..string.format("WIM_DATA","4.>n缓冲区%d存满...",Param.dwUser ))
//waveInAddBuffer(hWaveIn,Param,32);
}
case 959/*WIM_CLOSE*/ {
..console.log("WIM_CLOSE","5.>关闭音频设备...")
waveInStop(hWaveIn);
waveInReset(hWaveIn);
}
else {
..console.log("未定义信息")
}
}
},"void(pointer hWaveIn,INT uMsg,INT dwInstance,pointer dwParam1,pointer dwParam2)"
);
return waveInOpenA(,uDeviceID,waveFormat,fun_c,0,0x30000/*_CALLBACK_FUNCTION*/);
/* 返回结果
MMSYSERR_BADDEVICEID = 2; {设备ID超界}
MMSYSERR_ALLOCATED = 4; {指定的资源已被分配}
MMSYSERR_INVALHANDLE = 5; {设备句柄无效}
MMSYSERR_NODRIVER = 6; {没有安装驱动程序}
MMSYSERR_NOMEM = 7; {不能分配或锁定内存}
MMSYSERR_HANDLEBUSY = 12; {其他线程正在使用该设备}
WAVERR_BADFORMAT = 32; {设备不支持请求的波形格式}
*/
}
//开始录音
waveInStart = function(hWaveIn){
..console.log("[操作]开始录音...")
return Winmm.waveInStart(hWaveIn);
}
//暂停录音
waveInStop = function(hWaveIn){
..console.log("[操作]录音停止...")
return Winmm.waveInStop(hWaveIn);
}
//终止输入, 位置清0; 放弃未处理的缓冲区并返回给程序
waveInReset = function(hWaveIn){
..console.log("[操作]录音重置...")
return Winmm.waveInReset(hWaveIn);
}
//停止声音输入 提示: 如果未启动则调用无效, 但也返回 0; 缓冲区会被返回, TWaveHdr 结构中的 dwBytesRecorded 将包含返回的实际数据的长度.
waveInClose = function(hWaveIn){
..console.log("[操作]关闭录音...")
return Winmm.waveInClose(hWaveIn);
}
}
/**intellisense()
_MMSYSERR_NOERROR=@0/*MMSYSERR_NOERROR*/
_MMSYSERR_ERROR=@1/*MMSYSERR_ERROR*/
_MMSYSERR_BADDEVICEID=@2/*MMSYSERR_BADDEVICEID*/
_MMSYSERR_NOTENABLED=@3/*MMSYSERR_NOTENABLED*/
_MMSYSERR_ALLOCATED=@4/*MMSYSERR_ALLOCATED*/
_MMSYSERR_INVALHANDLE=@5/*MMSYSERR_INVALHANDLE*/
_MMSYSERR_NODRIVER=@6/*MMSYSERR_NODRIVER*/
_MMSYSERR_NOMEM=@7/*MMSYSERR_NOMEM*/
_MMSYSERR_NOTSUPPORTED=@8/*MMSYSERR_NOTSUPPORTED*/
_MMSYSERR_BADERRNUM=@9/*MMSYSERR_BADERRNUM*/
_MMSYSERR_INVALFLAG=@10/*MMSYSERR_INVALFLAG*/
_MMSYSERR_INVALPARAM=@11/*MMSYSERR_INVALPARAM*/
_MMSYSERR_HANDLEBUSY=@12/*MMSYSERR_HANDLEBUSY*/
_MMSYSERR_INVALIDALIAS=@13/*MMSYSERR_INVALIDALIAS*/
_MMSYSERR_BADDB=@14/*MMSYSERR_BADDB*/
_MMSYSERR_KEYNOTFOUND=@15/*MMSYSERR_KEYNOTFOUND*/
_MMSYSERR_READERROR=@16/*MMSYSERR_READERROR*/
_MMSYSERR_WRITEERROR=@17/*MMSYSERR_WRITEERROR*/
_MMSYSERR_DELETEERROR=@18/*MMSYSERR_DELETEERROR*/
_MMSYSERR_VALNOTFOUND=@19/*MMSYSERR_VALNOTFOUND*/
_MMSYSERR_NODRIVERCB=@20/*MMSYSERR_NODRIVERCB*/
_MMSYSERR_LASTERROR=@20/*MMSYSERR_LASTERROR*/
_WAVERR_BADFORMAT=@32/*WAVERR_BADFORMAT*/
_WAVERR_STILLPLAYING=@33/*WAVERR_STILLPLAYING*/
_WAVERR_UNPREPARED=@34/*WAVERR_UNPREPARED*/
end intellisense**/