【その2】pythonでメロディーを作りたい
準備編 pythonでメロディーを作りたい - エンジニア戦記←前回
第2回 ここ
第3回 【その3】Pythonでメロディーを奏でたい - エンジニア戦記
第4回 【その4】Pythonでメロディーを奏でたい-モジュール化とwavファイル出力 - エンジニア戦記
音を鳴らす
目標
音を鳴らす
環境
- python3
- windows10
- anaconda
概要
前回、環境を作成した。
とりあえず音をぶぃ~っと鳴らしたい。
音のプログラムはだいたい正弦波を作成し音声データとして流すのがセオリー。
言語に依らずやることは殆ど変わらない。
言語を絞って検索するなり、参考書を開いてみると大まかなプログラムは一緒。
ソース
import wave import struct import numpy as np import pyaudio from pylab import * def createSinWave (A, f0, fs, length): """振幅A,基本周波数f0, サンプリング周波数fs,再生時間length秒の正弦波を作成して返す""" data = [] for n in arange(length * fs): s = A * np.sin(2 * np.pi * f0 * n / fs) # 正弦波の計算 # 振幅の範囲を-1~1に設定 if s > 1.0: s = 1.0 if s < -1.0: s = -1.0 data.append(s) data = [int(x * 32767.0) for x in data]# [-32768, 32767]の整数値に変換 data = struct.pack("h" * len(data), *data) # バイナリデータに変換 return data #再生用関数 def play(data, fs, bit): p = pyaudio.PyAudio() stream = p.open(format=pyaudio.paInt16, channels=1, rate=int(fs), output=True) chunk = 1024 sp = 0 buffer = data[sp:sp+chunk] while buffer != b'': stream.write(buffer) sp = sp + chunk buffer = data[sp:sp+chunk] stream.close() p.terminate() if __name__ == "__main__" : freqList = [262, 294, 330, 349, 392, 440, 494, 523]# ドレミファの周波数[Hz] for f in freqList: data = createSinWave(1.0, f, 8000.0, 2.0) play(data, 8000, 16)
こちらのソースは参考ページのgithubのコード。
createSinWaveの中身は今のところ呪文だと思って大丈夫。
覚えておきたいところは
data = struct.pack("h" * len(data), *data)
でバイナリデータに変換しなきゃならないところ。
後々音声データをファイル化するときに、バイナリデータを使うことになる。
最後の行の
play(data, 8000, 16)
をforから外してdataを262や523といった周波数を決め打ちに変えると、その音がなる。