Kinectで音声を録音・再生するサンプル

2012年7月19日(木)
薬師寺 国安

前ページからの続きです。

音声を録音するプロシージャ

変数recordingLengthに、録音時間を表す変数noに16KHz/2Bitを乗算した値を格納しておきます。
バッファを1023確保します。
録音されたwaveファイル(recordedFileName)を作成モード(FileMode.Create)で初期化した、新しいFileStreamのインスタンスmyfileStreamオブジェクトを作成します。
AudioRecord.KinectAudioRecord名前空間から、音声を書き出すWriteWavHeaderメソッドを呼び出します。書式は下記。
WriteWavHeader(書き出すストリーム, 書き出されるデータの長さ)
mykinectSensor.AudioSource.Start()メソッドでオーディオのキャプチャリングを開始し、ストリームからデータ ファイルをコピーします。
Stream.Readメソッドで、現在のストリームからバイト シーケンスを読み取り、読み取ったバイト数の分だけストリームの位置を進めます。書式は下記。
Stream.Read(バイト配列,バッファ内のバイトオフセット(通常0),読み取る最大バイト数)
読み取ったバイト数が0より大きく、かつ、バイト数と共に加算されるtotalCount変数の値が、recordingLengthより小さい間、Stream.Writeメソッドで、現在のストリームにバイト シーケンスを書き込みます。
書き込んだバイト数の分だけストリームの現在位置を進めます。書式は下記。
Stream.Write(バイト配列,バッファ内のバイトオフセット(通常0),ストリームに書き込むバイト数)
音声記録の終了するFinishedRecordingプロシージャを呼び出します。

  Private Sub RecordAudioGo(ByVal mykinectSensor As KinectSensor)
    If mykinectSensor Is Nothing Then
      Return
    End If
 
    Dim recordingLength As Integer = CInt(Fix(no)) * 2 * 16000
    Dim buffer(1023) As Byte
 
    Using myfileStream As New FileStream(recordedFileName, FileMode.Create)
      WriteWavHeader(myfileStream, recordingLength) 
        Using audioStream As Stream = mykinectSensor.AudioSource.Start()
          Dim count As Integer
          Dim totalCount As Integer = 0
          count = audioStream.Read(buffer, 0, buffer.Length)
          Do While count > 0 AndAlso totalCount < recordingLength
            myfileStream.Write(buffer, 0, count)
            totalCount += count
            count = audioStream.Read(buffer, 0, buffer.Length)
          Loop
        End Using
      End Using
      FinishedRecording()
  End Sub

音声記録が終了した時に呼び出されるメソッド

非UI スレッドのデータをUI スレッド上で処理するため、Dispatcher クラスを使います。Dispatcherクラスの詳細については下記URLを参照してください。
→参照:Dispatcher クラス/クラス詳細(msdn)

[録音開始]ボタンの使用を不可とし、[再生]ボタンの使用を可能にします。変数noは0で初期化し、TextBlock1の中も消去します。

  Private Sub FinishedRecording()
    Dispatcher.BeginInvoke(Sub()
                           recordButton.IsEnabled = False
                           playButton.IsEnabled = True
                           no = 0
                           TextBlock1.Text = String.Empty
                         End Sub)
  End Sub

[再生]ボタンがクリックされた時の処理

タイマーを停止します。
[再生]ボタンの使用を不可とします。
wavファイルがNothingまたは空ではなく、存在している場合は、MediaElementのSourceプロパティにwavファイルを指定します。
メディアの読み込み時の動作を設定する MediaStateのLoadBehaviorプロパティにPlayを指定し、メディアのアンロード時の動作 を設定するMediaStateのUnloadedBehaviorプロパティにはCloseと指定します。これで、MediaElementが読み込まれた時に再生され、アンロード時にMediaElementが閉じられます。
TextBlock1に「再生中・・・・」と表示します。

  Private Sub playButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles playButton.Click
    myTimer.Stop()
    playButton.IsEnabled = False
    If (Not String.IsNullOrEmpty(recordedFileName)) AndAlso File.Exists(recordedFileName) Then
      MediaElement1.Source = New Uri(recordedFileName, UriKind.RelativeOrAbsolute)
      MediaElement1.LoadedBehavior = MediaState.Play
      MediaElement1.UnloadedBehavior = MediaState.Close
      TextBlock1.Text = "再生中・・・・"
    End If
  End Sub

再生が終了した時の処理

[再生]ボタンと[記録開始]ボタンの使用を不可とし、TextBlock1の中も消去します。タイマーを停止し、noの値を0で初期化します。

  Private Sub MediaElement1_MediaEnded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MediaElement1.MediaEnded
    recordButton.IsEnabled = False
    playButton.IsEnabled = False
    TextBlock1.Text = String.Empty
    myTimer.Stop()
    myTimer = Nothing
    no = 0
  End Sub

Kinectとオーディオを停止させる処理

Kinect センサーが動作している場合は停止させ、オーディオが動作している場合はこれも停止させます。
Kinect センサーのリソースを解放します。

  Private Sub StopKinect(ByVal sensor As KinectSensor)
    If sensor Is Nothing = False Then
      If sensor.IsRunning Then
        sensor.Stop()
        If sensor.AudioSource Is Nothing = False Then
          sensor.AudioSource.Stop()
          sensor.Dispose()
        End If
      End If
    End If
  End Sub

ウィンドウが閉じられた時の処理

動作しているKinectセンサーを引数に、Kinect センサーとオーディオを停止させるStopKinectプロシージャを実行します。

  Private Sub MainWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
    StopKinect(KinectSensorChooser1.Kinect)
  End Sub
End Class

今回のサンプルは以上で終了です。

  • Kinectで音声を録音・再生するサンプル

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています