Java 如何将混响效果附加到AudioRecord/PCM数据并将其保存到文件中?
我想录制麦克风的输入,附加混响效果,并将结果保存到文件中。我的使用案例是一个应用程序,它允许您在录制后唱一首歌并选择不同的预设混响选项,然后保存您的性能并将其存储在后端服务器上。我发送到服务器的文件需要应用混响效果 到目前为止,我已经能够使用Java 如何将混响效果附加到AudioRecord/PCM数据并将其保存到文件中?,java,android,pcm,android-audiorecord,Java,Android,Pcm,Android Audiorecord,我想录制麦克风的输入,附加混响效果,并将结果保存到文件中。我的使用案例是一个应用程序,它允许您在录制后唱一首歌并选择不同的预设混响选项,然后保存您的性能并将其存储在后端服务器上。我发送到服务器的文件需要应用混响效果 到目前为止,我已经能够使用AudioRecord录制输入,并且我可以在AudioTrack中添加混响效果来收听混响效果,但我一直在想如何保存嵌入混响效果的音频。以下是我目前掌握的情况: private void startRecording() { final int buf
AudioRecord
录制输入,并且我可以在AudioTrack
中添加混响效果来收听混响效果,但我一直在想如何保存嵌入混响效果的音频。以下是我目前掌握的情况:
private void startRecording() {
final int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT);
mRecorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSize);
if(NoiseSuppressor.isAvailable()) {
NoiseSuppressor ns = NoiseSuppressor.create(mRecorder.getAudioSessionId());
ns.setEnabled(true);
}
if(AcousticEchoCanceler.isAvailable()) {
AcousticEchoCanceler aec = AcousticEchoCanceler.create(mRecorder.getAudioSessionId());
aec.setEnabled(true);
}
mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, AUDIO_FORMAT, bufferSize, AudioTrack.MODE_STREAM);
PresetReverb reverb = new PresetReverb(1, mPlayer.getAudioSessionId());
reverb.setPreset(PresetReverb.PRESET_LARGEHALL);
reverb.setEnabled(true);
mPlayer.setAuxEffectSendLevel(1.f);
mRecorder.startRecording();
mPlayer.play();
new RecordingThread(mRecorder, mPlayer, bufferSize) {
@Override
public void onReleased() {
mRecorder = null;
mPlayer = null;
}
}.start();
}
public class RecordingThread extends Thread {
private static final String TAG = RecordingThread.class.getSimpleName();
private final AudioRecord mRecorder;
private final AudioTrack mPlayer;
private final int mBufferSize;
public RecordingThread(AudioRecord recorder, AudioTrack player, int bufferSize) {
mRecorder = recorder;
mPlayer = player;
mBufferSize = bufferSize;
}
@Override
public void run() {
byte[] buffer = new byte[mBufferSize];
int read;
while ((read = mRecorder.read(buffer, 0, buffer.length)) > 0) {
mPlayer.write(buffer, 0, buffer.length);
}
mRecorder.release();
mPlayer.release();
onReleased();
Timber.tag(TAG);
Timber.i("Exited with code %s", read);
}
public void onReleased() {
}
}
因此,理想情况下,最好能将预设混响
连接到录音
上,而不是音轨
,但当我这样做时,我会得到:
java.lang.RuntimeException: Cannot initialize effect engine for type: 47382d60-ddd8-11db-bf3a-0002a5d5c51b Error: -3
因此,现在我想我需要将PCM数据从录音
传输到某个外部服务/库,或者使用混响算法修改缓冲区。根据
预设混响是一种输出混音辅助效果,应在音频会话0上创建。为了让MediaPlayer或AudioTrack达到这种效果,必须将它们明确地连接到MediaPlayer或AudioTrack上,并且必须指定发送级别。将此效果附加到MediaPlayer或AudioTrack时,使用getId()方法返回的效果ID指定此特定效果
由于这是专为与audiotrack一起使用而设计的,因此不能附加到AudioRecord。我想你也有类似的结论
我建议您使用此SDK。它支持android和以下效果:
效果:回声、翻边、门、混响、rool、嗖嗖声、3波段均衡器、双四阶IIR滤波器(低通、高通、带通、高架、低架、参数化、陷波)
你也可以考虑一下。您可以使用此文件应用混响效果
祝你一切顺利
添加有关如何使用superpoweredSDK完成此操作的更多详细信息。superpowered SDK有一个名为SuperpoweredReverb的过滤器。其工作方式如下: 让我们通过一些代码来了解这一点:
reverb = new SuperpoweredReverb(samplerate);
reverb->enable(true);
reverb->setMix(floatValue); // Limited to >= 0.0f and <= 1.0f.
reverb->setRoomSize(floatValue); // Limited to >= 0.0f and <= 1.0f.
SuperpoweredShortIntToFloat(intBuffer, floatBuffer, numberOfSamples);
bool res = reverb->process(floatBuffer, floatBuffer, numberOfSamples);
SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples);
可选:将其他选项应用于此筛选器,例如
reverb->setMix(floatValue); // Limited to >= 0.0f and <= 1.0f.
reverb->setRoomSize(floatValue); // Limited to >= 0.0f and <= 1.0f.
调用过程以应用混响效果。此方法将应用混响效果并再次将输出复制到floatBuffer
bool res = reverb->process(floatBuffer, floatBuffer, numberOfSamples);
要将其转换回Int,请使用以下方法
SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples);
然后,您可以将此混响应用音频样本存储在您想要的任何位置,无论是在文件中还是播放它
superpoweredSDK还有一些发现,它还具有录制功能。看 例如:
recorder = new SuperpoweredRecorder(temporaryPath, samplerate);
recorder->start(destinationPath);
// With input samples
SuperpoweredShortIntToFloat(intBuffer, floatBuffer, numberOfSamples);
bool res = recorder->process(floatBuffer, NULL, numberOfSamples);
SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples);
谢谢你的回复。我已经尝试过Superpowered,但目前还极度缺乏教程和使用指南。所以我在尝试实现任何东西时完全迷失了方向。我的JNI经验非常有限。你能给我指出一个使用混响的超级强大的实现吗?JNI代码和android代码在repo中也可用。这个示例对于只听到混响效果很有用,但它没有显示如何保存具有效果的文件,只是显示如何在播放音频文件时应用效果,检查一下这个例子是否对你有帮助。参见SuperpoweredRecorder*recorder=新的SuperpoweredRecorder(pathTemp,44100,1);详情请浏览
SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples);
recorder = new SuperpoweredRecorder(temporaryPath, samplerate);
recorder->start(destinationPath);
// With input samples
SuperpoweredShortIntToFloat(intBuffer, floatBuffer, numberOfSamples);
bool res = recorder->process(floatBuffer, NULL, numberOfSamples);
SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples);