Answered by:
System.NullReferenceException was unhandled trying to read RIFF file header using FileGetObject()

Question
-
Structure RIFFHeader <VBFixedString(4)> Public RIFFtag As String ' "RIFF" Public Filesize As Long <VBFixedString(4)> Public WAVtag As String ' "WAVE" <VBFixedString(4)> Public FMTtag As String ' "fmt " Public FMTsize As Long Public CompressType As Integer Public Channels As Integer Public SampleRate As Long ' Samples per sec Public BytesPerSecond As Long ' = SampleRate * BytesPerSample Public BytesPerSample As Integer Public BitsPerSample As Integer End Structure
In a function to read the RIFF header...
Dim WaveHeader As New RIFFHeader FileOpen(1, WaveFile, OpenMode.Binary) FileGetObject(1, WaveHeader)
I'm getting an error
System.NullReferenceException was unhandled Message=Object reference not set to an instance of an object. Source=Microsoft.VisualBasic StackTrace: at Microsoft.VisualBasic.FileSystem.FileGetObject(Int32 FileNumber, Object& Value, Int64 RecordNumber) at Time.Radio.OnTheAir.WavLength(String WaveFile) in C:\Users\jhart\Personal\Time.Radio\Time.Radio\OnTheAir.vb:line 96 at Time.Radio.OnTheAir.Ticker_Tick(Object sender, EventArgs e) in C:\Users\jhart\Personal\Time.Radio\Time.Radio\OnTheAir.vb:line 45 at System.Windows.Forms.Timer.OnTick(EventArgs e) at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) at Time.Radio.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() InnerException:
I don't know how to fix this.Wednesday, August 29, 2012 8:02 PM
Answers
-
Cut down copy of your code for anyone who might follow in my footsteps
Declarations:
Const _Byte As Integer = 1 Const _word As Integer = 2 Const _dword As Integer = 4 Const _qword As Integer = 8 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 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 OFFSET Endian Description Public Structure Header Public Property ChunkID As Byte() ' Dword 0 Big Contains 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 Big Contains the letters "WAVE" in ASCII form (0x57415645 big-endian form). End Structure Public Structure FormatSubChunk Public Property Subchunk1ID As Byte() ' Dword 12 Big Contains the letters "fmt "(0x666d7420 big-endian form). Public Property Subchunk1Size As UInt32 ' Dword 16 little 16 for PCM. This is the size of the rest of the Subchunk which follows this number. Public Property AudioFormat As UInt16 ' Word 20 little PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression. Public Property NumChannels As UInt16 ' Word 22 little Mono = 1, Stereo = 2, etc. Public Property SampleRate As UInt32 ' Dword 24 little 8000, 44100, etc. Public Property ByteRate As UInt32 ' Dword 28 little == SampleRate * NumChannels * BitsPerSample/8 Public Property BlockAlign As UInt16 ' Word 32 little == NumChannels * BitsPerSample/8 Public Property BitsPerSample As UInt16 ' Word 34 little 8 bits = 8, 16 bits = 16, etc. End Structure Public Structure DataSubChunk Public Property Subchunk2ID As Byte() ' Dword 36 Big Contains the letters "data"(0x64617461 big-endian form). Public Property Subchunk2Size As UInt32 ' Dword 40 little == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data. Public Property Data As Byte() ' VariableLength 44 little The actual sound data. End Structure Public FileHeader As Header Public FileFormatSubChunk As FormatSubChunk Public FileDataSubChunk As DataSubChunk
Logic:
Public Sub OpenFile(FileName As String) Try If Not My.Computer.FileSystem.FileExists(FileName) Then Throw New Exception("File Does Not Exist!") End If Dim FileBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(FileName) 'Get Header Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword) Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0) Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword) 'Get FormatSubChunk Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword) Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0) Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0) Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0) Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0) Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0) Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0) Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0) 'Get DataSubChunck Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword) Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0) Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size) Catch Throw New Exception("File Is Invalid or corrupt!") End Try End Sub Private Function GetDataFromByteArray(ByVal ByteArray As Byte(), ByVal BlockOffset As Long, ByVal RangeStartOffset As Long, ByVal DataLength As Long) As Byte() On Error Resume Next Dim AnswerL As New List(Of Byte) Dim Answer(0 To CInt((DataLength - 1))) As Byte Dim CurrentOffset As Long For I = 0 To UBound(ByteArray) CurrentOffset = BlockOffset + I If CurrentOffset >= RangeStartOffset And CurrentOffset <= RangeStartOffset + DataLength Then AnswerL.Add(ByteArray(I)) End If Next Dim Count As Integer = 0 For Each bt As Byte In AnswerL Answer(Count) = bt Count += 1 Next GetDataFromByteArray = Answer End Function
The length of the sound file in seconds:
Function WavLength(ByVal WaveFile As String) As Long OpenFile(WaveFile) WavLength = Me.FileDataSubChunk.Subchunk2Size / Me.FileFormatSubChunk.ByteRate ' length in seconds End Function
Responsibilities first...
- Marked as answer by John L Hart IV Saturday, September 1, 2012 2:08 AM
Wednesday, August 29, 2012 9:02 PM
All replies
-
Please try the openfile method in my class I wrote, you can then access the individual structures of the wave file.
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 Const _Byte As Integer = 1 Const _word As Integer = 2 Const _dword As Integer = 4 Const _qword As Integer = 8 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 OFFSET Endian Description Structure Header Public Property ChunkID As Byte() ' Dword 0 Big Contains 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 Big Contains the letters "WAVE" in ASCII form (0x57415645 big-endian form). End Structure Structure FormatSubChunk Public Property Subchunk1ID As Byte() ' Dword 12 Big Contains the letters "fmt "(0x666d7420 big-endian form). Public Property Subchunk1Size As UInt32 ' Dword 16 little 16 for PCM. This is the size of the rest of the Subchunk which follows this number. Public Property AudioFormat As UInt16 ' Word 20 little PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression. Public Property NumChannels As UInt16 ' Word 22 little Mono = 1, Stereo = 2, etc. Public Property SampleRate As UInt32 ' Dword 24 little 8000, 44100, etc. Public Property ByteRate As UInt32 ' Dword 28 little == SampleRate * NumChannels * BitsPerSample/8 Public Property BlockAlign As UInt16 ' Word 32 little == NumChannels * BitsPerSample/8 Public Property BitsPerSample As UInt16 ' Word 34 little 8 bits = 8, 16 bits = 16, etc. End Structure Structure DataSubChunk Public Property Subchunk2ID As Byte() ' Dword 36 Big Contains the letters "data"(0x64617461 big-endian form). Public Property Subchunk2Size As UInt32 ' Dword 40 little == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data. Public Property Data As Byte() ' VariableLength 44 little The actual sound data. End Structure Public Sub OpenFile(FileName As String) Try If Not InStr(LCase(FileName), ".wav") Then Throw New Exception("Invalid File Extension Specified!") If Not My.Computer.FileSystem.FileExists(FileName) Then Throw New Exception("File Does Not Exist!") Dim FileBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(FileName) 'Get Header Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword) Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0) Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword) 'Get FormatSubChunk Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword) Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0) Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0) Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0) Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0) Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0) Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0) Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0) 'Get DataSubChunck Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword) Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0) Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size) Catch Throw New Exception("File Is Invalid or corrupt!") End Try End Sub Public Sub SetDirectBytes(FileBytes() As Byte) Try 'Get Header Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword) Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0) Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword) 'Get FormatSubChunk Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword) Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0) Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0) Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0) Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0) Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0) Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0) Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0) 'Get DataSubChunck Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword) Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0) Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size) Catch ex As Exception ' Throw New Exception("File Is Invalid or corrupt!") MsgBox(ex.StackTrace) End Try End Sub 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 Private Function GetDataFromByteArray(ByVal ByteArray As Byte(), ByVal BlockOffset As Long, ByVal RangeStartOffset As Long, ByVal DataLength As Long) As Byte() On Error Resume Next Dim AnswerL As New List(Of Byte) Dim Answer(0 To CInt((DataLength - 1))) As Byte Dim CurrentOffset As Long For I = 0 To UBound(ByteArray) CurrentOffset = BlockOffset + I If CurrentOffset >= RangeStartOffset Then If CurrentOffset <= RangeStartOffset + DataLength Then AnswerL.Add(ByteArray(I)) End If End If Next Dim count As Integer = -1 For Each bt As Byte In AnswerL count = count + 1 Answer(count) = bt Next Return Answer 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) ' gr.DrawPolygon(New Pen(Brushes.Yellow, 2), 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) 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(Brushes.Red, 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
If you want something you've never had, you need to do something you've never done.
- Proposed as answer by Mike Feng Friday, August 31, 2012 7:49 AM
Wednesday, August 29, 2012 8:07 PM -
I don't want to read the entire file, I'm just trying to determine the playing length - as follows.
WavLength = WaveHeader.Filesize \ WaveHeader.BytesPerSecond ' length in seconds
Responsibilities first...
Wednesday, August 29, 2012 8:14 PM -
I don't want to read the entire file, I'm just trying to determine the playing length - as follows.
WavLength = WaveHeader.Filesize \ WaveHeader.BytesPerSecond ' length in seconds
Responsibilities first...
If you use the open file method in my class, you can then access any element of the riff wave header. You can look and see how I am populating that field if you somehow think loading the file will consume too many resources. But the fields you are looking for are populated(individually) when you load my class.If you want something you've never had, you need to do something you've never done.
Wednesday, August 29, 2012 8:19 PM -
The code you offered worked... got me past my problem (thanks)
WavLength = Me.FileDataSubChunk.Subchunk2Size / Me.FileFormatSubChunk.ByteRate ' length in seconds
Yields the length of the audio in seconds
Responsibilities first...
- Proposed as answer by Mike Feng Friday, August 31, 2012 7:49 AM
Wednesday, August 29, 2012 8:59 PM -
The strange thing is that when I used the FileGet() method instead - the NullReferenceException went away and I was able to pull something (admittedly garbage) from the file... Why was FileGetObject upset with me?...
Responsibilities first...
Wednesday, August 29, 2012 8:59 PM -
Cut down copy of your code for anyone who might follow in my footsteps
Declarations:
Const _Byte As Integer = 1 Const _word As Integer = 2 Const _dword As Integer = 4 Const _qword As Integer = 8 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 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 OFFSET Endian Description Public Structure Header Public Property ChunkID As Byte() ' Dword 0 Big Contains 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 Big Contains the letters "WAVE" in ASCII form (0x57415645 big-endian form). End Structure Public Structure FormatSubChunk Public Property Subchunk1ID As Byte() ' Dword 12 Big Contains the letters "fmt "(0x666d7420 big-endian form). Public Property Subchunk1Size As UInt32 ' Dword 16 little 16 for PCM. This is the size of the rest of the Subchunk which follows this number. Public Property AudioFormat As UInt16 ' Word 20 little PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression. Public Property NumChannels As UInt16 ' Word 22 little Mono = 1, Stereo = 2, etc. Public Property SampleRate As UInt32 ' Dword 24 little 8000, 44100, etc. Public Property ByteRate As UInt32 ' Dword 28 little == SampleRate * NumChannels * BitsPerSample/8 Public Property BlockAlign As UInt16 ' Word 32 little == NumChannels * BitsPerSample/8 Public Property BitsPerSample As UInt16 ' Word 34 little 8 bits = 8, 16 bits = 16, etc. End Structure Public Structure DataSubChunk Public Property Subchunk2ID As Byte() ' Dword 36 Big Contains the letters "data"(0x64617461 big-endian form). Public Property Subchunk2Size As UInt32 ' Dword 40 little == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data. Public Property Data As Byte() ' VariableLength 44 little The actual sound data. End Structure Public FileHeader As Header Public FileFormatSubChunk As FormatSubChunk Public FileDataSubChunk As DataSubChunk
Logic:
Public Sub OpenFile(FileName As String) Try If Not My.Computer.FileSystem.FileExists(FileName) Then Throw New Exception("File Does Not Exist!") End If Dim FileBytes() As Byte = My.Computer.FileSystem.ReadAllBytes(FileName) 'Get Header Me.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, _dword) Me.FileHeader.ChunkSize = BitConverter.ToInt32(GetDataFromByteArray(FileBytes, 0, 4, _dword), 0) Me.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, _dword) 'Get FormatSubChunk Me.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, _dword) Me.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 16, _dword), 0) Me.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 20, _word), 0) Me.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 22, _word), 0) Me.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 24, _dword), 0) Me.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 28, _dword), 0) Me.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 32, _word), 0) Me.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(GetDataFromByteArray(FileBytes, 0, 34, _word), 0) 'Get DataSubChunck Me.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, _dword) Me.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(GetDataFromByteArray(FileBytes, 0, 40, _dword), 0) Me.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44, Me.FileDataSubChunk.Subchunk2Size) Catch Throw New Exception("File Is Invalid or corrupt!") End Try End Sub Private Function GetDataFromByteArray(ByVal ByteArray As Byte(), ByVal BlockOffset As Long, ByVal RangeStartOffset As Long, ByVal DataLength As Long) As Byte() On Error Resume Next Dim AnswerL As New List(Of Byte) Dim Answer(0 To CInt((DataLength - 1))) As Byte Dim CurrentOffset As Long For I = 0 To UBound(ByteArray) CurrentOffset = BlockOffset + I If CurrentOffset >= RangeStartOffset And CurrentOffset <= RangeStartOffset + DataLength Then AnswerL.Add(ByteArray(I)) End If Next Dim Count As Integer = 0 For Each bt As Byte In AnswerL Answer(Count) = bt Count += 1 Next GetDataFromByteArray = Answer End Function
The length of the sound file in seconds:
Function WavLength(ByVal WaveFile As String) As Long OpenFile(WaveFile) WavLength = Me.FileDataSubChunk.Subchunk2Size / Me.FileFormatSubChunk.ByteRate ' length in seconds End Function
Responsibilities first...
- Marked as answer by John L Hart IV Saturday, September 1, 2012 2:08 AM
Wednesday, August 29, 2012 9:02 PM -
The strange thing is that when I used the FileGet() method instead - the NullReferenceException went away and I was able to pull something (admittedly garbage) from the file... Why was FileGetObject upset with me?...
Responsibilities first...
Actually, check this out - Maybe you can retrace your steps?
http://msdn.microsoft.com/en-us/library/y1swwyc4%28v=vs.90%29.aspx
If you want something you've never had, you need to do something you've never done.
- Edited by Paul Ishak Wednesday, August 29, 2012 9:19 PM
- Proposed as answer by Mike Feng Friday, August 31, 2012 7:48 AM
Wednesday, August 29, 2012 9:17 PM -
I'm not sure that cutting down my original answer constitutes a unique and different answer. Either way glad my answer solved your poblem.
If you want something you've never had, you need to do something you've never done.
- Edited by Paul Ishak Saturday, September 1, 2012 2:30 AM
Saturday, September 1, 2012 2:21 AM