美文网首页
QT开发 音频重采样

QT开发 音频重采样

作者: 我有一只小毛驴_从来都不骑 | 来源:发表于2021-08-11 23:28 被阅读0次

44100_s16le_2
48000_f32le_2
48000_s32le_1
44100_s16le_2
相互转换

void FFmpegs::resampleAudio(const char *inFilename,
                            int inSampleRate,
                            AVSampleFormat inSampleFmt,
                            int inChLayout,

                            const char *outFilename,
                            int outSampleRate,
                            AVSampleFormat outSampleFmt,
                            int outChLayout) {

    // 文件名
    QFile inFile(inFilename);
    QFile outFile(outFilename);

    // 输入缓冲区
    // 指向缓冲区的指针
    uint8_t **inData = nullptr;
    // 缓冲区的大小
    int inLinesize = 0;
    // 声道数
    int inChs = av_get_channel_layout_nb_channels(inChLayout);
    // 一个样本的大小
    int inBytesPerSample = inChs * av_get_bytes_per_sample(inSampleFmt);
    // 缓冲区的样本数量
    int inSamples = 1024;
    // 读取文件数据的大小
    int len = 0;

    // 输出缓冲区
    // 指向缓冲区的指针
    uint8_t **outData = nullptr;
    // 缓冲区的大小
    int outLinesize = 0;
    // 声道数
    int outChs = av_get_channel_layout_nb_channels(outChLayout);
    // 一个样本的大小
    int outBytesPerSample = outChs * av_get_bytes_per_sample(outSampleFmt);
    // 缓冲区的样本数量
    int outSamples = av_rescale_rnd(outSampleRate, inSamples, inSampleRate, AV_ROUND_UP);

    qDebug() << "输入缓冲区" << inSampleRate << inSamples;
    qDebug() << "输出缓冲区" << outSampleRate << outSamples;

    // 返回结果
    int ret = 0;

    // 创建重采样上下文
    SwrContext *ctx = swr_alloc_set_opts(nullptr,
                                         // 输出参数
                                         outChLayout, outSampleFmt, outSampleRate,
                                         // 输入参数
                                         inChLayout, inSampleFmt, inSampleRate,
                                         0, nullptr);
    if (!ctx) {
        qDebug() << "swr_alloc_set_opts error";
        goto end;
    }

    // 初始化重采样上下文
    ret = swr_init(ctx);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() << "swr_init error:" << errbuf;
        goto end;
    }
    // 创建输入缓冲区
    ret = av_samples_alloc_array_and_samples(
              &inData,
              &inLinesize,
              inChs,
              inSamples,
              inSampleFmt,
              1);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() << "av_samples_alloc_array_and_samples error:" << errbuf;
        goto end;
    }

    // 创建输出缓冲区
    ret = av_samples_alloc_array_and_samples(
              &outData,
              &outLinesize,
              outChs,
              outSamples,
              outSampleFmt,
              1);
    if (ret < 0) {
        ERROR_BUF(ret);
        qDebug() << "av_samples_alloc_array_and_samples error:" << errbuf;
        goto end;
    }

    // 打开文件
    if (!inFile.open(QFile::ReadOnly)) {
        qDebug() << "file open error:" << inFilename;
        goto end;
    }
    if (!outFile.open(QFile::WriteOnly)) {
        qDebug() << "file open error:" << outFilename;
        goto end;
    }

    // 读取文件数据
    // inData[0] == *inData
    while ((len = inFile.read((char *) inData[0], inLinesize)) > 0) {
        // 读取的样本数量
        inSamples = len / inBytesPerSample;

        // 重采样(返回值转换后的样本数量)
        ret = swr_convert(ctx,
                          outData, outSamples,
                          (const uint8_t **) inData, inSamples
                         );

        if (ret < 0) {
            ERROR_BUF(ret);
            qDebug() << "swr_convert error:" << errbuf;
            goto end;
        }
   // 将转换后的数据写入到输出文件中
        // outData[0] == *outData
        outFile.write((char *) outData[0], ret * outBytesPerSample);
    }

    // 检查一下输出缓冲区是否还有残留的样本(已经重采样过的,转换过的)
    while ((ret = swr_convert(ctx,
                              outData, outSamples,
                              nullptr, 0)) > 0) {
        outFile.write((char *) outData[0], ret * outBytesPerSample);
    }

end:
    // 释放资源
    // 关闭文件
    inFile.close();
    outFile.close();

    // 释放输入缓冲区
    if (inData) {
        av_freep(&inData[0]);
    }
    av_freep(&inData);

    // 释放输出缓冲区
    if (outData) {
        av_freep(&outData[0]);
    }
    av_freep(&outData);

    // 释放重采样上下文
    swr_free(&ctx);
}

相关文章

  • QT开发 音频重采样

    44100_s16le_248000_f32le_248000_s32le_144100_s16le_2相互转换

  • FFmpeg实践记录八:【实战】音频编码---上

    请注意以下命令/事例均基于Mac环境 音频重采样 音频重采样(代码)

  • Android:使用FFmpeg对音频进行重采样

    在音频开发中,音频重采样是一个比较复杂的操作。假设有一个采样率为44100的音频,将其转换成采样率为32000的音...

  • FFmpeg音频重采样

    一、什么是音频重采样 音频重采样就是改变音频的采样率、采样格式、声道数等参数,使之按照我们期望的参数输出。比如我们...

  • 音频重采样

    什么是音频重采样 将音频三元组(采样率、采样大小、通道数)的值转换为另一组值。一旦他们三个中其中一个发生变化,就叫...

  • 音频重采样

    音频重采样的概念(Audio Resample) 将一个音频X,更改X的采样率、采样格式、声道数等参数,最终转换成...

  • 音频重采样

    定义: 将音频三元组(采样率、采样大小和通道数)的值转成另外一组值例如:将44100/16/2 转成48000/1...

  • FFmpeg - 音频重采样

    音频重采样步骤 创建采样上下文 设置输入缓冲区 设置输出缓冲区 打开文件开始重采样 检查输出缓冲区是否还有残余的样...

  • 4. 【音频编解码实战】

    音频重采样 就是将音频三元组(采样率 采样大小 通道数)的值转成另外一组值 1. 应用场景: 1、从设备采集的音频...

  • 音频重采样ffmpeg(九)

    前言 广义的音频重采样包括:1、采样格式转化:比如采样格式从16位整形变为浮点型2、采样率的转换:降采样和升采样,...

网友评论

      本文标题:QT开发 音频重采样

      本文链接:https://www.haomeiwen.com/subject/uqehbltx.html