使用format_wav_scp.py转换音频文件格式
使用format_wav_scp.py转换音频文件格式
format_wav_scp.py 是一个实用工具,用于转换 wav.scp 文件中指定的音频格式,而 format_wav_scp.sh 则是一个封装 format_wav_scp.py 的shell脚本。在典型的 template recipe 的stage3阶段,会使用 format_wav_scp.sh 将原始语料库的音频文件格式转换为实际需要输入DNN模型的音频格式。
format_wav_scp.py 和 format_wav_scp.sh 具有相同的功能,都能从 wav.scp 生成 wav.scp,但 format_wav_scp.sh 的不同之处在于它具备并行处理能力。
wav.scp -> [format_wav_scp.py] -> wav.scp
wav.scp -> [format_wav_scp.sh] -> wav.scp请注意,format_wav_scp.py会以线性PCM格式和sint16编码转储音频文件,无论输入音频格式如何。
快速使用
首先,你需要准备一个名为wav.scp的文本文件:
ID_a /some_where/a.wav
ID_b /some_where2/b.wav
...ID_a和ID_b是您可以任意命名的ID,用于指定音频文件。请注意我们不假设音频文件有任何目录结构。
# Please change directory before using our shell scripts
cd egs2/some_corpus/some_task
cmd=utils/run.pl
nj=10 # Number of parallel jobs
audio_format=flac # The audio codec of output files
fs=16k # The sampling frequency of output files
ref_channels=0 # If the input data has multiple channels and you want to use only a single channel in the file (please spicify the channel with 0-based number)
./scripts/audio/format_wav_scp.sh --nj "${nj}" --cmd "${cmd}" --audio_format "${audio_format}" --fs "${fs}" --ref_channels "${ref_channels}" somewhere/wav.scp output_dir
# Then, you can find output_dir/wav.scp另请参阅:
- 关于
wav.scp文件: https://github.com/espnet/data_example - 关于
cmd:使用作业调度系统
为什么需要对音频文件进行格式化?
从源网站获取的语料库中包含的音频数据以多种音频文件格式分布,即音频编解码器(wav格式的linear PCM、flac、mp3、DSD、u-law、a-law等)、采样频率(48khz、44.1khz、16khz、8khz等)、位深度(uint8、sint16、sint32、float20、float32等)、声道数(monaural单声道、stereo立体声或2声道以上)、字节序(little endian小端序或big endian大端序)。
当您尝试使用我们现有配方中尚未准备的语料库开发新配方时,当然也可以直接使用未经任何格式化的原始音频数据。但通常情况下,我们的DNN模型配置可能会针对特定音频格式进行优化,特别是采样频率和数据精度方面。如果您对新配方持保守态度,我们建议将其转换为原始配方使用的音频格式。例如,我们的ASR配方中通常使用16khz采样率和sint16精度的音频。
ESPnet2支持的音频文件格式
ESPnet采用python soundifile进行数据加载,因此支持的音频编解码器取决于libsndfile。
您可以通过以下命令检查soundfile支持的音频编解码器:
import soundfile
print(soundfile.available_formats())请注意,Kaldi的wav.scp原本要求音频格式为pcm_s16le类型的wav文件,但ESPnet2的wav.scp可以处理soundfile支持的所有音频格式。例如,您可以在wav.scp中使用flac格式作为format_wav_scp.py的输入/输出。
根据具体情况,您可以选择以下编解码器之一:
| 编解码器 | 压缩率 | 最大通道数 | 最大采样频率 | 备注 |
|---|---|---|---|---|
| wav (Microsoft wav 线性PCM格式) | 否 | 1024 | - | |
| flac | 无损 | 8 | 192khz | |
| mp3 | 有损 | 2 | 48khz | MP3的专利已过期 |
| ogg (Vorbis) | 有损 | 255 | 192khz | 发生段错误 |
默认情况下,我们选择flac格式,因为flac能以约55%的压缩率转换线性PCM文件且不损失数据。flac有助于降低IO负载,特别是在训练大规模语料库时。如需更改为其他格式,请在run.sh中使用--audio_format选项。
cd egs2/some_corpus/some_task
./run.sh --audio_format mp3请注意,如果语料库中的音频文件采用有损音频编解码器(如MP3)分发,最好保持原文件格式以避免用未压缩格式重复存储整个语料库。当输入音频格式与输出格式完全相同时,format_wav_scp.py会跳过输出文件生成并直接复用输入文件。
使用案例
案例1:从长录音中提取分段
创建wav.scp和segments文件,格式为The format is (时间单位为秒)。
wav.scp:
record_a a.wav
...segments:
segment_a record_a 0.98 11.56
segment_a record_a 12.34 15.43
...然后,您可以通过以下方式提取片段:
./scripts/audio/format_wav_scp.sh --segments segments wav.scp output_dir案例2:从视频编解码器中提取音频数据 / 使用soundfile不支持的格式
ffmpeg 是必需的。按如下方式创建 wav.scp:
ID_a ffmpeg -i "ID_a.mp4" -f wav -af pan="1c|c0=c0" -acodec pcm_s16le - |
ID_b ffmpeg -i "ID_b.mp4" -f wav -af pan="1c|c0=c0" -acodec pcm_s16le - |
...- Note:
-af panis pan filter.指定输出通道的c| 数量|c将输入流的第=c 个通道分配到输出流的第个通道
- 注意:
-map_channel选项已弃用,将被移除。
案例3:将NIST Sphere文件转换为wav格式
sph2pipe 是必需的。按如下方式创建 wav.scp:
ID_a sph2pipe -f wav -p -c 1 ID_a.sph |
ID_b sph2pipe -f wav -p -c 1 ID_b.sph |
...案例4:使用多通道输入机制
如果您需要从单声道音频文件生成多声道音频文件,请创建以下wav.scp:
ID_a a1.wav a2.wav
...并运行以下命令:
./scripts/audio/format_wav_scp.sh --multi_columns_input true wav.scp output_dir反之,如果您需要从多声道音频文件中提取单声道音频文件
./scripts/audio/format_wav_scp.sh --multi_columns_output true wav.scp output_dir然后,您可以获得类似以下文件的wav.scp:
ID_a output_dir/IDa-CH0.wav output_dir/ID_a-CH1.wav
...