如何访问和管理WP7中麦克风的原始数据
文章信息
本文翻译自How to access and manage the Microphone raw data in WP7
Contents |
简介
这篇文章将会解释在Windows Phone中如何管理麦克风的原始数据。这将会展示一个真实的项目,Shooter Assistant,一个协助射手训练奥运飞碟射击的专业项目,也适用于飞碟和双向飞碟专业的项目。
Shooter Assistant
奥林匹克飞碟射击专业是飞碟竞赛三大主要形式之一,一般使用12号双管猎枪。当射手把装了两发子弹的枪放在肩膀上并且被告知开始时,这个飞碟目标会自动即时发射。每个系列由二十五个飞盘组成。对于每个踏板共安排了三个飞碟机,所以一共有15个飞碟机。飞碟发射方向变化从0°到45°,向左或者向右。它的高度从10英尺的发射机向上1.50米到3.50米。飞碟在经历一个75到80米长的抛物线后会落地。发射速度通常介于100千米/小时和120千米/小时之间波动。通常情况下,目标集中在35米半径以内,射手有0.5到0.6秒的反应时间。
反应时间是成功的关键。快了或者慢了十分之一秒都会严重影响到比赛结果。
Shooter Assistant可以帮助射手这样训练:
戴上耳机,当命令下达后,蜂鸣声将会在0.5秒后响起,这意味着你必须按下扳机。当然反应时间随目标方向而变化。
根据收集到的结果(好的和坏的),使用基因算法,这个软件会适应你的反应时间。
创建项目
- 安装Windows Phone SDK
- 通过选择 文件 | 新建项目 菜单命令创建一个新的项目。
- 新建项目对话框将会显示。展开Visual C#模板,选择silverlight for Windows Phone模板。
- 选择Windows Phone应用程序模板。需要填写项目名。{注意|不要简单取名为“Microphone”}
- 在解决方案资源管理器中,右击 引用 ,选择 添加引用 。
- 从.NET组件列表中选择Microsoft.Xna.Framework,单击确定按钮。
- 如果你看到一个关于添加引用到Silverlight程序集的警告对话框,单击“是”按钮。
在你的MainPage.xaml.cs文件顶部添加以下using语句:
using System.IO;
using System.Windows.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
在MainPage.xaml.cs中,声明MainPage类的全局成员变量:
public partial class MainPage : PhoneApplicationPage
{
Microphone microphone = Microphone.Default;
byte[] buffer;
MemoryStream stream = new MemoryStream();
SoundEffect sound;
// Constructor
public MainPage()
{
添加以下代码到你的MainPage构造函数中,写在InitializeComponent函数调用后面
//构造函数
public MainPage()
{
InitializeComponent();
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(50);
dt.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
dt.Start();
microphone.BufferReady += new EventHandler<EventArgs>(microphone_BufferReady);
}
现在添加下面的方法来管理麦克风的原始数据。
void microphone_BufferReady(object sender, EventArgs e)
{
microphone.GetData(buffer);
// If you want to store the audio data in a stream
stream.Write(buffer, 0, buffer.Length);
}
检测音量变化,RMS函数
在你的MainPage类中声明一个全局变量,设置阈值:
public partial class MainPage : PhoneApplicationPage
{
Microphone microphone = Microphone.Default;
byte[] buffer;
MemoryStream stream = new MemoryStream();
SoundEffect sound;
....
private int minimumThreshold = 500;
....
void microphone_BufferReady(object sender, EventArgs e)
{
// Retrieve audio data
microphone.GetData(buffer);
// RMS Method
double rms = 0;
ushort byte1 = 0;
ushort byte2 = 0;
short value = 0;
int volume = 0;
rms = (short)(byte1 | (byte2 << 8));
for (int i = 0; i < buffer.Length - 1; i += 2)
{
byte1 = buffer[i];
byte2 = buffer[i + 1];
value = (short)(byte1 | (byte2 << 8));
rms += Math.Pow(value, 2);
}
rms /= (double)(buffer.Length / 2);
volume = (int)Math.Floor(Math.Sqrt(rms));
if ((volume > minimumThreshold))
{
System.Diagnostics.Debug.WriteLine("Threshold exceeded");
System.Diagnostics.Debug.WriteLine("buffer.Length" + buffer.Length + " Volume:" + volume);
}
}
开始录音
private void recordButton_Click(object sender, RoutedEventArgs e)
{
if (microphone.State == MicrophoneState.Stopped)
{
microphone.BufferDuration = TimeSpan.FromMilliseconds(1000);
buffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
microphone.Start();
System.Diagnostics.Debug.WriteLine("Threshold setted to:" + minimumThreshold);
}
}
结束录音
private void stopButton_Click(object sender, RoutedEventArgs e)
{
if (microphone.State == MicrophoneState.Started)
{
microphone.Stop();
}
}





(no comments yet)