Imports System
Imports System.Windows
Imports System.Windows.Media
Imports Microsoft.Kinect
Imports System.IO
Imports System.Threading
Imports System.ComponentModel

''' <summary>
''' Interaction logic for MainWindow.xaml
''' </summary>
''' <remarks></remarks>
Class MainWindow
    Implements INotifyPropertyChanged

    Private _recordingFileName As String
    Private _mplayer As MediaPlayer
    Private _isPlaying As Boolean
    Private _isNoiseSuppressionOn As Boolean
    Private _isAutomaticGainOn As Boolean
    Private _isAECOn As Boolean

    Public Sub New()

        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        AddHandler Me.Loaded, Sub()
                                  KinectSensor.KinectSensors(0).Start()
                              End Sub
        _mplayer = New MediaPlayer()
        AddHandler _mplayer.MediaEnded, Sub()
                                            _mplayer.Close()
                                            IsPlaying = False
                                        End Sub
        Me.DataContext = Me
    End Sub

    Private Function CreateAudioSource() As KinectAudioSource
        Dim source As KinectAudioSource = KinectSensor.KinectSensors(0).AudioSource
        source.BeamAngleMode = BeamAngleMode.Adaptive
        source.NoiseSuppression = _isNoiseSuppressionOn
        source.AutomaticGainControlEnabled = _isAutomaticGainOn

        If (IsAECOn) Then
            source.EchoCancellationMode = EchoCancellationMode.CancellationOnly
            source.AutomaticGainControlEnabled = False
            IsAutomaticGainOn = False
            source.EchoCancellationSpeakerIndex = 0
        End If

        Return source
    End Function

    Private lockObj As New Object()
    Private Sub RecordKinectAudio()
        SyncLock (lockObj)
            IsRecording = True

            Dim source As KinectAudioSource = CreateAudioSource()

            Dim time As String = DateTime.Now.ToString("hhmmss")
            _recordingFileName = time + ".wav"
            Using fileStream As New FileStream(_recordingFileName, FileMode.Create)
                RecorderHelper.WriteWavFile(source, fileStream)
            End Using

            IsRecording = False
        End SyncLock
    End Sub

    Private Sub Play()
        IsPlaying = True
        _mplayer.Open(New Uri(_recordingFileName, UriKind.Relative))
        _mplayer.Play()
    End Sub

    Private Sub Record()
        Dim _thread As New Thread(New ThreadStart(AddressOf RecordKinectAudio))
        _thread.Priority = ThreadPriority.Highest
        _thread.Start()
    End Sub

    Private Sub [Stop]()
        KinectSensor.KinectSensors(0).AudioSource.Stop()
        IsRecording = False
    End Sub

#Region "ユーザー操作"

    Private Sub button1_Click(sender As Object, e As RoutedEventArgs)
        Play()
    End Sub

    Private Sub button2_Click(sender As Object, e As RoutedEventArgs)
        Record()
    End Sub

    Private Sub button3_Click(sender As Object, e As RoutedEventArgs)
        [Stop]()
    End Sub

#End Region

#Region "プロパティ"

    Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    Private Sub NotifyPropertyChanged(propertyName As String)
        Dim handler As PropertyChangedEventHandler = PropertyChangedEvent
        If Nothing IsNot handler Then
            handler(Me, New PropertyChangedEventArgs(propertyName))
        End If
    End Sub

    Private Property IsPlaying As Boolean
        Get
            Return _isPlaying
        End Get
        Set(value As Boolean)
            If (_isPlaying <> value) Then
                _isPlaying = value
                NotifyPropertyChanged("IsRecordingEnabled")
            End If
        End Set
    End Property

    Private Property IsRecording As Boolean
        Get
            Return RecorderHelper.IsRecording
        End Get
        Set(value As Boolean)
            If (RecorderHelper.IsRecording <> value) Then
                RecorderHelper.IsRecording = value
                NotifyPropertyChanged("IsPlayingEnabled")
                NotifyPropertyChanged("IsRecordingEnabled")
                NotifyPropertyChanged("IsStopEnabled")
            End If
        End Set
    End Property

    Public ReadOnly Property IsPlayingEnabled As Boolean
        Get
            Return Not IsRecording
        End Get
    End Property

    Public ReadOnly Property IsRecordingEnabled As Boolean
        Get
            Return Not IsPlaying AndAlso Not IsRecording
        End Get
    End Property

    Public ReadOnly Property IsStopEnabled As Boolean
        Get
            Return IsRecording
        End Get
    End Property

    Public Property IsNoiseSuppressionOn As Boolean
        Get
            Return _isNoiseSuppressionOn
        End Get
        Set(value As Boolean)
            If (_isNoiseSuppressionOn <> value) Then
                _isNoiseSuppressionOn = value
                NotifyPropertyChanged("IsNoiseSuppressionOn")
            End If
        End Set
    End Property

    Public Property IsAutomaticGainOn As Boolean
        Get
            Return _isAutomaticGainOn
        End Get
        Set(value As Boolean)
            If (_isAutomaticGainOn <> value) Then
                _isAutomaticGainOn = value
                NotifyPropertyChanged("IsAutomaticGainOn")
            End If
        End Set
    End Property

    Public Property IsAECOn As Boolean
        Get
            Return _isAECOn
        End Get
        Set(value As Boolean)
            If (_isAECOn <> value) Then
                _isAECOn = value
                NotifyPropertyChanged("IsAECOn")
            End If
        End Set
    End Property
#End Region

End Class
