none
运用copymemory显示"值不在预期内"vb2008 winform RRS feed

  • 问题

  • 想做一个WAV音频文件发生器,遇到很多问题,请高手指教

    每运行到这句就卡住了!:CopyMemory(a(0), Wave, 44) 'a为一个数组,WAVE为一个结构体




    Public Class Form1
        Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Byte, ByVal Source As Object, ByVal Length As Long) 
        Private Declare Function sndPlaySoundMEM Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As Object, ByVal uFlags As Long) As Long

        Dim a() As Byte
        Dim b() As Byte
        Dim AnyString As String, AnyNumber, FileNum As Integer
        Private Structure WAVInfo
           ‘定义WAV文件格式
            Dim a_RIFF As String   '4
            Dim b_文件长度 As Long
            Dim c_Wave As String   '4
            Dim d_FMT As String  '4
            Dim e_过渡字节 As Long  '4
            Dim f_压缩格式 As Integer  '2
            Dim g_声道数 As Integer '0 = 单声道, 1 = 立体声  '2
            Dim h_采样率 As Long  '4
            Dim j_传送速率 As Long  '4
            Dim k_数据块调整 As Integer '2
            Dim l_每个样本的数据位数 As Integer '2
            Dim m_DATA As String  '4
            Dim n_语音数据长度 As Long '4
        End Structure
        Dim Wave As WAVInfo
       
    ‘ 产生WAV文件函数
    Sub makewave()
            Dim i As Single
            Dim j As Single
            ReDim a(4999 + 44)
            ReDim b(4999)
            'Dim k As Single
            Dim bl As Single
            'Dim m As Integer
            'Dim e As Integer
            'Dim st As Double


            Wave.b_文件长度 = UBound(a) + 1
            Wave.n_语音数据长度 = UBound(a) + 1 - 36
            CopyMemory(a(0), Wave, 44)               ’将文件头写入数据a中           ‘在此出错

     

            bl = Math.Tan(90 * 3.14 / 180)

            For j = 0 To UBound(b)
                i = Math.Tan((70 + (j Mod 19)) * 3.14 / 180)
                b(j) = 128 + i * 3 - 28
            Next j

            For j = 44 To UBound(a)
                i = b(j - 44) + Math.Sin(j * 3.14 / 5) * 40
                If i > 255 Then i = 255
                If i < 0 Then i = 0
                a(j) = i
            Next
            sndPlaySoundMEM(a(0), 7&)

        End Sub

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
                    Call makewave()

        End Sub

        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

           ’ 初始化文件格式

           Wave.a_RIFF = "RIFF" '4
            Wave.b_文件长度 = 0  '4
            Wave.c_Wave = "WAVE" '4
            Wave.d_FMT = "fmt "  '4
            Wave.e_过渡字节 = 16  '4
            Wave.f_压缩格式 = 1 ' 2
            Wave.g_声道数 = 1    '2
            Wave.h_采样率 = 22050 '  4
            Wave.j_传送速率 = 16000 '  4
            Wave.k_数据块调整 = 1 '2
            Wave.l_每个样本的数据位数 = 8  '2
            Wave.m_DATA = "data"  '4
            Wave.n_语音数据长度 = 0  '4
        End Sub
    End Class

    2009年5月19日 3:11

答案

  • Private Declare Function sndPlaySoundMEM Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As Byte(), ByVal uFlags As Integer) As Integer


    Sub makewave()
            Dim i As Single
            Dim j As Single

     

            ReDim a(4999 + 44)
            ReDim b(4999)
            'Dim k As Single
            Dim bl As Single
            'Dim m As Integer
            'Dim e As Integer
            'Dim st As Double


            Wave.b_文件长度 = UBound(b) + 1 + 36
            Wave.n_语音数据长度 = UBound(b) + 1


            Dim wavegch As GCHandle = GCHandle.Alloc(Wave)
            Dim waveptr = GCHandle.ToIntPtr(wavegch)
            Marshal.StructureToPtr(Wave, waveptr, True)

            
            CopyMemory(a, waveptr, 44)            

                  bl = Math.Tan(90 * 3.14 / 180)

            For j = 0 To UBound(b)
                i = Math.Tan((70 + (j Mod 19)) * 3.14 / 180)
                b(j) = 128 + i * 3 - 28
            Next j

            For j = 44 To UBound(a)
                i = b(j - 44) + Math.Sin(j * 3.14 / 5) * 40
                If i > 255 Then i = 255
                If i < 0 Then i = 0
                a(j) = i
            Next
            sndPlaySoundMEM(a, 7&)

         End Sub


    http://feiyun0112.cnblogs.com/
    2009年5月19日 6:41
    版主

