在 python 中从 TIMIT 数据库读取 WAV 文件
reading a WAV file from TIMIT database in python
我正在尝试从 python 中的 TIMIT 数据库中读取一个 wav 文件,但出现错误:
当我使用 wave 时:
wave.Error: file does not start with RIFF id
当我使用 scipy:
ValueError: File format b'NIST'... not understood.
当我使用 librosa 时,程序卡住了。
我尝试使用 sox 将其转换为 wav:
cmd = "sox " + wav_file + " -t wav " + new_wav
subprocess.call(cmd, shell=True)
但没有帮助。我看到一个引用包 scikits.audiolab 的旧答案,但它看起来不再受支持。
如何读取这些文件以获得数据的数组?
谢谢
从命令行发出此命令以验证其是否为 wav 文件……
xxd -b myaudiofile.wav | head
如果它是 wav 格式,它将显示为
00000000: 01010010 01001001 01000110 01000110 10111100 10101111 RIFF..
00000006: 00000001 00000000 01010111 01000001 01010110 01000101 ..WAVE
0000000c: 01100110 01101101 01110100 00100000 00010000 00000000 fmt ..
00000012: 00000000 00000000 00000001 00000000 00000001 00000000 ......
00000018: 01000000 00011111 00000000 00000000 01000000 00011111 @...@.
0000001e: 00000000 00000000 00000001 00000000 00001000 00000000 ......
00000024: 01100100 01100001 01110100 01100001 10011000 10101111 data..
0000002a: 00000001 00000000 10000001 10000000 10000001 10000000 ......
00000030: 10000001 10000000 10000001 10000000 10000001 10000000 ......
00000036: 10000001 10000000 10000001 10000000 10000001 10000000 ......
这里还有另一种显示二进制文件(如 WAV)内容的方法
od -A x -t x1z -v audio_util_test_file_custom.wav | head
000000 52 49 46 46 24 80 00 00 57 41 56 45 66 6d 74 20 >RIFF$...WAVEfmt <
000010 10 00 00 00 01 00 01 00 44 ac 00 00 88 58 01 00 >........D....X..<
000020 02 00 10 00 64 61 74 61 00 80 00 00 00 00 78 05 >....data......x.<
000030 ed 0a 5e 10 c6 15 25 1b 77 20 ba 25 eb 2a 08 30 >..^...%.w .%.*.0<
000040 0e 35 fc 39 cf 3e 84 43 1a 48 8e 4c de 50 08 55 >.5.9.>.C.H.L.P.U<
000050 0b 59 e4 5c 91 60 12 64 63 67 85 6a 74 6d 30 70 >.Y.\.`.dcg.jtm0p<
000060 b8 72 0a 75 25 77 09 79 b4 7a 26 7c 5d 7d 5a 7e >.r.u%w.y.z&|]}Z~<
000070 1c 7f a3 7f ee 7f fd 7f d0 7f 67 7f c3 7e e3 7d >..........g..~.}<
000080 c9 7c 74 7b e6 79 1e 78 1f 76 e8 73 7b 71 d9 6e >.|t{.y.x.v.s{q.n<
000090 03 6c fa 68 c1 65 57 62 c0 5e fd 5a 0f 57 f8 52 >.l.h.eWb.^.Z.W.R<
注意 wav 文件以字符 RIFF 开头
这是文件正在使用 wav 编解码器的强制性指示器...如果您的系统(我在 linux)没有上述命令行实用程序:xxd 然后使用 any hex editor like wxHexEditor 类似地检查您的 wav 文件确认您看到了 RIFF ...如果没有 RIFF 那么它根本就不是 wav 文件
这里是 wav 格式规范的详细信息
http://soundfile.sapp.org/doc/WaveFormat/
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
http://unusedino.de/ec64/technical/formats/wav.html
http://www.drdobbs.com/database/inside-the-riff-specification/184409308
http://www.topherlee.com/software/pcm-tut-wavformat.html
http://www.labbookpages.co.uk/audio/javaWavFiles.html
您的文件不是 WAV 文件。显然它是一个 NIST SPHERE 文件。从LDC web page: "Many LDC corpora contain speech files in NIST SPHERE format." According to the description of the NIST File Format开始,文件的前四个字符是NIST
。这就是 scipy 错误告诉您的内容:它不知道如何读取以 NIST
.
开头的文件
我怀疑如果您想使用您尝试过的任何库来读取文件,则必须 convert the file 到 WAV。要使用程序 sph2pipe
强制转换为 WAV,请使用命令选项 -f wav
(或等同于 -f rif
),例如
sph2pipe -f wav input.sph output.wav
如果您想要一个适用于文件夹中每个 wav 文件的通用代码 运行:
forfiles /s /m *.wav /c "cmd /c sph2pipe -f wav @file @fnameRIFF.wav"
它搜索每个可以找到的 wav 文件并创建一个 scipy 和 wave 都可以读取的 wav 文件,名称为 < base_name >RIFF.wav
我写了一个 python 脚本,它将所有方言中所有说话者所说的 NIST 格式的所有 .WAV 文件转换为 ca 的 .wav 文件
n 可以在您的系统上播放。
注意:所有方言文件夹都在 ./TIMIT/TRAIN/ 中。您可能需要根据您的项目结构更改 dialects_path(或者如果您在 Windows 上)
from sphfile import SPHFile
dialects_path = "./TIMIT/TRAIN/"
for dialect in dialects:
dialect_path = dialects_path + dialect
speakers = os.listdir(path = dialect_path)
for speaker in speakers:
speaker_path = os.path.join(dialect_path,speaker)
speaker_recordings = os.listdir(path = speaker_path)
wav_files = glob.glob(speaker_path + '/*.WAV')
for wav_file in wav_files:
sph = SPHFile(wav_file)
txt_file = ""
txt_file = wav_file[:-3] + "TXT"
f = open(txt_file,'r')
for line in f:
words = line.split(" ")
start_time = (int(words[0])/16000)
end_time = (int(words[1])/16000)
print("writing file ", wav_file)
sph.write_wav(wav_file.replace(".WAV",".wav"),start_time,end_time)
请使用sounddevice和soundfile获取
使用以下代码的 numpy 数组数据(和回放):
import matplotlib.pyplot as plt
import soundfile as sf
import sounddevice as sd
# https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav
data, fs = sf.read('LDC93S1.wav')
print(data.shape,fs)
sd.play(data, fs, blocking=True)
plt.plot(data)
plt.show()
输出
(46797,) 16000
示例 TIMIT 数据库 wav 文件:https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav
有时这可能是由于解压 7zip 文件的方法不正确造成的。我有一个类似的问题。我通过使用 7z x <datasetname>.7z
提取数据集解决了这个问题
我正在尝试从 python 中的 TIMIT 数据库中读取一个 wav 文件,但出现错误:
当我使用 wave 时:
wave.Error: file does not start with RIFF id
当我使用 scipy:
ValueError: File format b'NIST'... not understood.
当我使用 librosa 时,程序卡住了。 我尝试使用 sox 将其转换为 wav:
cmd = "sox " + wav_file + " -t wav " + new_wav
subprocess.call(cmd, shell=True)
但没有帮助。我看到一个引用包 scikits.audiolab 的旧答案,但它看起来不再受支持。
如何读取这些文件以获得数据的数组?
谢谢
从命令行发出此命令以验证其是否为 wav 文件……
xxd -b myaudiofile.wav | head
如果它是 wav 格式,它将显示为
00000000: 01010010 01001001 01000110 01000110 10111100 10101111 RIFF..
00000006: 00000001 00000000 01010111 01000001 01010110 01000101 ..WAVE
0000000c: 01100110 01101101 01110100 00100000 00010000 00000000 fmt ..
00000012: 00000000 00000000 00000001 00000000 00000001 00000000 ......
00000018: 01000000 00011111 00000000 00000000 01000000 00011111 @...@.
0000001e: 00000000 00000000 00000001 00000000 00001000 00000000 ......
00000024: 01100100 01100001 01110100 01100001 10011000 10101111 data..
0000002a: 00000001 00000000 10000001 10000000 10000001 10000000 ......
00000030: 10000001 10000000 10000001 10000000 10000001 10000000 ......
00000036: 10000001 10000000 10000001 10000000 10000001 10000000 ......
这里还有另一种显示二进制文件(如 WAV)内容的方法
od -A x -t x1z -v audio_util_test_file_custom.wav | head
000000 52 49 46 46 24 80 00 00 57 41 56 45 66 6d 74 20 >RIFF$...WAVEfmt <
000010 10 00 00 00 01 00 01 00 44 ac 00 00 88 58 01 00 >........D....X..<
000020 02 00 10 00 64 61 74 61 00 80 00 00 00 00 78 05 >....data......x.<
000030 ed 0a 5e 10 c6 15 25 1b 77 20 ba 25 eb 2a 08 30 >..^...%.w .%.*.0<
000040 0e 35 fc 39 cf 3e 84 43 1a 48 8e 4c de 50 08 55 >.5.9.>.C.H.L.P.U<
000050 0b 59 e4 5c 91 60 12 64 63 67 85 6a 74 6d 30 70 >.Y.\.`.dcg.jtm0p<
000060 b8 72 0a 75 25 77 09 79 b4 7a 26 7c 5d 7d 5a 7e >.r.u%w.y.z&|]}Z~<
000070 1c 7f a3 7f ee 7f fd 7f d0 7f 67 7f c3 7e e3 7d >..........g..~.}<
000080 c9 7c 74 7b e6 79 1e 78 1f 76 e8 73 7b 71 d9 6e >.|t{.y.x.v.s{q.n<
000090 03 6c fa 68 c1 65 57 62 c0 5e fd 5a 0f 57 f8 52 >.l.h.eWb.^.Z.W.R<
注意 wav 文件以字符 RIFF 开头 这是文件正在使用 wav 编解码器的强制性指示器...如果您的系统(我在 linux)没有上述命令行实用程序:xxd 然后使用 any hex editor like wxHexEditor 类似地检查您的 wav 文件确认您看到了 RIFF ...如果没有 RIFF 那么它根本就不是 wav 文件
这里是 wav 格式规范的详细信息
http://soundfile.sapp.org/doc/WaveFormat/
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
http://unusedino.de/ec64/technical/formats/wav.html
http://www.drdobbs.com/database/inside-the-riff-specification/184409308
http://www.topherlee.com/software/pcm-tut-wavformat.html
http://www.labbookpages.co.uk/audio/javaWavFiles.html
您的文件不是 WAV 文件。显然它是一个 NIST SPHERE 文件。从LDC web page: "Many LDC corpora contain speech files in NIST SPHERE format." According to the description of the NIST File Format开始,文件的前四个字符是NIST
。这就是 scipy 错误告诉您的内容:它不知道如何读取以 NIST
.
我怀疑如果您想使用您尝试过的任何库来读取文件,则必须 convert the file 到 WAV。要使用程序 sph2pipe
强制转换为 WAV,请使用命令选项 -f wav
(或等同于 -f rif
),例如
sph2pipe -f wav input.sph output.wav
如果您想要一个适用于文件夹中每个 wav 文件的通用代码 运行:
forfiles /s /m *.wav /c "cmd /c sph2pipe -f wav @file @fnameRIFF.wav"
它搜索每个可以找到的 wav 文件并创建一个 scipy 和 wave 都可以读取的 wav 文件,名称为 < base_name >RIFF.wav
我写了一个 python 脚本,它将所有方言中所有说话者所说的 NIST 格式的所有 .WAV 文件转换为 ca 的 .wav 文件 n 可以在您的系统上播放。
注意:所有方言文件夹都在 ./TIMIT/TRAIN/ 中。您可能需要根据您的项目结构更改 dialects_path(或者如果您在 Windows 上)
from sphfile import SPHFile
dialects_path = "./TIMIT/TRAIN/"
for dialect in dialects:
dialect_path = dialects_path + dialect
speakers = os.listdir(path = dialect_path)
for speaker in speakers:
speaker_path = os.path.join(dialect_path,speaker)
speaker_recordings = os.listdir(path = speaker_path)
wav_files = glob.glob(speaker_path + '/*.WAV')
for wav_file in wav_files:
sph = SPHFile(wav_file)
txt_file = ""
txt_file = wav_file[:-3] + "TXT"
f = open(txt_file,'r')
for line in f:
words = line.split(" ")
start_time = (int(words[0])/16000)
end_time = (int(words[1])/16000)
print("writing file ", wav_file)
sph.write_wav(wav_file.replace(".WAV",".wav"),start_time,end_time)
请使用sounddevice和soundfile获取 使用以下代码的 numpy 数组数据(和回放):
import matplotlib.pyplot as plt
import soundfile as sf
import sounddevice as sd
# https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav
data, fs = sf.read('LDC93S1.wav')
print(data.shape,fs)
sd.play(data, fs, blocking=True)
plt.plot(data)
plt.show()
输出
(46797,) 16000
示例 TIMIT 数据库 wav 文件:https://catalog.ldc.upenn.edu/desc/addenda/LDC93S1.wav
有时这可能是由于解压 7zip 文件的方法不正确造成的。我有一个类似的问题。我通过使用 7z x <datasetname>.7z