Подтвердить что ты не робот

Как вы подключаете эффект реверберации к данным 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

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

4b9b3361

Ответ 1

По 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-фильтры (low-pass, high-pass, bandpass, high-shelf, low-shelf, параметрический, вырез)

Вы также можете рассмотреть 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);