音频采样率转换处理

这篇具有很好参考价值的文章主要介绍了音频采样率转换处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、采样率转换

1、低采样率转换成高采样率

在音频处理中,插值法是一种常用的方法,用于将采样率较低的音频数据转换为采样率较高的音频数据。插值法的基本思想是,通过已知的采样点,推算出未知的采样点。常用的插值法有线性插值法、样条插值法等。
线性插值法:

线性插值法是一种简单的插值方法,它假设采样点之间的信号是线性的,通过已知的两个采样点,可以推算出它们之间的任意一个采样点。线性插值法的优点是计算简单,速度快,适用于采样率较低的情况。缺点是它只能拟合线性信号,对于非线性信号的拟合效果不佳。

输入帧大小 = 输入采样率 / 100
输出帧大小 = 输出采样率 / 100 / ( 123 / 125 )

/**
 * 将低采样率音频数据转换为高采样率音频数据
 * @param input_samples 输入采样值数组
 * @param output_samples 输出采样值数组
 * @param input_sample_rate 输入采样率
 * @param output_sample_rate 输出采样率
 * @param num_input_samples 输入采样值数量
 * @param num_output_samples 输出采样值数量
 */
void upsample(short *input_samples, short *output_samples, int input_sample_rate, int output_sample_rate, int num_input_samples, int num_output_samples) {
    // 计算输入采样率和输出采样率的比率
    float ratio = (float) output_sample_rate / input_sample_rate;
    int i, j;
    float index, frac;
    short sample1, sample2;

    // 对于每个输出采样点,计算其在输入采样点中的位置,并使用线性插值计算采样值
    for (i = 0; i < num_output_samples; i++) {
        index = i / ratio; // 计算输出采样点在输入采样点中的位置
        j = (int) index; // 计算最接近的输入采样点的索引
        frac = index - j; // 计算插值因子

        if (j < num_input_samples - 1) {
            // 如果最接近的两个输入采样点都在输入采样值数组中,则进行线性插值
            sample1 = input_samples[j];
            sample2 = input_samples[j+1];
            output_samples[i] = (1 - frac) * sample1 + frac * sample2;
        } else {
            // 如果最接近的两个输入采样点都在输入采样值数组之外,则使用最后一个输入采样点的值
            output_samples[i] = input_samples[num_input_samples-1];
        }
    }
}

样条插值法:

样条插值法是一种更加复杂的插值方法,它假设采样点之间的信号是光滑的,通过已知的多个采样点,可以推算出它们之间的任意一个采样点。样条插值法的优点是可以更好地拟合信号的曲线,从而得到更加精确的插值结果。缺点是计算复杂,速度较慢,适用于采样率较高的情况。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define M_PI 3.14159265358979323846

double cubic_spline_interp(double x, double *x_vals, double *y_vals, int n) {
    int i, j;
    double h[n], b[n], u[n], v[n], z[n], c[n], d[n], p, q, s, t, y;

    for (i = 0; i < n-1; i++) {
        h[i] = x_vals[i+1] - x_vals[i];
        b[i] = (y_vals[i+1] - y_vals[i]) / h[i];
    }

    u[1] = 2.0 * (h[0] + h[1]);
    v[1] = 6.0 * (b[1] - b[0]);

    for (i = 2; i < n-1; i++) {
        u[i] = 2.0 * (h[i-1] + h[i]) - (h[i-1] * h[i-1]) / u[i-1];
        v[i] = 6.0 * (b[i] - b[i-1]) - (h[i-1] * v[i-1]) / u[i-1];
    }

    z[n-1] = 0.0;
    c[n-1] = 0.0;

    for (i = n-2; i >= 1; i--) {
        z[i] = (v[i] - h[i] * z[i+1]) / u[i];
        c[i] = (z[i+1] - z[i]) / (3.0 * h[i]);
        d[i] = (b[i] - h[i] * (c[i] + z[i])) / h[i];
    }

    i = 0;
    j = n-1;

    while (j-i > 1) {
        int mid = (i + j) / 2;

        if (x > x_vals[mid]) {
            i = mid;
        } else {
            j = mid;
        }
    }

    p = x - x_vals[i];
    q = x_vals[i+1] - x;
    s = (p * p * p - h[i] * p * p) / (6.0 * h[i]);
    t = (q * q * q - h[i] * q * q) / (6.0 * h[i]);
    y = c[i] * s + c[i+1] * t + d[i] * p + d[i+1] * q;

    return y;
}

