音を鳴らす

いろいろ方法がありますが、簡単でどこでも使えるのが print("\x07") です。ASCII の 07 は音を鳴らすための文字です。いわゆるビープ音ですが、Mac はシステム環境設定の「サウンド」の「サウンドエフェクト」で音が選べます。

440Hzの正弦波を鳴らす方法はいろいろありますが、ここでは python-sounddevice というライブラリを使います。pip install sounddevice または conda install -c conda-forge python-sounddevice でインストールできます。音のデータは ±1 の範囲に収めます。

import numpy as np
import sounddevice as sd

x = 0.8 * np.sin(2 * np.pi * 440 * np.linspace(0, 1, 44101))
sd.play(x, 44100)

WAVファイルの読み書きは、Python標準ライブラリ wave や、次に説明する SciPy も使えますが、ここでは python-sounddevice と同じ開発者による soundfile ライブラリを使ってみます。pip install soundfile でインストールして、次のようにします:

import soundfile as sf
import sounddevice as sd

data, fs = sf.read("filename.wav")
sd.play(data, fs)

WAVファイルの作成

以下では SciPy を使ってみます。

880Hzの音と1320Hzの音を混ぜると、あるはずのない440Hzの音も聞こえるという話を聞いたので確かめてみましょう。NumPy と SciPy はインストールしておきます(pip install numpy scipy)。

import numpy as np
from scipy.io import wavfile

samplerate = 44100 # 44100Hzサンプリング
duration = 5       # 5秒
t = np.linspace(0, 2 * np.pi * duration, samplerate * duration + 1)

data = 10000 * (np.sin(880 * t) + np.sin(1320 * t))
wavfile.write("test.wav", samplerate, (data + 0.5).astype("int16"))

こうしてできた test.wav を再生してみましょう。Macであればターミナルに afplay test.wav と打ち込めば再生できます。

880Hzを左耳、1320Hzを右耳に出すには、data = ... の行を次のようにします:

data = 10000 * np.c_[np.sin(880 * t), np.sin(1320 * t)]

1320Hzのほうを少し小さい音にして、1秒遅れて出します:

w = np.append(np.zeros(samplerate), np.ones(samplerate * (duration - 1) + 1))
data = 10000 * np.sin(880 * t) + 5000 * w * np.sin(1320 * t)

いろいろ試してください。聞こえるのは差 (1320-880)Hz だという説もありますが、それなら高い方を例えば 1374 にすれば (1374-880)Hz でほぼレの音が聞こえるはずですね。

音楽を作る

musicpy が楽しそうです(そのうち書きます)。