Important alert: (current site time 5/23/2013 2:43:19 PM EDT)
 

VB icon

Wave File Class RIFF

Email
Submitted on: 5/22/2012 4:04:27 PM
By: Paul Ishak 
Level: Advanced
User Rating: Unrated
Compatibility: VB.NET
Views: 1139
author picture
(About the author)
 
     Create a WAV file with software VS using a microphone. According to MS RIFF specification.
 
code:
Can't Copy and Paste this?
Click here for a copy-and-paste friendly version of this code!
 
Terms of Agreement:   
By using this code, you agree to the following terms...   
  1. You may use this code in your own programs (and may compile it into a program and distribute it in compiled format for languages that allow it) freely and with no charge.
  2. You MAY NOT redistribute this code (for example to a web site) without written permission from the original author. Failure to do so is a violation of copyright laws.   
  3. You may link to this code from another website, but ONLY if it is not wrapped in a frame. 
  4. You will abide by any additional copyright restrictions which the author may have placed in the code or code's description.
				
//**************************************
// Name: Wave File Class RIFF
// Description:Create a WAV file with software VS using a microphone. According to MS RIFF specification.
// By: Paul Ishak
//
//This code is copyrighted and has// limited warranties.Please see http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=8786&lngWId=10//for details.//**************************************

