Charles Petzold
下载代码示例
在著名的波形的万神殿,简单的正弦曲线至高无上。 只是看着它,您可以看到其精髓的顺利起伏性质 — — 当它达到其峰值、 几乎停止,它冠,然后逐步加快速度减慢,达到它的最大速度横渡水平轴开始另一个经济放缓。
这种视觉印象更深的数学分析所证实。 正弦曲线在任意点的瞬时速度是对曲线切线。 图的那些速度,并可以得到另一个正弦曲线,由四分之一周期从原始偏移。 不要再使用这第二条曲线,它和那是显示加速度,偏移量从原来的半个周期,如中所示的正弦曲线图 1。
图 1 正弦曲线,其 (在紫罗兰色) 中速度与加速度 (Aqua)
在微积分术语中,正弦曲线是它自己的二阶导数的负值。 从基本物理学,我们知道部队是加速度,这意味着在任何物理过程中力在哪里与位移成反比,议案由正弦曲线描述成正比。 泉具有这一特点:越多你舒展了他们,更该部队在相反的方向。 但自然界中发现的许多其他物质有内在弹性,以及包括压缩和稀疏的空气。
考虑采摘的绷紧的字符串的被拉伸的动物皮肤,管道内空气的振动攻丝。 所有这些过程涉及弹性振动与正弦曲线的特征运动的对象。 更常见的是,这个正弦曲线被辅以额外的正弦曲线,其频率是基本频率的整倍数。在此组合中,正弦曲线被称为谐波。
本身,单个正弦曲线是可听见很无聊。 但把他们几个一起在谐波关系和声音获取有趣得多。 现实生活中,很多时候这些谐波的频率的基频,确切积分并不更加正确地被称为的言外之意。 这是这个组合的言外之意 — — 包括它们随时间的变化 — —,它定义一种乐器的特征的声音或音色。
一个特定波形的一个小片段可以被绘制成图作为函数的时间,在顶部所示图 2。 如果此波形重复每 4 ms,它有一个 250 Hz,这是接近中间 C 在钢琴上的频率。
图 2 波形在时间域 (顶部) 和频率域 (底部)
一些傅里叶分析,我们可以将此波形分成其组成的正弦曲线,和代表它有些不同的方式,在底部所示图 2。 此关系图中显示频率由安排这些构成正弦曲线相对的振幅。 在信号处理的行话, 图 2 显示波形的时域表示形式的等价性上顶部和底部的频率域表示形式。
在现实生活中的声音中其频率域表示形式将包含整个音频谱从 20 赫兹到 20000 赫兹,和时间推移不断变化。
频率域表示允许我们认为的声音作为集合的各种不同频率的正弦波,这往往有助于人们理解音频处理。
一种非常常见的音频处理涉及放大或衰减某频率范围的音频频谱中,从而改变声音的谐波组成。 这是一个称为一个筛选器的工具。 在模拟信号处理中,筛选器是电路 ; 他们在数字信号处理算法。
最常见的筛选器类型,因此称为低通、 高通和带通 ; 术语的频率是指让通过的筛选器。 低通滤波器强调较低频率的衰减更高的频率。 同样,高通滤波衰减较低的频率。 低通和高通过滤器定义特定的截止频率,指示衰减的开始位置。 带通滤波器没有截止频率,但中心频率起类似的作用。 围绕该中心频率范围以外的频率是弱毒疫苗。
大多数筛选器不能简单地阻止所有高于或低于特定频率的正弦波。 相反,与特定频率的正弦波被削弱基于其距离截止或中心频率与一个滚的作用了。 这滚坡受称为 Q,质量为站立的筛选器的属性。 具有较高的 Q 的筛选器已陡滚。
Q 因子是最简单的解释与带通滤波器。 图 3 显示的带通滤波器的频率范围的应用效果。 中心频率 f0,在标记和其他两个频率标记为 f1 和 f2 哪里带通滤波器衰减为 70.7 %f0 振幅的振幅。
图 3 中带通滤波器的带宽
为什么 70.7%吗? 作为波形的振幅的平方计算的波形力量和 f1 和 f2 表示一半它原始的力量在波形已被减毒的频率。 因为电源是振幅平方,在那些点的振幅是 1/2 或 0.707 的平方根。
Q 值是计算方法的中心频率除以两个半功率频率之间的差异:
Q = f0 / (f2 — — f1)
然而,f2 和 f0 之间的区别不是 f0 和 f1 之间的区别一样。 相反,比率是相同的:f2 / f0 等于 f0 / f1。 如果 f2 为双 f1,这就是倍频程,并且它是很容易计算 Q 等于平方根的 2,或大约 1.414。
F1 与 f2 的比例被称为筛选器的带宽,和经常在八度音阶中指定。 带宽 B 在八度音阶中,您可以计算 Q 就像这样:
随着带宽的下降,Q 增加和滚是更加陡峭。
我说过 f2 和 f1 是筛选器衰减一半权力的 f0 的频率。 一半的权力也被称为是-3 分贝。 分贝是响度的大致逼近人类认知对数刻度。 两个电源级别 P1 和 P0 的分贝的区别是:
db = 10·log10(P1/P0)
如果 P1 是半 P0,0.5 的基地 10 对数是-0.301 和是大约-3 的 10 倍。 当处理振幅,分贝计算为:
db = 20·log10(A1/A0)
0.707 的基地 10 对数是-0.15 和也是-3 的 20 倍。
每增加一倍的振幅对应增加 6 分贝,这就是为什么有时说 16 位采样率的音频 Cd,有 96 分贝的动态范围。
如果您使用 XAudio2 在 Windows 8 的程序中生成声音或修改现有的音乐文件的声音,将筛选器应用于那些声音是作为初始化的 XAUDIO2_FILTER_PARAMETERS 结构的三个字段和调用名为 SetFilterParameters 的方法一样简单。
如你所见在此列的最近分期付款,程序创建一个或多个实例的 IXAudio2SourceVoice 来定义波形本身、 和 IXAudio2 的单个实例MasteringVoice 要有效地将所有的源声音合并到单个音频流。 本文中稍后介绍你还会看到如何创建实例的 IXAudio2SubmixVoice 来控制处理和混合的途中掌握语音的声音。 源声音和 submix 声音支持的 SetFilterParameters 方法,但只有如果声音创建了 XAUDIO2_VOICE_USEFILTER 标志。
对 SetFilterParameters 的调用需要指向 XAUDIO2_FILTER_PARAMETERS 结构,有三个字段的指针:
类型:将设置为 XAUDIO2_FILTER_TYPE 枚举,其中包括低通、 高通和带通滤波器,以及一个槽口 (或乐队-拒绝) 筛选器的成员和单极低通和高通过滤器,(如你很快就会看到) 是更简单的筛选器的成员之一。
频率:设置为 2·sin(π·f0/fs),其中 f0 是截止频率,fs 是采样频率,哪里 f0 不大于 1/6 的 fs,这意味着的值设置为该字段是不大于 1。
OneOverQ:1 除以所需的 Q 因数,大于零且不大于 1.5。 因此,Q 不能少于 2/3,它对应于 2 倍频程的带宽。
我还没给你图,类似于图 3,这说明低通和高通过滤器如何衰减的频率。 有时这种图只是显示一个滚的作用,因而可以危险地欺骗性如果那样的实际筛选器不相当的工作。 是这种情况与 XAudio2 过滤器。 低通、 高通、 带通和槽口的筛选器,为 XAudio2 实现数字滤波器称为二阶,其中涉及到一个相当简单的算法,但不会创建一个简单的滚效果低通和高通滤波器的类型。 (如果你有兴趣在算法中,按照维基百科文章中的链接上"数字二阶滤波器"在 bit.ly/Yoeeq1.)
二阶滤波器往往在中心频率的带通滤波器和附近的低通和高通滤波器的截止频率产生共鸣。 这意味着该筛选器减轻一些频率,不仅放大了别人。 要明智地使用这些筛选器,您必须意识到这种效果。 幸运的是,此放大是相当容易预测。 对于带通滤波器,在中心频率的正弦波的振幅等于 Q 的一个因素的增加。 对于低通和高通滤波器,截止频率附近的最大放大是等于 Q 的较高值的 Q,但稍大于 Q 为较低的值。
图 4 显示所有 XAudio2 筛选器类型为 261.6 Hz (中间 C) 和 Q 的 1.414 的频率设置的影响。 水平轴是与一系列的 3 倍频程的上方和下方中间 C.对数 垂直轴显示在这些频率的正弦曲线的合成振幅。 1 的振幅在黑色水平线是没有筛选器。 其他所有行用不同的颜色都标识。
图 4 为 Q 的 1.414 筛选器的影响
例如,低通滤波器频率低于截止频率,通过让不仅放大了他们,并此放大增加你接近截止频率。 高通滤波器具有相反的效果。
图 5 是类似于图 4 但为 4.318 Q,其中与关联的 1/3 倍频程的带宽。 请注意在垂直轴不同以容纳增加的扩增。
图 5 为 Q 的 4.318 筛选器的影响
如果您想要使用的简单的低通或高通筛选器不会在所有放大,坚持单极的筛选器。 这些都是非常简单的筛选器只是受截止频率和他们不使用 Q 设置。 他们多函数一样的简单的低音和高音控制汽车音响。 但如果你想要使用更复杂的筛选,通过筛选您的程序必须补偿任何扩增。
如果您而是将实现您自己的过滤器,你可以做的以及通过创建 XAudio2 音频处理对象 (XAPO),这是一个类,获取对音频流的访问,并且可以实现效果。
若要允许我 (和你) 试验用的筛选器,我创建了一个名为 AudioFilterDemo 在这篇文章的可下载代码中包含的 Windows 8 项目。 图 6 说明它的运行。
图 6 AudioFilterDemo 程序
向顶部的三个振荡器是所有独立可控的、 与一个包含任一侧的中间 C.3 倍频程的频率范围 滑块是对数刻度但可调到笔记之间 10 司,这是一个增量称为 10 美分。
筛选器有一个频率滑块,以及一个滑块为 Q。 所有频率滑块都有工具提示标识说明和它的频率。 图 7 显示的方法,在三个波形源声音设置的筛选器,当有在控件中的更改时。
图 7 AudioFilterDemo 设置 XAudio2 筛选器参数
void MainPage::SetFilterParameters() { if (pSawtoothOscillator != nullptr) { XAUDIO2_FILTER_PARAMETERS filterParameters; if (currentFilterType != -1) { double cutoffFrequency = 440 * pow(2, (filterFrequencySlider->Value - 69) / 12); filterParameters.Type = XAUDIO2_FILTER_TYPE(currentFilterType); filterParameters.Frequency = float(2 * sin(3.14 * cutoffFrequency / 44100)); filterParameters.OneOverQ = float(1 / filterQSlider->Value); } else { // Documentation: // "acoustically equivalent to the filter being fully bypassed" filterParameters.Type = LowPassFilter; filterParameters.Frequency = 1.0f; filterParameters.OneOverQ = 1.0f; } pSawtoothOscillator->GetVoice()->SetFilterParameters( &filterParameters, XAUDIO2_COMMIT_ALL); pSquareWaveOscillator->GetVoice()->SetFilterParameters( &filterParameters, XAUDIO2_COMMIT_ALL); pSineWaveOscillator->GetVoice()->SetFilterParameters( &filterParameters, XAUDIO2_COMMIT_ALL); } }
底部面板是缩放的分贝音量仪。 这使您可以看到由此产生量为特定的波形和筛选器设置。 该程序使得没有调整到用户设置通过以外的其他卷。 如果这种流量计进入红色的这意味着程序产生了一种声音,是太吵了,和之前的音响系统在您的计算机上被剪切波形。
音量仪基于预定义的效果的类。 图 8 显示了用于创建这种效果的实例的代码。 该程序然后设置一个定时器,并调用 GetEffectParameters 以获取自上次调用 GetEffectParameters 输出声音的峰值水平。
图 8 创建卷米效果
// Create volume meter effect IUnknown * pVolumeMeterAPO; XAudio2CreateVolumeMeter(&pVolumeMeterAPO); // Reference the effect with two structures XAUDIO2_EFFECT_DESCRIPTOR effectDescriptor; effectDescriptor.pEffect = pVolumeMeterAPO; effectDescriptor.InitialState = true; effectDescriptor.OutputChannels = 2; XAUDIO2_EFFECT_CHAIN effectChain; effectChain.EffectCount = 1; effectChain.pEffectDescriptors = &effectDescriptor; // Set the effect on the mastering voice pMasteringVoice->SetEffectChain(&effectChain); // Release the local reference to the effect pVolumeMeterAPO->Release();
在此程序中一个有趣的行使是通过与 Q 的至少 4 种左右的带通滤波器发挥方波或锯齿波。 当您更改筛选器频率,你可以听到个别言外之意的波形。 方波仅奇数谐波,但锯齿波有奇数和偶数的谐波。
时间是,每个设备齐全的家庭音频安装包括包含行的垂直幻灯片电位器控制银行的带通滤波器图形均衡器。在一个图形均衡器,每个带通滤波器涵盖的三分之二或八度总音频频谱中的三分之一。 各专业的音响工程师,图形均衡器用于通过刺激或切割各种频率调整的声学响应的一个房间。 家庭用户经常安排"微笑"的模式中的滑块,仿效的在图 9、 刺激、 低、 高两端和离开的中间范围较软,不过分干扰的谈话。
图 9 GraphicEqualizer 程序
GraphicEqualizer 程序允许您从您的 Windows 8 的音乐库加载 MP3 或 WMA 文件并播放它通过一个 1/3 倍频程图形均衡器。 该程序包含 26 垂直滑块,其中每个是带通滤波器与相关联。 正如您所看到的每个滑块都标有在这一波段的中心频率。 在理论上,每个中心频率应该是多维数据集的根 2 (或约 1.26) 雇用比以前的筛选器,但很多的舍入高要保持合理的数字。 基于我在维基百科发现的 1/3 图形均衡器的一张照片,我标记为 20 hz,25、 31.5、 40 开始 26 滑块,穿过 6.3 千赫,停止 44,100 Hz 采样率的 7,350 Hz 限制。
最图形均衡器有单独的带区的电位器为左、 右通道,但我决定放弃那美化市容。
你见过怎么一个筛选器可应用于一个特定的 IXAudio2SourceVoice 实例,但 GraphicEqualizer 程序需要将 26 筛选器应用于源的声音。 这通过创建 26 IXAudio2SubmixVoice 实例对应于这些筛选器 (加上几个),并创建什么叫做 XAudio2"音频处理图",如中所示图 10。 每个框是一个派生自 IXAudio2Voice,三个接口的实例,框中标识的 GraphicEqualizer 程序中使用的变量名称。
图 10 在 GraphicEqualizer Program 中使用的音频处理图
IXAudio2SubmixVoice 实例无法生成其自己的声音。 这种特权被保留给源的声音。 但它可以获取输入从一个源的声音 (或另一个 submix 语音) ; 应用卷、 筛选器或影响 ; 结果到一个或多个 submix 声音,或掌握的声音传递。
在顶部的图 10 就是从音乐文件生成音乐的源声音。 在底部是掌握的声音的结果发送到计算机的声音硬件。两者之间是所有 submix 声音。
它是一个推模型:每当你创建一个源的声音或 submix 语音,您可以指示目标的声音 (或声音) 您想要接收的那声音输出。 稍后,您可以更改该输出与对 SetOutputVoices 的调用的目标。 如果您指定 NULL 在任一情况下,输出去掌握的声音。
您指明您要输出的语音与指针去 XAUDIO2_VOICE_SENDS 结构,其中包含两个字段:
SendCount 指示由 pSends 指向 XAUDIO2_VOICE_DESCRIPTOR 结构的数目。 它可以是零,以表明声音不去任何地方。 XAUDIO2_VOICE_DESCRIPTOR 结构也有两个字段:
喂进了银行的 26 submix 声音和一个能整合这些 26 的声音,从输出的两个 IXAudio2SubmixVoice 实例生成图形均衡器,并不严格所需,但它们简化了程序的结构。 无论何时,程序会创建一个新的源声音 — — 每当用户加载一个新的音乐文件中发生这种情况 — — 它只是需要直接源声音的输出到 pSourceVoiceOutput 的实例。
该程序还具有一个复选框按钮来绕过均衡器。 要断开音频处理图形均衡器,一切必要是在同一个 NULL 指针,指示它应该去掌握语音 pSourceVoiceOutput 上调用 SetOutputVoices。 恢复均衡器涉及到几个代码行来还原输出从 pSourceVoiceOutput 到 pEqualizerInput。
有几种的方法来定义的筛选器,包括图形均衡器。 一种方法是为每个滑块以更改该筛选器的 Q — — 实际上这会使筛选器更具限制性的当你增加滑块。 但我决定要在 1/3 倍频程带宽或 4.318,保持每个筛选器的 Q 因子和使用滑块来改变那 submix 声音的音量。 图形均衡器通常允许切换滑块的银行之间 ± 6 dB 范围和 ±12 dB 的范围,但是我决定在一个 ±24 dB 范围为更多的极端效果上。
在其中心位置均衡器滑块时,相应的 submix 声音已 1 默认卷。 通常,这将意味着声音只是通过 submix 声音不变。 但是,应用与 Q 4.318 submix 声音中的筛选器导致的振幅由在中心 fre 4.318 因素增加淬火。 要补偿,该程序将 submix 声音 pEqualizerOutput 的音量设置为 1 除以 Q。
与所有的滑块设置在他们的中心位置,单击该复选框可切换的均衡器和音频图卷中导致没有变化。 声音不会改变一点 — —无疑产生的方式的各种带通滤波器重叠 — — 但总体音量不会。
均衡器滑块设置为-24 其最低属性和最大值设置为 24,对应的增益的分贝。 当滑块的值更改,卷为相应 submix 语音设置在 ValueChanged 事件处理程序中,像这样:
Slider^ slider = dynamic_cast<Slider^>(sender); int bandIndex = (int)slider->Tag; float amplitude = float(pow(10, (args->NewValue / 20))); pEqualizerBands[bandIndex]->SetVolume(amplitude, 0);
那幅计算是逆的前面显示的分贝计算。 由此产生的振幅范围从大约 0.06 (在-24 dB) 到约 16 (在 24 dB)。如果你请记住,每个更改的 6 dB 是减半或加倍的中心振幅的 1,这些范围有意义。 但如果你摇晃了所有将滑块拖到其最大设置,整体振幅增加 16 的一个因素,结果很可能会被剪裁和扭曲。
换句话说,该程序隐式假定用户保持平衡的生活方式,并将降低,同时增加其他一些滑块。
Charles Petzold 是 MSDN 杂志和作者的"编程窗口,第 6 版"的长期贡献 (O'Reilly 媒体,2012年),一本关于编写应用程序的 Windows 8 书。 他的网站是 charlespetzold.com。
衷心感谢以下技术专家对本文的审阅:理查德 · Fricks (Microsoft)