私の愛する人、あなたが探しているものを理解している限り、あなたはデジタル信号処理(DSP)と呼ばれる理論分野に入っています。このエンジニアリング領域は、離散時間信号の単純な分析から複雑な適応フィルターに由来します。良いアイデアは、離散時間信号をベクトルと考えることです。このベクトルの各要素は、元の連続時間信号のサンプル値です。ベクトル形式でサンプルを取得したら、このベクトルにさまざまなデジタル信号技術を適用できます。
残念ながら、Pythonでは、オーディオファイルからNumPy配列ベクトルへの移行は、お気づきのとおり、かなり面倒です...あるプログラミング言語を他の言語よりも偶像化しない場合は、MatLab/Octaveを試してみることを強くお勧めします。Matlabを使用すると、ファイルからサンプルに簡単にアクセスできます。audioread()
このタスクをあなたに任せます:)そしてDSPのために特別に設計されたツールボックスがたくさんあります。
それでも、もしあなたが本当にこれのためにPythonに入るつもりなら、私はあなたをガイドするためのステップバイステップをあなたに与えるでしょう。
1.サンプルを入手する
.wav
ファイルからサンプルを取得する最も簡単な方法は次のとおりです。
from scipy.io import wavfile
sampling_rate, samples = wavfile.read(f'/path/to/file.wav')
または、wave
andstruct
パッケージを使用してサンプルを取得することもできます。
import numpy as np
import wave, struct
wav_file = wave.open(f'/path/to/file.wav', 'rb')
# from .wav file to binary data in hexadecimal
binary_data = wav_file.readframes(wav_file.getnframes())
# from binary file to samples
s = np.array(struct.unpack('{n}h'.format(n=wav_file.getnframes()*wav_file.getnchannels()), binary_data))
あなたの質問に答える:人間binary_data
がbytes
読める形式ではなく、機械にしか意味をなさないオブジェクトです。を入力して、このステートメントを検証できますtype(binary_data)
。この奇妙なキャラクターの束についてもう少し詳しく知りたい場合は、ここをクリックしてください。
オーディオがステレオの場合(つまり、2つのチャネルがある場合)、この信号の形状を変更して、で得られるのと同じフォーマットを実現できます。scipy.io
s_like_scipy = s.reshape(-1, wav_file.getnchannels())
各列はシャネルです。.wav
どちらの方法でも、ファイルから取得したサンプルを使用して、信号の時間的動作をプロットおよび理解できます。
どちらの方法でも、ファイルから取得したサンプルは、線形パルス符号変調(LPCM)で表されます。
2.オーディオサンプルにデジタル信号処理を実行します
その部分はあなたに任せます:)しかし、これはDSPを通してあなたを連れて行くための素晴らしい本です。残念ながら、Pythonを使った良い本はわかりません。通常、恐ろしい本です...しかし、心配しないでください。プログラミング言語をドメイン化する限り、その言語を使用しても理論はまったく同じように適用できます。
どんな本を手に取っても、プロアキスやオッペンハイムなどの古典的な作家に固執してください...彼らが使用する言語プログラミングについては気にしないでください。Pythonを使用したオーディオ用のDPSのより実用的なガイドについては、このページを参照してください。
3.フィルタリングされたオーディオサンプルを再生します
import pyaudio
p = pyaudio.PyAudio()
stream = p.open(format = p.get_format_from_width(wav_file.getsampwidth()),
channels = wav_file.getnchannels(),
rate = wav_file.getframerate(),
output = True)
# from samples to the new binary file
new_binary_data = struct.pack('{}h'.format(len(s)), *s)
stream.write(new_binary_data)
ここwav_file.getsampwidth()
で、はサンプルあたりのバイト数、wav_file.getframerate()
はサンプリングレートです。入力オーディオと同じパラメータを使用するだけです。
4.結果を新しい.wav
ファイルに保存します
wav_file=wave.open('/phat/to/new_file.wav', 'w')
wav_file.setparams((nchannels, sampwidth, sampling_rate, nframes, "NONE", "not compressed"))
for sample in s:
wav_file.writeframes(struct.pack('h', int(sample)))
ここnchannels
で、はチャネル数、sampwidth
はサンプルあたりのバイト数、sampling_rate
はサンプリングレート、nframes
はサンプルの総数です。