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 ...
随机推荐
- vue 实现 点击取消监控内容是否发生修改 若修改提示 是否需要保存
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Windows Server 2012 r2 显示计算机图标
在 Windows Server 2012 R2 系统中,微软取消了服务器桌面个性化选项,如何重新调出配置界面,在桌面上显示计算机图标,本文为大家介绍一下! Win2012我的电脑怎么显示到桌面? 一 ...
- [洛谷P2085]最小函数值
题目大意:有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,要求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...
- win2003系统同步Linux ntp server批处理
最后更新时间: 2018/12/15 一般windows配置时间服务器,只需要在windows系统右下角,点时间,里面配置好对应NTP服务器地址就行, 至多再修改一下注册表 HKEY_LOCAL_MA ...
- 在ubuntu上编译rasbian kernel(for raspberry pi 1)
raspberry pi官网的编译手册写的简洁有力,照着操作即可 https://www.raspberrypi.org/documentation/linux/kernel/building.md ...
- 软raid 实验
RAID0 条带卷 2+ 100% 读写速度快,不容错 RAID1 镜像卷 2 50% 读写速度一般,容错 RAID5 带奇偶校验的条带卷 3+ (n-1)/n 读写速度快,容错,允许坏一块盘 RAI ...
- Could not create connection to database server. Attempted reconnect 3 times. Giving up.错误
项目是基于springboot框架,昨天从git上pull代码之后也没有具体看更改的地方,结果运行的时候就报错了. java.sql.SQLNonTransientConnectionExceptio ...
- Jupyter Notebook 常用的快捷键
Jupyter Notebook 有两种键盘输入模式.编辑模式,允许你往单元中键入代码或文本:这时的单元框线是绿色的.命令模式,键盘输入运行程序命令:这时的单元框线是灰色. Shift+Enter : ...
- Vijos 1071 && caioj 1411 动态规划2:打牌 (背包方案输出)
非常奇怪的是,我在Vijos 1071能AC,在caioj 就只有50分 可以和前面一道题一样算方案,如果大于1就是多解 然后就输出方案就好了 #include<cstdio> #incl ...
- 紫书 例题 10-16 UVa 12230(数学期望)
感觉数学期望的和化学里面求元素的相对原子质量的算法是一样的 就是同位素的含量乘上质量然后求和得出 这道题因为等待时机是0到2*l/v均匀分配的,所以平均时间就是l/v 再加上过河的l/v, 最后加上步 ...