Как вы прикладываете эффект реверберации к данным AudioRecord / PCM и сохраняете их в файле?

Я хочу записать вход с микрофона, приложить эффект реверберации и сохранить результат в файле. Мой прецедент – это приложение, которое позволяет вам петь песню и выбирать различные предустановленные параметры реверберации после записи, а затем сохранять свою производительность и хранить ее на сервере. Файл, который я отправляю на сервер, должен иметь эффект реверберации, примененный к нему.

До сих пор мне удалось записать вход с помощью 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() { } } 

Поэтому в идеале было бы неплохо подключить PresetReverb к AudioRecord вместо AudioTrack , но когда я получу:

 java.lang.RuntimeException: Cannot initialize effect engine for type: 47382d60-ddd8-11db-bf3a-0002a5d5c51b Error: -3 

Итак, теперь я думаю, что мне нужно AudioRecord данные PCM из AudioRecord в некоторую внешнюю службу / библиотеку или изменить буфер с помощью любого алгоритма реверберации.

Solutions Collecting From Web of "Как вы прикладываете эффект реверберации к данным AudioRecord / PCM и сохраняете их в файле?"

Согласно https://developer.android.com/reference/android/media/audiofx/PresetReverb.html

PresetReverb является вспомогательным эффектом выходного смешения и должен быть создан в сеансе аудио 0. Для того, чтобы MediaPlayer или AudioTrack были включены в этот эффект, они должны быть явно привязаны к нему, и должен быть указан уровень отправки. Используйте идентификатор эффекта, возвращаемый методом getId (), чтобы назначить этот конкретный эффект при присоединении его к MediaPlayer или AudioTrack.

Поскольку это предназначено для использования с аудиотреком, это не может быть привязано к AudioRecord. Я думаю, у вас есть аналогичный вывод.

Я предлагаю вам использовать этот SDK https://github.com/superpoweredSDK/Low-Latency-Android-Audio-iOS-Audio-Engine . Он поддерживает андроид и следующие эффекты:

Эффекты: эхо, фленджер, ворота, реверберация , ролл, whoosh, 3-полосный эквалайзер, биквад IIR-фильтры (низкочастотный, высокочастотный, полосовой, высокоуровневый, с низкой полкой, параметрический, метка)

Вы также можете рассмотреть https://github.com/ClearVolume/ClearAudio . Вы можете использовать этот файл для применения эффекта реверберации https://github.com/ClearVolume/ClearAudio/blob/master/src/java/clearaudio/synthesizer/filters/ReverbFilter.java

Всего наилучшего !


Добавляем дополнительные сведения о том, как это можно сделать с помощью superpoweredSDK. У сверхмощного 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 = 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. 

Получить исходные образцы; Если образец находится в Integer, используйте SuperpoweredShortIntToFloat для преобразования. Здесь intBuffer имеет входные аудиопоследовательности, а numberOfSamples – количество выборок. floatBuffer будет содержать буфер с плавающим преобразованием

 SuperpoweredShortIntToFloat(intBuffer, floatBuffer, numberOfSamples); 

Вызовите процесс, чтобы применить эффект реверберации. Этот метод применит эффект реверберации и снова скопирует вывод в floatBuffer

 bool res = reverb->process(floatBuffer, floatBuffer, numberOfSamples); 

Чтобы преобразовать его обратно в Int, используйте следующий метод

 SuperpoweredFloatToShortInt(floatBuffer, intBuffer, numberOfSamples); 

Затем вы можете сохранить этот ревербератор, который будет использоваться в любом месте, в любом месте, либо в файле, либо воспроизвести его


Еще несколько выводов от superpoweredSDK, он также имеет функцию записи. См. http://superpowered.com/docs/class_superpowered_recorder.html.

Пример:

 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);