Звукозапись LibSNDfile / Obeo Android неправильно пишется заголовок - PullRequest
0 голосов
/ 26 февраля 2020

Я пишу Android приложение, которое записывает звук с помощью Obeo и записывает файл волны с помощью libsndfile.

Я проверил правильность данных аудиопотока, отредактировав Subchunk2Size, который определяет размер части данных файла. В результате получается воспроизводимый аудиофайл, который сообщает мне, что данные записываются, за исключением этой единственной переменной.

Поэтому возникает вопрос: почему libsndfile не записывает переменную subchunksize (размер данных) в заголовок волны?

Wave File Header Structure

Я открываю файл как RDWR, потому что аудио необходимо добавить (когда пользователь приостанавливает или останавливает звук, он может сохранить запись в тот же файл).

Вот код открытия файла:

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

      SF_INFO info;
    info.channels = channel_count;
    info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
    info.samplerate = sample_rate;
    // info.seekable = SF_TRUE;
    SNDFILE * file = sf_open(url.c_str(), SFM_RDWR, &info);

Obeo возвращает данные с помощью обратных вызовов. Это мой обратный вызов, который вызывается всякий раз, когда аудиоустройство заполняет указанный буфер.

DataCallbackResult Recorder::onAudioReady(
    oboe::AudioStream * stream, void * audio_data, int32_t num_of_frames){

    //  __android_log_print(ANDROID_LOG_INFO,
    //                     "AudioEngine", "Callback!.");

    sf_seek(file, 0, SEEK_END);
    sf_writef_short(file, reinterpret_cast<const short*>(audio_data), num_of_frames);

    return DataCallbackResult::Continue;
}

Позже в деконструкции класса я звоню:

   sf_write_sync(file);
   sf_close(file);

Это гекс двоичные данные, написанные Libsndfile.

 52494646 08000000 
 57415645 666D7420 
 10000000 03000200
 44AC0000 20620500 
 08002000 66616374 
 04000000 00000000  (data) 64617461 (subchunksize) 00000000

Любая информация от пользователей, которые использовали libsndfile на linux или android, очень ценится!

Спасибо.

1 Ответ

0 голосов
/ 29 февраля 2020

Полагаю, вам нужно указать свойство frames для info struct, который вы используете. Это позволяет файлу точно знать, насколько большим должен быть файл, когда он выделен.

т.е.

SF_INFO info;
info.samplerate = SAMPLE_RATE ;
info.frames     = SAMPLE_COUNT ; // 44100 * 4 (4 seconds of 44.1kHz sample rate)
info.channels       = 2 ;
info.format     = (SF_FORMAT_WAV | SF_FORMAT_PCM_24) ;

Это как показано в одном из примеров libsndfile .

...