📄 audiocapture.java
字号:
package sunstudio.record.au.audio.capture;
import com.ms.dll.*;
import com.ms.win32.*;
import java.util.*;
import sunstudio.util.*;
public class AudioCapture{
Vector listeners=new Vector();
DllLib dlllib;
int bufferlen=10;
byte[][] data=new byte[bufferlen][1600];
int dataPtr=0;
WAVEINCAPS waveincaps;
WAVEHDR[] wavehdr;
int[] deviceid=new int[2];
boolean useful=false;
c wcb;
boolean pause=true;//默认为暂停状态
boolean isclose=false;
boolean stop=false;
String audioOutInfo="GSM.723(165b/0.1s)";
private static final int WAVE_MAPPER=-1;
private static final int MMSYSERR_NOERROR=0;
private static final int CALLBACK_FUNCTION=0x00030000;
private static final int MM_WIM_OPEN=0x3BE;
private static final int MM_WIM_DATA=0x3C0;
private static final int MM_WIM_CLOSE=0x3BF;
WAVEFORMATEX waveformatex=null;
int muteValue=2500;
public AudioCapture(){
waveformatex=new WAVEFORMATEX();//音频采集格式
waveformatex.wFormatTag=1;
waveformatex.nChannels=1;
waveformatex.wBitsPerSample=16;
waveformatex.nSamplesPerSec=8000;
waveformatex.nBlockAlign=(short)((waveformatex.nChannels*waveformatex.wBitsPerSample)/8);
waveformatex.nAvgBytesPerSec=waveformatex.nSamplesPerSec*waveformatex.nBlockAlign;
waveformatex.cbSize=0;
dlllib=new DllLib();
waveincaps=new WAVEINCAPS();
wavehdr=new WAVEHDR[bufferlen];
}
public void addAudioDataListener(AudioDataListener lter){
listeners.addElement(lter);
}
void applyBuffer(){
for(int i=0;i<bufferlen;i++){
wavehdr[i]=new WAVEHDR();
int adr=dlllib.addrOfPinnedObject(dlllib.getPinnedHandle(data[i]));
wavehdr[i].lpData=adr;
wavehdr[i].dwBufferLength=1600;
wavehdr[i].dwUser=i;
wavehdr[i].dwFlags=0;
wavehdr[i].dwLoops=0;
}
}
int chkData(byte[] a){//将整型低16位高低位交叉并转为字节
int max=0;
for(int i=0;i<800;i++){
short m=(short)(SystemTool.byteToShort(a[2*i],a[2*i+1]));
a[2*i]=(byte)(m&0xff);
a[2*i+1]=(byte)(m>>>8&0xff);
if(Math.abs(m)>Math.abs(max))max=m;
}
return max;
}
public void close(){
if(!useful)return;
isclose=true;
waveInStop(deviceid[0]);
waveInReset(deviceid[0]);
waveInClose(deviceid[0]);
}
public String getAudioOutInfo(){
return audioOutInfo;
}
public boolean isUseful(){
return useful;
}
synchronized void notifyListener(int minValue,byte[] audioData){
AudioDataEvent evt=new AudioDataEvent(minValue,audioData);
for(Enumeration enu=listeners.elements();enu.hasMoreElements();)
((AudioDataListener)enu.nextElement()).onAudioDataArrived(evt);
}
public boolean open(){
useful=openDevice();
return useful;
}
boolean openDevice(){
if(waveInGetNumDevs()<1)return false;
if(waveInGetDevCaps(WAVE_MAPPER,waveincaps,dlllib.sizeOf(waveincaps))!=MMSYSERR_NOERROR)return false;
wcb=new c(this);
int hndpro=Root.alloc(wcb);
int adrpro=dlllib.addrOf(hndpro);
if(waveInOpen(deviceid,WAVE_MAPPER,waveformatex,adrpro,0,CALLBACK_FUNCTION)!=MMSYSERR_NOERROR)return false;
applyBuffer();
for(int i=0;i<bufferlen;i++)
if(waveInPrepareHeader(deviceid[0],wavehdr[i],dlllib.sizeOf(wavehdr[i]))!=MMSYSERR_NOERROR)
return false;
if(waveInStart(deviceid[0])!=MMSYSERR_NOERROR)return false;
return true;
}
void processData(int addrHdr){
if(isclose&&stop)return;
waveInAddBuffer(deviceid[0],wavehdr[dataPtr],dlllib.sizeOf(wavehdr[dataPtr]));
dataPtr++;
dataPtr%=bufferlen;
try{
WAVEHDR tmp=(WAVEHDR)dlllib.ptrToStruct(WAVEHDR.class,addrHdr);
if(!pause){
int max=chkData(data[tmp.dwUser]);
if(Math.abs(max)<muteValue)notifyListener(0,null);
else notifyListener(max,data[tmp.dwUser]);//Codec.encode(data[tmp.dwUser]));
}
}catch(Exception ee){}
}
/////////////////////////////////////////////////////
public void suspend_record(){
pause=true;
}
public void resume_record(){
pause=false;
}
public void start_record(){
pause=false;
stop=false;
waveInAddBuffer(deviceid[0],wavehdr[dataPtr],dlllib.sizeOf(wavehdr[dataPtr]));
}
public void stop_record(){
stop=true;
pause=true;
}
/////////////////////////////////////////////////////
/* public void setFilter(double volvalue){
if(volvalue<0||volvalue>1)return;
filter=(float)volvalue;
}
*/
public void setMuteValue(int muteValue){
this.muteValue=muteValue;
}
/**@dll.import("WINMM",auto)*/
private static native int waveInGetDevCaps(int uDeviceID,WAVEINCAPS pwic,int cbwic);
/**@dll.import("WINMM",auto)*/
private static native int waveInGetNumDevs();
/**@dll.import("WINMM",auto)*/
private static native int waveInOpen(int[] phwi,int uDeviceID,WAVEFORMATEX pwfx,int dwCallback,int dwInstance,int fdwOpen);
/**@dll.import("WINMM",auto)*/
private static native int waveInAddBuffer(int hwi,WAVEHDR pwh,int cbwh);
/**@dll.import("WINMM",auto)*/
private static native int waveInStart(int hwi);
/**@dll.import("WINMM",auto)*/
private static native int waveInPrepareHeader(int hwi,WAVEHDR pwh, int cbwh);
/**@dll.import("WINMM",auto)*/
private static native int waveInStop(int hwi);
/**@dll.import("WINMM",auto)*/
private static native int waveInClose(int hwi);
/**@dll.import("WINMM",auto)*/
public static native int waveInReset(int hwi);
private class c extends Callback{
AudioCapture record;
c(AudioCapture tt){
record=tt;
}
private boolean callback(int hwi,int msg,int dwInstance,int dwParam1,int dwParam2){
switch(msg){
case AudioCapture.MM_WIM_DATA:
record.processData(dwParam1);
break;
case AudioCapture.MM_WIM_OPEN:
break;
case AudioCapture.MM_WIM_CLOSE:
}
return true;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -