audio - 我的音频标准化代码正确吗?

标签 audio vb6 wav audio-recording wave

我想将音频文件标准化为最大。

为此,我使用以下代码:

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

最佳答案

这是不正确的,因为它会产生大量的裁剪。

代替:

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

最好这样做:
If iHighestDataValue >= -iLowestDataValue Then
    sngVolumeLevel = iHighestDataValue / 32767.
Else
    sngVolumeLevel = iLowestDataValue / -32768.
End If

关于audio - 我的音频标准化代码正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41401577/

相关文章:

performance - 如何减少 VB6 项目启动时间/查明是什么花了这么长时间

c# - 来自 .wav 文件的峰值频率

python - 测量Python中某些频率值内发生了多少事件

java - Android Studio 禁用点击声音

linux - 多核Linux系统上的实时音频

VB6(已编译)7Zip 命令行导致错误 10 ("The Array is Fixed or Temporarily Locked")

javascript - 如何使用 JavaScript/Tone.js 更改音高和播放速率?

c++ - C++ 函数的 VB6 声明给出 "Bad DLL calling convention"

audio - 通过命令提示符从Vob文件中剥离音频

c# - Windows Phone 8 可以播放 WAV 文件,但不能播放 MP3