确定 Visual Studio 2019 年的 WAV 持续时间
Determine WAV Duration Time in Visual Studio 2019
首先,感谢您考虑我的问题。我已经搜索了这个问题的解决方案,但没有找到任何利用现代 Visual Studio features/libraries/namespaces 等...
我需要确定 WAV 音频文件的持续时间(时间长度)。我想在几毫秒内得到结果 - 我可以从那里根据我的需要格式化数据。
能否举例说明如何做到这一点?
谢谢你
文件的元数据将在标准中定义。 wave 文件头已在 another SO question 中介绍,但重点是使用 C sharp。
VB.NET和C sharp的实现应该比较相似。 VB.NET 有一些限制,这意味着这种操作最好用另一种语言来完成。也就是说,新手 VB.NET 程序员几乎没有立即可用的东西,这本身就是一个危险信号,它可能以错误的方式使用 VB.NET。
有一个 project that tries to provide a .NET framework for grabbing metadata,但如果你不想让自己为 Wav 文件这样的依赖项而增加负担,那么你可以使用以下方法获得持续时间。
Dim wavFilePath As String = "Path\To\Your\Wav"
Dim fileReader As New System.IO.FileStream(wavFilePath, System.IO.FileMode.Open)
Dim numChannelsData(2) As Byte
Dim bitsPerSampleData(2) As Byte
Dim sampleRateData(4) As Byte
Dim subChunk2SizeData(4) As Byte
fileReader.Seek(22, System.IO.SeekOrigin.Begin)
fileReader.Read(numChannelsData, 0, 2)
fileReader.Seek(34, System.IO.SeekOrigin.Begin)
fileReader.Read(bitsPerSampleData, 0, 2)
fileReader.Seek(24, System.IO.SeekOrigin.Begin)
fileReader.Read(sampleRateData, 0, 4)
fileReader.Seek(40, System.IO.SeekOrigin.Begin)
fileReader.Read(subChunk2SizeData, 0, 4)
Dim numChannels As Int16 = BitConverter.ToInt16(numChannelsData)
Dim bitsPerSample = BitConverter.ToInt32(sampleRateData)
Dim sampleRate = BitConverter.ToInt16(bitsPerSampleData)
Dim subChunk2Size = BitConverter.ToInt32(subChunk2SizeData)
Dim numSamples = (subChunk2Size * 8) / (numChannels * bitsPerSample)
Dim durationInMilliseconds As Single = 1000 * Convert.ToSingle(numSamples) / (Convert.ToSingle(sampleRate))
Console.WriteLine(durationInMilliseconds)
对于那些搜索此解决方案的人,这里是调试代码。
请注意,这里不包括毫秒到时间字符串的转换。
另请注意,根据对此帖子的评论,没有标准的 Visual Basic 库可以导出 WAV 文件的持续时间。
选项显式
选项严格
进口 System.IO
Public Shared Function GetWAVDuration(ByVal strPathAndFilename As String) As String
REM *** SEE ALSO
REM *** http://soundfile.sapp.org/doc/WaveFormat/
REM *** CAUTION
REM *** On the WaveFormat web page, the positions of the values
REM *** SampleRate and BitsPerSample have been reversed.
REM ***
REM *** DEFINE LOCAL VARIABLES
REM *** Define Visual Basic BYTE Array Types
Dim byNumberOfChannels() As Byte
Dim bySamplesPerSec() As Byte
Dim byBitsPerSample() As Byte
Dim bySubChunkToSizeData() As Byte
Dim nNumberOfChannels As Int16
Dim nSamplesPerSec As Int16
Dim nBitsPerSample As Int32
Dim nSubChunkToSizeData As Int32
Dim dNumberOfSamples As Double
Dim nDurationInMillis As Int32
Dim strDuration As String
REM *** INITIALIZE LOCAL VARIABLES
byNumberOfChannels = New Byte(2) {}
bySamplesPerSec = New Byte(2) {}
byBitsPerSample = New Byte(4) {}
bySubChunkToSizeData = New Byte(4) {}
nNumberOfChannels = 0
nSamplesPerSec = 0
nBitsPerSample = 0L
nSubChunkToSizeData = 0L
dNumberOfSamples = 0.0
nDurationInMillis = 0
strDuration = ""
REM *** Initialize the return string value
GetWAVDuration = ""
REM ***************************************************************************
REM *** Open the Input File for READ Operations
Using fsFileStream = File.OpenRead(strPathAndFilename)
REM *** Get the Number of Audio Channels
fsFileStream.Seek(22, SeekOrigin.Begin)
fsFileStream.Read(byNumberOfChannels, 0, 2)
REM *** Get the Number of Bits Per Audio Sample
fsFileStream.Seek(24, SeekOrigin.Begin)
fsFileStream.Read(byBitsPerSample, 0, 4)
REM *** Get the number of samples taken per second
fsFileStream.Seek(34, SeekOrigin.Begin)
fsFileStream.Read(bySamplesPerSec, 0, 2)
REM *** Retrieve the size of the WAV data
REM *** payload in the file
fsFileStream.Seek(40, SeekOrigin.Begin)
fsFileStream.Read(bySubChunkToSizeData, 0, 4)
End Using
REM *** Convert Values from their BYTE representation
nNumberOfChannels = BitConverter.ToInt16(byNumberOfChannels, 0)
nBitsPerSample = BitConverter.ToInt32(byBitsPerSample, 0)
nSamplesPerSec = BitConverter.ToInt16(bySamplesPerSec, 0)
nSubChunkToSizeData = BitConverter.ToInt32(bySubChunkToSizeData, 0)
REM *** Compute the Duration of the WAV File
REM *** Derives the duration in milliseconds
REM *** Determine the number of Sound Samples
dNumberOfSamples = (nSubChunkToSizeData * 8) / (nNumberOfChannels * nBitsPerSample)
nDurationInMillis = Convert.ToInt32(1000 * Convert.ToSingle(dNumberOfSamples) / Convert.ToSingle(nSamplesPerSec))
REM *** Convert the time in Milliseconds to a string format
REM *** represented by "hh:mm:ss"
strDuration = ConvertMillisToTimeString(nDurationInMillis)
REM *** POST METHOD RETURNS
GetWAVDuration = strDuration
End Function
首先,感谢您考虑我的问题。我已经搜索了这个问题的解决方案,但没有找到任何利用现代 Visual Studio features/libraries/namespaces 等...
我需要确定 WAV 音频文件的持续时间(时间长度)。我想在几毫秒内得到结果 - 我可以从那里根据我的需要格式化数据。
能否举例说明如何做到这一点?
谢谢你
文件的元数据将在标准中定义。 wave 文件头已在 another SO question 中介绍,但重点是使用 C sharp。
VB.NET和C sharp的实现应该比较相似。 VB.NET 有一些限制,这意味着这种操作最好用另一种语言来完成。也就是说,新手 VB.NET 程序员几乎没有立即可用的东西,这本身就是一个危险信号,它可能以错误的方式使用 VB.NET。
有一个 project that tries to provide a .NET framework for grabbing metadata,但如果你不想让自己为 Wav 文件这样的依赖项而增加负担,那么你可以使用以下方法获得持续时间。
Dim wavFilePath As String = "Path\To\Your\Wav"
Dim fileReader As New System.IO.FileStream(wavFilePath, System.IO.FileMode.Open)
Dim numChannelsData(2) As Byte
Dim bitsPerSampleData(2) As Byte
Dim sampleRateData(4) As Byte
Dim subChunk2SizeData(4) As Byte
fileReader.Seek(22, System.IO.SeekOrigin.Begin)
fileReader.Read(numChannelsData, 0, 2)
fileReader.Seek(34, System.IO.SeekOrigin.Begin)
fileReader.Read(bitsPerSampleData, 0, 2)
fileReader.Seek(24, System.IO.SeekOrigin.Begin)
fileReader.Read(sampleRateData, 0, 4)
fileReader.Seek(40, System.IO.SeekOrigin.Begin)
fileReader.Read(subChunk2SizeData, 0, 4)
Dim numChannels As Int16 = BitConverter.ToInt16(numChannelsData)
Dim bitsPerSample = BitConverter.ToInt32(sampleRateData)
Dim sampleRate = BitConverter.ToInt16(bitsPerSampleData)
Dim subChunk2Size = BitConverter.ToInt32(subChunk2SizeData)
Dim numSamples = (subChunk2Size * 8) / (numChannels * bitsPerSample)
Dim durationInMilliseconds As Single = 1000 * Convert.ToSingle(numSamples) / (Convert.ToSingle(sampleRate))
Console.WriteLine(durationInMilliseconds)
对于那些搜索此解决方案的人,这里是调试代码。 请注意,这里不包括毫秒到时间字符串的转换。 另请注意,根据对此帖子的评论,没有标准的 Visual Basic 库可以导出 WAV 文件的持续时间。
选项显式 选项严格 进口 System.IO
Public Shared Function GetWAVDuration(ByVal strPathAndFilename As String) As String
REM *** SEE ALSO
REM *** http://soundfile.sapp.org/doc/WaveFormat/
REM *** CAUTION
REM *** On the WaveFormat web page, the positions of the values
REM *** SampleRate and BitsPerSample have been reversed.
REM ***
REM *** DEFINE LOCAL VARIABLES
REM *** Define Visual Basic BYTE Array Types
Dim byNumberOfChannels() As Byte
Dim bySamplesPerSec() As Byte
Dim byBitsPerSample() As Byte
Dim bySubChunkToSizeData() As Byte
Dim nNumberOfChannels As Int16
Dim nSamplesPerSec As Int16
Dim nBitsPerSample As Int32
Dim nSubChunkToSizeData As Int32
Dim dNumberOfSamples As Double
Dim nDurationInMillis As Int32
Dim strDuration As String
REM *** INITIALIZE LOCAL VARIABLES
byNumberOfChannels = New Byte(2) {}
bySamplesPerSec = New Byte(2) {}
byBitsPerSample = New Byte(4) {}
bySubChunkToSizeData = New Byte(4) {}
nNumberOfChannels = 0
nSamplesPerSec = 0
nBitsPerSample = 0L
nSubChunkToSizeData = 0L
dNumberOfSamples = 0.0
nDurationInMillis = 0
strDuration = ""
REM *** Initialize the return string value
GetWAVDuration = ""
REM ***************************************************************************
REM *** Open the Input File for READ Operations
Using fsFileStream = File.OpenRead(strPathAndFilename)
REM *** Get the Number of Audio Channels
fsFileStream.Seek(22, SeekOrigin.Begin)
fsFileStream.Read(byNumberOfChannels, 0, 2)
REM *** Get the Number of Bits Per Audio Sample
fsFileStream.Seek(24, SeekOrigin.Begin)
fsFileStream.Read(byBitsPerSample, 0, 4)
REM *** Get the number of samples taken per second
fsFileStream.Seek(34, SeekOrigin.Begin)
fsFileStream.Read(bySamplesPerSec, 0, 2)
REM *** Retrieve the size of the WAV data
REM *** payload in the file
fsFileStream.Seek(40, SeekOrigin.Begin)
fsFileStream.Read(bySubChunkToSizeData, 0, 4)
End Using
REM *** Convert Values from their BYTE representation
nNumberOfChannels = BitConverter.ToInt16(byNumberOfChannels, 0)
nBitsPerSample = BitConverter.ToInt32(byBitsPerSample, 0)
nSamplesPerSec = BitConverter.ToInt16(bySamplesPerSec, 0)
nSubChunkToSizeData = BitConverter.ToInt32(bySubChunkToSizeData, 0)
REM *** Compute the Duration of the WAV File
REM *** Derives the duration in milliseconds
REM *** Determine the number of Sound Samples
dNumberOfSamples = (nSubChunkToSizeData * 8) / (nNumberOfChannels * nBitsPerSample)
nDurationInMillis = Convert.ToInt32(1000 * Convert.ToSingle(dNumberOfSamples) / Convert.ToSingle(nSamplesPerSec))
REM *** Convert the time in Milliseconds to a string format
REM *** represented by "hh:mm:ss"
strDuration = ConvertMillisToTimeString(nDurationInMillis)
REM *** POST METHOD RETURNS
GetWAVDuration = strDuration
End Function