pcm_Resample.c 6.2 KB
#include "AudioDeal/FF_Statement.h"
#include "pcm_Resample.h"
#include "JZsdkLib.h"
#include "../AudioDeal.h"

//pcm的重采样结构体记录组
struct pcm_Resample
{
    SwrContext *m_swr;

    int In_SampleRate; //输入音频的码率
    //unsigned int  InCHLayout;
    AVChannelLayout  InCHLayout;
    enum AVSampleFormat InFormat;

    int Out_SampleRate; //输出音频的码率
    //unsigned int  Out_CHLayout;
    AVChannelLayout  Out_CHLayout;
    enum AVSampleFormat Out_Format;
}pcm_Resample; 


//初始化重编码器
/*****************
 * 
 *  输入变量
 *  音频库结构体
 *  输入的音频采样率 输入的音频频道数, 输入的音频格式 
 * *************/
T_JZsdkReturnCode FF_Resample_Init(struct AudioDealInfo *AD_Info,
    unsigned int in_sampleRate, AVChannelLayout in_ch_layout, enum AVSampleFormat in_format) 
{
    // 尝试获取或分配ResampleInfo  
    struct pcm_Resample **ResampleInfoPtr = (struct pcm_Resample **)&AD_Info->ResampleInfo;  
    if (*ResampleInfoPtr == NULL) {  
        // 分配内存  
        *ResampleInfoPtr = (struct pcm_Resample *)malloc(sizeof(struct pcm_Resample));  
        if (*ResampleInfoPtr == NULL) {  
            // 内存分配失败处理  
            return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 使用更具体的错误码  
        }  
        (*ResampleInfoPtr)->m_swr = NULL;  
    }  

     // 现在你可以安全地使用ResampleInfo了  
    struct pcm_Resample *ResampleInfo = *ResampleInfoPtr;
  
    if (ResampleInfo->m_swr == NULL) {  
        ResampleInfo->m_swr = swr_alloc();  
        if (!ResampleInfo->m_swr) {  
            JZSDK_LOG_ERROR("Failed to allocate the resampling context");  
            return JZ_ERROR_SYSTEM_MODULE_CODE_INVALID_PARAMETER; // 或者更具体的错误码  
        }  
    }  

    ResampleInfo->In_SampleRate = in_sampleRate;
    ResampleInfo->InFormat = in_format;
    //ResampleInfo->InCHLayout = in_ch_layout;
    av_channel_layout_copy(&(ResampleInfo->InCHLayout), &in_ch_layout);
    
    ResampleInfo->Out_SampleRate = AD_Info->Target_SampleRate;
    ResampleInfo->Out_Format = AD_Info->Target_SampleFormat;
    //ResampleInfo->Out_CHLayout = AD_Info->Target_ChannelLayout;
    av_channel_layout_copy(&(ResampleInfo->Out_CHLayout), &AD_Info->Target_ChannelLayout);

    //记录当前输入的比特率
    AD_Info->Raw_SampleRate = in_sampleRate;
    AD_Info->Raw_SampleFormat = in_format;
    //AD_Info->Raw_ChannelLayout = in_ch_layout;
    av_channel_layout_copy(&(AD_Info->Raw_ChannelLayout), &in_ch_layout);

    // 设置输入参数  
    //av_opt_set_int(ResampleInfo->m_swr, "in_channel_layout", ResampleInfo->InCHLayout, 0);  
    av_opt_set_chlayout(ResampleInfo->m_swr, "in_chlayout",    &ResampleInfo->InCHLayout, 0);
    av_opt_set_sample_fmt(ResampleInfo->m_swr, "in_sample_fmt", ResampleInfo->InFormat, 0);  
    av_opt_set_int(ResampleInfo->m_swr, "in_sample_rate", ResampleInfo->In_SampleRate, 0);

    // 设置输出参数  
    //av_opt_set_int(ResampleInfo->m_swr, "out_channel_layout", ResampleInfo->Out_CHLayout, 0);  
    av_opt_set_chlayout(ResampleInfo->m_swr, "out_chlayout",    &ResampleInfo->Out_CHLayout, 0);
    av_opt_set_sample_fmt(ResampleInfo->m_swr, "out_sample_fmt", ResampleInfo->Out_Format, 0);  
    av_opt_set_int(ResampleInfo->m_swr, "out_sample_rate", ResampleInfo->Out_SampleRate, 0);  
  
    // 初始化重采样上下文  
    if (swr_init(ResampleInfo->m_swr) < 0) {  
        printf("Failed to initialize the resampling context\n");  
        swr_free(&ResampleInfo->m_swr); // 释放已分配的 SwrContext  
        ResampleInfo->m_swr = NULL;
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;  
    }  
  
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;  
}

