Kinect 开发 —— 录音
不涉及语音识别~~
<Window x:Class="KinectRecordAudio.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Audio Recorder" Height="226" Width="405">
<Grid Width="369" Height="170">
<Button Content="Play" Height="44" HorizontalAlignment="Left" Margin="12,13,0,0" Name="button1" VerticalAlignment="Top" Width="114" Click="button1_Click" IsEnabled="{Binding IsPlayingEnabled}" FontSize="18"></Button>
<Button Content="Record" Height="44" HorizontalAlignment="Left" Margin="132,13,0,0" Name="button2" VerticalAlignment="Top" Width="110" Click="button2_Click" IsEnabled="{Binding IsRecordingEnabled}" FontSize="18"/>
<Button Content="Stop" Height="44" HorizontalAlignment="Left" Margin="248,13,0,0" Name="button3" VerticalAlignment="Top" Width="107" Click="button3_Click" IsEnabled="{Binding IsStopEnabled}" FontSize="18"/>
<CheckBox Content="Noise Suppression" Height="16" HorizontalAlignment="Left" Margin="16,77,0,0" VerticalAlignment="Top" Width="142" IsChecked="{Binding IsNoiseSuppressionOn}" />
<CheckBox Content="Automatic Gain Control" Height="16" HorizontalAlignment="Left" Margin="16,104,0,0" VerticalAlignment="Top" IsChecked="{Binding IsAutomaticGainOn}"/>
<CheckBox Content="AEC" Height="44" HorizontalAlignment="Left" IsChecked="{Binding IsAECOn}" Margin="16,129,0,0" VerticalAlignment="Top" />
</Grid>
</Window>
namespace KinectRecordAudio
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
// INotifyPropertyChanged 接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知。 string _recordingFileName; // 录音文件名
MediaPlayer _mplayer;
bool _isPlaying;
bool _isNoiseSuppressionOn;
bool _isAutomaticGainOn;
bool _isAECOn; // IsEnabled="{Binding IsRecordingEnabled}" 将控件与方法绑定 public MainWindow()
{
InitializeComponent();
this.Loaded += delegate { KinectSensor.KinectSensors[].Start(); };
_mplayer = new MediaPlayer();
_mplayer.MediaEnded += delegate { _mplayer.Close(); IsPlaying = false; };
this.DataContext = this;
} private void Play()
{
IsPlaying = true;
_mplayer.Open(new Uri(_recordingFileName, UriKind.Relative));
_mplayer.Play();
} private void Record()
{
Thread thread = new Thread(new ThreadStart(RecordKinectAudio));
thread.Priority = ThreadPriority.Highest; // 线程优先级
thread.Start();
} private void Stop()
{
KinectSensor.KinectSensors[].AudioSource.Stop();
IsRecording = false;
}
private object lockObj = new object(); private void RecordKinectAudio()
{
lock (lockObj)
{
// 线程加锁
IsRecording = true; var source = CreateAudioSource(); var time = DateTime.Now.ToString("hhmmss");
_recordingFileName = time + ".wav";
using (var fileStream =
new FileStream(_recordingFileName, FileMode.Create))
{
RecorderHelper.WriteWavFile(source, fileStream);
} IsRecording = false;
} } private KinectAudioSource CreateAudioSource()
{
var source = KinectSensor.KinectSensors[].AudioSource;
source.BeamAngleMode = BeamAngleMode.Adaptive;
source.NoiseSuppression = _isNoiseSuppressionOn;
source.AutomaticGainControlEnabled = _isAutomaticGainOn; if (IsAECOn)
{
source.EchoCancellationMode = EchoCancellationMode.CancellationOnly;
source.AutomaticGainControlEnabled = false;
IsAutomaticGainOn = false;
source.EchoCancellationSpeakerIndex = ;
} return source; // 返回经过处理的数据源
} #region user interaction handlers private void button1_Click(object sender, RoutedEventArgs e)
{
Play();
} private void button2_Click(object sender, RoutedEventArgs e)
{
Record();
} private void button3_Click(object sender, RoutedEventArgs e)
{
Stop();
} #endregion #region properties public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
} private bool IsPlaying
{
get
{
return _isPlaying;
}
set
{
if (_isPlaying != value)
{
_isPlaying = value;
OnPropertyChanged("IsRecordingEnabled");
}
}
} private bool IsRecording
{
get
{
return RecorderHelper.IsRecording;
}
set
{
if (RecorderHelper.IsRecording != value)
{
RecorderHelper.IsRecording = value;
OnPropertyChanged("IsPlayingEnabled");
OnPropertyChanged("IsRecordingEnabled");
OnPropertyChanged("IsStopEnabled");
}
}
}
public bool IsPlayingEnabled
{
get { return !IsRecording; }
} public bool IsRecordingEnabled
{
get { return !IsPlaying && !IsRecording; }
} public bool IsStopEnabled
{
get { return IsRecording; }
} public bool IsNoiseSuppressionOn
{
get
{
return _isNoiseSuppressionOn;
}
set
{
if (_isNoiseSuppressionOn != value)
{
_isNoiseSuppressionOn = value;
OnPropertyChanged("IsNoiseSuppressionOn");
}
}
} public bool IsAutomaticGainOn
{
get
{
return _isAutomaticGainOn;
}
set
{
if (_isAutomaticGainOn != value)
{
_isAutomaticGainOn = value;
OnPropertyChanged("IsAutomaticGainOn");
}
}
} public bool IsAECOn
{
get
{
return _isAECOn;
}
set
{
if (_isAECOn != value)
{
_isAECOn = value;
OnPropertyChanged("IsAECOn");
}
}
} #endregion
}
}
class RecorderHelper
{
static byte[] buffer = new byte[];
static bool _isRecording; public static bool IsRecording
{
get
{
return _isRecording;
}
set
{
_isRecording = value;
}
} public static void WriteWavFile(KinectAudioSource source, FileStream fileStream)
{
var size = ;
//write wav header placeholder
WriteWavHeader(fileStream, size); // size=0;
using (var audioStream = source.Start())
{
// Starts capturing audio from the device. The data can be read using the returned stream.
//chunk audio stream to file
while (audioStream.Read(buffer, , buffer.Length) > && _isRecording)
{
fileStream.Write(buffer, , buffer.Length);
size += buffer.Length; }
} //write real wav header
// 方法开始写入一个假的头文件,然后读取Kinect中的音频数据流,然后填充FileStream对象,直到_isRecoding属性被设置为false。然后检查已经写入到文件中的数据流大小,用这个值来改写之前写入的文件头
long prePosition = fileStream.Position;
fileStream.Seek(, SeekOrigin.Begin);
WriteWavHeader(fileStream, size); // size = file length
fileStream.Seek(prePosition, SeekOrigin.Begin);
fileStream.Flush();
} public static void WriteWavHeader(Stream stream, int dataLength)
{
using (MemoryStream memStream = new MemoryStream())
{
// 基于指定的字节数组初始化 MemoryStream 类的无法调整大小的新实例 int cbFormat = ;
WAVEFORMATEX format = new WAVEFORMATEX()
{
wFormatTag = ,
nChannels = ,
nSamplesPerSec = ,
nAvgBytesPerSec = ,
nBlockAlign = ,
wBitsPerSample = ,
cbSize =
}; using (var bw = new BinaryWriter(memStream))
{ WriteString(memStream, "RIFF");
bw.Write(dataLength + cbFormat + );
WriteString(memStream, "WAVE");
WriteString(memStream, "fmt ");
bw.Write(cbFormat); bw.Write(format.wFormatTag);
bw.Write(format.nChannels);
bw.Write(format.nSamplesPerSec);
bw.Write(format.nAvgBytesPerSec);
bw.Write(format.nBlockAlign);
bw.Write(format.wBitsPerSample);
bw.Write(format.cbSize); WriteString(memStream, "data");
bw.Write(dataLength); memStream.WriteTo(stream);
}
}
} static void WriteString(Stream stream, string s)
{
byte[] bytes = Encoding.ASCII.GetBytes(s);
stream.Write(bytes, , bytes.Length);
} struct WAVEFORMATEX
{
public ushort wFormatTag;
public ushort nChannels;
public uint nSamplesPerSec;
public uint nAvgBytesPerSec;
public ushort nBlockAlign;
public ushort wBitsPerSample;
public ushort cbSize;
}
}
C#不支持直接写wma文件,需要C++的 WAVEFORMATEX 结构体
Kinect 开发 —— 录音的更多相关文章
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- Kinect开发资源汇总
Kinect开发资源汇总 转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- Kinect 开发 —— 杂一
Kinect 提供了非托管(C++)和托管(.NET)两种开发方式的SDK,如果您用C++开发的话,需要安装Speech Runtime(V11),Kinect for Windows Runtime ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
- Kinect 开发 —— 全息图
Kinect的另一个有趣的应用是伪全息图(pseudo-hologram).3D图像可以根据人物在Kinect前面的各种位置进行倾斜和移动.如果方法够好,可以营造出3D控件中3D图像的效果,这样可以用 ...
- Kinect 开发 —— 进阶指引(上)
本文将会介绍一些第三方类库如何来帮助处理Kinect传感器提供的数据.使用不同的技术进行Kinect开发,可以发掘出Kinect应用的强大功能.另一方面如果不使用这些为了特定处理目的而开发的一些类库, ...
- Kinect开发 —— 基础知识
转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...
随机推荐
- 请教如何用 peewee 实现类似 django ORM 的这种查询效果。
本人新入坑的小白,如有不对的地方请包涵~~~! 在 django 中代码如下:模型定义: class Friends(models.Model): first_id = models.IntegerF ...
- Android chromium 2
Overview JNI (Java Native Interface) is the mechanism that enables Java code to call native function ...
- Unix版权史
原文出处: 阮一峰 这几天,我在读<Unix编程艺术>. 书中介绍了Unix的发展历史.我发现,这是一个很好的例子,说明现行版权制度具有阻碍社会发展的负面作用. 2. Unix诞生于 ...
- POJ 3567 Cactus Reloaded(仙人掌直径)
题意 裸的仙人掌直径. 题解 先考虑基环树的直径:先算出每颗“树”的直径,再在环上跑DP 再考虑仙人掌的直径:把每个基环树缩成一条边,边长为基环树深度. #include<iostream> ...
- HN0I2000最优乘车 (最短路变形)
HN0I2000最优乘车 (最短路变形) 版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址! [试题]为了简化城市公共汽车收费系 ...
- 解决MAC下PHP连接MYSQL错误Warning: mysql_connect(): No such file or directory in conn.php
今天在mac上用php去连接mysql数据库,出现了 mac PHP Warning: mysql_connect(): [2002] No such file... 详细例如以下所看到的: Dir ...
- Deferred Rendering(三)反锯齿和半透明问题
Deferred 框架下的AA 前面说过Deferred 框架下无法使用硬件AA.这句话不严谨: Deferred Shading在G-Buffer之后,物体几何信息全被抛弃了,导致兴许每一个像素都独 ...
- numpy 数据类型与 Python 原生数据类型
查看 numpy 数据类型和 Python 原生数据类型之间的对应关系: In [51]: dict([(d, type(np.zeros(1,d).tolist()[0])) for d in (n ...
- 手把手教你如何在Ubuntu系统中安装Pycharm
前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Py ...
- BZOJ5408: string(广义后缀自动机,LCT)
传送门 解题思路: 首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内. 那么考虑一个新的点在串中对串答案的贡献在一条树链 ...