C语言实现16k、48kpcm数据的双向重采样

注意事项

  1. 音频重采样过程中使用有符号数,确保计算过程正确。
  2. 在48k->16k的下采样过程中,3个采样点数据相加取平均值不用担心溢出问题。已使用测试代码确认在Linux、Windows均正常。

重采样代码

/**
 * @brief Resample audio from 16kHz to 48kHz
 *
 * @param src_data pointer to src data
 * @param len length of src data
 * @param channel channel count of src data
 * @param dst_data pointer to destination data, caller shoud allocate enough
 * buffer to store
 */
static void prv_rtc_resample_16k_to_48k(const uint8_t *src_data, int len,
                                        int channel, uint8_t *dst_data) {
  const int16_t *src_data_index = (const int16_t *)src_data;
  int16_t *dst_data_index = (int16_t *)dst_data;
  const int samples = len / (channel * (sizeof(int16_t) * sizeof(uint8_t)));
  for (int i = 0; i < samples; i++) {
    for (int j = 0; j < channel; j++) {
      dst_data_index[i * 3 * channel + j * 3 + 0] =
          src_data_index[i * channel + j];
      dst_data_index[i * 3 * channel + j * 3 + 1] =
          src_data_index[i * channel + j];
      dst_data_index[i * 3 * channel + j * 3 + 2] =
          src_data_index[i * channel + j];
    }
  }
}

/**
 * @brief Resample audio from 48kHz to 16kHz
 *
 * @param src_data pointer to src data
 * @param len length of src data
 * @param channel channel count of src data
 * @param dst_data pointer to destination data, caller shoud allocate enough
 * buffer to store
 */
static void prv_rtc_resample_48k_to_16k(const uint8_t *src_data, int len,
                                        int channel, uint8_t *dst_data) {
  const int16_t *src_data_index = (const int16_t *)src_data;
  int16_t *dst_data_index = (int16_t *)dst_data;
  const int samples = len / (3 * channel * (sizeof(int16_t) * sizeof(uint8_t)));
  for (int i = 0; i < samples; i++) {
    for (int j = 0; j < channel; j++) {
      dst_data_index[i * channel + j] =
          (src_data_index[i * 3 * channel + j * 3 + 0] +
           src_data_index[i * 3 * channel + j * 3 + 1] +
           src_data_index[i * 3 * channel + j * 3 + 2]) /
          3;
    }
  }
}

int16_t数据溢出测试

代码

#include <stdio.h>
#include <stdint.h>

int main() {
	int16_t tmp1 = 0x7fff, tmp2 = 0x7fff, tmp3 = 0x7fff;
	int16_t sum1 = tmp1 + tmp2 + tmp3;
	int32_t sum2 = tmp1 + tmp2 + tmp3;

	printf("sum1: %d, sum1/3: %d, %d\n", sum1, sum1 / 3, ((tmp1 + tmp2 + tmp3) / 3));
	printf("sum1: %d, sum1/3: %d\n", sum2, sum2 / 3);

	return 0;
}

测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值