2013/09/17

C#.Net 透過Kinect取得聲音來源方位

Kinect麥克風以感應器為中心,辨識±50度聲音來源


透過聲音來源,我們可以再去限制其範圍,最後將其範圍資料導入,去得知聲音內容





XAML:
<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="250" Loaded="Window_Loaded_1">
    <Grid>
        <Label x:Name="label" Content="Label" HorizontalAlignment="Left" Margin="10,21,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window>


程式碼:
using Microsoft.Kinect;
using System.Windows;

namespace WpfApplication2
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private KinectSensor sensor;

        public MainWindow()
        {
            InitializeComponent();
            KinectSensor.KinectSensors.StatusChanged +=
                KinectSensors_StatusChanged;
            label.Content = "";
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            if (KinectSensor.KinectSensors.Count == 0)
            {
                MessageBox.Show("請將Kinect接上電腦");
            }
            else
            {
                this.sensor = KinectSensor.KinectSensors[0];
                this.sensor.Start();
                InitiateAudioSource();
            }
        }

        private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                case KinectStatus.Connected:
                    if (sensor == null)
                    {
                        this.sensor = KinectSensor.KinectSensors[0];
                        this.sensor.Start();
                    }
                    break;

                case KinectStatus.Disconnected:
                    this.sensor.Stop();
                    this.sensor = null;
                    break;
            }
        }

        private void InitiateAudioSource()
        {
            KinectAudioSource audioSource = sensor.AudioSource;
            audioSource.NoiseSuppression = true;
            audioSource.AutomaticGainControlEnabled = true;
            audioSource.BeamAngleMode = BeamAngleMode.Adaptive;
            audioSource.BeamAngleChanged += AudioSource_BeamAngleChanged;
            audioSource.Start();
        }


        private void AudioSource_BeamAngleChanged(object sender, BeamAngleChangedEventArgs e)
        {
            if (e.Angle > 0)
            {
                label.Content = string.Format("聲音是從右邊發出來的,"
                + "角度為{0:F}", e.Angle);
            }
            else if (e.Angle < 0)
            {
                label.Content = string.Format("聲音是從左邊發出來的,"
                + "角度為{0:F}", e.Angle);
            }
            else
            {
                label.Content = string.Format("聲音是從中間發出來的,"
                + "角度為{0:F}", e.Angle);
            }
        }
    }
}



該程式主要是透過BeamAngleChanged去取得到該事件,BeamAngleChanged又是什麼呢?
BeamAngleChanged是經由聲音方位變換後觸發的事件,不過該事件觸發會造成CPU使用率提高,所以可能會有延遲的現象發生

該事件觸發時,我們可以透過BeamAngleChangedEventArgs的變數e去取得到角度,再去辨別聲音方位



參考資料:
Kinect體感程式探索-使用C#
http://www.dotblogs.com.tw/marcus116/archive/2012/03/11/70655.aspx
http://epaper.gotop.com.tw/PDFSample/ACL038800.pdf
http://msdn.microsoft.com/en-us/library/microsoft.kinect.beamanglemode


圖片來源:
http://files.channel9.msdn.com/wlwimages/f1dda9cc6de74512b7c19f0101402403/KinectAudioPoisitioning2%5B2%5D.png