我想将一个音量较小的WAV文件的音量放大,已经读取到了数据区的数据,以Byte的形式存放在变量中,这个WAV是双声道、16位的,相关的参数已经取得。请教高手,Byte的形式存放在变量中的数据,如何分离出来,并提高音量。最好给出代码,谢谢。

解决方案 »

  1.   

    本帖最后由 bcrun 于 2010-07-30 09:21:06 编辑
      

  2.   

    楼上的是说WAV格式,要是能调节音量就好了
      

  3.   

    将 WAV 里面的声道数据按 8bit/16bit 值进行等比放大就是调高音量。
      

  4.   

    Dim yByte() As Byte         '音乐数据字节数组
    ReDim yByte(my_wavData.nSize) 'my_wavData.nSize就是音乐数据的长度Open App.Path & "\123.wav" For Binary Access Read As #1
    Open App.Path & "\456.wav" For Binary Access Write As #2 X$ = Input(44, #1)        '文件头长度为44
    Get #1, , yByte至此,如果这个WAV已知是16bit、双声道的,如何写入456.WAV,以提高音量? 
      

  5.   

    最好不用控件,对WAV的数据按字节进行操作不行么?
      

  6.   

    Private Type WAVERIFF
            sID As String
            nSize As Long
            sType As String
    End TypePrivate Type WAVEdata
            sID As String
            nSize As Long
            dData As Byte
    End TypePrivate Type WAVEfact
            sID As String
            nSize As Long
            dData As Long
    End Type
    Private Type WAVEFORMAT
            nID As String
            nSize  As Long              '值为16或18,为18时则最后又附加信息
            wFormatTag As Integer       '编码方式
            nChannels As Integer        '声道1-单声道;2-双声道
            nSamplesPerSec As Long      '采样频率
            nAvgBytesPerSec As Long     '每秒字节数
            nBlockAlign As Integer      '数据块对齐单位(每个采样需要的字节数)
            nBitsPerSample As Integer   '块调整值=声道数*采样位数/8 (注意数据类型,不是Long,微软的数据结构定义错了)
            nBitsPerSample1 As String   '附加信息
    End Type
    Dim my_wav As WAVEFORMAT
    Dim my_wavfact As WAVEfact
    Dim my_wavData As WAVEdata
    Dim my_wavRIFF As WAVERIFF
    Dim yByte() As Byte      '音乐数据字节数组
    Dim waveHDR(43) As BytePrivate Sub Form_Load()
    '导入的声音文件Fname
    Dim Fname As String
    Fname = App.Path & "\888.wav"Label3.Caption = "修改时间: " & FileDateTime(Fname)
    Label1.Caption = "文件: " & FnameOpen Fname For Binary Access Read As #1
    Label2.Caption = "大小: " & LOF(1) & " 字节"
    Close #1
    Open Fname For Binary Access Read As #1
      Get #1, , waveHDR    'WAV文件的头部
    Close #1
     
    Open Fname For Binary Access Read As #1
        '第一部分“RIFF”
       With my_wavRIFF
         .sID = Input(4, #1)        '格式标志“RIFF”,4个字节
         Get #1, , .nSize            '文件长度LONG类型,大小等于WAV文件大小减去ID和Size所占用的字节
        .sType = Input(4, #1)       '“WAVE”,4个字节
       End With
        
        '第二部分“fmt ”
      With my_wav
                  .nID = Input(4, #1)      '“fmt ”,4个字节
        Get #1, , .nSize                   'size,值为16或18,为18时则最后又附加信息
        Get #1, , .wFormatTag              '编码方式
        Get #1, , .nChannels               '声道1-单声道;2-双声道
        Get #1, , .nSamplesPerSec          '采样率(单位:赫兹)典型值:11025、22050、44100、48000Hz
        Get #1, , .nAvgBytesPerSec         '每秒字节数
        Get #1, , .nBlockAlign             '数据块对齐单位(每个采样需要的字节数)设定资料区所占的byte数
        Get #1, , .nBitsPerSample          '块调整值=声道数*采样位数/8
        If .nSize = 18 Then .nBitsPerSample1 = Input(2, #1)
        
      End WithLabel8 = my_wav.nID & " 声道:" & my_wav.nChannels & " 采样率:" & my_wav.nSamplesPerSec & _
             " 每秒字节数:" & my_wav.nAvgBytesPerSec & " 每个采样点数:" & my_wav.nBitsPerSample
       '第三部分
    With my_wavfact
        .sID = Input(4, #1)                 '标志"fact"
        If .sID = "data" Then GoTo dataA
         Get #1, , .nSize                   '数值为4
         Get #1, , .dData
    End With
        dataA:  '第四部分
      With my_wavData
      If my_wavfact.sID = "data" Then
      my_wavfact.sID = ""
      .sID = "data"
      Get #1, , .nSize
      'Get #1, , .dData '数据暂时不读取
      End If
      End WithLabel4 = my_wavfact.sID & my_wavData.sID & "数据长度:" & my_wavData.nSize'以下是将相关数据处理后,写入999.WAV文件Open App.Path & "\999.wav" For Binary Access Write As #2 '打开目标文件
      Put #2, 1, waveHDR       '写入文件头部
      
      Dim a() As Byte
      Dim ii As Long
      Dim b As Byte
       
      ReDim a(my_wavData.nSize) '定义WAV文件的数据长度数组
      
      
      Get #1, , a
      For ii = 45 To my_wavData.nSize + 44
      
      '音频数据以128(8位)或32768(16位)两个数为音频波形中线值
      '我想将音量放大50%,就应该用下边的算法了
      '可以写入后的文件没有一点声音
      
      If a(i) >= 32768 Then
      a(i) = a(i) * 1.5
      Else
      a(i) = a(i) * 0.5
      End If
       Put #2, ii, a(i)
      Next
      
      
    Close #1
    Close #2
    End Sub
    我的源程序是这样的,请大家看看。
      

  7.   

    1)你用 Beyond Compare 2 之类的工具二进制比较两个文件,除了声道数据部分其他是否相同。
    2)16位数据是两个字节,a(i) 始终是一个字节,怎么想的?
    3)For ii 的循环中 i 没变过,你一直处理始终不变的 a(i)?
    4)Get #1, , a是从文件头之后开始读取,
    Put #2, ii, a(i)是从文件位置 45 开始写?
      

  8.   

    16位数据是两个字节
     
    Dim q  As Byte
    Dim b As ByteFor ii = 45 To my_wavData.nSize + 44
    Get #1, , q
    'Debug.Print q
    '对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
      If q = 256 Then GoTo aaq
      Select Case q
      Case Is > 128
           b = q * 0.6
     Case Is < 128
           b = q * 1.4
     Case 128
           b = q
     End Select
      
    aaq:
      Put #2, ii, b音质方面还需要改进,请指教了。
      

  9.   

    要用 Integer 类型 2 字节一起处理,按照你的做法
    &H1280 (  4736) -> &H1980 (  6528)
    &H8080 (-32640) -> &H8080 (-32640)
    &H7090 ( 28816) -> &H9D56 (-25258)
    怎么不失真?
      

  10.   

    是这样么?
    Dim q  As Integer
    Dim b As IntegerFor ii = 45 To my_wavData.nSize + 44
    Get #1, , q
    'Debug.Print q
    '对这个q 进行操作才有效,不过就是音质方面不是很饱满,放大的效果达到了
      If q = 256 Then GoTo aaq
      Select Case q
      Case Is > 128
           b = q * 0.6
     Case Is < 128
           b = q * 1.4
     Case 128
           b = q
     End Select
      
    aaq:
      Put #2, ii, b
    next
      

  11.   

    Integer 的区间是 [-32768, 32767],再仔细想想!还有要不失真地放大,应该先扫描一遍数据,求出现有波形的振幅,计算
      放大比率 = 32767 / 现有振幅
    然后用这个比率去放大波形。
    否则波形的峰、谷可能会被切平。
      

  12.   

    Dim q           As Integer
    Dim b           As Integer
    Dim lPosition   As Long
    Dim lMax        As Long
    Dim dScale      As DoublelPosition = Seek(1)
    lMax = 0
    For ii = 45 To my_wavData.nSize + 44
        Get #1, , q
        lMax 为 Abs(q) 的最大值
    Next
    dScale = 32767 / lMaxSeek #1, lPosition
    For ii = 45 To my_wavData.nSize + 44
        Get #1, , q
        b 为 q 按 dScale 倍率放大
        Put #2, ii, b
    Next
      

  13.   

    lMax 为 Abs(q) 的最大值
    b 为 q 按 dScale 倍率放大
    这个运行效率可能太低了,要是将这2个过程写出来就好了
      

  14.   

    我按照Tiger_Zhao说的方法做,得到的是一片杂音。还希望Tiger_Zhao能具体贴一下代码
      

  15.   

    Cool Edit Pro软件应该可以,不过想要的是代码
      

  16.   

    分是给了,不过Tiger_Zhao说的做法,还是没有做出来。
      

  17.   

    找到了一份C++的代码,哪位大侠可以改写成VB的代码吗。/*---------------------------------------
    method name : AmplifyPCMData
    comment : 对PCM数据的音量进行放大
    parameter : 
    pData PCM数据
    nLen PCM数据的长度
    nBitsPerSample 每个Sample的位数,一般为8的整数
    multiple 放大倍数
    result : S_OK 成功
    ---------------------------------------*/
    int AmplifyPCMData(BYTE* pData, int nLen, int nBitsPerSample, float multiple)
    {
    int nCur = 0;
    if (16 == nBitsPerSample)
    {
    while (nCur < nLen)
    {
    short* volum = (short*)(pData + nCur);
    *volum = (*volum) * multiple;
    if (*volum > SHRT_MAX)//爆音的处理
    {
    *volum = SHRT_MAX;
    }
    *(short*)(pData + nCur) = *volum  ;
    nCur += 2;
    }

    }
    else if (8 == nBitsPerSample)
    {
    while (nCur < nLen)
    {
    BYTE* volum = pData + nCur;
    *volum = (*volum) * multiple;
    if (*volum > 255)//爆音的处理
    {
    *volum = 255;
    }
    *pData  = *volum  ;
    nCur ++;
    }

    }
    return S_OK;

    }