2016-05-11 3 views
1

Я использую библиотеку FFmpeg для декодирования и (возможно) изменения некоторого звука.Демультипликация звука с помощью ffmpeg

мне удалось использовать следующие функции для перебора всех кадров аудиофайла:

avformat_open_input // Obtains formatContext 
avformat_find_stream_info 
av_find_best_stream // The argument AVMEDIA_TYPE_AUDIO is fed in to find the audio stream 
avcodec_open2 // Obtains codecContext 
av_init_packet 

// The following is used to loop through the frames 
av_read_frame 
avcodec_decode_audio4 

В конце концов, у меня есть эти три значения, доступные на каждой итерации

int dataSize; // return value of avcodec_decode_audio4 
AVFrame* frame; 
AVCodecContext* codecContext; // Codec context of the best stream 

Я должен что такая петля может использоваться для итерации по всем образцам:

for (int i = 0; i < frame->nb_samples; ++i) 
{ 
    // Bytes/Sample is known to be 4 
    // Extracts audio from Channel 1. There are in total 2 channels. 
    int* sample = (int*)frame->data[0] + dataSize * i; 
    // Now *sample is accessible 
} 

Однако, когда я построил данные с использованием gnuplot, я не получил форму волны, как ожидалось, и некоторые из значений достигли предел 32-битных целых чисел: (аудиопоток в первые несколько секунд не отключается) Plot

I предположим, что некоторая форма квантования продолжается, чтобы данные не были интерпретированы математически. Что мне делать, чтобы де-квантовать это?

+0

При типичной частоте дискретизации 44.1, 18.000 образцов составляет около 4,3 секунды, так что вы, конечно, 'не видя типичной формы волны. Попробуйте масштабирование и посмотрите, похоже ли оно в отличие от ожидаемого. – Linuxios

+0

@ Linuxios I увеличился примерно до 100 мс (4410 выборок), и график показывает некоторую периодичность, но величина не отражает объем звука, поскольку он часто достигает +/- 2147483647 –

+0

Это не обязательно так. Что-то может покрыть весь спектр 24-битного звука и все еще воспроизводиться тихо. Если вы откроете исходный файл в чем-то вроде Audacity, что вы видите, если вы посмотрите на ту же часть формы волны? – Linuxios

ответ

2
for (int i = 0; i < frame->nb_samples; ++i) 
{ 
    // Bytes/Sample is known to be 4 
    // Extracts audio from Channel 1. There are in total 2 channels. 
    int* sample = (int*)frame->data[0] + dataSize * i; 
    // Now *sample is accessible 
} 

Ну ... Нет Итак, в первую очередь, мы должны знать тип данных. Проверьте frame->format. Это enum AVSampleFormat, скорее всего, flt, fltp, s16 или s16p.

Итак, как вы интерпретируете frame->data[] с учетом формата? Ну, во-первых, это плоский или нет? Если он является плоским, это означает, что каждый канал находится в frame-> data [n], где n - номер канала. frame->channels - количество каналов. Если он не является плоским, это означает, что все данные чередуются (на выборку) в frame->data[0].

Во-вторых, какой тип хранения? Если это s16/s16p, это int16_t *. Если это flt/fltp, это float *. Таким образом, правильная интерпретация fltp будет:

for (int c = 0; c < frame->channels; c++) { 
    float *samples = frame->data[c]; 
    for (int i = 0; i < frame->nb_samples; i++) { 
     float sample = samples[i]; 
     // now this sample is accessible, it's in the range [-1.0, 1.0] 
    } 
} 

В то время как для S16, было бы:

int16_t *samples = frame->data[0]; 
for (int c = 0; c < frame->channels; c++) { 
    for (int i = 0; i < frame->nb_samples; i++) { 
     int sample = samples[i * frame->channels + c]; 
     // now this sample is accessible, it's in the range [-32768,32767] 
    } 
} 
+0

Какова амплитуда, соответствующая значениям краев? ('+/- 1.0' для с плавающей запятой и' -32768,32767' для целых чисел) –

+0

Значения краевого значения представляют собой масштаб сигнала, а амплитудой (относительно масштаба) сигнала является громкость (громкость) аудиосигнал. –

+0

Нормально ли встречаться с NaN и из связанных значений при чтении FLTP? –

Смежные вопросы