【Python/numpy/soundfile】wavを指定したフォーマット(周波数など)に変換する
2023-7-11 | Python
Pythonでnumpyとsoundfileを使ってwavを指定したフォーマット(周波数など)に変換したい!
概要
今回の記事では、Pythonでnumpyとsoundfileを使ってwavを指定したフォーマット(周波数など)に変換するサンプルを掲載する。
仕様書
環境
- Python 3.10.6
手順書
今回はnumpyとsoundfileというライブラリを使うのでインストールする。
pip install numpy soundfile
下記は、in
フォルダに保存されてるwavファイルをに指定のフォーマットに変換してout
フォルダに出力する例。
to_rate
に周波数、to_subtype
にはエンコードの種類、to_channels
にチャンネル数を指定する。
import os
import wave
import numpy as np
import soundfile as sf
in_dir = "in/"
out_dir = "out/"
to_rate = 44100
to_subtype = 'PCM_16'
to_channels = 2
for filename in os.listdir(in_dir):
if filename.endswith(".wav"):
wav_path = os.path.join(in_dir, filename)
print("formatting: ", wav_path)
base_name = os.path.splitext(filename)[0]
formated_dir = os.path.join(out_dir, base_name + ".wav")
data, rate = sf.read(wav_path)
if to_subtype == 'FLOAT' and info.subtype != 'FLOAT':
print('to float32')
to_data = data.astype(np.float32)
elif to_subtype == 'DOUBLE' and info.subtype != 'DOUBLE':
print('to float64')
to_data = data.astype(np.float64)
elif to_subtype == 'int8' and info.subtype != 'PCM_8':
print('to int8')
to_data = (data * np.iinfo(np.int8).max).astype(np.int8)
elif to_subtype == 'PCM_16' and info.subtype != 'PCM_16':
print('to int16')
to_data = (data * np.iinfo(np.int16).max).astype(np.int16)
elif to_subtype == 'PCM_24' and info.subtype != 'PCM_24':
print('to int24')
to_data = (data * np.iinfo(np.int24).max).astype(np.int24)
elif to_subtype == 'PCM_32' and info.subtype != 'PCM_32':
print('to int32')
to_data = (data * np.iinfo(np.int32).max).astype(np.int32)
elif to_subtype == 'PCM_64' and info.subtype != 'PCM_64':
print('to int64')
to_data = (data * np.iinfo(np.int64).max).astype(np.int64)
elif to_subtype == 'PCM_128' and info.subtype != 'PCM_128':
print('to int128')
to_data = (data * np.iinfo(np.int128).max).astype(np.int128)
else:
print('to none')
to_data = data
if to_channels == 1 and to_data.shape[1] > 1:
to_data = np.mean(to_data, axis=1)
elif to_channels == 2 and len(to_data.shape) == 1:
to_data = np.vstack([to_data, to_data]).T
elif to_channels == 2 and len(to_data.shape) > 2:
to_data = to_data[:, [0, 1]]
elif to_channels == 3 and len(to_data.shape) > 3:
to_data = to_data[:, [0, 1, 2]]
print(to_data.shape)
sf.write(formated_dir, to_data, to_rate, format='WAV', subtype=to_subtype)
今回はCDと同じ音質のWAVファイルに変換してる。
to_rate = 44100
to_subtype = 'PCM_16'
to_channels = 2
機械学習で使われるFLOAT
型に変換したい場合は下記のような感じ。
to_rate = 44100
to_subtype = 'FLOAT'
to_channels = 2
よく使われるビット深度やチャンネル数の変換は実装してるんだけども、全パターンを網羅してるわけでないことを留意されたし。
まとめ(感想文)
これも、音声を機械学習させる前の下処理に使えるかもね!