2012-09-26 171 views
2

編輯:解決在下面的自我回答。在VB.net播放音頻文件(.wav)w /音量控制

我已經看了所有,但我找不到任何有用的音量控制音頻文件播放。 我試過XNA; SLIMDX和「Microsoft.VisualBasic.Devices.Audio」,但沒有任何幫助。 我發現有音量控制的選項太複雜,我無法弄清楚如何使用,而我目前所使用的方法並不能讓您做任何事情,不僅僅是播放(背景有或沒有循環,或暫停執行直到結束)並停止。

這裏是我當前的代碼:

Dim AD As New Microsoft.VisualBasic.Devices.Audio 
    Sub Play() 
     Dim af() As Byte = IO.File.ReadAllBytes("music.wav") 
     AD.Play(af, AudioPlayMode.BackgroundLoop) 
    End Sub 

這個循環在後臺「music.wav」,但我不能暫停/搜索,或控制音量。有沒有簡單的方法(如上所述)從緩衝區播放音頻文件並控制音量?我已經找遍了,但沒有找到我的項目的作品。

System: Win7 64-bit

VS version: 2010

Language: VB.net

哦,還有一兩件事,首先緩衝聲音是我需要爲我的解決方案,以及(你可以在我當前的代碼見)

有沒有人有一個解決的辦法? :)

+0

我發現n音訊是我所需要的,但是當我的應用程序關閉我得到這個錯誤:「waveout的設備沒有在WaveOut.Finalize()關閉了」任何人都知道是什麼原因導致這個錯誤?我也檢查過,在WaveOut類中沒有「完成」方法。 – user1666788

+2

你需要調用WaveOut.Dispose() – catflier

+0

@cat哦耶thx一堆!解決了這個錯誤:D – user1666788

回答

4

我找到答案了一點,所以在這裏尋找身邊後的我發現我的問題解決方案:

下載Naudio和引用添加到您的項目。

然後將下面的代碼是如何使用它加載音頻從一個緩衝區:

Dim Wave1 As New NAudio.Wave.WaveOut 'Wave out device for playing the sound 

Dim xa() As Byte = IO.File.ReadAllBytes("C:\YourPath\YourWave.wav") 'Your Buffer 

Sub PlaySound() 

     Dim data As New IO.MemoryStream(xa) 'Data stream for the buffer 

     Wave1.Init(New NAudio.Wave.BlockAlignReductionStream(NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(New NAudio.Wave.WaveFileReader(data)))) 

     Wave1.Volume = 0.1 'Sets the Volume to 10% 

     Wave1.Play() 

End Sub 

WaveFileReader可以改成你需要爲準讀卡器(即MP3一個」 .MP3" 文件)加載您的音頻文件,但代碼原樣加載「.wav」文件。

哦也,當你做是爲了避免錯誤不會忘記

WaveOut.Dispose() 

我希望我的研究可以幫助別人:)

1

您是否嘗試過使用Media Player control

+0

我剛纔試過了,但我找不到從緩衝區加載文件的方法。有沒有辦法將字節數據直接加載到MediaPlayer控件中?通過流或緩衝區數組 – user1666788

+0

像這樣:Dim af()As Byte = IO.File.ReadAllBytes(「music.wav」) – user1666788

0

嘿,我甲肝使一個類來處理波(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 

末級

0

因爲似乎是在VB.NET使用n音訊的小文件,而不是隨處可見的C#示例,並進一步到@ user1666788的評論,這是讓它播放VB.NET的MP3文件的簡單方法,而不是WAV。

Public Shared Wave1 As New NAudio.Wave.WaveOut 'Wave out device for playing the sound 

Public Sub btn_PlayPause_Click(sender As Object, e As EventArgs) Handles btn_PlayPause.Click 

     Dim file As String = "C:\test.mp3" 
     Dim data As New NAudio.Wave.Mp3FileReader(file) 
     Wave1.Init(data) 
     Wave1.Play() 
End Sub