Kinectで音声を録音・再生するサンプル[3ページ目]

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

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

変数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

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

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30