2016-12-30 6 views
1

オーディオファイルを最大で正規化します。 私のオーディオ正規化コードは正しいですか?

私はこのコードを使用しています、それを行うには:

Dim iHighestDataValue As Integer 
Dim iLowestDataValue As Integer 

Dim i& 
For i = 1 To dc.wavedatasize/2 
    Get #iFile, , DataValue(i) ' reads data value into array 

    If DataValue(i) > iHighestDataValue Then 
     iHighestDataValue = DataValue(i) 
    End If 

    If DataValue(i) < iLowestDataValue Then 
     iLowestDataValue = DataValue(i) 
    End If 
Next 

Dim sngVolumeLevel As Single 
sngVolumeLevel = ((iHighestDataValue + (iLowestDataValue * -1))/2)/32767 

それはほとんどすべてのファイルのために正常に動作しますが、一つのファイルのために、最後の行は失敗します。

iHighestDataValueは13445、iLowestDataValueは-21940です。

最後の行に何か間違いがあります。 VB6でこの(正しい)計算を処理できないか、またはエラーを導入しただけでVB6で発生するエラーですか?私は別々の計算に最後の行を入れて

、それが正常に動作します:

Dim sngHighest As Single 
If iHighestDataValue > 32767 Then 
    sngHighest = 32767 
Else 
    sngHighest = iHighestDataValue 
End If 

Dim sngLowest As Single 
If iLowestDataValue < -32767 Then 
    sngLowest = -32767 
Else 
    sngLowest = iLowestDataValue 
End If 
sngLowest = sngLowest * -1 

Dim sngVolumeLevel As Single 
sngVolumeLevel = (sngHighest + sngLowest)/2 
sngVolumeLevel = (sngVolumeLevel/32767) 

ありがとうございました!

PS: ここでは、関数の最後、正規の部分である:

Dim tem As Long 

For i = 1 To dc.wavedatasize/2 
    tem = CLng(DataValue(i) * 1/sngVolumeLevel) 
    If tem > 32767 Then 
     tem = 32767 ' prevents integer overflow error 
    End If 
    If tem < -32767 Then 
     tem = -32767 ' prevents integer overflow error 
    End If 
    DataValue(i) = CInt(tem) ' changes data value 
Next i 

wh.riffdatasize = dc.wavedatasize + Len(wh) + Len(wf) 'Riff chunk size may be different 
' beacause some input wave files may contain information chunk which is not written in output file 

iFile = FreeFile 

Kill uPath 'Delete the original/source file. We will overwrite it with the normalized version of this file 

Open uPath For Binary As #iFile 
Put #iFile, , wh ' writes the wave header 
Put #iFile, , wf ' writes wave format 
Put #iFile, , dc ' writes the 8 byte string "data" and wave dataa size 

For i = 1 To dc.wavedatasize/2 
    Put #iFile, , DataValue(i) ' writes data value in ouput file 
Next i 

Close #iFile 

答えて

2

それはクリッピングを大量に生成するので、それは正しくありません。

の代わりに:

sngVolumeLevel = ((iHighestDataValue + (iLowestDataValue * -1))/2)/32767 

より良い次の操作を行います。

If iHighestDataValue >= -iLowestDataValue Then 
    sngVolumeLevel = iHighestDataValue/32767. 
Else 
    sngVolumeLevel = iLowestDataValue/-32768. 
End If 
+0

すごい、ありがとう! – tmighty

関連する問題