适用于 XNA 开发人员的音频分析框架





5.00/5 (14投票s)
创建一个音频分析框架,使几乎不懂音频分析的开发人员能够开发音频驱动游戏
引言
对于非专业人士来说,音频分析可能是一个令人生畏的主题。在创建需要此主题的软件时尤其如此。有许多可用的框架有助于开发音频驱动软件,但很少有能满足那些对音频分析知识有限的人的需求。该项目的目标是开发一个音频分析框架,专门用于 C# XNA 项目的实现,它将使对音频分析几乎没有理解的开发人员能够开发音频驱动游戏。该项目的结果是一个简单、功能齐全且文档完善的音频分析框架;一个不需要广泛先验知识即可使用,并且易于集成到任何 XNA 项目中的框架。该解决方案的含义导致了最终框架的进一步开发、通用化和完善;以便未来的 XNA 开发人员能够获得复杂且不宽容的现有音频分析框架的简单替代方案。
背景
该项目首先深入研究现有流行游戏的音频同步方面,以了解框架应提供的功能。接下来,对预分析和实时分析技术开发的研究导致了操纵 XNA 现有类的决定,以从当前播放的音频中提取可视化数据;这最终成为最终实时音频分析框架的基础。
音频分析概念设计
XNA 可视化数据提供从 20hz 到 20khz 的对数频率刻度(MSDN)。Rose, J (2002) 解释说,听力是对数的;这意味着低频下仅几赫兹 (Hz) 的变化听起来与高频下数百赫兹的变化相同。这相当于中频段位于约 1kHz 左右,而不是线性中点 10kHz。因此,在创建我的音频分析类时,我将使用 Rose, J (2002) 的工作作为参考,相应地将可视化数据数组分成低、中和高频段。
低:20 – 600 Hz - 这包括 20 到 100 Hz 之间的极限低音、100 到 300 Hz 之间的中低音,以及最后 300-600Hz 之间的低中音。低频段包含低音和高音振幅的平均值,这对于跟踪节奏至关重要。
中:600 Hz – 2.4 kHz – 这包括识别对话和识别不同乐器的谐波的关键频率。中频段可用于监控人类语音样本。
高:2.4 kHz – 20 kHz – 该频段范围从低端到高端。高频段,重点是 2.4 kHz 到 9.6 kHz,主要为音频传达能量、活力和亮度。
为了创建每个频段,对可视化数据数组中包含的每个频率的当前振幅进行采样,然后将其除以采样的频率数以创建一个单一的平均振幅结果。此结果随后用作计算动态变量的基础。
已知可视化数据数组是对数的,每个频段要采样的频率数使用 Rm09 (2010) 发布以下方程计算:
10^(arrayPosition * 0.01171875 + 1.30103),其中 arrayPosition = VisualisationData[0..255]
此方程使用 log 10 返回指定位置的 Hz 值。使用此公式,计算必须从可视化数据数组中采样的频率范围以创建每个频段
低:20 – 600 Hz
10^(0 * 0.01171875 + 1.30103) = 20.00 Hz
10^(126 * 0.01171875 + 1.30103) = 599.22 Hz
中:600 Hz – 2.4 kHz
10^(127 * 0.01171875 + 1.30103) = 615.61 Hz
10^(178 * 0.01171875 + 1.30103) = 2437.62 Hz
高:2.4 kHz – 20 kHz
10^(179 * 0.01171875 + 1.30103) = 2504.29 Hz
10^(255 * 0.01171875 + 1.30103) = 19467.54 Hz
注意:快速数学检查:127+52+77 = 256。这是正确的频率总数 (0 - 255)。
对于每个频段,计算包含的振幅之和。然后将总和除以范围以创建平均振幅值。例如,对于中频段,计算频率 127 到 178 的振幅之和,然后除以范围 52。
Using the Code
以下指南仅详细说明了音频分析类 (AAC) 的推荐设置和使用。开发人员如果觉得舒适,应随意偏离这些程序。请使用本文顶部的“下载音频分析类源代码”链接获取“AudioAnalysisXNAClass.cs”的副本。
设置(使用 Visual Studio 2010)
导入音频分析类 (AAC)
- 创建一个新的 XNA 4.0 项目。(如果您计划使用现有的 XNA 4.0 项目,请跳过此步骤)。
- 右键单击您的 XNA 4.0 项目 -> 添加 -> 现有项… ->
- 导航到您的 AudioAnalysisXNAClass.cs 副本
- 将其添加到您的 XNA 4.0 项目。
- 使用解决方案资源管理器,双击新添加的 AudioAnalysisXNAClass.cs 打开并查看其代码。在第 8 行,将命名空间从“
FinalYearProject
”更改为您的项目命名空间。 - AAC 现已成功添加到您的项目!
初始化音频分析类 (AAC)
- 如果您创建了一个新的 XNA 4.0 项目,请通过双击解决方案资源管理器打开 Game1.cs。如果您使用的是现有 XNA 4.0 项目,请打开等效类。(此类将包含 XNA 的游戏循环:
Initialize()
、LoadContent()
、UnloadContent()
、Update(GameTime gameTime)
和Draw(GameTime gameTime)
。) - 在此类的顶部实例化
AudioAnalysisXNAClass
,详见图 1 第 14 行。图 1 - 实例化 AudioAnalysisXNAClass - 在
Initialize()
方法内部,初始化AudioAnalysisXNAClass
对象,详见图 2 第 114 行。(这将调用AudioAnalysisXNAClass
类的构造函数,启用可视化数据)。图 2 - 初始化 AudioAnalysisXNAClass - AAC 现已成功初始化到您的项目中。
更新音频分析类 (AAC)
建议 AAC 的可视化数据数组和频段每个游戏循环只更新一次。这样,可视化数据将与音乐保持充分同步。虽然在每帧中多次调用 AAC 的更新函数,例如在每次 AAC“get
”函数调用之前,将提供更大的同步。但它也会对性能产生负面影响。因此,当每个游戏循环中多次调用更新函数时,务必谨慎。
- 在
Update(GameTime gameTime)
内部,按以下顺序调用 AAC 的update
方法audioAnalysis.Update();
- 必须首先调用此方法。此方法更新可视化数据数组;从 XNA 的MediaPlayer
类当前播放的音频中提取 256 个频率的振幅。如果没有音频正在播放,则每个频率的振幅将设置为0
。audioAnalysis.updateAverageLowFrequencyData();
- 此方法使用更新后的可视化数据数组更新低频段的平均振幅。audioAnalysis.updateAverageLowFrequencyData();
- 此方法使用更新后的可视化数据数组更新中频段的平均振幅。audioAnalysis.updateAverageLowFrequencyData();
- 此方法使用更新后的可视化数据数组更新高频段的平均振幅。
- 有关如何正确更新 AAC 的示例,请参见图 3。图 3 - 如何正确更新 AudioAnalysisXNAClass
- 如果您已正确执行上述步骤,则 AAC 现已成功地每个游戏循环更新一次!
获取器和设置器
音频分析类 (AAC) 包含其每个 private
变量的获取器和设置器方法;lowFrBandAverage
、midFrBandAverage
、highFrBandAverage
。
设置方法
如果您希望手动覆盖 update
函数并指定自己的平均振幅值,则可以使用 set
方法。有关此示例,请参见图 4。
但是,下次调用低、中、高频平均更新方法时,这些手动值将被替换为根据音频的当前低、中、高平均值。
获取方法
如果您希望检查变量包含的值,则可以使用 get
方法。以下代码片段使用图 4 中的代码,每个游戏循环手动设置平均振幅变量的值,然后“获取”并将手动设置的值打印到控制台,详见图 5。
protected override void Update(GameTime gameTime)
{
//FIRST: Update visualization data.
audioAnalysis.Update();
////////////////////////////////////////////////////////////////////
/* SECOND: Update the average amplitude for each frequency band, //
// using the current visualization data. */
////////////////////////////////////////////////////////////////////
//Update the average amplitude for the low frequency band.
audioAnalysis.updateAverageLowFrequencyData();
//Update the average amplitude for the mid frequency band.
audioAnalysis.updateAverageMidFrequencyData();
//Update the average amplitude for the high frequency band.
audioAnalysis.updateAverageHighFrequencyData();
manuallySetValues(); //Manually set all of the average frequency values
getAverageAmplitudes(); //Print all of the average frequency values to the console.
}
最后,如果需要,get
方法也可以用于创建额外的方法。创建额外的方法是我为经验丰富的音频分析框架用户提供的一个选项。当然,他们也可以直接在音频分析类本身中实现新方法。新方法的创建很大程度上取决于个人开发人员的创造力和独创性。图 6 显示了创建新方法的非常简单的示例,该方法使用 get
方法将中频段的平均振幅与 min float
值进行比较,以返回 min
或 max
double 值。
音频分析类功能概述
以下部分将提供一个示例,说明如何将每个函数集中的一个方法用于 XNA 项目。每个函数集中的其余方法将不进行演示,因为它们的工作方式完全相同,只是它们将使用不同的频段平均值计算返回值。用于计算返回值的频段平均值在方法名称中指定。例如,方法“getBool_2StepLowFrq
”将使用低频段平均值计算返回值,如方法名称末尾的“LowFrq
”所指定。而“getBool_2StepMidFrq
”将使用中频段平均值计算返回值,如方法名称末尾的“MidFrq
”所指定。最后,“getBool_2StepHighFrq
”将使用高频段平均值计算返回值,如方法名称末尾的“HighFrq
”所指定。
还应注意,方法名称中指定的频段将在某种程度上决定返回变量的可能用途。例如,使用低频段计算返回值最适合控制节奏的变量。而使用中频段最适合与音频中的人类语音样本相关的变量,或者可能是主合成器旋律。最后,使用高频段最适合传达能量或亮度的变量。但是,最终,这将取决于各个开发人员的创造力以及他们对这 3 个频段的知识,这将最终决定它们的使用方式。
最后,每个频段平均值始终介于 0.0f
和 1.0f
之间。指定超出这些边界的值将导致某些返回值无法获得。
函数集 1 示例:2 步返回音频动态 C# 布尔变量
此方法用于使用低频段返回布尔变量。如果音频片段的低频段平均值大于 0.49f
(任意值),此方法会将布尔变量“shoot
”设置为 true
。然后,此变量可用作敌方单位在设置为 true
时开火的触发器。否则,如果音频的平均低频段小于 0.49f
,则返回 false
,敌人将停止射击。
bool shoot = audioAnalysis.getBool_2StepLowFrq(0.49f);
函数集 2 示例:2 步返回音频动态 C# 整型变量
此方法用于使用低频段返回两个整型变量之一。如果音频片段的低频段平均值大于 0.54f
,此方法会将整型变量 gameIntensity1Or6
设置为 6
。否则,如果未满足此条件,gameIntensity1Or6
将设置为 1
。此变量可用作触发器,当 gameIntensity1Or6
的值设置为 6
时,生成不同类型的敌人,而不是设置为 1
时。
int gameIntensity1Or6 = audioAnalysis.getInt_2StepLowFrq(1, 6, 0.54f);
函数集 3 示例:6 步返回音频动态 C# 整型变量
此方法用于使用低频段返回 1 到 6 之间的整数值。如果音频片段的低频段平均值小于 0.1f
,则返回 minInt 值 1。如果频段平均值大于 0.1f
,但小于或等于 0.2f
,则返回 2。如果频段平均值大于 0.2f
,但小于或等于 0.3f
,则返回 3
。如果频段平均值大于 0.3f
,但小于或等于 0.4f
,则返回 4
。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则返回 5
。最后,如果频段平均值大于 0.54f
,则返回最大值 6
。
每次返回一个值时,gameIntensity1To6
的值都将设置为该值。同样,此变量可用作触发器,可能用于生成不同类型的敌人。
与上一个方法的唯一区别是,此方法能够生成 6 种不同类型的敌人,而不仅仅是 2 种。
int gameIntensity1To6 = audioAnalysis.getInt_6StepLowFrq(1, 6, 0.1f, 0.2f, 0.3f, 0.4f, 0.54f);
函数集 4 示例 – 2 步返回音频动态 C# 浮点变量
此方法用于使用低频段返回两个 float
变量之一。如果音频片段的低频段平均值大于 0.45f
,此方法会将 float
变量 enemyMoveSpeed
设置为 4.5f
。否则,如果未满足此条件,enemyMoveSpeed
将设置为 0.9f
。此变量可用于调节敌人移动速度。因此,当音乐强度较低时,敌人移动缓慢,而当音乐强度增加时,敌人移动更快。
float enemyMoveSpeed = audioAnalysis.getFloat_2StepLowFrq(0.9f, 4.5f, 0.45f);
函数集 5 示例 – 6 步返回音频动态 C# 浮点变量
此方法用于使用中频段返回 0.75f
到 9.1337f
之间的浮点值。如果音频片段的中频段平均值小于 0.2f
,则返回 0.75f
。如果频段平均值大于 0.2f
,但小于或等于 0.3f
,则返回 1.96f
。如果频段平均值大于 0.3f
,但小于或等于 0.4f
,则返回 3.75f
。如果频段平均值大于 0.4f
,但小于或等于 0.5f
,则返回 5.55f
。如果频段平均值大于 0.5f
,但小于或等于 0.64f
,则返回 7.34f
。最后,如果频段平均值大于 0.64f
,则返回最大值 9.1337f
。
返回的 float
存储在 enemyAnimation
变量中,例如可用于调节敌人动画的比例。
Float enemyAnimation = audioAnalysis.getFloat_6StepMidFrq( 0.75f, 9.1337f, 0.2f, 0.3f, 0.4f,
0.5f, 0.64f);
函数集 6 – 2 步返回音频动态 C# 字符串变量
此方法用于使用高频段返回两个 String
之一。如果高频平均值高于 0.0f
,则 highFrqMonitor
String
变量将设置为包含“高频激活”。否则,它将返回“无高频”。此变量可用于监视高频平均值的状态,可能用于向用户显示音频样本当前不包含高频时。
String highFrqMonitor = audioAnalysis.getString_2StepHighFrq( "No highs",
"High frequencies active", 0.0f);
函数集 7 示例 – 6 步返回音频动态 C# 字符串变量
此方法用于使用中频段返回六个 String
之一。如果音频片段的中频段平均值小于 0.1f
,则返回“非常低”。如果频段平均值大于 0.1f
,但小于或等于 0.2f
,则返回“低”。如果频段平均值大于 0.2f
,但小于或等于 0.3f
,则返回“低-中”。如果频段平均值大于 0.3f
,但小于或等于 0.4f
,则返回“中”。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则返回“高”。最后,如果频段平均值大于 0.54f
,则返回“非常高”。
与上一个方法类似,midFrqMonitor
变量可能用于向用户显示中频段的强度。
String midFrqMonitor = audioAnalysis.getString_6StepMidFrq( "Very low", "Low", "Low-Medium",
"Medium", "High", "Very High", 0.1f, 0.2f, 0.3f, 0.4f, 0.54f);
函数集 8 示例 – 3 步返回音频动态 XNA Vector2 变量
此方法用于使用低频段返回三个 Vector2
变量之一。如果音频片段的低频段平均值小于 0.4f
,则返回 minParticleTrailVelocity
。如果频段平均值大于 0.4f
,但小于或等于 0.54f,则返回 midParticleTrailVelocity
。最后,如果频段平均值大于 0.54f
,则返回 maxParticleTrailVelocity
。
currentParticleTrailVelocity
变量可能用于调节粒子在轨迹效果中移动的速度,使用提供的三个速度之一作为参数。
//Example particle trail velocities:
Vector2 minParticleTrailVelocity = new Vector2(0.7f, 0.7f);
Vector2 midParticleTrailVelocity = new Vector2(2.0f, 2.0f);
Vector2 maxParticleTrailVelocity = new Vector2(4.0f, 4.0f);
Vector2 currentParticleTrailVelocity = audioAnalysis.getVector2_3StepLowFrq(
minParticleTrailVelocity, midParticleTrailVelocity, maxParticleTrailVelocity, 0.4f, 0.54f);
函数集 9 示例 – 6 步返回音频动态 XNA Vector2 变量
此方法用于使用中频段返回六个 Vector2
变量之一。如果音频片段的中频段平均值小于 0.1f
,则返回 verySmallParticleExplosionVelocity
。如果频段平均值大于 0.1f
,但小于或等于 0.2f
,则返回 smallParticleExplosionVelocity
。如果频段平均值大于 0.2f
,但小于或等于 0.3f
,则返回 mediumParticleExplosionVelocity
。如果频段平均值大于 0.3f
,但小于或等于 0.4f
,则返回 bigParticleExplosionVelocity
。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则返回 veryBigParticleExplosionVelocity
。最后,如果频段平均值大于 0.54f
,则返回 massiveParticleExplosionVelocity
。
currentParticleExplosionVelocity
变量可用于调节粒子在爆炸中移动的速度,使用提供的六个速度之一作为参数。
// Example particle explosion velocities:
Vector2 verySmallParticleExplosionVelocity = new Vector2(0.5f, 0.5f);
Vector2 smallParticleExplosionVelocity = new Vector2(1.5f, 1.5f);
Vector2 mediumParticleExplosionVelocity = new Vector2(5.0f, 5.0f);
Vector2 bigParticleExplosionVelocity = new Vector2(10.0f, 10.0f);
Vector2 veryBigParticleExplosionVelocity = new Vector2(15.0f, 15.0f);
Vector2 massiveParticleExplosionVelocity = new Vector2(25.0f, 25.0f);
Vector2 currentParticleExplosionVelocity = audioAnalysis.getVector2_6StepMidFrq(
verySmallParticleExplosionVelocity, smallParticleExplosionVelocity,
mediumParticleExplosionVelocity, bigParticleExplosionVelocity,
bigParticleExplosionVelocity, massiveParticleExplosionVelocity, 0.1f, 0.2f, 0.3f, 0.4f, 0.54f);
函数集 10 示例 – 3 步返回音频动态 XNA TimeSpan 变量
此方法用于使用低频段返回三个 TimeSpan
变量之一。如果音频片段的低频段平均值小于 0.4f
,则 maxFireRateInterval
将使用 TimeSpan.FromSeconds(maxFireRateInterval)
转换为 TimeSpan
,然后返回。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则 midFireRateInterval
将使用 TimeSpan.FromSeconds(midFireRateInterval)
转换为 TimeSpan
,然后返回。最后,如果频段平均值大于 0.54f
,则 minFireRateInterval
将使用 TimeSpan.FromSeconds(minFireRateInterval)
转换为 TimeSpan
,然后返回。
timeSpanBetweenShots
变量可能用于调节发射弹丸之间的时间。例如,当低频段平均值低于 0.4f
时,弹丸将几乎完全停止发射,这取决于用于设置返回 TimeSpan
的 maxFireRateInterval float
。而当低频段平均值大于 0.54f
时,弹丸将以极快的速度发射,这取决于用于设置返回 TimeSpan
的 minFireRateInterval float
。当低频段平均值介于 0.1f
和 0.7f
之间时,弹丸将根据确切的当前平均值以其他 TimeSpan
速率之一发射。
//Example fire rate intervals, as floats:
float minFireRateInterval = 0.05f;
float midFireRateInterval = 0.15f;
float maxFireRateInterval = 10000f; //This basically turns off shooting.
TimeSpan timeSpanBetweenShots = audioAnalysis.getTimeSpan_3StepLowFrq(
minFireRateInterval, midFireRateInterval, maxFireRateInterval, 0.4f, 0.54f);
函数集 11 示例 – 6 步返回音频动态 XNA TimeSpan 变量
此方法用于使用低频段返回六个 TimeSpan
变量之一。如果音频片段的低频段平均值小于 0.1f
,则 slowestInterval
将使用 TimeSpan.FromSeconds(slowestInterval)
转换为 TimeSpan
,然后返回。如果频段平均值大于 0.1f
,但小于或等于 0.2f
,则 slowInterval
将使用 TimeSpan.FromSeconds(slowInterval)
转换为 TimeSpan
,然后返回。如果频段平均值大于 0.2f
,但小于或等于 0.3f
,则 mediumInterval
将使用 TimeSpan.FromSeconds(mediumInterval)
转换为 TimeSpan
,然后返回。如果频段平均值大于 0.3f
,但小于或等于 0.4f
,则 fastInterval
将使用 TimeSpan.FromSeconds(fastInterval)
转换为 TimeSpan
,然后返回。如果频段平均值大于 0.4f
,但小于或等于 0.7f
,则 veryFastInterval
将使用 TimeSpan.FromSeconds(veryFastInterval)
转换为 TimeSpan
,然后返回。最后,如果频段平均值大于 0.7f
,则 extremelyFastInterval
将使用 TimeSpan.FromSeconds(extremelyFastInterval)
转换为 TimeSpan
,然后返回。
timeSpanBetweenSpawning
变量可能用于调节敌人生成之间的时间。例如,当低频段平均值低于 0.1f
时,敌人将几乎完全停止生成,这取决于用于设置返回 TimeSpan
的 slowestInterval float
。而当低频段平均值大于 0.7f
时,敌人将以极快的速度生成,这取决于用于设置返回 TimeSpan
的 extremelyFastInterval float
。当低频段平均值介于 0.1f
和 0.7f
之间时,敌人将根据确切的当前平均值以其他 TimeSpan
速率之一生成。
float extremelyFastInterval = 0.05f;
float veryFastInterval = 0.2f;
float fastInterval = 0.3f;
float mediumInterval = 0.5f;
float slowInterval = 0.9f;
float slowestInterval = 10000f; //This basically stops spawning.
TimeSpan timeSpanBetweenSpawning = audioAnalysis.getTimeSpan_6StepLowFrq(
extremelyFastInterval, veryFastInterval, fastInterval, mediumInterval,
slowInterval, slowestInterval, 0.1f, 0.2f, 0.3f, 0.4f, 0.7f);
函数集 12 示例 – 3 步返回音频动态 XNA 颜色变量
此方法用于使用低频段返回三个 Color
变量之一。如果音频片段的低频段平均值小于 0.4f
,则返回 colour_LowResponce
。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则返回 colour_MediumResponce
。最后,如果频段平均值大于 0.54f
,则返回 colour_HighResponce
。
currentColour
变量可能用于调节粒子轨迹或爆炸的颜色。
Color colour_LowResponce = new Color(1.0f, 0.0f, 0.0f); // Red
Color colour_MediumResponce = new Color(0.0f, 1.0f, 0.0f); // Green
Color colour_HighResponce = new Color(0.0f, 0.0f, 1.0f); // Blue
Color currentColour = audioAnalysis.getColour_3StepLowFrq( colour_LowResponce,
colour_MediumResponce, colour_HighResponce, 0.4f, 0.54f);
函数集 13 示例 – 6 步返回音频动态 XNA 颜色变量
此方法用于使用高频段返回六个 Color
变量之一。如果音频片段的高频段平均值小于 0.2f
,则返回 colour_MinResponce
。如果频段平均值大于 0.2f
,但小于或等于 0.25f
,则返回 colour_LowMediumResponce
。如果频段平均值大于 0.25f
,但小于或等于 0.3f
,则返回 colour_MediumResponce
。如果频段平均值大于 0.3f
,但小于或等于 0.35f
,则返回 colour_HighMediumResponce
。如果频段平均值大于 0.35f
,但小于或等于 0.7f
,则返回 colour_HighResponce
。最后,如果频段平均值大于 0.7f
,则返回 colour_MaxResponce
。
currentColour
变量可用于调节项目的背景颜色。因此,当高频平均值非常大时,背景颜色将变为浅灰色。而当它是一个低值时,它将保持黑色或深灰色。这将创建背景颜色频闪效果——在高频峰值(例如踩镲敲击)时将背景颜色闪烁为浅灰色。
Color colour_MinResponce = new Color(0, 0, 0); // Black
Color colour_LowMediumResponce = new Color(3, 3, 3); // Very very dark grey
Color colour_MediumResponce = new Color(6, 6, 6); // Very dark grey
Color colour_HighMediumResponce = new Color(9, 9, 9); // dark grey
Color colour_HighResponce = new Color(12, 12, 12); // grey
Color colour_MaxResponce = new Color(40, 40, 40); // light grey
Color currentColour = audioAnalysis.getColour_6StepHighFrq( colour_MinResponce,
colour_LowMediumResponce, colour_MediumResponce, colour_HighMediumResponce,
colour_HighResponce, colour_MaxResponce,
0.2f, 0.25f, 0.3f, 0.35f, 0.7f);
函数集 14 示例 – 3 步返回音频动态 XNA Color[] 数组
此方法用于使用低频段返回三个 Color
数组,Color[]
之一。如果音频片段的低频段平均值小于 0.4f
,则返回 audioVisColourArray1
。如果频段平均值大于 0.4f
,但小于或等于 0.54f
,则返回 audioVisColourArray2
。最后,如果频段平均值大于 0.54f
,则返回 audioVisColourArray3
。
currentColourArray
可用于调节多个同步工作/颜色组合项目的颜色——并提供一种比简单地多次调用 getColour
方法更有效的返回颜色组合的方法。
//initialize colour arrays for audio analysis use:
audioVisColourArray1 = new Color[2]; //array of 2 colours
audioVisColourArray2 = new Color[2]; //array of 2 colours
audioVisColourArray3 = new Color[2]; //array of 2 colours
//Colours for a low response
audioVisColourArray1[0] = new Color(0, 153, 153);
audioVisColourArray1[1] = new Color(153, 153, 0);
//Colours for a medium response
audioVisColourArray2[0] = new Color(152, 237, 0);
audioVisColourArray2[1] = new Color(0, 237, 152);
//Colours for a high response
audioVisColourArray3[0] = new Color(208, 0, 110);
audioVisColourArray3[1] = new Color(110, 0, 208);
//A new array larger enough to hold largest colour combination returned by the AAC (2).
Color[] currentColourArray = new Color[2];
//Get the currentColourArray from using the AAC.
Color[] currentColourArray = audioAnalysis.getColourArray_3StepLowFrq(
audioVisColourArray1, audioVisColourArray2, audioVisColourArray3, 0.4f, 0.54f);
音频驱动原型游戏
除了这个框架之外,还创建了一个 2D“音频驱动”游戏,参见图 7、8 和 9。该游戏实现了音频分析框架,展示了其一些可能的功能。此原型游戏已作为 XNA 可执行文件上传到 GitHub,并附带完整的源代码。
未来考虑
根据我现在所知,我将考虑对音频分析类进行一些重大更改。在创建音频分析类时,我仔细考虑了功能与性能的影响。由于此框架旨在供开发人员使用,他们可能正在构建已经对性能产生显著影响的应用程序,因此我的方法尽可能地影响最小非常重要。考虑到这一点,我决定牺牲少量功能和可维护性,为每种返回数据类型生成两组函数。这样,如果开发人员只希望简单地“开或关”地返回两个指定值,对他们的程序影响最小,则 2Step
函数可提供最佳性能。另一方面,6Step
函数提供了一些额外功能,但代价是稍微更高的影响,但提供了更平滑的值返回曲线,并允许开发人员指定六个不同的返回值。
如果我将来要继续使用音频分析类,我将尝试分析这两种方法造成的影响。如果差异相对较小,我将考虑放弃两者,转而采用 10Step
方法。我这样做的理由是,10Step
方法可能会通过平滑的返回曲线为开发人员提供单个方法所需的最大功能。同时,与 6Step
方法一样,也可以通过以使其超出范围的方式(超出范围是指超出 0 到 1 的归一化振幅数组)操作参数,将其用作 2、3、4 等步长方法。例如,10Step
函数可以轻松转换为 XStep
函数。如果 X 是您希望函数从中选择的参数数量,从 string1
到 string10
,则必须在范围内输入 X-1 个参数进行计算,从 float max 参数开始,到 float min 参数结束。
致谢
- 音乐由 Andreas Estensen (Est&Sen) 创作。请点击此处查看他的 Facebook 页面获取更多信息!
参考文献
- MSDN - '
MediaPlayer.GetVisualizationData
method' http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.mediaplayer.getvisualizationdata.aspx (访问日期:2013/04/20) - Rm09 (2010) – 'Understanding
VisualizationData
': http://xboxforums.create.msdn.com/forums/t/22707.aspx (访问日期:2013/04/20) - Rose, J (2002) – ‘Range Finder’: http://www.dplay.com/tutorial/bands/index.html (访问日期:2013/02/10)
历史
- 2013 年 5 月 16 日:初始版本
- 2016 年 4 月 27 日:更新