gpt4 book ai didi

java - AudioRecord 并不总是记录预期的内容

转载 作者:行者123 更新时间:2023-12-01 12:40:43 26 4
gpt4 key购买 nike

我在使用 AudioRecord 时遇到问题。

我正在开发一个应用程序,需要记录来自 MIC 的一些脉冲响应并用它制作一些 DSP。

捕获的音频存储在 WAV 文件中,然后从该文件绘制。

我创建了一个名为 GrabaAudio 的类,预计可以录制 3 秒长的 wav 文件。

问题是我只获得 3 秒和 1,5 秒的 ramonly wav 文件,没有明确的原因。

这就是我应该始终获得的:

波形:

Image

但实际上,有时只是得到这个结果,而大多数时候这是我得到的:

Image

真正令人好奇的是,当我在情节中获得预期结果时,我播放 wav 文件以查看实际录制的内容,并且我可以听到脉冲,但只是 1,5 秒而不是3. 因此得到的样本是预期的一半。

另一方面,当我获得具有重复脉冲的图时,样本数是预期的并且 wav 持续时间是 3 秒,但我不知道为什么脉冲出现两次。

你们知道我做错了什么吗?

这是代码的相关部分:

@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;
}

最佳答案

我遇到了 AudioRecord 在读取序列中返回重复数据的问题,通过更改 AudioRecord 缓冲区的大小来解决,以便不是音频数据缓冲区大小的精确倍数,例如,尝试:

    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize*9);

此外,您确定写入始终能够跟上读取吗?我会插入一些日志语句来检查时间。您可能需要将读取的数据复制到内存中并在另一个线程中写入。

关于java - AudioRecord 并不总是记录预期的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25125890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com