如何在vb.net中从.wav文件中读取字节

3
我正在尝试处理.wav文件,已经成功通过创建字节数组来播放文件并随机播放声音(可参见以下代码)。我想知道是否有一种方法可以从.wav文件中获取字节。我的想法是,如果能够获取.wav文件的字节,就可以像随机噪声一样播放声音,这应该可以让我找出如何修改声音的方法。
播放.wav文件:
    Dim SoundDevice = New Microsoft.DirectX.DirectSound.Device
Dim SbufferOriginal = New Microsoft.DirectX.DirectSound.SecondaryBuffer(SoundFilePath, SoundDevice)
Private Sub PlaySound()
    Try
        SbufferOriginal = New Microsoft.DirectX.DirectSound.SecondaryBuffer(SoundFilePath, SoundDevice)
        SoundDevice.SetCooperativeLevel(Me.Handle, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal)
        SbufferOriginal.Play(0, Microsoft.DirectX.DirectSound.BufferPlayFlags.Looping)
    Catch ex As Exception
        'do something for exception
    End Try
End Sub

使用直接声音播放随机噪声:

DSdev.SetCooperativeLevel(Me.Handle, CooperativeLevel.Normal)

DSformat = New WaveFormat()
DSformat.BitsPerSample = 8
DSformat.Channels = 1
DSformat.BlockAlign = 1
DSformat.FormatTag = WaveFormatTag.Pcm
DSformat.SamplesPerSecond = 8000
DSformat.AverageBytesPerSecond = DSformat.SamplesPerSecond *
DSformat.BlockAlign

'buffer description
DSdes = New BufferDescription(DSformat)
DSdes.BufferBytes = 3 * DSformat.AverageBytesPerSecond

'create the buffer
DSbuffer = New Microsoft.DirectX.DirectSound.SecondaryBuffer(DSdes, DSdev)

'generate ramdom data (white noise)
Dim rawsamples(22050) As Byte
Dim rnd1 = New System.Random()
Dim tmepno As Integer = 150





For j = 0 To 5
    DSbuffer.Stop()
    Dim i As Integer
    For i = 0 To 22050
        rawsamples(i) = 250
        tmepno += 1
        If tmepno = 255 Then
            tmepno = 150
        End If
        'rnd1.Next(255)
    Next i

    ' load audio samples to secondary buffer
    DSbuffer.Write(0, rawsamples, LockFlag.EntireBuffer)

    'play audio buffer
    DSbuffer.Play(0, BufferPlayFlags.Default)
    Threading.Thread.Sleep(250)
Next

我想要做的是从一个.wav文件中获取字节数组,这样我就可以像播放随机噪声一样播放它。

提前感谢!

更新:

我已经写了以下代码来使用从.wav文件中读取的字节:

    Dim justsounddata(bytearray.GetLength(0) - 44 - 1) As Byte
    Dim bitstring As String
    For i = 0 To justsounddata.GetLength(0) - 1
        'RichTextBox1.AppendText(bytearray(i))
        justsounddata(justsounddata.GetLength(0) - 1 - i) = bytearray(i + 44)
        bitstring &= bytearray(i)
    Next

    RichTextBox1.Text = bitstring

    Dim workingvalue As String



    DSdev.SetCooperativeLevel(Me.Handle, CooperativeLevel.Normal)

    DSformat = New WaveFormat()

    workingvalue = Mid(bitstring, 35, 2)
    workingvalue = StrReverse(workingvalue)
    DSformat.BitsPerSample = workingvalue
    'CInt(bitspersample)

    workingvalue = Mid(bitstring, 23, 2)
    workingvalue = StrReverse(workingvalue)
    DSformat.Channels = workingvalue

    workingvalue = Mid(bitstring, 33, 2)
    workingvalue = StrReverse(workingvalue)
    DSformat.BlockAlign = workingvalue

    workingvalue = Mid(bitstring, 9, 4)
    'workingvalue = StrReverse(workingvalue)
    DSformat.FormatTag = workingvalue

    workingvalue = Mid(bitstring, 25, 4)
    workingvalue = StrReverse(workingvalue)
    DSformat.SamplesPerSecond = workingvalue

    'CInt(samplesspersecond)
    DSformat.AverageBytesPerSecond = DSformat.SamplesPerSecond * DSformat.BlockAlign
    'CInt(bitrate)

    'buffer description
    DSdes = New BufferDescription(DSformat)
    DSdes.BufferBytes = 3 * DSformat.AverageBytesPerSecond

    'create the buffer
    DSbuffer = New Microsoft.DirectX.DirectSound.SecondaryBuffer(DSdes, DSdev)

    'generate ramdom data (white noise)
    Dim rawsamples(22050) As Byte
    Dim rnd1 = New System.Random()
    Dim tmepno As Integer = 150


    ' load audio samples to secondary buffer
    'DSbuffer.Write(0, rawsamples, LockFlag.EntireBuffer)

    DSbuffer.Write(0, justsounddata, LockFlag.EntireBuffer)

    'play audio buffer
    '
    DSbuffer.Play(0, BufferPlayFlags.Default)

错误出现在这一行:
DSbuffer = New Microsoft.DirectX.DirectSound.SecondaryBuffer(DSdes, DSdev)

错误信息是:“值不在预期范围内。”

我相信每个变量的数组位已经正确读取。我也注意到了字节序。再次感谢您的帮助 :)


你可能想搜索“.wav文件格式”并阅读规范。 - the_lotus
谢谢您的快速回复。我已经了解了文件格式,但不确定如何将 .wav 文件字节读入字节数组中。一旦完成这一步骤,我预计还需要拆分文件为其组成的数据块。对于其他需要 .wav 文件格式信息的人,我发现这个网站很有用:https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ - FraserOfSmeg
1个回答

2
您可以使用 File.ReadAllBytes 读取文件的所有数据。或者使用 FileStream 读取文件,然后使用 Serializer.Serialize 将数据放入类中。

我刚刚尝试了一下,它给了我一个很大的字节数组。据我所知,这正是我需要的。谢谢!:D - FraserOfSmeg
这可能会帮助您将Web头文件序列化为类:http://arstechnica.com/civis/viewtopic.php?f=20&t=781690 - the_lotus
嗨,我的代码仍然存在错误。我已经附上了我的新代码,用于获取和播放.wav文件数据以及我收到的错误。再次帮助我将不胜感激。 - FraserOfSmeg
@user1601928 这现在是一个有点不同的问题。我对DirectX的了解还不够,无法提供帮助。 - the_lotus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接