使うもの
Python組み込みモジュールのwave.pyを使います。
前提
24bit などを扱うと面倒(*1)なので、ここでは 16bit int, 44.1kHz の音源を作ります。
実装
main.py
import wave
import numpy as np
from random import uniform
from struct import pack
# 保存するwaveファイルのファイル名を指定
filename = './output.wav'
# チャンネル数
n_ch = 2 # 1: mono, 2: stereo
# サンプル幅(ビット深度を8で割った値)
s_width = 2 # 2: 16bit, 3: 24bit, 4: 32bit
# サンプリング周波数
s_rate = 44100 # Hz
# 音源の長さ(ここでは3秒とする)
t_length = 3 # sec
# サンプル数
n_samples = t_length * s_rate
# この後で使う波形を定義しておく
def sin(t, f):
return np.sin(2*np.pi*f*t)
def tri(t, f):
u = int(2*f*t + 0.5)
return (-1)**u * (4*f*t - 2*u)
def sqr(t, f):
return 1 if 0 <= f*t - int(f*t) < 0.5 else -1
def saw(t, f):
return 2*f*t - 2*int(f*t + 0.5)
def noise():
return uniform(-1, 1)
# data_array には1サンプルごとにL, Rの順番で変位の値(int)が入る
# 各要素は -32768~32767 の範囲内に収める必要がある
data_array = []
# 最大振幅
A_max = 32767 # = 0.5 * (2**16) - 1
for i_samples in range(n_samples):
# 秒単位での時間
t_i = i_samples / s_rate # sec
# ここで sin の代わりに saw などを用いると音色が変わる
L_i = A_max * sin(t_i, 440)
data_array.append(int(L_i))
R_i = A_max * sin(t_i, 440)
data_array.append(int(R_i))
# wav 書き出し
with wave.open(filename, 'w') as wf:
wf.setnchannels(n_ch)
wf.setsampwidth(s_width)
wf.setframerate(s_rate)
data_binary = pack("h" * n_ch * n_samples, *data_array)
wf.writeframes(data_binary)
実行
python main.py
と実行すれば output.wav が出てきます。
おわり
色々パラメータを変えて遊んでみて下さい。
参考文献
(*1) Pythonでのwavファイル操作
(*2) pythonのwaveモジュール