全部回复

  • Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Byte(), ByVal Source As IntPtr, ByVal Length As Integer)

    Dim wavegch As GCHandle = GCHandle.Alloc(Wave)
            Dim waveptr = GCHandle.ToIntPtr(wavegch)
            Marshal.StructureToPtr(Wave, waveptr, True)

            CopyMemory(a, waveptr, 44) 


    http://feiyun0112.cnblogs.com/
    2009年5月19日 3:39
    版主
  • 谢谢您的指导
    试了一下,说GCHandle 是未定义的类型,
    marshal也是一样,请问是否要加入什么命名空间?
    加上什么代码?
     

    2009年5月19日 4:28
  • Imports System.Runtime.InteropServices


     <StructLayout(LayoutKind.Sequential, Pack:=1)> _
        Private Structure WAVInfo
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
            Dim a_RIFF As Char()   '4
            Dim b_文件长度 As Int32
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
            Dim c_Wave As Char()   '4
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
            Dim d_FMT As Char()  '4
            Dim e_过渡字节 As Int32  '4
            Dim f_压缩格式 As Int16  '2
            Dim g_声道数 As Int16 '0 = 单声道, 1 = 立体声  '2
            Dim h_采样率 As Int32  '4
            Dim j_传送速率 As Int32  '4
            Dim k_数据块调整 As Int16 '2
            Dim l_每个样本的数据位数 As Int16 '2
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
            Dim m_DATA As Char()  '4
            Dim n_语音数据长度 As Int32 '4
        End Structure
    http://feiyun0112.cnblogs.com/
    2009年5月19日 4:51
    版主
  • my god1
    还是不行,

    弱弱的问下,
    能否请大侠帮偶写这个制作WAV的程序?
    文件格式就是代码里的那些

    我现在的问题是,不知道怎么将代表文件格式的结构体数据写到一个数组当中
    打算用一个数组的前几位存放文件的格式,后面就存放音频文件的数据(可是是随便一个三角函数什么的产生的一个数组就行了)

    这样数组所指向的地址就是一个音频文件了。

    或者也可以改成,直接向写硬盘成一个WAV文件
    可是如何将WAV的头文件,即结构体里面的字符啊,数据啊一起全部写到硬盘上?
    仅用
     FileOpen(1, "C:\Documents and Settings\Administrator\桌面\hi.wav", OpenMode.Output)

                Print(1,结构体名?) 
    又不行!
    实在是弄不懂
    不知大侠可否帮忙?
           
    2009年5月19日 5:22
  • Private Declare Function sndPlaySoundMEM Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As Byte(), ByVal uFlags As Integer) As Integer


    Sub makewave()
            Dim i As Single
            Dim j As Single

     

            ReDim a(4999 + 44)
            ReDim b(4999)
            'Dim k As Single
            Dim bl As Single
            'Dim m As Integer
            'Dim e As Integer
            'Dim st As Double


            Wave.b_文件长度 = UBound(b) + 1 + 36
            Wave.n_语音数据长度 = UBound(b) + 1


            Dim wavegch As GCHandle = GCHandle.Alloc(Wave)
            Dim waveptr = GCHandle.ToIntPtr(wavegch)
            Marshal.StructureToPtr(Wave, waveptr, True)

            
            CopyMemory(a, waveptr, 44)            

                  bl = Math.Tan(90 * 3.14 / 180)

            For j = 0 To UBound(b)
                i = Math.Tan((70 + (j Mod 19)) * 3.14 / 180)
                b(j) = 128 + i * 3 - 28
            Next j

            For j = 44 To UBound(a)
                i = b(j - 44) + Math.Sin(j * 3.14 / 5) * 40
                If i > 255 Then i = 255
                If i < 0 Then i = 0
                a(j) = i
            Next
            sndPlaySoundMEM(a, 7&)

         End Sub


    http://feiyun0112.cnblogs.com/
    2009年5月19日 6:41
    版主