移动应用程序 调整铃声音量,避免环境噪音
Figure 4 RMS 计算
public double CalcRMS(MainTest.DisplayLineDelegate ShowLine)
{
byte[] data = new byte[dwBytesRecorded];
Marshal.Copy(lpData, data, 0, data.Length);
double temp = 0, sum = 0;
int j = 0;
ShowLine(data.Length.ToString());
for (int i = 0; i < data.Length; i++)
{
temp = (double)data[i] - 127.50;
sum = sum + (temp * temp);
j++;
}
return Math.Sqrt(sum / j);
}
映射函数取 RMS 值并定义将用于设置 Pocket PC 当前铃声水平的值。虽然完成它需要更多的经验,但是移动电话功能的简单配置文件对演示就足够了。
正如我先前所述,此技术的缺点在于,扬声器和麦克风功能有显著差异的每种电话型号都将可能需要一个配置文件。解决这个问题的办法是通过创建配置界面,让用户设置适合各种地点的参考值,或者可以提供一个网站,在上面提供各种配置文件。在本文中,我将仅介绍输入一组参考值的方法。然而,怀着这个目的,我将向您介绍如何获取映射值,以便可以为任何电话的配置文件复制它们。
RMS 值是通过录制许多与特定 dB 水平关联的常见声音环境而生成的。理论上,这项录制工作须经过很长一段时间才能完成(例如,有人在咖啡馆掉了一个盘子,而此时您正在采样),而且它应包括您认为可能需要接电话的普通环境。然后,可以将每种环境的平均读数用作音量设置的上限和下限。
一旦参考值计算好,就必须即刻创建自适应配置文件。这只是定义了移动电话将如何基于不同的值来自调铃声水平。您可以考虑许多其他策略。例如,如果电话处于一个非常吵闹的环境中,您甚至可以开启振动。对于我的演示,我将仅用参考值将麦克风输入映射到五个音量。
可以使用注册表来设置 Pocket PC 的铃声水平。注册表值位于 ControlPanel\SoundCategories\Ring 下的 HKEY_CURRENT_USER,要更改的值是 InitVol,该值范围是 0 到 5。
代码使用标准注册表写函数来设置铃声音量值。给定了上限和下限后,映射可以确定铃声的适当值,具体实现为若干个条件语句。
public Wave.MMSYSERR AutoSetVolume(MainTest.DisplayLineDelegate ShowLine)
{
double AverageRMS = 0.00;
if (!m_inited)xreturn Wave.MMSYSERR.ERROR;
if (m_recording) Stop();
try
{
// Write the data recorded to each buffer.
// Get RMS value for each block and take the average
// across all blocks.
for (int i = 0; i < m_numBlocks; i++)
{
if (m_whdr[i] != null)
{
AverageRMS = AverageRMS + m_whdr[i].CalcRMS(ShowLine);
}
}
AverageRMS = AverageRMS / m_numBlocks;
ShowLine("Average RMS: " + AverageRMS);
// Select volume based on reference values.
uint Volume = 0;
if (AverageRMS > 35.00)
{
//Range of this value for the volume control is from
//0x0000 (min) non to 0x0005 (max).
Volume = 5;
}
else if ((AverageRMS <= 35.00) && (AverageRMS > 30.00))
{
//Range of this value for the volume control is from
//0x0000 (min) non to 0x0005 (max).
Volume = 4;
}
else if ((AverageRMS <= 30.00) && (AverageRMS > 20.00))
{
//Range of this value for the volume control is from
//0x0000 (min) non to 0x0005 (max).
Volume = 3;
}
else if ((AverageRMS <= 20.00) && (AverageRMS > 10.00))
{
//Range of this value for the volume control is from
//0x0000 (min) non to 0x0005 (max).
Volume = 2;
}
else
{
//Range of this value for the volume control is from
//0x0000 (min) non to 0x0005 (max).
Volume = 1;
}
ShowLine("Set Volume to: " + Volume.ToString());
PInvokeLibrary.Registry.CreateValueDWORD(
"ControlPanel\\SoundCategories\\Ring", "InitVol",
Volume);
return Wave.MMSYSERR.NOERROR;
}
catch { return Wave.MMSYSERR.ERROR; }
finally { FreeWaveBuffers(); }
}