Imports System.Text
Imports Microsoft.Kinect
Imports system.IO


Class RecorderHelper
    Shared buffer(4096 - 1) As Byte
    Shared _isRecording As Boolean

    Public Shared Property IsRecording As Boolean
        Get
            Return _isRecording
        End Get
        Set(value As Boolean)
            _isRecording = value
        End Set
    End Property

    Structure WAVEFORMATEX
        Public wFormatTag As UShort
        Public nChannels As UShort
        Public nSamplesPerSec As UInteger
        Public nAvgBytesPerSec As UInteger
        Public nBlockAlign As UShort
        Public wBitsPerSample As UShort
        Public cbSize As UShort
    End Structure

    Public Shared Sub WriteWavFile(source As KinectAudioSource, _fileStream As FileStream)
        Dim size As Integer = 0
        'wavヘッダーのプレースホルダーを書き込む
        WriteWavHeader(_fileStream, size)
        Using audioStream As Stream = source.Start()
            'オーディオストリームをファイルにブロック単位で書き込む
            Do While (audioStream.Read(buffer, 0, buffer.Length) > 0 AndAlso _isRecording)
                _fileStream.Write(buffer, 0, buffer.Length)
                size += buffer.Length
            Loop
        end using

        '実際のwavヘッダーを書き込む
        Dim prePosition As Long = _fileStream.Position
        _fileStream.Seek(0, SeekOrigin.Begin)
        WriteWavHeader(_fileStream, size)
        _fileStream.Seek(prePosition, SeekOrigin.Begin)
        _fileStream.Flush()
    End Sub

    Public Shared Sub WriteWavHeader(_stream As Stream, dataLength As Integer)
        Using memStream As MemoryStream = New MemoryStream(64 - 1)
            Dim cbFormat As Integer = 18
            Dim Format As New WAVEFORMATEX With {.wFormatTag = 1,
                                                 .nChannels = 1,
                                                 .nSamplesPerSec = 16000,
                                                 .nAvgBytesPerSec = 32000,
                                                 .nBlockAlign = 2,
                                                 .wBitsPerSample = 16,
                                                 .cbSize = 0
                                                }

            Using bw As New BinaryWriter(memStream)

                WriteString(memStream, "RIFF")
                bw.Write(dataLength + cbFormat + 4)
                WriteString(memStream, "WAVE")
                WriteString(memStream, "fmt ")
                bw.Write(cbFormat)

                bw.Write(Format.wFormatTag)
                bw.Write(Format.nChannels)
                bw.Write(Format.nSamplesPerSec)
                bw.Write(Format.nAvgBytesPerSec)
                bw.Write(Format.nBlockAlign)
                bw.Write(Format.wBitsPerSample)
                bw.Write(Format.cbSize)

                WriteString(memStream, "data")
                bw.Write(dataLength)
                memStream.WriteTo(_stream)
            End Using
        End Using
    End Sub

    Shared Sub WriteString(_stream As Stream, s As String)
        Dim bytes() As Byte = Encoding.ASCII.GetBytes(s)
        _stream.Write(bytes, 0, bytes.Length)
    End Sub
End Class