我试图录制音频并检测静音以停止录制和写入文件。以下是此处已提供的代码段:Android audio capture silence detection
public class RecordAudio extends AsyncTask<Void, Double, Void> {
@Override
protected Void doInBackground(Void... arg0) {
Log.w(TAG, "doInBackground");
try {
String filename = getTempFilename();
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bufferSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
while (started) {
int bufferReadResult = audioRecord.read(buffer, 0,bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != bufferReadResult){
//check signal
//put a threshold
int foundPeak = searchThreshold(buffer,threshold);
if (foundPeak >- 1) { //found signal
//record signal
byte[] byteBuffer =ShortToByte(buffer,bufferReadResult);
try {
os.write(byteBuffer);
} catch (IOException e) {
e.printStackTrace();
}
} else {//count the time
//don't save signal
Log.d(TAG, "Silence...");
}
} else {
Toast.makeText(getBaseContext(), "Error!!!!", Toast.LENGTH_SHORT).show();
}
}
audioRecord.stop();
//close file
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
copyWaveFile(getTempFilename(),getFilename());
deleteTempFile();
} catch (Throwable t) {
t.printStackTrace();
Log.e("AudioRecord", "Recording Failed");
}
return null;
}
byte [] ShortToByte(short [] input, int elements) {
int short_index, byte_index;
int iterations = elements; //input.length;
byte [] buffer = new byte[iterations * 2];
short_index = byte_index = 0;
for(/*NOP*/; short_index != iterations; /*NOP*/)
{
buffer[byte_index] = (byte) (input[short_index] & 0x00FF);
buffer[byte_index + 1] = (byte) ((input[short_index] & 0xFF00) >> 8);
++short_index; byte_index += 2;
}
return buffer;
}
int searchThreshold(short[]arr,short thr){
int peakIndex;
int arrLen=arr.length;
for (peakIndex=0;peakIndex<arrLen;peakIndex++){
if ((arr[peakIndex]>=thr) || (arr[peakIndex]<=-thr)){
Log.d(TAG, String.valueOf(arr[peakIndex]) + " - " + String.valueOf(peakIndex));
return peakIndex;
}
}
return -1; //not found
}
问题是我无法检测信号中的静音。每当我读取缓冲区时,我得到的值大于32000或小于-32000(我将其解释为信号的最大可能幅度,因为缓冲区由短整数值组成),即使存在静音,因此阈值这决定了什么是&#34;噪音&#34;什么是总是达到沉默,而searchThreshold函数永远不会返回-1。
有没有人经历过同样的事?我正在使用Samsung S5设备进行测试。
提前致谢
答案 0 :(得分:0)
实际上,缓冲区中接近32000或-32000的值表示静音,当检测到信号时,值趋于零。所以我把searchThreshold函数中的条件反转如下,我实现了我想要的。
int searchThreshold(short[]arr,short thr_upper, short thr_lower){
int peakIndex;
int arrLen=arr.length;
for (peakIndex=0;peakIndex<arrLen;peakIndex++){
if ((arr[peakIndex] <= thr_upper) && (arr[peakIndex] >= thr_lower )){
return peakIndex;
}
}
return -1; //not found
}