2015-09-09 23 views
0

我有一个波形文件(PCM)。 我已经删除了标题并将音频数据读取到一个字节数组中。秒到音频文件中的字节位置

我想找出给定时间值的字节位置(例如6,72911493013085E-02秒)。

我写了一个转换器功能:

Public Function SecondsToBytePos(ByVal uSeconds As Double, ByVal uSamplesPerSecond As Long, ByVal uChannels As Long, ByVal uBitsPerSample) As Long 

    Dim lRet& 
    lRet = (uSeconds * ((uSamplesPerSecond * uChannels * uBitsPerSample)/8)) 

    SecondsToBytePos = lRet 

End Function 

然而,当我使用

SecondsToBytePos(6,72911493013085E-02,48000,1,16)

我得到的偶数值6460

这是不正确的,因为字节数组是从零开始的,所以这个值需要是奇数。

2个字节组成1个double/float值,所以偶数值永远不会发生。

有没有人在我的转换器功能中看到任何缺陷?

谢谢你的帮助。

编辑:这是一种不同的方法:

Public Function SecondsToBytePos(ByVal uSeconds As Double, ByVal uSamplesPerSecond As Long, ByVal uChannels As Long, ByVal uBitsPerSample) As Long 

    Dim g_lBlockAlign As Long=2 

    Dim lret& 
    lret = (uSeconds * ((uSamplesPerSecond * uChannels * uBitsPerSample)/8)) 

    If (lret Mod g_lBlockAlign) > 0 Then 
     Dim lRem& 
     lRem = (lret \ g_lBlockAlign) + 1 
     lret = lRem * g_lBlockAlign 
    End If 

    SecondsToBytePos = lret 

End Function 

回答

0

你的假设,即返回值必须是奇数是错误的 - 因为你转换为字节,而不是样品或帧。

如果希望第一信道的第一样本的字节位置开始在时间uSeconds:

frameNumber = Floor(uSeconds * uSamplesPerSecond) 
bytePos = frameNumber * numChannels * bitsPerSample/8 

bytePos将numChannels * bitsPerSample/8

如果希望字节的倍数的的第一样本的位置的任何通道起始于时间uSeconds:

sampleNumber = Floor(uSeconds * uSamplesPerSecond * numChannels) 
bytePos = sampleNumber * bitsPerSample/8 

这里bytePos将多倍bitsPerSample/8

我会怀疑你想要frameNumber,因为它与你的数据对齐 - 如果你想从该位置回放,例如你的左和右将留在左侧和右侧。

+0

该文件是单声道的。样本是1个双/平面值,即2个字节。你仍然认为我的假设是错误的吗? – MaikenRosk

+0

是的,它适用于所有情况。考虑一个简单的例子。 1秒48kHz音频,单声道,16位。您首先转换为96000字节的数量。然后,您使用秒来索引该数字。如果你在0.5秒时要求字节,那么你将得到48000.如果你要求在(0.5 +(1/48000.0))处的字节,你将得到48001.我的答案的要点是,你需要保留在索引之前构建你的愿望,然后*将该答案转换为字节。 – jaket

+0

我不信任“楼层”。我在帖子中增加了另一种方法。我也可以使用这种BlockAlign方法吗? – MaikenRosk