Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用音量控制在VB.net中播放音频文件(.wav)_Vb.net_Audio_Xna_Directx_Volume - Fatal编程技术网

使用音量控制在VB.net中播放音频文件(.wav)

使用音量控制在VB.net中播放音频文件(.wav),vb.net,audio,xna,directx,volume,Vb.net,Audio,Xna,Directx,Volume,编辑:在下面的自我回答中解决。 我找遍了所有地方,但我找不到任何有用的音量控制播放音频文件。 我试过XNA;SLIMDX和“Microsoft.VisualBasic.Devices.Audio”,但没有任何帮助。 我发现有音量控制的选项太复杂了,我不知道如何使用,而且我目前使用的方法只允许播放(带或不带循环的背景,或暂停执行直到播放结束)和停止 以下是我当前的代码: Dim AD As New Microsoft.VisualBasic.Devices.Audio Sub Play()

编辑:在下面的自我回答中解决。

我找遍了所有地方,但我找不到任何有用的音量控制播放音频文件。 我试过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”,但我无法暂停/查找它或控制音量。是否有任何简单的方法(如上所述)从缓冲区播放音频文件并控制音频音量?我找遍了所有地方,但没有找到适合我的项目的

系统:Win7 64位

VS版本:2010

语言:VB.net

哦,还有一件事,我的解决方案也需要首先缓冲音频(正如您在我当前的代码中看到的)


有人能解决这个问题吗?:)

你试过使用吗?

我在四处搜索后找到了答案,下面是我为我的问题找到的解决方案:

下载并添加对项目的引用

下面的代码是如何使用它从缓冲区加载音频:

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
WaveileReader可以更改为您需要的任何读取器(即用于“.MP3”文件的MP3读取器)来加载音频文件,但代码的工作原理与加载“.wav”文件的工作原理相同

哦,还有,别忘了

WaveOut.Dispose()
当你完成了避免错误的步骤


我希望我的研究能帮助一些人:)

嘿,我有一个类来处理wave(pcm)文件,希望这能帮助你。。它尚未完成,但可能会有所帮助

Imports System.IO
导入System.Runtime.InteropServices 导入System.ComponentModel

公共结构波头 作为Char()的公共块 公共块大小为Int32 公共格式为Char() 作为Char()的公共子chunk1 公共子chunk1大小为Int32 公共音频格式为Int16 公共频道如Int16 作为Int32的公共采样器 公共字节数为Int32 公共区块对齐为Int16 公共位示例为Int16 公共子chunk2作为Char() 公共子缓存大小为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
区域“财产”
End Class

由于在VB.NET中使用naudio的文档似乎很少,而到处都是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

我刚才试过了,但找不到从缓冲区加载文件的方法。有没有办法将字节数据直接加载到MediaPlayer控件中?通过以下流或缓冲区阵列:Dim af()作为Byte=IO.File.ReadAllBytes(“music.wav”),我发现NAudio是我所需要的,但是当我的应用程序关闭时,我得到了这个错误:“WaveOut设备在WaveOut.Finalize()时未关闭”有人知道是什么导致了这个错误吗?我还检查了WaveOut类中没有“finalize”方法。您需要调用WaveOut.Dispose()@cat-oh-yeah-thx-a bunch!这就解决了错误:D
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
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
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