gpt4 book ai didi

java - android AcousticEchoCanceler 似乎不适用于大多数设备

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:15:51 29 4
gpt4 key购买 nike

我正在构建一个应用程序,它需要麦克风来消除来自扬声器的任何声音。看起来这个问题几乎是一个在线的阴谋,因为其他有完全相同问题的人在很长一段时间内都没有得到回应。

Android 的原生硬件加速 AcousticEchoCanceler 似乎无法在大多数设备上运行。在许多设备上进行的测试以及似乎可以正常工作的设备包括 Nexus 5 和 Moto X,而几乎所有测试的三星设备都无法消除背景声音。注意:所有测试的手机都为 AcousticEchoCanceler.isAvailable()

但是,必须有一个解决方案,因为 Skype 或 WhatsApp 等应用程序似乎会取消其应用程序上下文之外的声音,即扬声器正在通话,麦克风会取消收到的任何反馈。

这个简化的录音应用程序将声音录制到一个文件中,然后在单击播放时播放它。

主 Activity .java

public class MainActivity extends Activity {

Button startRec, stopRec, playBack;
int minBufferSizeIn;
AudioRecord audioRecord;
short[] audioData;
Boolean recording;
int sampleRateInHz = 48000;
private String TAG = "TAG";

/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startRec = (Button) findViewById(R.id.startrec);
stopRec = (Button) findViewById(R.id.stoprec);
playBack = (Button) findViewById(R.id.playback);

startRec.setOnClickListener(startRecOnClickListener);
stopRec.setOnClickListener(stopRecOnClickListener);
playBack.setOnClickListener(playBackOnClickListener);
playBack.setEnabled(false);
startRec.setEnabled(true);
stopRec.setEnabled(false);

minBufferSizeIn = AudioRecord.getMinBufferSize(sampleRateInHz,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);

audioData = new short[minBufferSizeIn];

audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
sampleRateInHz,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSizeIn);

}

OnClickListener startRecOnClickListener
= new OnClickListener() {

@Override
public void onClick(View arg0) {
playBack.setEnabled(false);
startRec.setEnabled(false);
stopRec.setEnabled(true);
Thread recordThread = new Thread(new Runnable() {

@Override
public void run() {
recording = true;
startRecord();
}

});

recordThread.start();

}
};


OnClickListener stopRecOnClickListener
= new OnClickListener() {

@Override
public void onClick(View arg0) {
playBack.setEnabled(true);
startRec.setEnabled(false);
stopRec.setEnabled(false);
recording = false;
}
};



OnClickListener playBackOnClickListener
= new OnClickListener() {

@Override
public void onClick(View v) {
playBack.setEnabled(false);
startRec.setEnabled(true);
stopRec.setEnabled(false);
playRecord();
}

};


@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void startRecord() {
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");

try {
FileOutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);

NoiseSuppressor ns;
AcousticEchoCanceler aec;

if (NoiseSuppressor.isAvailable()) {
ns = NoiseSuppressor.create(audioRecord.getAudioSessionId());
if (ns != null) {
ns.setEnabled(true);
} else {
Log.e(TAG, "AudioInput: NoiseSuppressor is null and not enabled");
}
}

if (AcousticEchoCanceler.isAvailable()) {
aec = AcousticEchoCanceler.create(audioRecord.getAudioSessionId());
if (aec != null) {
aec.setEnabled(true);
} else {
Log.e(TAG, "AudioInput: AcousticEchoCanceler is null and not enabled");
}
}
audioRecord.startRecording();

while (recording) {
int numberOfShort = audioRecord.read(audioData, 0, minBufferSizeIn);
for (int i = 0; i < numberOfShort; i++) {
dataOutputStream.writeShort(audioData[i]);
}
}

audioRecord.stop();
dataOutputStream.close();

} catch (IOException e) {
e.printStackTrace();
}
}

void playRecord() {
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");

int shortSizeInBytes = Short.SIZE / Byte.SIZE;

int bufferSizeInBytes = (int) (file.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];

try {
FileInputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);

int i = 0;
while (dataInputStream.available() > 0) {
audioData[i] = dataInputStream.readShort();
i++;
}

dataInputStream.close();

AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC, sampleRateInHz,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
while(audioTrack.getState() != AudioTrack.STATE_INITIALIZED){

}
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);


} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/startrec"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Start Recording Test" />
<Button
android:id="@+id/stoprec"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Stop Recording" />
<Button
android:id="@+id/playback"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Play Back" />

</LinearLayout>

AndroidManfist.xml权限

    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

要验证设备是否工作,只需在后台播放一些内容,然后单击 Start Recording 录制一个小扇区,然后单击 Stop Recording 此时单击 播放 并检查您是否听到背景声音。如果您能听到背景声音,则 AEC 没有工作。但是为什么会出现这种不一致,或者我如何实现回声消除(我已经在我的应用程序中使用 WebRTC 在我的应用程序上下文中进行噪声消除)

如有任何帮助,我们将不胜感激!

最佳答案

我在 S6 设备上遇到了同样的问题。我尝试了多种设置,发现了一组似乎启用了 AEC。我和你的设置之间的差异似乎是:

  • 16k 采样率
  • audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);

对于其他人,我不确定需要哪些设置才能让 AEC 正常工作。我知道我的同一个应用程序有

  • 48k 采样率
  • 没有 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
  • 没有 android.permission.MODIFY_AUDIO_SETTINGS

没有成功 AEC。

关于java - android AcousticEchoCanceler 似乎不适用于大多数设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35350320/

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