c++ - 使用 ffmpeg 对音频进行去量化

标签 c++ audio ffmpeg signal-processing libavcodec

我正在使用 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

我认为正在进行某种形式的量化以防止数据被数学解释。我应该怎么做才能对此进行去量化?

最佳答案

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
}

嗯...不。所以,首先,我们需要知道数据类型。检查框架->格式。这是一个enum AVSampleFormat ,最有可能是 flt、fltp、s16 或 s16p。

那么,给定的格式如何解释frame->data[]?嗯,首先,它是平面还是非平面?如果是平面的,则意味着每个 channel 都在frame->data[n]中,其中n是 channel 号。 frame->channels 是 channel 数。如果它不是平面的,则意味着所有数据都在 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]
    }
}

关于c++ - 使用 ffmpeg 对音频进行去量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37151584/

相关文章:

ffmpeg - 如何将水印添加到 rtmp 流?

c++ - 我是否必须重写一个函数才能在 QT 中工作?

ios - 如何在iOS中使用原始数据播放音频?

audio - 使用rtsp将多个音频客户端流式传输到wowza

java - 使用 mp3spi 在 jar 中播放 MP3

ffmpeg - 最好的服务器端视频处理库或软件

C++:未初始化的变量垃圾

c++ - 使用 win32/C++ 检索多个显示信息

c++ - 在 VC++ 11 中使用别名声明

ffmpeg - 在 FFmpeg 中使用 -filter_complex amerge 时混合流