这个例子展示了如何模拟一个数字音频多频带动态范围压缩系统。
动态范围压缩通过衰减强峰的水平来减少信号的动态范围,同时保持较弱的峰值不变。压缩在音频录制,混合和广播中具有应用。
多频带压缩通过首先将音频信号分成多个频段,然后通过其自身独立可调节的压缩机将音频信号分成不同的音频频段。多频带压缩广泛用于音频母带,通常包含在音频工作站中。
在该示例中的多频带压缩机首先使用多频带交叉滤波器将音频信号分成不同的频带。LinkWitz-Riley交叉过滤器用于获得整体allpass频率响应。然后使用单独的动态范围压缩机压缩每个频带。键压缩机特性,例如压缩比,攻击和释放时间,阈值和膝关节宽度为每个频带可独立地调谐。展示了压缩对信号动态范围的影响。
LinkWitz-Riley Crossover滤波器包括低通和高通滤波器的组合,每个滤波器通过级联两个低通或高通巴特滤波器组成。求和两个滤波器的响应在交叉频率下产生0 dB的增益,使得交叉起到ALLPASS滤波器(因此在音频信号中引入没有失真)。
交叉Filter.
可以用来实现Linkwitz-Riley System对象。由于Linkwitz-Riley交叉滤波器是由两个巴特沃斯滤波器级联而成的,因此其顺序总是均匀的。巴特沃斯滤波器的斜率等于6*Ndb / octave,在哪里N是过滤顺序。当CrossoverSlopes
的属性交叉Filter.
是整除12
(即过滤器是偶数排序的),对象实现Linkwitz-Riley交叉。否则,该对象实现巴特沃斯交叉,其中低通和高通部分都使用单个巴特沃斯滤波器实现交叉索引/ 6.
.
下面是一个使用四阶Linkwitz-Riley交叉滤波器过滤信号的例子。注意,低通和高通部分在交叉频率上都有- 6db增益。低通和高通部分之和为全通。
Fs = 44100;% Linkwitz-Riley过滤器交叉= crossoverFilter (1 5000 4 * 6, Fs);%传递函数估计量transferFuncEstimator = dsp。TransferFunctionEstimator (...'频率范围','片面',“SpectralAverages”20);frameLength = 1024;scope = dsp.arrayplot(...“PlotType”,“行”,...“YLimits”, -40年[1],...'ylabel',“(dB)级”,...“XScale”,“日志”,...'SampleIncrement',(fs / 2)/(frameLength / 2 + 1),...'xlabel',的频率(赫兹),...'标题',“第八阶林克维茨-赖利交叉滤镜”,...“ShowLegend”,真的,...'ChannelNames',{'乐队1','乐队2',“和”});抽搐尽管toc < 10 in = randn(帧长度,1);%返回交叉滤波器的低通和高通响应[ylp, yhp] =交叉(的);%对响应求和Y = YLP + YHP;v = transferfuncestimator(Repmat(在,1,3),[YLP YHP Y]);范围(20 * log10(abs(v)));结束
交叉Filter.
还可用于通过在树状结构中组合双频交叉滤波器和全通滤波器来实现多频交叉滤波器。该滤波器将频谱分成多个波段,使它们的和是一个完美的全通滤波器。
下面的例子显示了一个四阶Linkwitz-Riley交叉滤波器组成的四波段交叉滤波器。注意四个频带之和的全通响应。
Fs = 44100;交叉= cross - verfilter (3,[2e3 5e3 10e3],[24 24 24],44100);transferFuncEstimator = dsp。TransferFunctionEstimator ('频率范围','片面',“SpectralAverages”20);l = 2 ^ 14;scope = dsp.arrayplot(...“PlotType”,“行”,...“XOffset”0,...“YLimits”-120年[5],...“XScale”,“日志”,...'SampleIncrement', 5 * Fs/(L/2 + 1),...'ylabel','频率响应(DB)',...'xlabel',的频率(赫兹),...'标题',“四人交叉过滤”,...“ShowLegend”,真的,...'ChannelNames',{'乐队1','乐队2','乐队3',“四级”,“和”});抽搐;尽管TOC <10 IN = RANDN(L,1);把信号分成四个波段[YLP,YBP1,YBP2,YHP] =交叉(IN);Y = YLP + YBP1 + YBP2 + YHP;z = transferfuncestimator(Repmat(In,1,5),[YLP,YBP1,YBP2,YHP,Y]);范围(20 * log10(abs(z))))结束
压缩机
是一个动态范围的压缩机系统对象。当输入信号超过指定的阈值时,将对其进行压缩。压缩量由指定的压缩比控制。攻击和释放时间决定了压缩机启动或停止压缩的速度。膝宽为压缩机增益在阈值附近提供了一个平滑的过渡。最后,可以在压缩机的输出端应用一个补偿增益。这种补偿性增益同样地放大了强峰值和弱峰值。
压缩机的静态压缩特性取决于压缩比、阀值和膝宽。下面的例子说明了硬膝盖的静态压缩特性:
DRC =压缩机(-15,5);可视化(DRC);
为了查看阈值,比率和膝关节宽度对压缩机的静态特性的影响,改变了值的值阈值
,比
和KneeWidth
属性。静态特征图应相应地改变。
压缩机的攻击时间被定义为当信号电平超过阈值时,压缩机的增益从其最终值的10%到90%所花费的时间(在MSEC中)。当信号电平下降到阈值以下时,压缩机的释放时间被定义为时刻(以秒为单位),压缩机的增益从其值的90%降至10%。下面的示例说明了不同释放和攻击时间的信号包络:
Fs = 44100;刚果民主共和国=压缩机(-10年5...“SampleRate”Fs,...'攻击时间', 0.050,...“ReleaseTime”, 0.200,...“MakeUpGainMode”,“属性”);x = [(Fs, 1); 0.1 * 1 (Fs, 1)];刚果民主共和国(y, g) = (x);t = (1/Fs) * (0: 2*Fs - 1);图次要情节(211)情节(t, x);持有上网格上绘图(t,y,“r”)ylabel(“振幅”)传说(“输入”,“压缩输出”)子图(212)绘图(t,g)网格上传奇(“压缩机获得(dB)”)xlabel('时间(秒)')ylabel('收益(DB)')
输入最大电平为0db,高于指定的- 10db门限。0db输入时压缩机稳态输出为-10 + 10/5 = - 8db。因此增益为-8 dB。攻击时间定义为输入电平高于门限值时,即从-0.8 dB到-7.2 dB,压缩机增益从最终值的10%上升到90%的时间。让我们计算压缩阶段的增益分别等于-0.8 dB和-7.2 dB的次数:
[~,t1] = min(abs(g(1:Fs) + 0.1 * 8));[~,t2] = min(abs(1:Fs) + 0.9 * 8);tAttack = (t2 - t1) / Fs;流('攻击时间是%d s\n'tAttack)
攻击时间是5.000000e-02秒
然后输入信号掉回0,其中没有压缩。当输入远低于阈值时,或者在这种情况下,将释放时间定义为增益从其绝对值的90%到10%所花费的时间,或者在这种情况下,-7.2dB至-0.8 dB。让我们发现没有压缩阶段的收益等于-7.2 db和-0.8 db的时间:
[~,t1] = min(abs(f:end) + 0.9 * 8));[~,t2] = min(abs(g(Fs:end) + 0.1 * 8));tRelease = (t2 - t1) / Fs;流('释放时间是%d s\n'tRelease)
释放时间是2.000000e-01秒
下面的示例说明了动态范围压缩对音频信号的影响。压缩阈值设置为-15dB,压缩比为7。
frameLength = 1024;读者= dsp。AudioFileReader (“文件名”,...“rockguitar - 16 - 44 - p1 -立体声- 72 secs.wav”,...“SamplesPerFrame”,frameLength);%压缩机。阈值= - 15db,比值= 7刚果民主共和国=压缩机(-15 7...“SampleRate”,读者。赞美,...“MakeUpGainMode”,“属性”,...“KneeWidth”5);范围= timescope (“SampleRate”,读者。赞美,...“TimeSpanSource”,“属性”,...“时间间隔”, 1'bufferLength'Fs * 4,...'showgrid',真的,...“LayoutDimensions”,[2 1],...“NumInputPorts”2,...'timespanoverrunaction','滚动');范围。ActiveDisplay = 1;范围。ylimit = [-1 1];scope.showlegend = true;scope.channelnames = {“原始音频与压缩音频”};scope.activedisplay = 2;scope.ylimits = [-6 0];scope.ylabel ='收益(DB)';scope.showlegend = true;scope.channelnames = {“压缩机增益(dB)”};尽管~isDone(reader) x = reader();刚果民主共和国(y, g) = (x);x1 = x (: 1);日元= y (: 1);范围((x1, y1), g (: 1))结束
以下模型实现了多波段动态范围压缩示例:
模型=“audiomultibanddynamiccompression”;open_system(模型)
在本例中,首先使用多频带交叉滤波器将音频信号划分为四个频带。每个带使用一个单独的压缩机压缩。然后将这四个波段重新组合形成音频输出。计算未压缩和压缩信号的动态范围(定义为信号的最大绝对值与信号均方根的比值)。要听到原始和压缩音频信号的区别,请拨动顶层的开关。
该模型集成了用于与仿真交互的用户界面(UI)。UI允许您调优参数,结果立即反映在模拟中。要启动控制模拟的UI,请单击模型上的“启动参数调优UI”链接。
set_param(模型,“StopTime”,'(1/44100) * 8192 * 20');SIM(型号);
关闭模型:
bdclose(模型)
HelperMultibandCompressionSim
是MATLAB函数包含的多频带动态范围压缩示例的实现。它对构成算法的对象进行实例化、初始化和步骤化。
功能multibandAudioCompressionExampleApp
包裹在HelperMultibandCompressionSim
并迭代调用它。它还绘制了未压缩和压缩音频信号。绘图发生在plotResults
函数的输入是'true'。
执行multibandAudioCompressionExampleApp
在范围上运行模拟并绘制结果。请注意,只要用户没有显式地停止它,模拟就会一直运行。
multibandAudioCompressionExampleApp
启动一个用于与模拟交互的UI。UI允许您调优参数,结果立即反映在模拟中。更多关于用户界面的信息,请参考helpercreateparamtuningui.
.
MATLAB编码器可以用来生成C代码的函数HelperMultibandCompressionSim
.为了为您的平台生成一个mex文件,请执行HelperMultibandCompressionCodeGeneration
.
通过调用包装函数multibandAudioCompressionExampleApp
与'真的'
作为参数,生成的MEX-file可以用来代替HelperMultibandCompressionSim
的模拟。在这个场景中,UI仍然在MATLAB环境中运行,但是主要的处理算法是由一个mex文件执行的。在这种模式下,性能得到了改善,而不会影响参数的调优能力。
调用multibandAudioCompressionExampleApp(真正的)
使用mex文件进行模拟。同样,模拟会一直运行,直到用户从UI显式地停止它。