PCM16BIT-单通道重采样库libsamplrate使用

博客介绍了文件重采样和数据块重采样的方法。整个文件重采样利用一个接口实现,数据块重采样因工作需要已封装成api,并给出了完整代码。
  1. 整个文件的重采样:主要利用一个接口即可:
/*
*	参数哦说明:
*		src_sample_rate:输入源pcm的采样率
*		dst_sample_rate:需要转换后的PCM采样率
*		src_pcm_data:输入源PCM数据的地址
*		src_pcm_len:输入源PCM数据的长度
*		dst_pcm_data:转换后的PCM数据地址(这个预先要分配正确,否则会导致程序段错误)
*		dst_pcm_len:转换后的PCM数据长度
*/
bool resimple_func(int src_sample_rate,int dst_sample_rate,unsigned char* src_pcm_data,int src_pcm_len,unsigned char* dst_pcm_data,int * dst_pcm_len)
{
	bool ret = false;
	float* in = NULL;
	float* out = NULL;
	
	int in_len = src_pcm_len/2;
	in = (float*)malloc(in_len*sizeof(float));
	
	double ratio = dst_sample_rate*1.0/src_sample_rate;
	out_len = ratio * in_len;
	out = (float*)malloc(ouut_len*sizeof(float));
	/* 接口需要用到float,利用库接口转换成float型 */
	src_short_to_float_array((short*)src_pcm_data,in,in_len);
	
	SRC_DATA src_data;
	src_data.end_of_data = 0;
	src_data.input_frames = in_len;
	src_data.out_frames = out_len;
	src_data.data_in = in;
	src_data.data_out = out;
	src_data.src_ratio = ratio;
	if(src_simple(&src_data,SRC_LINEAR,1) ==0)
	{
		*dst_pcm_len = src_data.output_frames_gen*2;
		/* 将float 转换成short型 */
		src_float_to_short_array(src_data.out,(short*)dst_pcm_data,src_data.output_frames_gen);
		ret = true;
	}
	
	free(in);
	free(out);
	return ret ;
}
  1. 数据块的重采样:因为工作需要,已经将其封装成api,其完整代码如下:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <samplerate.h>
#include <unistd.h>

#include <fcntl.h>

#define SAMPLE_FRAME_MAX (4096)

/***
**   日期:2022-07-06 16:00:17
**   作者: leo.liu
**   函数作用:获取句柄
**   参数说明:
***/
static bool resamplerate_open(SRC_STATE **handle, SRC_DATA **frame)
{
	static SRC_STATE *src_state = NULL;
	static SRC_DATA src_data;
	if (src_state == NULL)
	{
		int error = -1;
		src_state = src_new(SRC_LINEAR, 1, &error);

		static float in[SAMPLE_FRAME_MAX] = {0};
		static float out[SAMPLE_FRAME_MAX] = {0};
		src_data.data_in = in;
		src_data.data_out = out;
		src_data.output_frames = SAMPLE_FRAME_MAX;
		src_data.end_of_input = 1;
	}
	*handle = src_state;
	*frame = &src_data;
	return true;
}
/***
**   日期:2022-07-06 16:00:25
**   作者: leo.liu
**   函数作用:初始化参数
**   参数说明:
***/
static bool resamplerate_init(SRC_STATE *handle_id, SRC_DATA *frame, int src_sample, int dst_sample, const char *src_pcm, int src_frames)
{
	memset((float *)frame->data_in, 0, SAMPLE_FRAME_MAX * sizeof(float));
	memset(frame->data_out, 0, SAMPLE_FRAME_MAX * sizeof(float));

	frame->input_frames = src_frames / 2;
	frame->src_ratio = dst_sample * 1.0 / src_sample;
	src_short_to_float_array((const short *)src_pcm, (float *)frame->data_in, frame->input_frames);
	return true;
}
/***
**   日期:2022-07-06 16:06:02
**   作者: leo.liu
**   函数作用:开始转换
**   参数说明:
***/
static bool resamplerate_cover(SRC_STATE *handle_id, SRC_DATA *frame, unsigned char *data, int *data_len)
{
	int ret = 0;
	src_reset(handle_id);
	if ((ret = src_process(handle_id, frame)) == 0)
	{
		*data_len = frame->output_frames_gen * 2;
		src_float_to_short_array(frame->data_out, (short *)data, frame->output_frames_gen);
		return true;
	}
	return false;
}
bool pcm_resamplerate(int src_sample, int dst_sample, const char *src_pcm, int src_frames, unsigned char *dst_pcm, int *dst_frames)
{
	SRC_STATE *handle_id;
	SRC_DATA *frame;

	resamplerate_open(&handle_id, &frame);

	resamplerate_init(handle_id, frame, src_sample, dst_sample, src_pcm, src_frames);

	resamplerate_cover(handle_id, frame, dst_pcm, dst_frames);

	return true;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值