ZBLOG

C++ FFmpeg 获取wav文件 分贝的最大值和最小值

要获取WAV文件中音频的最大值和最小值,你可以使用FFmpeg库来读取音频数据,并通过遍历样本点来计算分贝值。

首先,确保你已经安装了FFmpeg库并正确配置了项目。

接下来,可以按照以下步骤进行:

  1. 包含必要的头文件:
#include <iostream>
#include <cmath>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
}
  1. 初始化FFmpeg:
av_register_all();
  1. 打开WAV文件并获取音频流信息:
AVFormatContext* formatContext = nullptr;
if (avformat_open_input(&formatContext, "your_file.wav", nullptr, nullptr) != 0) {
    // 处理打开失败的情况
}

if (avformat_find_stream_info(formatContext, nullptr) < 0) {
    // 处理无法获取音频流信息的情况
}

int audioStreamIndex = -1;
for (unsigned int i = 0; i < formatContext->nb_streams; ++i) {
    if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
        audioStreamIndex = i;
        break;
    }
}

if (audioStreamIndex == -1) {
    // 处理找不到音频流的情况
}

AVCodecParameters* codecParams = formatContext->streams[audioStreamIndex]->codecpar;
  1. 查找解码器并打开解码器上下文:
AVCodec* codec = avcodec_find_decoder(codecParams->codec_id);
if (!codec) {
    // 处理找不到解码器的情况
}

AVCodecContext* codecContext = avcodec_alloc_context3(codec);
if (!codecContext) {
    // 处理解码器上下文分配失败的情况
}

if (avcodec_parameters_to_context(codecContext, codecParams) < 0) {
    // 处理解码器参数设置失败的情况
}

if (avcodec_open2(codecContext, codec, nullptr) < 0) {
    // 处理打开解码器失败的情况
}
  1. 创建音频重采样上下文:
SwrContext* swrContext = swr_alloc_set_opts(nullptr,
                                            AV_CH_LAYOUT_MONO, AV_SAMPLE_FMT_FLT, sampleRate,
                                            codecContext->channel_layout, static_cast<AVSampleFormat>(codecContext->sample_fmt), codecContext->sample_rate,
                                            0, nullptr);

if (!swrContext || swr_init(swrContext) < 0) {
    // 处理音频重采样上下文创建失败的情况
}
  1. 分配音频帧和缓冲区:
AVFrame* frame = av_frame_alloc();
if (!frame) {
    // 处理音频帧分配失败的情况
}

uint8_t** buffer = reinterpret_cast<uint8_t**>(av_mallocz_array(sizeof(uint8_t*), 1));
int bufferSize = av_samples_get_buffer_size(nullptr, 1, frame->nb_samples,
                                             static_cast<AVSampleFormat>(frame->format), 1);
*buffer = reinterpret_cast<uint8_t*>(av_malloc(bufferSize));

if (!*buffer) {
    // 处理音频缓冲区分配失败的情况
}

avcodec_fill_audio_frame(frame, 1, static_cast<AVSampleFormat>(frame->format), *buffer, bufferSize, 1);
  1. 读取音频数据并计算最大值和最小值:
int gotFrame;
AVPacket packet;
double maxDB = -INFINITY; // 最大值初始化为负无穷
double minDB = INFINITY;  // 最小值初始化为正无穷

while (av_read_frame(formatContext, &packet) >= 0) {
    if (packet.stream_index == audioStreamIndex) {
        avcodec_decode_audio4(codecContext, frame, &gotFrame, &packet);

        if (gotFrame) {
            int numSamples = frame->nb_samples;

            // 音频重采样
            uint8_t** convertedBuffer = nullptr;
            av_samples_alloc_array_and_samples(&convertedBuffer,
                                               nullptr,
                                               1,
                                               numSamples,
                                               AV_SAMPLE_FMT_FLT,
                                               0);

            swr_convert(swrContext, convertedBuffer, numSamples,
                        const_cast<const uint8_t**>(frame->extended_data), frame->nb_samples);

            // 计算最大值和最小值
            for (int i = 0; i < numSamples; ++i) {
                float sampleValue = reinterpret_cast<float*>(convertedBuffer[0])[i];
                double dBValue = 20 * std::log10(std::fabs(sampleValue));

                if (dBValue > maxDB) {
                    maxDB = dBValue;
                }

                if (dBValue < minDB) {
                    minDB = dBValue;
                }
            }

            av_freep(&convertedBuffer[0]);
            av_freep(&convertedBuffer);
        }
    }

    av_packet_unref(&packet);
}
  1. 清理资源:
av_frame_free(&frame);
avcodec_close(codecContext);
avformat_close_input(&formatContext);
swr_free(&swrContext);

if (*buffer) {
    av_freep(buffer);
}

av_free(buffer);

这样,你就可以通过遍历音频数据,计算分贝值,从而获取WAV文件中音频的最大值和最小值。请注意,上述代码仅提供了基本的框架和思路,你可能需要根据实际需求进行适当修改和完善。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=1808

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?