确定wav文件的位深度

use*_*074 4 python audio sox bit-depth wave

我正在寻找一种快速,最好是标准的库机制来确定wav文件的位深度,例如“ 16位”或“ 24位”。

我正在使用对Sox的子过程调用来获取过多的音频元数据,但是子过程调用非常慢,并且我目前只能从Sox可靠地获得的唯一信息是位深度。

内置的wave模块不具有“ getbitdepth()”之类的功能,并且与24位的wav文件也不兼容-我可以使用wave模块使用“ tryexcept”来访问文件元数据(如果可以,请手动记录它是16位的),然后调用sox(在sox将执行分析以准确记录其位深度的位置)上。我担心的是,这种方法感觉像是猜测。如果读取8位文件怎么办?如果不是,我将手动分配16位。

SciPy.io.wavefile也与24位音频不兼容,因此会产生类似的问题。

教程非常有趣,甚至包括一些非常低级的脚本示例(至少对于Python来说是低级),这些示例可从wav文件头中提取信息-不幸的是,这些脚本不适用于16位音频。

有什么方法可以简单地(无需调用sox)确定我要检查的wav文件的位深度?

我正在使用的wave标头解析器脚本如下:

import struct
import os

def print_wave_header(f):
    '''
    Function takes an audio file path as a parameter and 
    returns a dictionary of metadata parsed from the header
    '''
    r = {} #the results of the header parse
    r['path'] = f
    fin = open(f,"rb") # Read wav file, "r flag" - read, "b flag" - binary 
    ChunkID=fin.read(4) # First four bytes are ChunkID which must be "RIFF" in ASCII
    r["ChunkID"]=ChunkID
    ChunkSizeString=fin.read(4) # Total Size of File in Bytes - 8 Bytes
    ChunkSize=struct.unpack('I',ChunkSizeString) # 'I' Format is to to treat the 4 bytes as unsigned 32-bit inter
    TotalSize=ChunkSize[0]+8 # The subscript is used because struct unpack returns everything as tuple
    r["TotalSize"]=TotalSize
    DataSize=TotalSize-44 # This is the number of bytes of data
    r["DataSize"]=DataSize
    Format=fin.read(4) # "WAVE" in ASCII
    r["Format"]=Format
    SubChunk1ID=fin.read(4) # "fmt " in ASCII
    r["SubChunk1ID"]=SubChunk1ID
    SubChunk1SizeString=fin.read(4) # Should be 16 (PCM, Pulse Code Modulation)
    SubChunk1Size=struct.unpack("I",SubChunk1SizeString) # 'I' format to treat as unsigned 32-bit integer
    r["SubChunk1Size"]=SubChunk1Size
    AudioFormatString=fin.read(2) # Should be 1 (PCM)
    AudioFormat=struct.unpack("H",AudioFormatString) ## 'H' format to treat as unsigned 16-bit integer
    r["AudioFormat"]=AudioFormat[0]
    NumChannelsString=fin.read(2) # Should be 1 for mono, 2 for stereo
    NumChannels=struct.unpack("H",NumChannelsString) # 'H' unsigned 16-bit integer
    r["NumChannels"]=NumChannels[0]
    SampleRateString=fin.read(4) # Should be 44100 (CD sampling rate)
    SampleRate=struct.unpack("I",SampleRateString)
    r["SampleRate"]=SampleRate[0]
    ByteRateString=fin.read(4) # 44100*NumChan*2 (88200 - Mono, 176400 - Stereo)
    ByteRate=struct.unpack("I",ByteRateString) # 'I' unsigned 32 bit integer
    r["ByteRate"]=ByteRate[0]
    BlockAlignString=fin.read(2) # NumChan*2 (2 - Mono, 4 - Stereo)
    BlockAlign=struct.unpack("H",BlockAlignString) # 'H' unsigned 16-bit integer
    r["BlockAlign"]=BlockAlign[0]
    BitsPerSampleString=fin.read(2) # 16 (CD has 16-bits per sample for each channel)
    BitsPerSample=struct.unpack("H",BitsPerSampleString) # 'H' unsigned 16-bit integer
    r["BitsPerSample"]=BitsPerSample[0]
    SubChunk2ID=fin.read(4) # "data" in ASCII
    r["SubChunk2ID"]=SubChunk2ID
    SubChunk2SizeString=fin.read(4) # Number of Data Bytes, Same as DataSize
    SubChunk2Size=struct.unpack("I",SubChunk2SizeString)
    r["SubChunk2Size"]=SubChunk2Size[0]
    S1String=fin.read(2) # Read first data, number between -32768 and 32767
    S1=struct.unpack("h",S1String)
    r["S1"]=S1[0]
    S2String=fin.read(2) # Read second data, number between -32768 and 32767
    S2=struct.unpack("h",S2String)
    r["S2"]=S2[0]
    S3String=fin.read(2) # Read second data, number between -32768 and 32767
    S3=struct.unpack("h",S3String)
    r["S3"]=S3[0]
    S4String=fin.read(2) # Read second data, number between -32768 and 32767
    S4=struct.unpack("h",S4String)
    r["S4"]=S4[0]
    S5String=fin.read(2) # Read second data, number between -32768 and 32767
    S5=struct.unpack("h",S5String)
    r["S5"]=S5[0]
    fin.close()
    return r
Run Code Online (Sandbox Code Playgroud)

Mar*_*oma 7

基本上与 Matthias 的答案相同,但使用可复制粘贴的代码。

要求

pip install soundfile
Run Code Online (Sandbox Code Playgroud)

代码

pip install soundfile
Run Code Online (Sandbox Code Playgroud)

解释

  • 通道:通常为 2,这意味着您有一个左扬声器和一个右扬声器。
  • 采样率:音频信号是模拟的,但我们想用数字表示它们。这意味着我们希望在价值和时间上离散化它们。采样率给出了我们每秒获得一个值的次数。单位是赫兹。采样率至少需要是原始声音最高频率的两倍,否则会出现混叠。人类听觉范围从 ~20Hz 到 ~20kHz,因此您可以切断 20kHZ 以上的任何声音。这意味着超过 40kHz 的采样率没有多大意义。
  • 位深位深越高,可以捕捉的动态范围越大。动态范围是乐器、部分或音乐的最安静和最响亮音量之间的差异。典型值似乎是 16 位或 24 位。16 位的位深度具有 96 dB 的理论动态范围,而 24 位具有 144 dB 的动态范围()。
  • 子类型PCM_16表示 16 位深度,其中 PCM 代表Pulse-Code Modulation

选择

如果您只寻找命令行工具,那么我可以推荐MediaInfo

$ mediainfo example.wav
General
Complete name                            : example.wav
Format                                   : Wave
File size                                : 83.2 MiB
Duration                                 : 8 min 14 s
Overall bit rate mode                    : Constant
Overall bit rate                         : 1 411 kb/s

Audio
Format                                   : PCM
Format settings                          : Little / Signed
Codec ID                                 : 1
Duration                                 : 8 min 14 s
Bit rate mode                            : Constant
Bit rate                                 : 1 411.2 kb/s
Channel(s)                               : 2 channels
Sampling rate                            : 44.1 kHz
Bit depth                                : 16 bits
Stream size                              : 83.2 MiB (100%)
Run Code Online (Sandbox Code Playgroud)


Mat*_*ias 5

我强烈建议使用soundfile模块(但请注意,我非常有偏见,因为我写了很大一部分)。

在那里,您可以将文件作为soundfile.SoundFile对象打开,该对象具有一个子类型属性,其中包含您要查找的信息。

在您的情况下,可能是'PCM_16''PCM_24'