嘿,我甲肝使一個類來處理波(PCM)的文件,希望這將有助於ü..其尚未完成,但可能會有所幫助。
Imports System.IO
進口System.Runtime.InteropServices 導入系統。ComponentModel
公共結構WaveHeader 公共塊存儲爲CHAR() 公共塊大小作爲的Int32 公共格式爲char() 公共SubChunk1爲CHAR() 公共SubChunk1Size作爲的Int32 公共的AudioFormat作爲Int16的 公共頻道作爲Int16的 公共採樣率作爲的Int32 公共ByteRate作爲的Int32 公共BlockAlign作爲Int16的 公共BitsPerSample作爲Int16的 公共SubChunk2爲CHAR() 公共SubChunk2Size作爲的Int32 末端結構
公共枚舉國家 無 播放 暫停 停止 成品 結束枚舉
公共類WAV
Private watch As New Stopwatch
Private WithEvents timer As New Timer
Private mystate As State = State.None
Private myheader As WaveHeader
Private myurl As String = Nothing
Private mytotaltime As Double = 0
Private Declare Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal process As IntPtr, ByVal minimumWorkingSetSize As Integer, ByVal maximumWorkingSetSize As Integer) As Integer
Event OnPlayStateChange(ByVal e As State)
Public Shared Sub FlushMemory()
GC.Collect()
GC.WaitForPendingFinalizers()
If (Environment.OSVersion.Platform = PlatformID.Win32NT) Then
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1)
End If
End Sub
Sub New()
timer.Interval = 1
timer.Start()
End Sub
Function readheader(ByVal url As String)
Dim fh As WaveHeader
Dim stream As New FileStream(url, FileMode.Open)
Dim br As New BinaryReader(stream)
fh.Chunk = br.ReadChars(4)
fh.ChunkSize = br.ReadInt32
fh.Format = br.ReadChars(4)
fh.SubChunk1 = br.ReadChars(4)
fh.SubChunk1Size = br.ReadInt32
fh.AudioFormat = br.ReadInt16
fh.Channels = br.ReadInt16
fh.SampleRate = br.ReadInt32
fh.ByteRate = br.ReadInt32
fh.BlockAlign = br.ReadInt16
fh.BitsPerSample = br.ReadInt16
For i = 1 To fh.SubChunk1Size - 16
br.ReadByte()
Next
fh.SubChunk2 = br.ReadChars(4)
fh.SubChunk2Size = br.ReadInt32
br.Close()
stream.Close()
Return Header2String(fh)
End Function
Function Header2String(ByVal fh As WaveHeader)
Dim t As String = ""
t &= "Chunk " & fh.Chunk & Environment.NewLine
t &= "Chunksize " & fh.ChunkSize & Environment.NewLine
t &= "Format " & fh.Format & Environment.NewLine
t &= "subChunk1 " & fh.SubChunk1 & Environment.NewLine
t &= "subchunk1size " & fh.SubChunk1Size & Environment.NewLine
t &= "PCM " & fh.AudioFormat & Environment.NewLine
t &= "Channels " & fh.Channels & Environment.NewLine
t &= "Samplerate " & fh.SampleRate & Environment.NewLine
t &= "ByteRate " & fh.ByteRate & Environment.NewLine
t &= "Block Align " & fh.BlockAlign & Environment.NewLine
t &= "Bits/Sample " & fh.BitsPerSample & Environment.NewLine
t &= "subChunk2 " & fh.SubChunk2 & Environment.NewLine
t &= "subChunk2size " & fh.SubChunk2Size & Environment.NewLine
Return t
End Function
Function StopAudio()
My.Computer.Audio.Stop()
watch.Stop()
watch.Reset()
If PlayState = State.Playing Or PlayState = State.Paused Then
mystate = State.Stopped
End If
Return 0
End Function
Function playAudio(ByVal url As String)
If My.Computer.FileSystem.FileExists(url) Then
Try
My.Computer.Audio.Play(SongStream(url, 0), AudioPlayMode.Background)
'My.Computer.Audio.Play(fast(url, 0, CDbl(form1.TextBox4.Text)), AudioPlayMode.Background)
watch.Restart()
mystate = State.Playing
RaiseEvent OnPlayStateChange(State.Playing)
myurl = url
Catch ex As Exception
Throw New Exception("Error! Can't Play The File.")
'MsgBox(ex.Message)
End Try
Else
Throw New Exception("File Not Exist.")
End If
Return 0
End Function
Function PauseAudio()
If PlayState = State.Playing Then
My.Computer.Audio.Stop()
watch.Stop()
mystate = State.Paused
RaiseEvent OnPlayStateChange(State.Paused)
End If
Return 0
End Function
Function ResumeAudio()
If PlayState = State.Paused And IsNothing(URL) = False Then
Try
My.Computer.Audio.Play(SongStream(URL, time), AudioPlayMode.Background)
watch.Start()
mystate = State.Playing
RaiseEvent OnPlayStateChange(State.Playing)
Catch : End Try
End If
Return 0
End Function
Private Function fast(ByVal url As String, ByVal position As Double, ByVal speed As Single)
Dim fh As New WaveHeader
Dim stream As New FileStream(url, FileMode.Open)
Dim br As New BinaryReader(stream)
fh.Chunk = br.ReadChars(4)
fh.ChunkSize = br.ReadInt32
fh.Format = br.ReadChars(4)
fh.SubChunk1 = br.ReadChars(4)
fh.SubChunk1Size = br.ReadInt32
fh.AudioFormat = br.ReadInt16
fh.Channels = br.ReadInt16
fh.SampleRate = br.ReadInt32
fh.ByteRate = br.ReadInt32
fh.BlockAlign = br.ReadInt16
fh.BitsPerSample = br.ReadInt16
fh.SampleRate *= speed
fh.ByteRate *= speed
For i = 1 To fh.SubChunk1Size - 16
br.ReadChar()
Next
stream.Position = fh.SubChunk1Size + 20
fh.SubChunk2 = br.ReadChars(4)
fh.SubChunk2Size = br.ReadInt32
If fh.Channels = 6 Then
fh.Channels = 2
fh.BlockAlign = fh.Channels * fh.BitsPerSample/8
fh.SampleRate = fh.SampleRate * (6/fh.Channels)
End If
position = Math.Round(CInt(position/1000) * fh.ByteRate)
If position >= fh.SubChunk2Size Then
Throw New Exception("Songs isn't that long")
End If
mytotaltime = Math.Round(fh.SubChunk2Size/fh.ByteRate)
fh.SubChunk2Size -= position
Dim header() As Byte = {Asc("R"), Asc("I"), Asc("F"), Asc("F"), 0, 0, 0, 0, Asc("W"), Asc("A"), Asc("V"), Asc("E"), Asc("f"), Asc("m"), Asc("t"), Asc(" "), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Asc("d"), Asc("a"), Asc("t"), Asc("a"), 0, 0, 0, 0}
BitConverter.GetBytes(fh.SubChunk2Size).CopyTo(header, 40)
BitConverter.GetBytes(fh.BitsPerSample).CopyTo(header, 34)
BitConverter.GetBytes(fh.BlockAlign).CopyTo(header, 32)
BitConverter.GetBytes(fh.ByteRate).CopyTo(header, 28)
BitConverter.GetBytes(fh.SampleRate).CopyTo(header, 24)
BitConverter.GetBytes(fh.Channels).CopyTo(header, 22)
BitConverter.GetBytes(fh.AudioFormat).CopyTo(header, 20)
BitConverter.GetBytes(16).CopyTo(header, 16)
BitConverter.GetBytes(fh.SubChunk2Size + 36).CopyTo(header, 4)
myheader = fh
Dim audio(fh.SubChunk2Size + 44) As Byte
header.CopyTo(audio, 0)
stream.Position = position
br.ReadBytes(fh.SubChunk2Size).CopyTo(audio, 44)
br.Dispose()
stream.Dispose()
br = Nothing
stream = Nothing
Return audio
End Function
Private Function SongStream(ByVal url As String, ByVal position As Double)
Dim fh As New WaveHeader
Dim stream As New FileStream(url, FileMode.Open)
Dim br As New BinaryReader(stream)
fh.Chunk = br.ReadChars(4)
fh.ChunkSize = br.ReadInt32
fh.Format = br.ReadChars(4)
fh.SubChunk1 = br.ReadChars(4)
fh.SubChunk1Size = br.ReadInt32
fh.AudioFormat = br.ReadInt16
fh.Channels = br.ReadInt16
fh.SampleRate = br.ReadInt32
fh.ByteRate = br.ReadInt32
fh.BlockAlign = br.ReadInt16
fh.BitsPerSample = br.ReadInt16
For i = 1 To fh.SubChunk1Size - 16
br.ReadChar()
Next
stream.Position = fh.SubChunk1Size + 20
fh.SubChunk2 = br.ReadChars(4)
fh.SubChunk2Size = br.ReadInt32
If fh.Channels = 6 Then
fh.Channels = 2
fh.BlockAlign = fh.Channels * fh.BitsPerSample/8
fh.SampleRate = fh.SampleRate * (6/fh.Channels)
End If
position = Math.Round(CInt(position/1000) * fh.ByteRate)
If position >= fh.SubChunk2Size Then
Throw New Exception("Songs isn't that long")
End If
mytotaltime = Math.Round(fh.SubChunk2Size/fh.ByteRate)
fh.SubChunk2Size -= position
Dim header() As Byte = {Asc("R"), Asc("I"), Asc("F"), Asc("F"), 0, 0, 0, 0, Asc("W"), Asc("A"), Asc("V"), Asc("E"), Asc("f"), Asc("m"), Asc("t"), Asc(" "), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Asc("d"), Asc("a"), Asc("t"), Asc("a"), 0, 0, 0, 0}
BitConverter.GetBytes(fh.SubChunk2Size).CopyTo(header, 40)
BitConverter.GetBytes(fh.BitsPerSample).CopyTo(header, 34)
BitConverter.GetBytes(fh.BlockAlign).CopyTo(header, 32)
BitConverter.GetBytes(fh.ByteRate).CopyTo(header, 28)
BitConverter.GetBytes(fh.SampleRate).CopyTo(header, 24)
BitConverter.GetBytes(fh.Channels).CopyTo(header, 22)
BitConverter.GetBytes(fh.AudioFormat).CopyTo(header, 20)
BitConverter.GetBytes(16).CopyTo(header, 16)
BitConverter.GetBytes(fh.SubChunk2Size + 36).CopyTo(header, 4)
myheader = fh
Dim audio(fh.SubChunk2Size + 44) As Byte
header.CopyTo(audio, 0)
stream.Position = position
br.ReadBytes(fh.SubChunk2Size).CopyTo(audio, 44)
br.Dispose()
stream.Dispose()
br = Nothing
stream = Nothing
Return audio
End Function
地區 「屬性」
<Browsable(False)> ReadOnly Property PlayState
Get
Return mystate
End Get
End Property
<Browsable(False)> ReadOnly Property URL
Get
Return myurl
End Get
End Property
ReadOnly Property TotalTime
Get
Return mytotaltime
End Get
End Property
ReadOnly Property time
Get
Return watch.ElapsedMilliseconds
End Get
End Property
ReadOnly Property timestamp
Get
Return watch.Elapsed.ToString
End Get
End Property
端部區域
Private Sub timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer.Tick
If Not TotalTime = 0 Then
If TotalTime <= time/1000 Then
watch.Stop()
watch.Reset()
mystate = State.Finished
RaiseEvent OnPlayStateChange(State.Finished)
End If
End If
FlushMemory()
End Sub
ReadOnly Property SongHeader As WaveHeader
Get
Return myheader
End Get
End Property
末級
公共類spactrum
Dim h As WaveHeader
Function readheader(ByVal url As String)
Dim fh As WaveHeader
Dim stream As New FileStream(url, FileMode.Open)
Dim br As New BinaryReader(stream)
fh.Chunk = br.ReadChars(4)
fh.ChunkSize = br.ReadInt32
fh.Format = br.ReadChars(4)
fh.SubChunk1 = br.ReadChars(4)
fh.SubChunk1Size = br.ReadInt32
fh.AudioFormat = br.ReadInt16
fh.Channels = br.ReadInt16
fh.SampleRate = br.ReadInt32
fh.ByteRate = br.ReadInt32
fh.BlockAlign = br.ReadInt16
fh.BitsPerSample = br.ReadInt16
For i = 1 To fh.SubChunk1Size - 16
br.ReadByte()
Next
fh.SubChunk2 = br.ReadChars(4)
fh.SubChunk2Size = br.ReadInt32
h = fh
Return br.ReadBytes(fh.SubChunk2Size)
End Function
Function showit()
Dim b As New Bitmap(500, 200)
Dim g As Graphics = Graphics.FromImage(b)
Dim d() As Byte = readheader("songs\s.wav")
'Dim t As Integer = d.Count
For i = 0 To d.Count - 1
Dim x = CInt((i/d.Count) * 500)
Dim y = CInt(d(i).ToString) - 200
g.DrawLine(Pens.Black, x, 0, x, y)
Next
'g.FillEllipse(Brushes.Black, 0, 0, 500, 300)
Return b.Clone
End Function
末級
我發現n音訊是我所需要的,但是當我的應用程序關閉我得到這個錯誤:「waveout的設備沒有在WaveOut.Finalize()關閉了」任何人都知道是什麼原因導致這個錯誤?我也檢查過,在WaveOut類中沒有「完成」方法。 – user1666788
你需要調用WaveOut.Dispose() – catflier
@cat哦耶thx一堆!解決了這個錯誤:D – user1666788