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

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

参照の追加

VS2010のメニューから「プロジェクト(P)/参照の追加(R)」と選択して、各種コンポーネントを追加しておきます。今回追加するのは、Microsoft.Samples.Kinect.WpfViewersとMicrosoft.Kinect、それにソリューションエクスプローラー内のDLLフォルダにあるAudioRecordの二つです。

Microsoft.Samples.Kinect.WpfViewersは、 Kinectforwindowssdkv1.zipを下記のURLよりダウンロードし、解凍してできるフォルダ
(\KinectforWindowsSDKV1\KinectforWindowsSDKV1\2.Setting Up Dev Environment\SettingUpDevEnvironmentVB\SettingUpDevEnvironment\bin\Release)内にある、
Microsoft.Samples.Kinect.WpfViewers.dllを、参照の追加で追加してください。

→参照:Kinectforwindowssdkv1(Rapidlibrary)

(*)KinectSensorChooserをデザイン画面上に追加した時点で、このMicrosoft.Samples.Kinect.WpfViewers.dllは既に参照されていることになります。

Microsoft.Kinect.dllは、C:\Program Files\Microsoft SDKs\Kinect\v1.5\Assemblies内に存在しますので、これを指定します。

AudioRecord.dllはソリューションエクスプローラー内にDLLというフォルダを作成し、その中に置いています。既に、このDLLは参照していますので、あらためて参照する必要はありませんが、参照のエラーが表示された場合は、再度「参照の追加」でDLLフォルダ内のAudioRecord.dllを指定してください。このDLLファイルは音声を録音するためのメソッドを含んでいます。

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

Option Strict On

音声を記録するクラスの含まれる、AudioRecord.KinectAudioRecord名前空間をインポートします。DLLフォルダ内のAudioRecord.dllに含まれています。

Imports AudioRecord.KinectAudioRecord

Imports Microsoft.Kinect

マルチスレッド プログラミングを実現するクラスと、インターフェースが用意されているクラスが含まれる、System.Threading名前空間をインポートします。

Imports System.Threading

タイマーの機能を提供するクラスの含まれる、System.Windows.Threading名前空間をインポートします。

Imports System.Windows.Threading
Imports System.IO
Class MainWindow
  Dim recordedFileName As String

タイマーを表すDispatcherTimerクラス用オブジェクト変数myTimerを宣言します。

 Dim myTimer As DispatcherTimer
 Dim no As Integer = 0

ページが読み込まれた時の処理

KinectSensorChooser1.KinectSensorChangedイベントで、Kinectが接続されているかどうかを確認します。
古いセンサーが動作している時は停止させ、古いKinectのオーディオストリームも停止させます。
新しいセンサーを取得し、Kinectセンサーを開始します。

Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
 
    AddHandler KinectSensorChooser1.KinectSensorChanged, Sub(kinectSender As Object, kinectArgs As DependencyPropertyChangedEventArgs)
                Dim oldSensor = CType(kinectArgs.OldValue, KinectSensor)
                If oldSensor Is Nothing = False Then
                  oldSensor.Stop()
                  oldSensor.AudioSource.Stop()
                End If
 
              Dim sensor As KinectSensor = CType(kinectArgs.NewValue, KinectSensor)
              sensor.Start()
                            End Sub
  End Sub

ComboBoxの値が選択された時の処理

ComboBoxから選択された項目を、ComboBoxItemにキャストし、Contentの値を整数にキャストして変数noに格納しておきます。
[記録開始]ボタンの使用を可能にします。
TextBlock2にメンバ変数noが持っている値を残り秒数として表示します。

  Private Sub ComboBox1_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles ComboBox1.SelectionChanged
    no = 0
    no = CInt(DirectCast(ComboBox1.SelectedItem, ComboBoxItem).Content)
    recordButton.IsEnabled = True
    TextBlock2.Text = "録音時間残り" & no.ToString & "秒"
  End Sub

[記録開始]ボタンがクリックされた時の処理

新しいタイマーのインスタンス、myTimerオブジェクトを作成します。
指定したタイマーの間隔が経過し、タイマーが有効である場合にTickイベントが発生しますが、この際、AddHandlerステートメントでイベントハンドラを登録し、Startメソッドでタイマーを開始します。
イベントハンドラ内では以下の処理を行います。
減算する変数noの値が0の時はタイマーを停止します。そうでない場合は、変数noの値を1ずつ減算します。ComboBoxより選択された数値から1ずつ減算されていき、TextBlock2には、その値を残り秒数として表示します。
[記録開始]ボタンの使用を不可とし、TextBlock1に「録音中・・・・」と表示します。録音された音声ファイル名は、現在の時間分秒に.wavという拡張子を付けたものとします。
スレッドが実行を開始するときに呼び出される、RecordAudioメソッドのアドレスで初期化された新しいThreadのオブジェクト、myThreadを作成します。
メソッドを渡すときは、AddressOf 演算子を使用します。Visual BasicではThreadStart コンストラクターが自動的に呼び出されます。
Startメソッドで、動作しているKinectセンサーを引数にThreadを開始します。
タイマーの間隔を1秒とします。

Threadコンストラクターの詳細については下記URLを参照してください。
→参照:Thread コンストラクター (ParameterizedThreadStart)(msdn)

  Private Sub recordButton_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles recordButton.Click
    myTimer = New DispatcherTimer
    AddHandler myTimer.Tick, Sub(timerSender As Object, timerArgs As EventArgs)
 
                             If no = 0 Then
                               myTimer.Stop()
                               no = 0
                               TextBlock2.Text = "録音時間残り" & no.ToString & "秒"
                             Else
                               TextBlock2.Text = "録音時間残り" & no.ToString & "秒"
                               no = no - 1
                             End If
                           End Sub
    myTimer.Start()
 
    recordButton.IsEnabled = False
    TextBlock1.Text = "録音中・・・・"
    recordedFileName = Date.Now.ToString("yyyyMMddHHmmss") & ".wav"
    Dim myThread As New Thread(AddressOf RecordAudio)
    myThread.Start(KinectSensorChooser1.Kinect)
    myTimer.Interval = New TimeSpan(0, 0, 1)
  End Sub

Threadで呼び出されるメソッド

KinectSensorを取得して、それを引数にRecordAudioGoプロシージャを実行します。

  Private Sub RecordAudio(ByVal kinectSensor As Object)
    Dim sensor As KinectSensor = CType(kinectSensor, KinectSensor)
    RecordAudioGo(sensor)
  End Sub
  • 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メルマガ会員のサービス内容を見る

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