前言
最近做sensor二供料的兼容,发现,两个料的sensor sample rate不一致,会影响到算法的滤波器效果,因此需要做一下resample,借鉴了一下高通的resample方式,此篇文章做一个简单的分析
一、高通resample方式
高通resample的实现函数是在resampler/src/sns_resampler_sensor_instance_island.c
中
static sns_rc
resampler_process_sample( resampler_instance_state *state,
resampler_sample * restrict input_sample,
resampler_sample * restrict output_sample, int32_t axis_cnt)
{
sns_rc rc = SNS_RC_SUCCESS;
//allocating the required space using uint64_t (so that the start address is aligned) and typecasting to resampler_sample
uint64_t t_sample[((ALIGN_8(sizeof(resampler_sample)) + axis_cnt*sizeof(float))/sizeof(uint64_t))+1];
resampler_sample* tmp_sample=(resampler_sample*)t_sample;
tmp_sample->axis_cnt_bytes=axis_cnt * sizeof(float);
tmp_sample->data=(float*)((uint8_t*)tmp_sample + ALIGN_8(sizeof(resampler_sample)));
sns_time sample_timestamp = 0;
bool new_sample = false;
// PEND: sample sample check
resampler_cic_obj_s* cic_obj = &state->cic_obj;
resampler_interp_obj_s* int_obj = &state->interp_obj;
sample_timestamp = input_sample->ts;
switch ( state->quality )
{
case SNS_RESAMPLER_QUALITY_CURRENT_SAMPLE:
if ( state->cur_samp_obj.sampling_count == 0 )
{
// PEND: add min_acceptable_gap check
sns_memscpy(output_sample->data,output_sample->axis_cnt_bytes,
input_sample->data,input_sample->axis_cnt_bytes);
output_sample->ts = sample_timestamp;
}
state->cur_samp_obj.sampling_count++;
state->cur_samp_obj.sampling_count %= state->cur_samp_obj.sampling_factor;
//assigning input sample accuracy to output sample
output_sample->status = input_sample->status;
break;
case SNS_RESAMPLER_QUALITY_INTERPOLATED:
resampler_interp_update(int_obj, input_sample, &output_sample->status);
new_sample = resampler_interpolate(int_obj, output_sample->data, axis_cnt);
if ( new_sample )
{
output_sample->ts = int_obj->desired_timestamp;
RESAMPLER_UPDATE_INTERP_TS(int_obj);
}
break;
case SNS_RESAMPLER_QUALITY_INTERPOLATED_FILTERED:
resampler_interp_update(int_obj, input_sample, &output_sample->status);
new_sample = resampler_interpolate(int_obj, tmp_sample->data, axis_cnt);
if ( !new_sample )
{
break;
}
tmp_sample->ts = int_obj->desired_timestamp;
RESAMPLER_UPDATE_INTERP_TS(int_obj);
//Output sample has the intermediate accuracy status of the interpolation. This needs to be assigned to the tmp_sample before passing it on for filtering
tmp_sample->status = output_sample->status;
sns_memscpy(input_sample->data, input_sample->axis_cnt_bytes,
tmp_sample->data, tmp_sample->axis_cnt_bytes);
input_sample->ts = tmp_sample->ts;
input_sample->status = tmp_sample->status;
/* fallthrough */
case SNS_RESAMPLER_QUALITY_FILTERED:
resampler_cic_update(cic_obj,
input_sample,
output_sample,
axis_cnt);
break;
}
return rc;
}
可以看到,一共是分为了4种方式
SNS_RESAMPLER_QUALITY_CURRENT_SAMPLE = 0,
SNS_RESAMPLER_QUALITY_FILTERED = 1,
SNS_RESAMPLER_QUALITY_INTERPOLATED_FILTERED = 2,
SNS_RESAMPLER_QUALITY_INTERPOLATED = 3
1.1 简单抽值
SNS_RESAMPLER_QUALITY_CURRENT_SAMPLE
这是一种简单抽值的方式,适用于输入采样率和输出采样率是倍数关系,
1.2 线性插值
SNS_RESAMPLER_QUALITY_FILTERED
SNS_RESAMPLER_QUALITY_INTERPOLATED_FILTERED
两个都是线性插值,通过在相邻两个数据点之间进行线性插值来估计中间数值,
不过第二个带了滤波,会将输出的值,赋值给Input,用于下一次值的计算(没细看,猜的),
1.3 cic滤波器
积分梳状滤波器,一种比较经典的滤波器,常用于resample,以上的几种降采样方式,在高频信号中,可能会出现频谱混叠,一般都会做一个抗混叠滤波器(一般为低通滤波器,根据实际应用去选择,也可以用带通),最开始我们也是考虑的这种方式,但是会十分消耗硬件资源,因此放弃了。
因此CIC滤波器实现了一种简单的方式,可以规避这个问题。
二、结果
最终考虑到我们自己的sensor架构和硬件性能,选用了线性插值的方式做resample,