|
openal教程(七)
多普勒效应
首先,我们要来复习一下高中物理学,不要害怕。多普勒效应与我们每个人都有关,他是一个
逻辑过程,就要看你是否对他感兴趣。在理解多普勒效应是什么之前,我们必须明白“声音”
是什么。简单的讲,声音就是你的大脑被空气中的连续波打断。波从一个点发出,在空气中
旅行的样子请参考下图:(详细图请参考 http://www.devmaster.net/articles/openal-tutorials/lesson7.php)
在这张图中,用红S代表声源的位置,红L代表听众的位置。现在,声源和听众都在移动。
声源向外发出声波,在这张图中,我们用蓝圆表示。在这张图中,听众能很好的感受声音。
多普勒效应没有在这张图中表示出来;多普勒效应描述的是弯曲的声音在移动。
你可以在这张图中做一些改动。当声源发出声音时,可以看出他是从原点向外扩散,最好
的例子是池子中的水波。当你丢一块石块到水中时,将看见一圈一圈的水圈从一点扩散。我们
来看第二张图片:
现在,声源在移动,用红色的箭头表示。实际上,声源是带着速度向听众移动。注意图中
声波之间的位置。这就是多普勒效应。实际上,声源是在移动中的不同位置发散声波。
听众是怎样感受声音的呢?注意第二张图表中在声源和听众之间的声波的距离是逐渐在压缩。这就引起声波跑到了一起,听起来特别尖,急。在这里,我们要讲一下频率。声波之间的
距离实际上是由声音的频率引起的。当声源在移动中发散声音时,他也引起了频率的改变。你
也许注意到了在不同的位置的声波的距离。例如,在移动声源的对面,声波的距离实际上很宽。
因此,他的频率很底。听众感受声音频率的强弱是由听众的位置相关的。
听众的移动也能引起频率的变化。这一点很难用图形表示。如果声源固定,听众向声源移动,那么听众感受的频率的变化和声源是一样的。如果你还不能理解,请参考下面的图片:
这两张图片表示不同声波形式的声音。请看第一张,请看那两波段的顶点。那声波的顶点和上
面图式的蓝圈的距离相同。第二张图代表压缩的声波。当你对比着看这两张图时,你将发现明显的不同。第二张图的声波更多,这也代表他的频率更大。
还要附加一点,声音的速度就是声波的速度。如果声源的速度大于声波的速度,那么声源将冲破声音屏障。
OPENAL中的物理学
从上面的讲述,我们学习了多普勒效应。下面我们将讲解多普勒效应是怎样在OPENAL中应用的。在OPENAL中的文件中是这样解释的:
“多普勒效应依靠声源的速度和听众与介质的关系,声音在介质中的蔓延速度。”
我们可以这样理解,有3个要素影响着听众听的声音的最总频率。这些因素分别是:声源的速度,听众的速度和声音的速度。
当我们谈到“介质”,就是声源和听者的载体。例如,声音在水下和空气中传播是不一样的。空气和水是不同的介质。
在OPENAL 中,OPENAL是通过计算多普勒效应,因此我们需要定义一些变量来影响计算。计算公式如下:
shift = DOPPLER_FACTOR * freq * (DOPPLER_VELOCITY - l.velocity) / (DOPPLER_VELOCITY + s.velocity)
在公式中‘l’和‘s’分别代表听众和声源。‘freq’代表发散的声波的最初频率,‘shift’被声波的频率改变。这些最后的转移频率将被OPENAL的所有声音流样本化。
我们已经知道用‘AL_VELOCITY'在’alListenerfv' and 'alSourcefv'函数中定义声源和听众的速度。当文件导入缓冲器时,‘freq’将直接来自缓冲器。下面的函数将为你设置永久的值。
ALvoid alDopplerFactor(ALfloat factor);
ALvoid alDopplerVelocity(ALfloat velocity);
‘alDopplerFactor’设置否定的值将引起'AL_INVALID_VALUE'的错误,并且整个控制将被忽略。如果设置为0将可能引起争议。做这些将使多普勒效应失效。对多普勒效应的影响将由方程式的大小的改变决定。设置为1.0将不会影响什么。在0.1 to 1.0之间设置任何值将使多普勒效应减少到最小。并且如果设置的值超过1.0将是影响最大化。
'alDopplerVelocity'设置否定的值或0将引起'AL_INVALID_VALUE'的错误,并且整个控制将被忽略。如果设置为0将可能引起争议。Setting this will be like setting how fast sound can move through the medium. OpenAL has no sense of medium, but setting the velocity will give the effect of a medium. OpenAL also has no sense of units (kilometer, miles, parsecs), so keep that in mind when you set this value so it is consistent with all other notions of units that you have defined.
See the Java Bindings for OpenAL page for the Java version of this tutorial (adapted by: Athomas Goldberg)
|
|