我的音频标准化代码是不是正确?
Posted
技术标签:
【中文标题】我的音频标准化代码是不是正确?【英文标题】:Is my audio normalization code correct?我的音频标准化代码是否正确? 【发布时间】:2016-12-30 19:20:36 【问题描述】:我想将音频文件标准化到最大。
为此,我使用以下代码:
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 无法处理这个(正确的)计算而发生的错误,还是我引入了任何错误?
当我将最后一行放入单独的计算中时,它工作正常:
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
【问题讨论】:
【参考方案1】:这是不正确的,因为它会产生大量的剪辑。
代替:
sngVolumeLevel = ((iHighestDataValue + (iLowestDataValue * -1)) / 2) / 32767
最好这样做:
If iHighestDataValue >= -iLowestDataValue Then
sngVolumeLevel = iHighestDataValue / 32767.
Else
sngVolumeLevel = iLowestDataValue / -32768.
End If
【讨论】:
以上是关于我的音频标准化代码是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章