Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
WaveProof - CWaveReader.vb

CWaveReader.vb

Caricato da: Totem
Scarica il programma completo

  1. Class CWAVReader
  2.     'by ENO
  3.     'To Read a WAV File and Populate basic Properties
  4.     'On 3/11/2007
  5.     'For AfricaDotNet user group
  6.  
  7.     'BigEndian bytes number 0 - 4
  8.     Private mChunkID As String
  9.     Public ReadOnly Property ChunkID() As String
  10.         Get
  11.             ChunkID = mChunkID
  12.         End Get
  13.     End Property
  14.     'from the Constructor
  15.     Private mWAVFileName As String
  16.     Public ReadOnly Property WAVFileName() As String
  17.         Get
  18.             WAVFileName = mWAVFileName
  19.         End Get
  20.     End Property
  21.  
  22.     'Constructor to open stream
  23.     Sub New(ByVal SoundFilePathName As String)
  24.         mWAVFileName = SoundFilePathName
  25.         mOpen = OpenWAVStream(mWAVFileName)
  26.         '******************* MAIN WORK HERE ******************
  27.         'Parse the WAV file and read the
  28.         If mOpen Then
  29.             'Read the Header Data in THIS ORDER
  30.             'Each Read results to the File Pointer Moving
  31.             mChunkID = ReadChunkID(mWAVStream)
  32.             mChunkSize = ReadChunkSize(mWAVStream)
  33.             mFormatID = ReadFormatID(mWAVStream)
  34.             mSubChunkID = ReadSubChunkID(mWAVStream)
  35.             mSubChunkSize = ReadSubChunkSize(mWAVStream)
  36.             mAudioFormat = ReadAudioFormat(mWAVStream)
  37.             mNumChannels = ReadNumChannels(mWAVStream)
  38.             mSampleRate = ReadSampleRate(mWAVStream)
  39.             mByteRate = ReadByteRate(mWAVStream)
  40.             mBlockAlign = ReadBlockAlign(mWAVStream)
  41.             mBitsPerSample = ReadBitsPerSample(mWAVStream)
  42.             mSubChunkIDTwo = ReadSubChunkIDTwo(mWAVStream)
  43.             mSubChunkSizeTwo = ReadSubChunkSizeTwo(mWAVStream)
  44.             mWaveSoundData = ReadWAVSampleData(mWAVStream)
  45.             mWAVStream.Close()
  46.         End If
  47.     End Sub
  48.  
  49.     'Property to tell if stream is open or not
  50.     Private mOpen As Boolean
  51.     Public ReadOnly Property IsWAVFileOPen() As Boolean
  52.         Get
  53.             IsWAVFileOPen = mOpen
  54.         End Get
  55.     End Property
  56.  
  57.     'Open an IO Binary Stream to Read the WavFile
  58.     Private mWAVStream As IO.BinaryReader
  59.     Private Function OpenWAVStream(ByVal SoundFilePathName As String) As Boolean
  60.         Dim WAVStreamReader As IO.StreamReader
  61.         WAVStreamReader = New IO.StreamReader(SoundFilePathName)
  62.         mWAVStream = New IO.BinaryReader(WAVStreamReader.BaseStream)
  63.         If mWAVStream Is Nothing Then
  64.             Return False
  65.         Else
  66.             Return True
  67.         End If
  68.     End Function
  69.  
  70.     'Dipose the resource
  71.     Sub Dispose()
  72.         If Not mWAVStream Is Nothing Then
  73.             mWAVStream.Close()
  74.             mWAVStream = Nothing
  75.             mOpen = False
  76.         End If
  77.         GC.SuppressFinalize(Me)
  78.     End Sub
  79.  
  80.     'Close the stream
  81.     Protected Overrides Sub Finalize()
  82.         Me.Dispose()
  83.         MyBase.Finalize()
  84.     End Sub
  85.  
  86.     'Read the ChunkID and return a string
  87.     Private Function ReadChunkID(ByVal WAVIOstreamReader As IO.BinaryReader) As String
  88.         Dim DataBuffer() As Byte
  89.         Dim DataEncoder As System.Text.ASCIIEncoding
  90.         Dim TempString As Char()
  91.  
  92.         DataEncoder = New System.Text.ASCIIEncoding
  93.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  94.         'Ensure we have data to spit out
  95.         If DataBuffer.Length <> 0 Then
  96.             TempString = DataEncoder.GetChars(DataBuffer, 0, 4)
  97.             Return TempString(0) & TempString(1) & TempString(2) & TempString(3)
  98.         Else
  99.             Return ""
  100.         End If
  101.     End Function
  102.  
  103.     'Chunk size little endian bytes No. 5-13
  104.     Private mChunkSize As Long
  105.     Public ReadOnly Property ChunkSize() As Long
  106.         Get
  107.             ChunkSize = mChunkSize
  108.         End Get
  109.     End Property
  110.  
  111.     'Read the ChunkID and return a string
  112.     Private Function ReadChunkSize(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  113.         Dim DataBuffer() As Byte
  114.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  115.         ReadChunkSize = CLng(GetLittleEndianStringValue(DataBuffer))
  116.     End Function
  117.  
  118.     'BigEndian bytes number 9 - 13
  119.     Private mFormatID As String
  120.     Public ReadOnly Property FormatID() As String
  121.         Get
  122.             FormatID = mFormatID
  123.         End Get
  124.     End Property
  125.  
  126.     'Read the Format and return a string
  127.     Private Function ReadFormatID(ByVal WAVIOstreamReader As IO.BinaryReader) As String
  128.         Dim DataBuffer() As Byte
  129.         Dim DataEncoder As System.Text.ASCIIEncoding
  130.         Dim TempString As Char()
  131.  
  132.         DataEncoder = New System.Text.ASCIIEncoding
  133.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  134.         'Ensure we have data to spit out
  135.         If DataBuffer.Length <> 0 Then
  136.             TempString = DataEncoder.GetChars(DataBuffer, 0, 4)
  137.             Return TempString(0) & TempString(1) & TempString(2) & TempString(3)
  138.         Else
  139.             Return ""
  140.         End If
  141.     End Function
  142.  
  143.     'Little Endian bytes number 13 - 17
  144.     Private mSubChunkID As String
  145.     Public ReadOnly Property SubChunkID() As String
  146.         Get
  147.             SubChunkID = mSubChunkID
  148.         End Get
  149.     End Property
  150.  
  151.     'Read the sub chunkID and return a string
  152.     Private Function ReadSubChunkID(ByVal WAVIOstreamReader As IO.BinaryReader) As String
  153.         Dim DataBuffer() As Byte
  154.         Dim DataEncoder As System.Text.ASCIIEncoding
  155.         Dim TempString As Char()
  156.  
  157.         DataEncoder = New System.Text.ASCIIEncoding
  158.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  159.         'Ensure we have data to spit out
  160.         If DataBuffer.Length <> 0 Then
  161.             TempString = DataEncoder.GetChars(DataBuffer, 0, 4)
  162.             Return TempString(0) & TempString(1) & TempString(2) & TempString(3)
  163.         Else
  164.             Return ""
  165.         End If
  166.     End Function
  167.  
  168.     'SubChunk size little endian bytes No. 17-21
  169.     Private mSubChunkSize As Long
  170.     Public ReadOnly Property SubChunkSize() As Long
  171.         Get
  172.             SubChunkSize = mSubChunkSize
  173.         End Get
  174.     End Property
  175.  
  176.     'Read the SubChunkID and return a string
  177.     Private Function ReadSubChunkSize(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  178.         Dim DataBuffer() As Byte
  179.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  180.         ReadSubChunkSize = CLng(GetLittleEndianStringValue(DataBuffer))
  181.     End Function
  182.  
  183.     'Audio Format little endian bytes No. 20-22
  184.     Private mAudioFormat As Long
  185.     Public ReadOnly Property AudioFormat() As Long
  186.         Get
  187.             AudioFormat = mAudioFormat
  188.         End Get
  189.     End Property
  190.  
  191.     'Read the SubChunkID and return a string
  192.     Private Function ReadAudioFormat(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  193.         Dim DataBuffer() As Byte
  194.         DataBuffer = WAVIOstreamReader.ReadBytes(2)
  195.         ReadAudioFormat = CLng(GetLittleEndianStringValueDuplex(DataBuffer))
  196.     End Function
  197.  
  198.     'Number of Channels little endian bytes No. 22-24
  199.     Private mNumChannels As Long
  200.     Public ReadOnly Property NumChannels() As Long
  201.         Get
  202.             NumChannels = mNumChannels
  203.         End Get
  204.     End Property
  205.  
  206.     'Read the SubChunkID and return a string
  207.     Private Function ReadNumChannels(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  208.         Dim DataBuffer() As Byte
  209.         DataBuffer = WAVIOstreamReader.ReadBytes(2)
  210.         ReadNumChannels = CLng(GetLittleEndianStringValueDuplex(DataBuffer))
  211.     End Function
  212.  
  213.     'Sample Rate little endian bytes No. 24-28
  214.     Private mSampleRate As Long
  215.     Public ReadOnly Property SampleRate() As Long
  216.         Get
  217.             SampleRate = mSampleRate
  218.         End Get
  219.     End Property
  220.  
  221.     Public ReadOnly Property Frequency() As Long
  222.         Get
  223.             Frequency = mSampleRate
  224.         End Get
  225.     End Property
  226.  
  227.     'Get the number of samples
  228.     Public ReadOnly Property NumberOfSamples() As Long
  229.         Get
  230.             NumberOfSamples = SubChunkSizeTwo * 8 \ (NumChannels * BitsPerSample)
  231.         End Get
  232.     End Property
  233.  
  234.     'Read the Sample Rate and return a string
  235.     Private Function ReadSampleRate(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  236.         Dim DataBuffer() As Byte
  237.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  238.         ReadSampleRate = CLng(GetLittleEndianStringValue(DataBuffer))
  239.     End Function
  240.  
  241.     'Byte Rate little endian bytes No. 28-32
  242.     Private mByteRate As Long
  243.     Public ReadOnly Property ByteRate() As Long
  244.         Get
  245.             ByteRate = mByteRate
  246.         End Get
  247.     End Property
  248.  
  249.     'Get the play time in seconds
  250.     Public ReadOnly Property PlayTimeSeconds() As Single
  251.         Get
  252.             PlayTimeSeconds = CSng(SubChunkSizeTwo / ByteRate)
  253.         End Get
  254.     End Property
  255.  
  256.     'Read the Byte Rate and return a string
  257.     Private Function ReadByteRate(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  258.         Dim DataBuffer() As Byte
  259.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  260.         ReadByteRate = CLng(GetLittleEndianStringValue(DataBuffer))
  261.     End Function
  262.  
  263.     'Block Align little endian bytes No. 32-34
  264.     Private mBlockAlign As Long
  265.     Public ReadOnly Property BlockAlign() As Long
  266.         Get
  267.             BlockAlign = mBlockAlign
  268.         End Get
  269.     End Property
  270.  
  271.     'Read the Block Align and return a string
  272.     Private Function ReadBlockAlign(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  273.         Dim DataBuffer() As Byte
  274.         DataBuffer = WAVIOstreamReader.ReadBytes(2)
  275.         ReadBlockAlign = CLng(GetLittleEndianStringValueDuplex(DataBuffer))
  276.  
  277.     End Function
  278.  
  279.     'Buits Per Sample little endian bytes No. 34-36
  280.     Private mBitsPerSample As Long
  281.     Public ReadOnly Property BitsPerSample() As Long
  282.         Get
  283.             BitsPerSample = mBitsPerSample
  284.         End Get
  285.     End Property
  286.  
  287.     'Read the Bits Per Sample and return a string
  288.     Private Function ReadBitsPerSample(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  289.         Dim DataBuffer() As Byte
  290.         DataBuffer = WAVIOstreamReader.ReadBytes(2)
  291.         ReadBitsPerSample = CLng(GetLittleEndianStringValueDuplex(DataBuffer))
  292.  
  293.     End Function
  294.  
  295.     'Buits Per Sample Big endian bytes No. 36-40
  296.     Private mSubChunkIDTwo As String
  297.     Public ReadOnly Property SubChunkIDTwo() As String
  298.         Get
  299.             SubChunkIDTwo = mSubChunkIDTwo
  300.         End Get
  301.     End Property
  302.  
  303.     'Read the SubChunkTwoID Sample and return a string
  304.     Private Function ReadSubChunkIDTwo(ByVal WAVIOstreamReader As IO.BinaryReader) As String
  305.         Dim DataBuffer() As Byte
  306.         Dim DataEncoder As System.Text.ASCIIEncoding
  307.         Dim TempString As Char()
  308.         Dim Datastr As String
  309.  
  310.         DataEncoder = New System.Text.ASCIIEncoding
  311.         DataBuffer = WAVIOstreamReader.ReadBytes(1)
  312.         'Ensure we have data to spit out
  313.         TempString = DataEncoder.GetChars(DataBuffer, 0, 1)
  314.         Datastr = TempString(0)
  315.         If Datastr <> "d" Then
  316.             'Read until you get data
  317.             DataBuffer = WAVIOstreamReader.ReadBytes(1)
  318.             TempString = DataEncoder.GetChars(DataBuffer, 0, 1)
  319.             Datastr = TempString(0)
  320.             While Datastr <> "d"
  321.                 DataBuffer = WAVIOstreamReader.ReadBytes(1)
  322.                 TempString = DataEncoder.GetChars(DataBuffer, 0, 1)
  323.                 Datastr = TempString(0)
  324.             End While
  325.             DataBuffer = WAVIOstreamReader.ReadBytes(3)
  326.             TempString = DataEncoder.GetChars(DataBuffer, 0, 3)
  327.             Datastr = "d" & (TempString(0) & TempString(1) & TempString(2))
  328.  
  329.         Else
  330.             DataBuffer = WAVIOstreamReader.ReadBytes(3)
  331.             TempString = DataEncoder.GetChars(DataBuffer, 0, 3)
  332.             Datastr = "d" & (TempString(0) & TempString(1) & TempString(2))
  333.             Return Datastr
  334.         End If
  335.     End Function
  336.  
  337.     'Buits Per Sample little endian bytes No. 40-44
  338.     Private mSubChunkSizeTwo As Long
  339.     Public ReadOnly Property SubChunkSizeTwo() As Long
  340.         Get
  341.             SubChunkSizeTwo = mSubChunkSizeTwo
  342.         End Get
  343.     End Property
  344.  
  345.     'Read the Bits Per Sample and return a string
  346.     Private Function ReadSubChunkSizeTwo(ByVal WAVIOstreamReader As IO.BinaryReader) As Long
  347.         Dim DataBuffer() As Byte
  348.         DataBuffer = WAVIOstreamReader.ReadBytes(4)
  349.         ReadSubChunkSizeTwo = CLng(GetLittleEndianStringValue(DataBuffer))
  350.     End Function
  351.  
  352.     'Get the little endian value
  353.     Private Function GetLittleEndianStringValueDuplex(ByVal DataBuffer() As Byte) As String
  354.         Dim ValueString As String = "&h"
  355.  
  356.         If DataBuffer.Length <> 0 Then
  357.             'In little endian
  358.             If Hex(DataBuffer(1)).Length = 1 Then
  359.                 ValueString &= "0" & Hex(DataBuffer(1))
  360.             Else
  361.                 ValueString &= Hex(DataBuffer(1))
  362.             End If
  363.  
  364.             If Hex(DataBuffer(0)).Length = 1 Then
  365.                 ValueString &= "0" & Hex(DataBuffer(0))
  366.             Else
  367.                 ValueString &= Hex(DataBuffer(0))
  368.             End If
  369.         Else
  370.             ValueString = "0"
  371.         End If
  372.         GetLittleEndianStringValueDuplex = ValueString
  373.     End Function
  374.  
  375.     'Get the small endian value
  376.     Private Function GetLittleEndianStringValue(ByVal DataBuffer() As Byte) As String
  377.         Dim ValueString As String = "&h"
  378.  
  379.         If DataBuffer.Length <> 0 Then
  380.             'In little endian we reverse the aray data and pad the same where the
  381.             'length is 1
  382.             If Hex(DataBuffer(3)).Length = 1 Then
  383.                 ValueString &= "0" & Hex(DataBuffer(3))
  384.             Else
  385.                 ValueString &= Hex(DataBuffer(3))
  386.             End If
  387.  
  388.             If Hex(DataBuffer(2)).Length = 1 Then
  389.                 ValueString &= "0" & Hex(DataBuffer(2))
  390.             Else
  391.                 ValueString &= Hex(DataBuffer(2))
  392.             End If
  393.  
  394.             If Hex(DataBuffer(1)).Length = 1 Then
  395.                 ValueString &= "0" & Hex(DataBuffer(1))
  396.             Else
  397.                 ValueString &= Hex(DataBuffer(1))
  398.             End If
  399.  
  400.             If Hex(DataBuffer(0)).Length = 1 Then
  401.                 ValueString &= "0" & Hex(DataBuffer(0))
  402.             Else
  403.                 ValueString &= Hex(DataBuffer(0))
  404.             End If
  405.         Else
  406.             ValueString = "0"
  407.         End If
  408.         GetLittleEndianStringValue = ValueString
  409.     End Function
  410.  
  411.     'Buffers to hold Data
  412.     Private mWaveSoundData As Byte()
  413.  
  414.     'Return the sound Data to display
  415.     ReadOnly Property WaveSoundData() As Byte()
  416.         Get
  417.             WaveSoundData = mWaveSoundData
  418.         End Get
  419.     End Property
  420.  
  421.     'Read Data to Pans both left and right
  422.     Private Function ReadWAVSampleData(ByVal WAVIOstreamReader As IO.BinaryReader) As Byte()
  423.         Dim tempBuffer() As Byte
  424.         tempBuffer = WAVIOstreamReader.ReadBytes(CInt(mSubChunkSizeTwo))
  425.         Return tempBuffer
  426.     End Function
  427.  
  428.     'returns the wave data as a byte array
  429.     Public Function GetSoundDataValue() As Int16()
  430.         Dim DataCount As Integer
  431.         Dim tempStream As IO.BinaryReader
  432.         tempStream = New IO.BinaryReader(New IO.MemoryStream(mWaveSoundData))
  433.         tempStream.BaseStream.Position = 0
  434.         'Create a data array to hold the data read from the stream
  435.         'Read chunks of int16 from the stream (already aligned!)
  436.         Dim tempData(CInt(tempStream.BaseStream.Length / 2)) As Int16
  437.         While DataCount <= tempData.Length - 2
  438.             tempData(DataCount) = tempStream.ReadInt16()
  439.             DataCount += 1
  440.         End While
  441.         tempStream.Close()
  442.         tempStream = Nothing
  443.         Return tempData
  444.     End Function
  445. End Class