Захват аудиоданных и сохранение в необработанный файл PCM в AudioFlinger - PullRequest
6 голосов
/ 06 октября 2019

После некоторых исследований я обнаружил, что возможно захватить аудиоданные в libaudioflinger Android.

Я думаю, что аудиоданные записываются в HAL здесь:

ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);

Полный код: https://android.googlesource.com/platform/frameworks/av/+/lollipop-release/services/audioflinger/Threads.cpp#2118

Итак, я хотел бы сохранить смещение mSinkBuffer + в файл (который, как я ожидал, будет необработанным аудиофайлом PCM). Я использовал эти потоки, чтобы записать его в файл:

std::ofstream audioData ("/data/audiodata.raw", std::fstream::app);
audioData.write((char *)mSinkBuffer + offset, count);
audioData.close();

Файл успешно записан и в нем есть данные. Но когда я воспроизводил файл PCM (audiodata.raw) с помощью aplay или ffplay, единственный звук, который я получал, это шум.

aplay -t raw -c 2 -f S16_LE -r 48000 audiodata.raw

Я беспокоился о конфигурации aplay. Поэтому я распечатываю некоторые записи libaudioflinger:

10-07 10:14:54.575  1300  1366 I AudioFlinger: I/O handle: 13
10-07 10:14:54.575  1300  1366 I AudioFlinger: Standby: no
10-07 10:14:54.575  1300  1366 I AudioFlinger: Sample rate: 48000 Hz
10-07 10:14:54.575  1300  1366 I AudioFlinger: HAL frame count: 512
10-07 10:14:54.575  1300  1366 I AudioFlinger: HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
10-07 10:14:54.575  1300  1366 I AudioFlinger: HAL buffer size: 2048 bytes
10-07 10:14:54.575  1300  1366 I AudioFlinger: Channel count: 2
10-07 10:14:54.575  1300  1366 I AudioFlinger: Channel mask: 0x00000003 (front-left, front-right)
10-07 10:14:54.575  1300  1366 I AudioFlinger: Processing format: 0x5 (AUDIO_FORMAT_PCM_FLOAT)
10-07 10:14:54.576  1300  1366 I AudioFlinger: Processing frame size: 8 bytes
10-07 10:14:54.576  1300  1366 I AudioFlinger: Pending config events:
10-07 10:14:54.576  1300  1366 I AudioFlinger:  none
10-07 10:14:54.576  1300  1366 I AudioFlinger: Output device: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
10-07 10:14:54.576  1300  1366 I AudioFlinger: Input device: 0 (AUDIO_DEVICE_NONE)
10-07 10:14:54.576  1300  1366 I AudioFlinger: Audio source: 0 (default)

Я не знаю, что я сделал не так. Пожалуйста, помогите мне!

Спасибо заранее!

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Открыть файл в дополнении | двоичный режим

std :: ofstream audioData ("/data/audiodata.raw", std :: fstream :: app | std :: fstream :: binary);

двоичный - двоичный - Операции выполняются в двоичном режиме, а не в текстовом.

Буфер необработанного PCM должен записываться в двоичном режиме.

Пожалуйста, проверьтекод для разницы между байтами и счетчиком (добавлены некоторые комментарии для справки, надеюсь, это решит вашу проблему)

if (mNormalSink != 0) {

    /* Count is the number of Frames or sample written != bytes  */
    const size_t count = mBytesRemaining / mFrameSize;

    ATRACE_BEGIN("write");
    // update the setpoint when AudioFlinger::mScreenState changes
    uint32_t screenState = AudioFlinger::mScreenState;
    if (screenState != mScreenState) {
        mScreenState = screenState;
        MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
        if (pipe != NULL) {
            pipe->setAvgFrames((mScreenState & 1) ?
                    (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
        }
    }
    ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);

    ATRACE_END();
    if (framesWritten > 0) {
        bytesWritten = framesWritten * mFrameSize;
        // std::ofstream audioData ("/data/audiodata.raw", std::fstream::binary);
        /* File write or stream write is the number of bytes written to the file */
        audioData.write((char *)mSinkBuffer + offset, bytesWritten);
        // audioData.close();
    } else {
        bytesWritten = framesWritten;
    }
// otherwise use the HAL / AudioStreamOut directly
}

Audacity - Открыть необработанный файл

Файл -> Импорт-> необработанные данные

Выберите путь к необработанному файлу

В зависимости от вложенного необработанного файла.

Используйте эти настройки

Кодировка: 32-разрядное число с плавающей запятой

Порядок байтов: Little Endian

Каналы: 2 канала (стерео)

Начальное смещение: 0

Сумма для импорта: 100

Частота дискретизации: 48000

Файл воспроизводится правильно без каких-либо сбоев / шумов.

0 голосов
/ 10 октября 2019

Когда вам нужно воспроизвести ваш сырой файл, вы должны использовать формат кодека для звуковых кадров, такой как wav, mp3 и т. Д. Попробуйте передать необработанные данные в wav WAVEFORMAT, определенный в winmm, и получить аудио с устройств, которые могутоткрываться и закрываться с помощью типов WAVEFORMAT в C ++.

...