Java 录音并不总是记录预期的内容
我的录音有问题 我正在开发一个应用程序,需要记录一些麦克风的脉冲响应,并用它制作一些DSP 捕获的音频存储在WAV文件中,然后从该文件打印 我创建了一个名为GrabaAudio的类,它将记录一个3秒长的wav文件 问题是我在没有明确原因的情况下获得了3秒和1,5秒的ramdonly wav文件 这是我一直都希望得到的: 波形: 但实际上,这个结果有时只是得到的,而大多数时候我得到的是: 真正奇怪的是,当我在绘图中获得预期结果时,我播放wav文件以查看实际记录的内容,我可以听到脉冲,但只持续1,5秒而不是3秒。因此,获得的样本是预期的一半 另一方面,当我获得具有重复脉冲的绘图时,样本数量是预期的,wav持续时间是3秒,但我不知道为什么脉冲出现两次 你们知道我做错了什么吗 以下是守则的相关部分:Java 录音并不总是记录预期的内容,java,android,arrays,wav,audiorecord,Java,Android,Arrays,Wav,Audiorecord,我的录音有问题 我正在开发一个应用程序,需要记录一些麦克风的脉冲响应,并用它制作一些DSP 捕获的音频存储在WAV文件中,然后从该文件打印 我创建了一个名为GrabaAudio的类,它将记录一个3秒长的wav文件 问题是我在没有明确原因的情况下获得了3秒和1,5秒的ramdonly wav文件 这是我一直都希望得到的: 波形: 但实际上,这个结果有时只是得到的,而大多数时候我得到的是: 真正奇怪的是,当我在绘图中获得预期结果时,我播放wav文件以查看实际记录的内容,我可以听到脉冲,但只持续1
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@SuppressLint("NewApi")
public class GrabaAudio {
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
public int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
public boolean isRecording = false;
public boolean triggered=false, processed=false;
int bufferTotal=0, read=0, indice=0, indice2=0;
byte[] circBuffer=new byte[8192*3];//AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
//RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING)*3
AutomaticGainControl agc;
File file= new File(getFilename());
CircularArrayList<Byte> circ= new CircularArrayList ((AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING))/2);
int circCapacity=circ.capacity();
Main main;
public GrabaAudio(){
bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING);
if (bufferSize <8192){
bufferSize=8192;
}
//boolean tiene=agc.getEnabled();
}
public void startRecording(){
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize*6);
agc = AutomaticGainControl.create(recorder.getAudioSessionId());
final boolean agc2=agc.isAvailable();
int i = recorder.getState();
if(i==1)
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
@Override
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
public void writeAudioDataToFile(){
byte data[] = new byte[6*bufferSize];
byte arrayBytes[]= new byte [3*bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(null != os){
while(isRecording){
read = recorder.read(data, 0, 6*bufferSize);
//**************************************
arrayBytes=calculateImpulseLevel(data);
if(AudioRecord.ERROR_INVALID_OPERATION != read && indice>=(bufferSize*3-3) ){
try {
os.write(arrayBytes);
processed=true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private byte[] calculateImpulseLevel(byte[] array){
double[] arraySamples=new double[array.length/2];
for (int i=0,j=0; i<=array.length-2 ;i+=2){
double sampleAmpl=(double)Math.abs((array[i+1] << 8 | array[i] & 0xff)/32767.0);
if (sampleAmpl<0.3 && !triggered){
int s=circ.size();
if (s<circCapacity){
circ.add(array[i]);
circ.add(array[i+1]);
} else {
circ.remove(0);
circ.add(array[i]);
circ.remove(0);
circ.add(array[i+1]);
}
} else{
if(!triggered){
triggered=true;
} indice=indice2+(bufferSize/2);
if (indice>3*bufferSize-2){
i=array.length;
}else{
circBuffer[indice]=array[i];
circBuffer[indice+1]=array[i+1];
indice2+=2;
arraySamples[j]=sampleAmpl;
}
}}
System.arraycopy(toByteArray(circ),0,circBuffer,0,circ.size());
return circBuffer;
}
@TargetApi(Build.VERSION\u CODES.JELLY\u BEAN)
@SuppressLint(“新API”)
公共类GrabaAudio{
专用静态最终整数记录器_BPP=16;
专用静态最终字符串音频\u记录器\u文件\u EXT\u WAV=“.WAV”;
专用静态最终字符串音频\u记录器\u文件夹=“音频记录器”;
专用静态最终字符串音频\u记录器\u TEMP\u FILE=“录制\u TEMP.raw”;
公共int记录仪\u采样器=8000;
专用静态最终整数记录器\u通道=单声道中的AudioFormat.CHANNEL\u;
专用静态最终整数记录器\u音频\u编码=AudioFormat.ENCODING\u PCM\u 16位;
专用录音机=空;
私有int bufferSize=0;
私有线程recordingThread=null;
公共布尔值isRecording=false;
公共布尔触发=false,处理=false;
int bufferTotal=0,read=0,indice=0,indice2=0;
byte[]circBuffer=新字节[8192*3];//AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
//录音机\声道、录音机\音频\编码)*3
自动增益控制;
File File=新文件(getFilename());
CircularRayList circ=新的CircularRayList((AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
录像机(u)频道,,
录音机(音频(编码))/2);
int circCapacity=circ.capacity();
主要的;
公共图书馆{
bufferSize=AudioRecord.getMinBufferSize(记录器\u采样器,
录像机(u)频道,,
录音机(音频编码);
如果(bufferSize=(bufferSize*3-3)){
试一试{
os.write(数组字节);
已处理=真;
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
试一试{
os.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
专用字节[]计算脉冲电平(字节[]数组){
double[]arraySamples=新的double[array.length/2];
对于(int i=0,j=0;i我遇到了音频记录在读取序列中返回重复数据的问题,通过更改音频记录缓冲区的大小以使其不是音频数据缓冲区大小的精确倍数来解决,例如,尝试:
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize*9);
另外,您是否确定写入总是能够跟上读取?我将插入一些日志语句来检查计时。您可能需要将读取的数据复制到内存中,然后写入另一个线程