void resample_audio(double *audio_data, int orig_sr, int new_sr, int num_samples) {
    int i, j, num_new_samples;
    double *new_audio_data, *time_stamps, time_per_sample;

    time_per_sample = 1.0 / orig_sr;
    num_new_samples = (int) round(num_samples * (double) new_sr / (double) orig_sr);
    new_audio_data = (double *) malloc(num_new_samples * sizeof(double));
    time_stamps = (double *) malloc(num_new_samples * sizeof(double));

    for (i = 0; i < num_new_samples; i++) {
        time_stamps[i] = i * (1.0 / new_sr);
        new_audio_data[i] = 0.0;

        for (j = 0; j < num_samples-1; j++) {
            double start_time = j * time_per_sample;
            double end_time = (j+1) * time_per_sample;
            double start_val = audio_data[j];
            double end_val = audio_data[j+1];
            double time = time_stamps[i];

            if (time >= start_time && time <= end_time) {
                double x_vals[4] = { start_time, start_time + time_per_sample / 3.0, end_time - time_per_sample / 3.0, end_time };
                double y_vals[4] = { start_val, cubic_spline_interp(start_time + time_per_sample / 3.0, time_stamps, audio_data, num_samples), cubic_spline_interp(end_time - time_per_sample / 3.0, time_stamps, audio_data, num_samples), end_val };
                new_audio_data[i] = cubic_spline_interp(time, x_vals, y_vals, 4);
                break;
            }
        }
    }

    for (i = 0; i < num_new_samples; i++) {
        audio_data[i] = new_audio_data[i];
    }

    free(new_audio_data);
    free(time_stamps);
}
2、高采样率转换成低采样率

抽样(Downsampling):将高采样率的音频数据按照一定的比例进行抽样,得到低采样率的音频数据。抽样的方法包括平均值抽样、最大值抽样、最小值抽样等。

低通滤波(Low-pass filtering):通过低通滤波器将高采样率的音频数据中高于低采样率的频率部分滤掉,得到低采样率的音频数据。

重采样(Resampling):通过一定的数学算法,将高采样率的音频数据转换为低采样率的音频数据。常用的重采样算法包括线性插值、样条插值、多项式插值等。

奇偶抽取(Decimation):将高采样率的音频数据中的奇数或偶数样本抽出来,得到低采样率的音频数据。文章来源地址https://www.toymoban.com/news/detail-702854.html

