Pythonで音を鳴らす
前回、numpy:三角関数(sin、cos、tan)、逆三角関数(arcsin、arccos、arctan)の計算の仕方を解説しました。
今回は前回学んだ三角関数を使って、Jupyter Notebook上で音を鳴らしてみたり、作成した音を保存したりする方法を紹介します。
三角関数と音が何の関係があるんだと思われるかもしれませんが、音は波で三角関数のsinやcosも波なわけで、パソコン上で音を作成するにはsinやcosを使うのです。
ということで始めていきましょう。
Jupyter Notebook上で音を鳴らす
まずはJupyter Notebook上で音を鳴らす方法です。
この場合IPythonという標準ライブラリを使います。
import numpy as np
import IPython
rate = 48000
duration = 2.0
angle_list = np.arange(0, rate * duration)
sound = np.sin(2 * np.pi * 523 / rate * angle_list)
IPython.display.Audio(sound, rate=rate, autoplay=True)
この場合、まず「angle_list = np.arange(0, rate * duration)」でX軸方向の値のリスト(角度のリスト)を作成します。
そして「sound = np.sin(2 * np.pi * 523 / rate * angle_list)」で音のデータを作成しています。
ここで波動の式が「\(y=A sin(2\pi T)t\)」(A:振幅の大きさ、T:周期、t:時間)であり、angle_listが時間tのリスト、そして523/rateが周期となります。
今回、rate=48000、つまりデータは48000個/秒になります。
音程の高さは1秒間に波が何回振幅するかなので、例えば532Hzの音(ドの音)を鳴らすには532回振幅/秒であるため、532/48000が周期となるわけです(間違っていたらごめんなさい)。
「IPython.display.Audio(sound, rate=rate, autoplay=True)」でJupyter Notebook上で音を鳴らしますが、「IPython.display.Audio(音のデータ, rate=データの周波数)」が基本形です。
そして「autoplay=True」にすると自動で再生されるようになります。
実行するとこんな音楽再生用のバーが表示されます。
ちなみに先ほど作成した音はこんな感じです。
次に音程をレ(659Hz) に変えてみましょう。
import numpy as np
import IPython
rate = 48000
duration = 2.0
angle_list = np.arange(0, rate * duration)
sound = np.sin(2 * np.pi * 659 / rate * angle_list)
IPython.display.Audio(sound, rate=rate, autoplay=True)
実行結果
私は絶対音感はないのでこれが正しいレなのか分かりませんが、先ほどの音とは違う音になっていることは分かります。
音量を変える方法
音量を変える場合はまず「sound = np.sin(2 * np.pi * 523 / rate * angle_list)」のnp.sinの前に係数をつけます。
つまり10%の音量にしたければ「sound = 0.1 * np.sin(2 * np.pi * 523 / rate * angle_list)」となります。
間違っても最後に係数をつけないでください。
「sound = 0.1 * np.sin(2 * np.pi * 523 / rate * angle_list) * 0.1」とすると角度が周期が0.1倍されて音程が変わります。
そしてもう一つ。
「IPython.display.Audioにnormalize=Falseを追加」します。
つまりこんな感じ。
import numpy as np
import IPython
rate = 48000
duration = 2.0
angle_list = np.arange(0, rate * duration)
sound = 0.1 * np.sin(2 * np.pi * 523 / rate * angle_list)
IPython.display.Audio(sound, rate=rate, autoplay=True, normalize=False)
実行結果
IPython.display.Audioでは基本ノーマライズをしている、つまり音量が一定になるように処理されているため、音量を変えたい場合は「normalize=False」のオプションをつける必要があるようです。
音の保存
音の保存をするには「scipy.io.wavfileモジュール」を使用します。
そのためインポート文として「from scipy.io.wavfile import write」を追加します。
そして音を保存するには「write(ファイルパス, rate=音の周波数, data=音のデータ)」とします。
import numpy as np
import IPython
from scipy.io.wavfile import write
rate = 48000
duration = 2.0
angle_list = np.arange(0, rate * duration)
sound = np.sin(2 * np.pi * 523 / rate * angle_list)
write('./python-sound1-4.wav', rate=rate, data=sound)
実行結果
ただし環境によっては上記の方法で保存したデータを読み込めない場合があります。
私の場合は上記のプログラムをWindowsで試した時、また上記のプログラムを使ってMacで出力し、Mac上で再生できた音をWordpress上にアップロードした時には再生できませんでした。
どうやらその原因は音データを作成しているnumpyにあるようで、環境によって異なる形式で出力してしまうようです。
そのため「np.asarray(データ, dtype=データ型)」でデータ型を適切な形にしてやる必要があります。
私が成功したデータ型は「np.float32」で、これで出力したデータであれば、Windows上でもWordpress上でも再生できました。
import numpy as np
import IPython
from scipy.io.wavfile import write
rate = 48000
duration = 2.0
angle_list = np.arange(0, rate * duration)
sound = np.sin(2 * np.pi * 523 / rate * angle_list)
sound = np.asarray(sound, dtype=np.float32)
write('./python-sound1-5.wav', rate=rate, data=sound)
ホワイトノイズの作成
せっかくなのでホワイトノイズの作成方法も紹介しておきます。
ホワイトノイズはリラックス効果のある「サー」といった感じのランダムなノイズ音です。
昔、深夜にテレビが放送終了後に見られた砂嵐状態の画面の音です。
この場合の音声データは「np.random.random(size=rate *duration)*2 -1」として作成します。
np.random.randomでは0以上1未満のランダムな値を「size=」で指定した個数だけ作成します。
ホワイトノイズを作るにはプラスの値だけでなく、マイナスの値も必要なので、値を2倍することで0以上2未満の数値リストにして、さらに1を引くことで-1以上1未満の値のリストにします。
import numpy as np
import IPython
from scipy.io.wavfile import write
rate = 48000
duration = 2
sound = 0.25 * (np.random.random(size=rate*duration)*2 -1)
sound = np.asarray(sound, dtype=np.float32)
write('python-sound1-6.wav', rate=rate, data=sound)
音を使用するにはwaveという標準ライブラリもあるようですが、使い方がかなり難しいので、簡単な音を作るにはこちらを使う方が楽に、そして速くできると思います。
次回は複数のリストを同時にソート(順番の並び替え)を行う方法を解説していきます。
ではでは今回はこんな感じで。
コメント