发明内容
本发明目的在于提供一种运算量小且简单实效的音频重采样方法。
本发明的目的可以通过以下方案实现,一种音频重采样方法,步骤包括:
(A)根据采样函数生成有限冲激响应滤波器系数,并将所有有限冲激响应滤波器系数组成的系数表存储在外部存储器中;
(B)初始化参数,参数包括相位屏蔽器、滤波器长度、源样本序号、滤波器步长和样本放大序号;
(C)对输入声音样本进行预处理:根据输出的要求,将单声道输入重采样成单声道输出或重采样成双声道输出;双声道输入重采样成单声道输出或重采样成双声道输出;
(D)对预处理后的声音样本进行再处理,在向上或向下重采样过程中根据不同重采样比从外部存储空间选择并加载不同滤波器组系数组,在向上重采样时对应进行插值并用有限冲激响应波波器进行滤波处理,在向下重采样时对应进行抽取并用有限冲激响应滤波器进行滤波处理;输出重采样后的声音样本。
本发明所述的生成有限冲激响应滤波器系数表的步骤包括:
(a)初始化滤波器组标识号,设定阶数标识号为0;
(b)检测阶数标识号是否小于滤波器组数目:如果否,则结束;如果是,则进行下一步;
(c)初始化系数标识号,设定系数标识号为0;
(d)检测系数标识号是否小于滤波器阶数:如果否,则阶数标识号自动加1,并返回步骤(b);如果是,则进行下一步;
(e)根据采样函数得出FIR滤波器系数;
(f)将上一步得到的系数写入系数表,然后系数标识号自动加1,再返回步骤(d)。
本发明所述的初始化参数步骤中,如果采样方式为向上重采样,则相位屏蔽器的值限制在0~1023的范围内;源样本序号值初始化为-7~0之间;滤波器长度为8;滤波器步长根据输出采样率与输入采样率的比值来取值。
本发明所述的初始化参数步骤中,如果采样方式为向下重采样,则相位屏蔽器的值限制在0~1023的范围内;源样本序号值初始化为-7~0之间;滤波器步长根据输出采样率/输入采样率比取值;滤波器长度则视下采样比进行设置,通常设置为(8/下采样比)。
本发明所述的插值并FIR滤波处理步骤为:
(g)准备好1024个系数已经确定的FIR滤波器,以第0个滤波器作为当前滤波器,
(h)从源声音样本中取第源样本序号个样本为一个输入,与前面的7个样本组成当前滤波器的8个输入数据,
(i)进行滤波,即将8个数据输入滤波器,经过与滤波器系数的累乘加运算,获得一个输出,即为一个滤波后,也即重采样后的声音样本,
(j)样本放大序号进行累加操作,累加长度为滤波器步长;再将样本放大序号右移10位,如果移位后结果等于源样本序号,则依照滤波器步长,选择另外一个滤波器,再跳到步骤(i);否则,将移位后的值更新到到源样本序号(SAMPLEINDEX),跳到步骤(h);直到所有源声音样本已经全部处理结束。
本发明所述的抽取并FIR滤波处理步骤为:
(1)准备好1024个系数已经确定的FIR滤波器,以第0个滤波器作为当前滤波器,
(2)从源声音样本中取第源样本序号个样本为一个输入,与前面的滤波器长度减1所得数目个样本,组成当前滤波器的滤波器长度数目个输入数据,
(3)进行滤波,即将滤波器长度个数据输入滤波器,经过与滤波器系数的累乘加运算,获得一个输出,即为一个滤波后,也即重采样后的声音样本,
(4)样本放大序号进行累加操作,累加长度为滤波器步长,再将样本放大序号右移10位,将移位后的值更新到源样本序号,跳到步骤(2),直到所有源声音样本已经全部处理结束。
本发明所述的FIR滤波器系数表基于黑人-奈特窗采样函数生成为一维数组,每组大小即为滤波器阶数。
本发明所述的FIR滤波器系数表的大小由有限冲激响应滤波器阶数和重采样相位移动计数决定,重采样相位移动计数由重采样相位移动因子决定。
本发明如果是单声道处理成双声道,只需要将每个声音样本重复一次即可;如果是双声道变成单声道,取每对左右声道的数据的平均值,作为输出单声道的一个声音样本。
本发明相对现有技术优点在于:由于预先计算出了滤波器的各个参数,并组成参数表写入外部存储器如闪存(Flash)中,在算法上大大减少了计算强度。实施时,代码也相应的变得简洁,运算效率高,占用CPU资源极少,即使在ARM7的处理器下,只需要10MHz左右主频。处理后音频信号完整、频谱不丢失、不增加多余频谱,音质绝对不比原始音频音质差。不同采样频率的音频数据可以通过重采样变成相同采样率,从而可以达到混音效果。
具体实施方式
一种音频的重采样方法,首先生成FIR滤波器系数表。
滤波器组系数预先处理好,这些系数表基于黑人-奈特窗Blackman-Nuttall加窗的采样函数生成。系数表为一维数组,但实际是分组的,每组大小即滤波器阶数。例如上采样滤波器系数表,每8个数组元素为一组,代表一组8阶滤波器的系数。重采样时,获取系数并非按顺序依次从系数表中读取,而是根据重采样输出输入比,进行跳组选系数。滤波器系数预先算好了,滤波器组也就确定下来了,不需要在重采样过程中动态运算系数,增加运算量。
如图1所示,将滤波器组序号FilterbankID置零,然后检测阶数标识号是否小于滤波器组数目FilerbankCount,如果不小于,说明系数表已经完整生成,程序便自动退出。如果阶数标识号小于滤波器组数目FilerbankCount,则将系数标识号CoefID置零,检测系数标识号是否小于滤波器长度FilterLen。因为每一组的系数大小等于滤波器长度FilterLen,所以当系数标识号等于阶数时,表明完成了该组系数的计算,使阶数标识号自加1后返回到阶数标识号与滤波器组数目FilerbankCount比较的步骤。如果系数标识号小于滤波器长度,则依次计算中间系数X、Y、W,最后算出系数coef。将该系数写入系数表后系数标识号自动加1,并返回系数标识号与滤波器长度比较的步骤。循环计算出每一组中的每一个系数,直至全部计算完毕,程序退出。将计算好的系数表写入外部存储器如闪存中备用。
系数x、y、w和coef分别按下面的方法进行。M_PI为圆周率;
Factor=OutSamplrate/InSamplerate;
x=M_PI*((CoefID-FilterLen/2)-FilterID/PhaseShiftCount)*Factor;
y=sin(x)/x;
w=2.0*x/(factor*FilterLen)+M_PI;
coef=y*(0.3635-0.4891*cos(w)+0.1365*cos(2*w)-0.0106*cos(3*w));
上面算出的coef即对应的一个系数。
在向上重采样和向下重采样的滤波器系数表生成方法是一样的,只是因为阶数的不同而大小不一致。对于向上重采样,设定阶数为8,所以所有向上重采样的过程可以使用同一组系数表。而向下重采样则根据不同的采样比动态调整阶数,所以一次向下重采样对应一个系数表。
滤波器系数表的大小由滤波器阶数(FilterLen)和重采样相位移动计数(PhaseShiftCount)决定。而PhaseShiftCount由重采样相位移动因子(PhaseShiftFactor)决定,即PhaseShiftCount为1左移PhaseShiftFactor位得到。通常,PhaseShiftFactor可设置为10;为了降低运算量,对于输入采样率大于32KHz,PSF也可设置为6,并不会影响重采样效果。例如对向上采样(upsample),FIR滤波器系数表大小为8192(即FilterLen*PhaseShiftCount,其中FilterLen为8,PhaseShiftCount为1024)。
向上重采样步骤:
如图2所示,向上重采样是将每个输入声音样本输入到多个滤波器中,从而输出多个声音样本,达到插值并滤波的效果。
初始化参数,参数包括:相位屏蔽器(PHASEMASK)、滤波器长度(FILTERLEN)、源样本序号(SAMPLEINDEX)、滤波器步长(FILTERINC)和样本放大序号(SINDEX)。相位屏蔽器用于确保在启动每次滤波之前,选择的波波器组开始序号在合法的范围内;滤波器长度即每次滤波的阶数,也即有限冲激响应滤波器(FIR)的阶数,向上采样时,该值固定为8,向下采样时,为(8*输入采样率/输出采样率);源样本序号即将要被处理的声音样本在所有源样本中的排序,一般可初始化为0;滤波器步长即进行完一次滤波后,获取下一组滤波器系数的寻找步长,该值为(向上采样:输入采样率*1024/输出采样率);样本放大序号用于确认是否进行插值或抽取操作,可初始化为0,是放大了1024倍的样本序号;
初始化时,先确定PhaseMask和阶数,然后初始化Sampleindex和Filterinc等参数。通常将设为PHASEMASK=1023,即0b0011,1111,1111,用于对SAMPLEINDEX进行屏蔽操作,将其限定在0-1023范围内;向上采样情况下FilterLen=8,即预设的滤波器阶数。SAMPLEINDEX是指当前处理输入声音样本在整组输入的标号,初始化为-7到0之间。FILTERINC即进行完一次滤波后,获取下一组滤波器系数的寻找步长,该值根据输出采样率/输入采样率比取值,如输出32000HZ,输入8KHZ,则FILTERINC=FilterLen*32000/8000。
然后根据输入的声音样本的声道数和要求输出的声道数预处理样本,如单声道输入要重采样成双声道输出,必须将输入单声道处理成双声道;双声道输入,由于是左右声道交错排列,还必须处理成按左右声道顺序排列。如果是单声道处理成双声道,只需要将每个声音样本重复一次即可;如果是双声道变成单声道,取每对左右声道的数据的平均值,作为输出单声道的一个声音样本。
对预处理后的声音样本进行插值并FIR滤波。处理过程可以这样理解,预先准备好1024个系数已经确定的FIR滤波器,输入声音样本按顺序依次选择不同的滤波器进行滤波后,输出即为重采样后的声音样本;根据不同的重采样比,每个输入声音样本会输入到若干个滤波器,从而输出多个声音样本,从而达到插值并滤波的效果。
上述插值并FIR滤波的具体处理步骤为:
1)准备好1024个系数已经确定的FIR滤波器,以第0个滤波器作为当前滤波器。
2)从源声音样本中取第SAMPLEINDEX(源样本序号)个样本为一个输入,与前面的F个样本组成当前滤波器的8个输入数据。
3)进行滤波,即将8个数据输入滤波器,经过与滤波器系数的累乘加运算,获得一个输出,即为一个滤波后,也即重采样后的声音样本。
4)样本放大序号(SINDEX)进行累加操作,累加长度为滤波器步长(FILTER_INC)。再将SINDEX右移10位,如果移位后结果等于SAMPLEINDEX(源样本序号),则依照滤波器步长(FILTERINC),选择另外一个滤波器,再跳到第3)步骤;否则,将移位后的值更新到到SAMPLEINDEX(源样本序号),跑到步骤2)。直到所有源声音样本已经全部处理结束。
向下重采样步骤:
如图3所示,向下重采样是将原音频样本按比例抽取后,输入到滤波器,生成对应的输出样本。
首先确定PHASEMASK、FilterLen,并初始化SAMPLEINDEX、FILTERINC等。通常,PHASEMASK=1023,即0b 1111111111,用于对SAMPLEINDEX进行屏蔽操作,将其限定在0-1023范围内;向下采样情况下FilterLen=8/下采样比,如48KHZ重采样成24KHZ,则FilterLen=16。SAMPLEINDEX是指当前处理输入声音样本在整组输入的标号,初始化为-7到0之间。FILTERINC即进行完一次滤波后,获取下一组滤波器系数的寻找步长,该值可根据输出采样率/输入采样率比取值,如输出32000HZ,输入8KHZ,则FILTERINC=FilterLen*32000/8000。
然后对输入声音样本预处理,如单声道输入要重采样成双声道输出,必须将输入单声道处理成双声道;双声道输入,由于是左右声道交错排列,还必须处理成按左右声道顺序排列。如果是单声道处理成双声道,只需要将每个声音样本重复一次即可;如果是双声道变成单声道,取每对左右声道的数据的平均值,作为输出单声道的一个声音样本。
最后对预处理后的声音样本进行抽取并FIR滤波。处理过程可以这样理解,预先准备好的滤波器系数已经确定的FIR滤波器,输入声音样本按顺序依次选择不同的滤波器进行滤波后,输出即为重采样后的声音样本;根据不同的重采样比,每个输入声音样本会输入到若干个滤波器,从而输出多个声音样本,从而达到抽取(即降采样率)并滤波的效果。
上述的抽取并FIR滤波的具体处理步骤为:
1)准备好1024个系数已经确定的FIR滤波器,以第0个滤波器作为当前滤波器。
2)从源声音样本中取第SAMPLEINDEX(源样本序号)个样本为一个输入,与前面的滤波器长度(FILTERLEN)-1个样本组成当前滤波器的FILTERLEN个输入数据。
3)进行滤波,即将FILTERLEN个数据输入滤波器,经过与滤波器系数的累乘加运算,获得一个输出,即为一个滤波后,也即重采样后的声音样本。
4)样本放大序号(SINDEX)进行累加操作,累加长度为滤波器步长(FILTER_INC)。再将SINDEX右移10位,将移位后的值更新到到SAMPLEINDEX(源样本序号),跳到步骤2)。直到所有源声音样本已经全部处理结束。
上述的重采样处理是按声道进行的,即输入声音样本应该合理组织,同一个声道声音样本连续存放;对于一组要处理的长度为2L的左右声道交错存放的立体声声音样本,需要重新组织成前面L个样本全是左声道声音样本,后面L个样本全是右声道声音样本。
上述的FIR滤波的过程就是一个乘累加的过程,如y(n)=a0*x(n)+a1*x(n-1)+…+a7*x(n-7)为一个8阶滤波运算。对于刚开始重采样,通常将x(-1),x(-2),……,x(-7)视为0进行处理。但这样处理并非总是稳妥,在有些组合下,在开始处会产生异样的噪音。原因是用0进行乘累加,相当于没有累加,处理后输出的声音样本会比后面用非0数据进行乘累加的输出相差很大,导致声音突变,产生高频信号,从而引起异常声音。而本发明中,将其处理成x(1),x(2),……,x(7),将滤波器的初始输入不用0代替,而是用源声音样本中最前面声音样本值代替,经测试,效果良好。
在混音处理中,当几种不同采样率的音频/语音进行混音时,需要重采样成一致的采样率才能进行混音处理。蓝牙立体声,由于蓝牙音乐编码协议只定义了四种采样率:16K、32K、44K和48KHz,当需要通过蓝牙播放其它采样率的音乐时,必须经过重采样再经蓝牙播放。通过本发明可以达到上述要求,并且运算量低、功耗低、算法简单和软件时间代码简洁。