到了这里,关于音频采样率转换处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FFmpeg】音视频录制 ① ( 查询系统中 ffmpeg 可录制的音视频输入设备 | 使用 ffmpeg 命令录制音视频数据 | 录制视频数据命令 |录制音频数据| 同时录制音频和视频数据命令 )

    在 Windows 系统中 , 使用 ffmpeg 命令 录制 音视频 , 需要先获取 系统的 音视频设备 信息 , 录制 音视频 本质上是从 系统音视频设备 中获取数据 ; 执行 命令 , 可以获取 系统中 ffmpeg 可用的 DirectShow 音视频输入设备 ; 命令参数解析 : -list_devices true : 列出所有 ffmpeg 的 指定类型的可

    2024年04月25日
    浏览(92)
  • qt+ffmpeg 实现音视频播放(二)之音频播放

    通过  avformat_open_input () 打开媒体文件并分配和初始化  AVFormatContext   结构体。 函数原型如下: int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options); 参数说明: - `ps`:指向 `AVFormatContext` 结构体指针的指针,用于存储打开的媒体文件的信息。

    2024年04月22日
    浏览(57)
  • 音视频 FFmpeg音视频处理流程

    推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家: 零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核) https://xxetb.xet.tech/s/VsFMs

    2024年02月12日
    浏览(69)
  • ffmpeg系列学习——FFmpeg的音视频处理

    1.音视频的采样率、采样位深度和声道数 音频和视频的采样率、采样位深度和声道数是媒体文件中的重要参数,它们会直接影响到音视频的质量和文件大小。下面对它们进行详细解释: 采样率 采样率指音频每秒钟采样的次数,用赫兹(Hz)表示。采样率越高,音频的还原度越

    2024年02月04日
    浏览(64)
  • [音视频处理] FFmpeg使用指北1-视频解码

    本文将详细介绍如何使用ffmpeg 4.4在C++中解码多种格式的媒体文件,这些媒体文件可以是视频、视频流、图片,或是桌面截屏或USB摄像头的实时图片。解码文件后,还将每帧图片转换为OpenCV的Mat格式以供后续使用。 目录 1 基于ffmpeg的媒体文件解码 1.1 简介 1.2 详细代码 2 ffmpeg函

    2024年02月07日
    浏览(67)
  • FFmpeg音视频处理工具介绍及应用

    FFmpeg项目由 Fabrice Bellard在2000年创立。到目前为止,FFmpeg项目的开发者仍然与VLC、MPV、dav1d、x264等多媒体开源项目有着广泛的重叠。Ffmpeg(FastForward Mpeg)是一款遵循GPL的开源软件,在音视频处理方面表现十分优秀,几乎囊括了现存所有的视音频格式的编码,解码、转码、混合

    2024年02月08日
    浏览(78)
  • Java工程使用ffmpeg进行音视频格式转换(ws.schild)

    JAVE (Java Audio Video Encoder)是一个纯Java的音视频编码器和解码器库,它是基于FFmpeg。JAVE库提供了一些简单易用的API,用于音频和视频格式的转换、编码、解码等操作。它对于一些基本的音视频处理任务来说是一个不错的选择。 这些库都是基于FFmpeg的,并允许在Java中处理音频和

    2024年02月14日
    浏览(98)
  • 【音视频开发】FFmpeg转换与封装 I - MP4格式

    1 FFmpeg转换与封装 1.1 MP4格式转换 1.1.1 MP4格式标准         FFmpeg支持的媒体封装格式具有多样性与全面性,与此, 我们还可以使用FFmpeg来对媒体格式进行转换与封装 。 在互联网常见的格式中,跨平台最好的应该是 MP4 文件,因为 MP4 文件既可以在PC 平台的Flashplayer中播放,

    2024年02月08日
    浏览(84)
  • JavaCV与FFmpeg:音视频流处理技巧

    1. JavaCV简介 JavaCV是一个开源的Java接口,为OpenCV、FFmpeg和其他类似工具提供了封装。它允许Java开发者直接在他们的应用程序中使用这些强大的本地库,而无需深入了解复杂的本地代码。JavaCV特别适用于处理图像和视频数据,提供了一系列的功能,如图像捕获、处理和视频编解

    2024年02月04日
    浏览(61)
  • 音视频处理 ffmpeg中级开发 H264编码

    libavcodec/avcodec.h 常用的数据结构 AVCodec 编码器结构体 AVCodecContext 编码器上下文 AVFrame 解码后的帧 结构体内存的分配和释放 av_frame_alloc 申请 av_frame_free() 释放 avcodec_alloc_context3() 创建编码器上下文 avcodec_free_context() 释放编码器上下文 解码步骤 avcodec_find_decoder 查找解码器 avcod

    2024年02月01日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包