• 如何去除Wave檔靜音的部分

由於Wave檔的檔頭有44Byte 由45Byte開始才是資料所在
每筆資料長度和它的Bit數有關

  • 8Bit的音檔 每筆資料長度是1Bytes 所以要用Byte型態的變數
  • 16Bit的音檔 每筆資料長度是2Bytes 當然就是用Integer型態的變數

音檔有分成單聲道,雙聲道等等

  • 單聲道的音檔由單一個資料構成。
  • 雙聲道的音檔由兩筆資料構成,一筆由左聲道輸出,一筆由右聲道。

而資料的值

  • 8Bit的音檔 值是以128為基準 大於128的在基準上 反之就在下面 由於VB的值是界於0~255 因此必須先減掉128
  • 16bit音檔 對於VB而言並不需要最任何移位的改變 就是以零為基準

其他更詳細的部分 我會在以後的文章填上,基本上這個問題只需要這三種知識就夠了 程式如下


Option Explicit
'PCM 音檔檔頭
Private Type PCMFORM '以下為44byte的檔頭
    wRiffFormatTag As String * 4 '1~4存放的是RIFF字串
    wfdataSize As Long '5~8存放的是資料區塊大小
' NOTE : 資料區塊大小=(檔案大小-8)
    wFormatTag As String * 4 '9~12存放的是WAVE字串
    wFormatName  As String * 4 '13~16存放的是子區塊識別名稱
    wCsize As Long '17~20存放的是子區塊大小
    wWavefmt As Integer '21~22存放的是聲檔格式,0x0001表PCM格式
    wChannels As Integer '23~24存放的是聲道數
    wSamplesPerSec As Long '25~28存放的每秒取樣數
    wBytePerSec As Long '29~32存放的是每秒資料量
' NOTE : 每秒資料量=(聲道數*位元數*每秒取樣數/8)
    wBytePerSample As Integer '33~34存放的是子區塊位元組
' NOTE : 子區塊位元組=(位元數/8)
    wBitsPerSample As Integer '35~36存放的是取樣位組元數
    wData As String * 4 '存放的是data字串
    wDataSize As Long '實際聲檔大小
' NOTE : 這個值為檔案大小減去檔頭(44BYTE)後的值
End Type

Public Sub eraseQu(sFileName As String, dFileName As String, Prs As Byte)
Dim bData() As Byte '用來存放8bit音檔資料

Dim iData() As Integer '用來存放16bit音檔資料

Dim pHandle As PCMFORM '檔頭
Dim i As Long, j As Long
Open sFileName For Binary As #1 '開啟來源檔
Get #1, 1, pHandle '讀出44Byte的檔頭

If pHandle.wBitsPerSample = 8 Then '這是8bit音檔
   
    Open dFileName For Random As #2 Len = 1 '每筆資料是1Bytes
    j = 44 '由於要從45Bytes讀起
    ReDim bData(1 To pHandle.wDataSize) '設定Buffer大小以讀入檔案
    'pHandle.wDataSize 由檔頭可知是實際生檔大小
    Get #1, 45, bData
    If pHandle.wChannels = 1 Then '單聲道
        For i = 1 To pHandle.wDataSize
            If Abs(bData(i) - 128) >= 128 * Prs \ 100 Then
                j = j + 1
                Put #2, j, bData(i)
            End If
        Next
    ElseIf pHandle.wChannels = 2 Then '雙聲道
        For i = 1 To pHandle.wDataSize - 1 Step 2
            If Abs((bData(i) - 128) + (bData(i + 1) - 128)) \ 2 >= 128 * Prs \ 100 Then
                j = j + 1
                Put #2, j, bData(i)
                j = j + 1
                Put #2, j, bData(i + 1)
            End If
        Next
    End If
ElseIf pHandle.wBitsPerSample = 16 Then
    Open dFileName For Random As #2 Len = 2
    j = 22
    ReDim iData(1 To pHandle.wDataSize / 2)
    Get #1, 45, iData
    If pHandle.wChannels = 1 Then '單聲道
        For i = 1 To pHandle.wDataSize / 2
            If Abs(CLng(iData(i))) >= 32768 * Prs \ 100 Then
                j = j + 1
                Put #2, j, iData(i)
            End If
        Next
    ElseIf pHandle.wChannels = 2 Then '雙聲道
        For i = 1 To pHandle.wDataSize / 2 - 1 Step 2
            If ( Abs(iData(i)) + ABS( iData(i + 1) ) ) / 2 >= 32768 * Prs \ 100 Then
                j = j + 1
                Put #2, j, iData(i)
                j = j + 1
                Put #2, j, iData(i + 1)
            End If
        Next
   
    End If
Else
    Exit Sub
End If

pHandle.wfdataSize = LOF(2) - 8
pHandle.wDataSize = LOF(2) - 44

Erase bData
Erase iData
Close
Open dFileName For Binary As #1
Put #1, , pHandle
Close
Unload Me
End Sub
假設要將C:\ty16.wav去掉靜音部分 存入c:\1ty16.wav 只要這樣
eraseQu "C:\ty16.wav", "c:\1ty16.wav", 3
'其中3是比例,值介於0~99,假設100是音量的最大值,0是都沒有聲音,如果第三個參數 傳入3,會將比例小於3的資料去除,實際上比例1~5的部份從波形來看是趨近於直線的,如果你設成0,會少去掉很多你聽不到的部分,這個值就由各位自行取捨
去除靜音前

去除靜音後 (使用比例3)


  • 文件出處

  Honey

VB心得筆記歡迎各位的指教,如果您有任何文章或資料願意提供給我們的,請來信到VBNote

如果對本站有任何建議,歡迎來信給Honey,我們會盡快給您答覆