ffmpeg代码:swr_convert 音频重采样产生噪音的原因记录

音频重采样产生噪音的原因

1. 输入原始音频采样数不足
// 当 inLen < m_avframe->nb_samples时,会产生噪音噪音
int ret = swr_convert(m_swr_ctx,
                  m_avframe->extended_data, 		// out:重采样数据存储缓存区
                  m_avframe->nb_samples,			// out:重采样样本数
                  (const uint8_t**)m_pcmPointer, 	// in:原始音频数据缓冲区
                  inLen);							// in:原始音频样本数

class Resample
{
private:
    SwrContext*         m_swr_ctx;

    int                 m_src_channels;
    int                 m_src_sample_rate;
    AVSampleFormat      m_src_sample_fmt;

    int                 m_dts_channels;
    int                 m_dts_sample_rate;
    AVSampleFormat      m_dts_sample_fmt;

public:
    Resample(int src_channels, int src_sample_rate, AVSampleFormat src_sample_fmt,
             int dts_channels, int dts_sample_rate, AVSampleFormat dts_sample_fmt);
    virtual ~Resample();

    bool init();

    // 获取重采样需要的原样本数
    int get_need_bytes();
    /**
     * 获取采样输出的样本数
     * @param srcLen  输入的原样本数
     * @return 重采样后输出的样本数
     */
    int get_out_bytes(int srcLen);

    bool resample(uint8_t** srcBuf, int& srcLen, uint8_t** dtsBuf, int& dtsLen);
};

// Resample.cpp 

#include "Resample.h"

Resample::Resample(int src_channels, int src_sample_rate, AVSampleFormat src_sample_fmt,
                   int dts_channels, int dts_sample_rate, AVSampleFormat dts_sample_fmt)
{
    m_src_channels    = src_channels;
    m_src_sample_rate = src_sample_rate;
    m_src_sample_fmt  = src_sample_fmt;
    m_dts_channels    = dts_channels;
    m_dts_sample_rate = dts_sample_rate;
    m_dts_sample_fmt  = dts_sample_fmt;

    m_swr_ctx = NULL;
}


Resample::~Resample()
{
    if ( m_swr_ctx ) {
        swr_free(&m_swr_ctx);
    }

}


bool Resample::init()
{
    m_swr_ctx = swr_alloc_set_opts(NULL,
                                   av_get_default_channel_layout(m_dts_channels), 
                                   m_dts_sample_fmt, 
                                   m_dts_sample_rate,
                                   av_get_default_channel_layout(m_src_channels), 
                                   m_src_sample_fmt, 
                                   m_src_sample_rate,
                                   0, NULL);
    if (!m_swr_ctx) {
        return false;
    }

    int ret = swr_init(m_swr_ctx);
    if (ret < 0) {
        return false;
    }

    return true;
}

int Resample::get_need_bytes()
{
    return av_get_bytes_per_sample(m_dts_sample_fmt) * m_dts_sample_rate * m_dts_channels;
}

int Resample::get_out_bytes(int srcLen)
{
    return av_rescale_rnd(swr_get_delay(m_swr_ctx, m_src_sample_rate) + srcLen, m_dts_sample_rate, srcLen, AV_ROUND_UP);
}

bool Resample::resample(uint8_t** srcBuf, int& srcLen, uint8_t** dtsBuf, int& dtsLen)
{
    //判断是否有足够的原始采样数据
    if ( srcLen < ( av_get_bytes_per_sample(m_dts_sample_fmt) * m_dts_sample_rate * m_dts_channels) ) {
        return false;
    }

    int ret = swr_convert(m_swr_ctx, dtsBuf, dtsLen, (const uint8_t**)srcBuf, srcLen);
    if (ret < 0) {
        return false;
    }
    return true;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值