//重置重编码器
T_JZsdkReturnCode FF_Resample_Reset(struct AudioDealInfo *AD_Info,
    unsigned int in_sampleRate, AVChannelLayout in_ch_layout, enum AVSampleFormat in_format) 
{

    int ResetFlag = JZ_FLAGCODE_OFF;

    //对比编码器新设置与当前设置是否相同
    int ret = av_channel_layout_compare(&in_ch_layout, &AD_Info->Raw_ChannelLayout);
    if (ret != 0)
    {
        ResetFlag = JZ_FLAGCODE_ON;
    }

    if (in_sampleRate != AD_Info->Raw_SampleRate)
    {
        ResetFlag = JZ_FLAGCODE_ON;
    }

    if (in_format != AD_Info->Raw_SampleFormat)
    {
        ResetFlag = JZ_FLAGCODE_ON;
    }
    
    if (ResetFlag == JZ_FLAGCODE_OFF)
    {
        return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
    }
    
    struct pcm_Resample *ResampleInfo = (struct pcm_Resample *)AD_Info->ResampleInfo;

    ret = 0;
    if(ResampleInfo->m_swr != NULL)
    {
        swr_free(&ResampleInfo->m_swr);
        ResampleInfo->m_swr = NULL;
    }

    return FF_Resample_Init(AD_Info, in_sampleRate, in_ch_layout, in_format);
}


void *FF_Resample_Send_And_Get_ResampleData(struct AudioDealInfo *AD_Info, unsigned char **src, int nb_samples, int *out_nb_samples)  
{  
    int ret = 0;  
    unsigned char *dst = NULL;  

    struct pcm_Resample *ResampleInfo = (struct pcm_Resample *)AD_Info->ResampleInfo;

    //按采样率缩放样本数量
    *out_nb_samples = av_rescale_rnd(nb_samples, ResampleInfo->Out_SampleRate, ResampleInfo->In_SampleRate, AV_ROUND_UP);  
    //printf("重采样得到的预计输出样本数量为%d\n",*out_nb_samples);

    //放置输出数据的数组
    ret = av_samples_alloc(&dst, NULL, 2, *out_nb_samples, AV_SAMPLE_FMT_S16, 0);  
    if (ret < 0) {  
        printf("[ERROR][Resample]av_samples_alloc failed\n");  
        return NULL;  
    }  

    JZSDK_LOG_INFO("原长度 *out_nb_samples:%d",*out_nb_samples);

    //重采样
    ret = swr_convert(ResampleInfo->m_swr, &dst, *out_nb_samples, (const uint8_t**)src, nb_samples);  
    if (ret < 0) {  
        printf("[ERROR][Resample]swr_convert failed\n");  
        av_freep(&dst); // 释放之前分配的内存  
        return NULL;  
    }  

    JZSDK_LOG_INFO("重采样后长度:%d", ret);

    *out_nb_samples = ret;
  
    return (void*)dst;  
}

//用于释放掉,执行重采样后得到的新数据的内存
T_JZsdkReturnCode FF_Resample_freeReasmpleData(void *dst)
{
    if (dst != NULL)
    {
        av_free(dst);
        dst = NULL;    
    }
    
    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}