2012-09-26 103 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