Imports System.Text
Public Class Wave
'By Paul Ishak
'WAVE PCM soundfile format 
'The Canonical WAVE file format
'As Described Here: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
Public FileHeader As Header
Public FileFormatSubChunk As FormatSubChunk
Public FileDataSubChunk As DataSubChunk
Public Structure WaveFileOptions
Public SampleRate As WavSampleRate
Public AudioFormat As Format
Public BitsPerSample As BitsPerSample
Public NumberOfChannels As NumberOfChannels
Public FormatSize As FormatSize
Public NumberOfSamples As UInt32
Public Data As Byte()
End Structure
'DATATYPE OFFSETEndianDescription
Structure Header
Public Property ChunkID As Byte() ' Dword 0 BigContains the letters "RIFF" in ASCII form(0x52494646 big-endian form).
Public Property ChunkSize As UInt32 'Dword 4 Little 36 + SubChunk2Size, or more precisely: 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
Public Property Format As Byte() 'Dword 8 BigContains the letters "WAVE" in ASCII form (0x57415645 big-endian form).
End Structure
Structure FormatSubChunk
Public Property Subchunk1ID As Byte() ' Dword 12BigContains the letters "fmt "(0x666d7420 big-endian form).
Public Property Subchunk1Size As UInt32 'Dword 16little 16 for PCM. This is the size of the rest of the Subchunk which follows this number.
Public Property AudioFormat As UInt16 ' Word20little PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression.
Public Property NumChannels As UInt16 ' Word22little Mono = 1, Stereo = 2, etc.
Public Property SampleRate As UInt32 'Dword 24little 8000, 44100, etc.
Public Property ByteRate As UInt32 ' Dword 28little == SampleRate * NumChannels * BitsPerSample/8
Public Property BlockAlign As UInt16 'Word32little == NumChannels * BitsPerSample/8
Public Property BitsPerSample As UInt16 'Word34little 8 bits = 8, 16 bits = 16, etc.
End Structure
Structure DataSubChunk
Public Property Subchunk2ID As Byte() ' Dword 36BigContains the letters "data"(0x64617461 big-endian form).
Public Property Subchunk2Size As UInt32 'Dword 40little == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
Public Property Data As Byte() ' VariableLength 44little The actual sound data.
End Structure
Public Function GetBytes() As Byte()
Dim Results As Byte() = Nothing
Results = CombineArrays(FileHeader.ChunkID, BitConverter.GetBytes(FileHeader.ChunkSize))
Results = CombineArrays(Results, FileHeader.Format)
Results = CombineArrays(Results, FileFormatSubChunk.Subchunk1ID)
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.Subchunk1Size))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.AudioFormat))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.NumChannels))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.SampleRate))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.ByteRate))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BlockAlign))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BitsPerSample))
Results = CombineArrays(Results, FileDataSubChunk.Subchunk2ID)
Results = CombineArrays(Results, BitConverter.GetBytes(FileDataSubChunk.Subchunk2Size))
Results = CombineArrays(Results, FileDataSubChunk.Data)
Return Results
End Function
Function CombineArrays(Array1() As Byte, Array2() As Byte) As Byte()
Dim AllResults(Array1.Length + Array2.Length - 1) As Byte
Array1.CopyTo(AllResults, 0)
Array2.CopyTo(AllResults, Array1.Length)
Return AllResults
End Function
Public Function ViewBinary(Optional HexOffsets As Boolean = True) As String
Dim asc As New StringBuilder
Dim Hex As New StringBuilder
Dim result As New StringBuilder
Dim MB As Byte() = Me.GetBytes
Select Case HexOffsets
Case True
result.Append(" OFFSET " & "" & "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F " & "" & "0123456789ABCDEF" & vbCrLf & vbCrLf)
Case False
result.Append(" OFFSET " & "" & "00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 " & "" & "0123456789012345" & vbCrLf & vbCrLf)
End Select
Dim Count As Integer = -16
For Each B As Byte In MB
Count = Count + 1
Hex.Append(B.ToString("X2") & " ")
If B > 32 And B < 128 Then
asc.Append(Chr(B))
Else
asc.Append(".")
End If
If Count Mod 16 = 0 Then
Select Case HexOffsets
Case True
result.Append(Count.ToString("X").PadLeft(8, "0") & "" & Hex.ToString & "" & asc.ToString & vbCrLf)
Case False
result.Append(Count.ToString.PadLeft(8, "0") & "" & Hex.ToString & "" & asc.ToString & vbCrLf)
End Select
Hex.Remove(0, Hex.ToString.Length)
asc.Remove(0, asc.ToString.Length)
End If
Next
Dim Counts As String = String.Empty
Select Case HexOffsets
Case True
Counts = (Count + (16 - (Count Mod 16))).ToString("X").PadLeft(8, "0").ToString
Case False
Counts = (Count + (16 - (Count Mod 16))).ToString.PadLeft(8, "0").ToString
End Select
Dim H As Integer = 64 - Hex.ToString.Length
Dim FinalHex As String = Hex.ToString & Space(H)
result.Append(Counts & "" & FinalHex & "" & asc.ToString & vbCrLf)
Return result.ToString
End Function
Public Shared Function SelectWavData(PictureBox As PictureBox, SelectionColor As Color, Origin As Integer, TextColor As Color, Optional SetLocal As Integer = -1) As SelectedData
Dim LocalMousePosition As Point = PictureBox.PointToClient(Cursor.Position)
Dim BM As New Bitmap(PictureBox.Size.Width, PictureBox.Size.Height)
Dim gr As Graphics = Graphics.FromImage(BM)
Dim Pen As New Pen(Brushes.Green, 1)
If SetLocal > -1 Then
LocalMousePosition.X = SetLocal
End If
If LocalMousePosition.X > PictureBox.ClientRectangle.Width Then
LocalMousePosition.X = PictureBox.ClientRectangle.Width
End If
If LocalMousePosition.X < 0 Then
LocalMousePosition.X = 0
End If
Dim Line1point1 As New Point(LocalMousePosition.X, 0)
Dim Line1point2 As New Point(LocalMousePosition.X, PictureBox.ClientRectangle.Height)
Dim Line2point1 As New Point(Origin, 0)
Dim Line2point2 As New Point(Origin, PictureBox.ClientRectangle.Height)
Dim Poly(3) As Point
Poly(0) = Line1point1
Poly(1) = Line2point1
Poly(2) = Line2point2
Poly(3) = Line1point2
If Origin = LocalMousePosition.X = False Then
gr.FillPolygon(New SolidBrush(SelectionColor), Poly)
End If
PictureBox.Image = BM
Select Case LocalMousePosition.X > Origin
Case True
gr.DrawString("Selected Range(" & Origin & "-" & LocalMousePosition.X & ")", New Font("Consolas", 8), New SolidBrush(TextColor), 1, 1)
Return New SelectedData(Origin, LocalMousePosition.X)
Case Else
gr.DrawString("Selected Range(" & LocalMousePosition.X & "-" & Origin & ")", New Font("Consolas", 8), New SolidBrush(TextColor), 1, 1)
Return New SelectedData(LocalMousePosition.X, Origin)
End Select
End Function
Public Shared Sub DrawWave(PictureBox As PictureBox, GridSize As Integer, CurrentWaveFile As Wave, GridColor As Color, SineColor As Color, CrosshairColor As Color)
Dim Bytes As Byte() = CurrentWaveFile.FileDataSubChunk.Data
Dim Data(0 To UBound(Bytes)) As UInt16
Dim Count As Integer = -1
For Each b As Byte In Bytes
Count = Count + 1
Data(Count) = CType(b, UInt16)
Next
Dim InvertedData(0 To UBound(Bytes)) As UInt32
For I = 0 To UBound(Data)
InvertedData(I) = ((255 - Data(I)) \ 2) + ((PictureBox.Height - (255 \ 2)) \ 2)
Next
Dim Points As New List(Of Point)
For I = 0 To UBound(InvertedData)
Dim Point As New Point(InvertedData(I), I + 1)
Points.Add(Point)
Next
Dim PointsArr() As Point = Points.ToArray
Dim BM As New Bitmap(PictureBox.Height, PictureBox.Width)
Dim gr As Graphics = Graphics.FromImage(BM)
Dim Pen As New Pen(SineColor, 1)
Dim pen2 As New Pen(CrosshairColor, 3)
Dim pen3 As New Pen(GridColor, 1)
For I = 1 To PictureBox.Width Step GridSize
gr.DrawLine(pen3, New Point(0, I), New Point(PictureBox.Height, I))
gr.DrawLine(pen3, New Point(I, 0), New Point(I, PictureBox.Width))
Next
gr.DrawLines(Pen, PointsArr)
gr.DrawLine(pen2, New Point(0, PictureBox.ClientRectangle.Width / 2), New Point(PictureBox.Height, PictureBox.ClientRectangle.Width / 2))
gr.DrawLine(pen3, New Point(0, PictureBox.ClientRectangle.Width / 2), New Point(PictureBox.Height, PictureBox.ClientRectangle.Width / 2))
BM.RotateFlip(RotateFlipType.Rotate270FlipNone)
PictureBox.BackgroundImage = BM
End Sub
Public Structure SelectedData
Public SelectionStart As Integer
Public SelectionEnd As Integer
Sub New(SelectionStart As Integer, SelectionEnd As Integer)
Me.SelectionStart = SelectionStart
Me.SelectionEnd = SelectionEnd
End Sub
End Structure
Sub New(Options As WaveFileOptions)
FileHeader.ChunkID = Encoding.ASCII.GetBytes("RIFF")
FileFormatSubChunk.Subchunk1Size = Options.FormatSize
FileFormatSubChunk.NumChannels = Options.NumberOfChannels
FileFormatSubChunk.BitsPerSample = Options.BitsPerSample
FileDataSubChunk.Subchunk2Size = Options.NumberOfSamples * Options.NumberOfChannels * Options.BitsPerSample / 8
FileHeader.ChunkSize = 4 + (8 + FileFormatSubChunk.Subchunk1Size) + (8 + FileDataSubChunk.Subchunk2Size)
FileHeader.Format = Encoding.ASCII.GetBytes("WAVE")
FileFormatSubChunk.Subchunk1ID = Encoding.ASCII.GetBytes("fmt ")
FileFormatSubChunk.AudioFormat = Options.AudioFormat
FileFormatSubChunk.SampleRate = Options.SampleRate
FileFormatSubChunk.ByteRate = Options.SampleRate * Options.NumberOfChannels * Options.BitsPerSample / 8
FileFormatSubChunk.BlockAlign = Options.NumberOfChannels * Options.BitsPerSample / 8
FileDataSubChunk.Subchunk2ID = Encoding.ASCII.GetBytes("data")
FileDataSubChunk.Data = Options.Data
End Sub
Public Enum WavSampleRate As UInt32
hz8000 = 8000
hz11025 = 11025
hz16000 = 16000
hz22050 = 22050
hz32000 = 32000
hz44100 = 44100
hz48000 = 48000
hz96000 = 96000
hz192000 = 192000
End Enum
Public Enum Format As UInt16
Standard = 1
End Enum
Public Enum BitsPerSample As UInt16
bps_8 = 8
bps_16 = 16
bps_32 = 32
bps_64 = 64
bps_128 = 128
bps_256 = 256
End Enum
Public Enum NumberOfChannels As UInt16
Mono = 1
Stereo = 2
End Enum
Public Enum FormatSize As UInt32
PCM = 16
End Enum
End Class


Other 17 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this code (in the Advanced category)?
(The code with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular code, please click here instead.)
 

To post feedback, first please login.