はじめに
M-1が面白すぎて投稿が遅れてしまった。
この記事は Pythonその3 Advent Calendar 2019 の23日目の記事です。この記事ではnumpyなどで生成した正弦波をステレオのwav形式で出力する方法について記述します。
概要
今回はLchに880Hzの正弦波Rchに440Hzの正弦波を出力する5秒間のwavファイルを出力しようと思います。
コード
import numpy as np
import wave # wave
import struct # structpack
def createWavFile():
Fs = 44.1*1000 # 44.1 kHz
Lch = 880 # Hz
Rch = 440 # Hz
scale = 10**(-3/10) # -6dBで生成
t = 5 # 5秒
N = Fs*t # サンプル数
filename = "L440R880.wav"
# 正弦波の配列を生成
sinwaveL = scale * np.array([np.sin(2*np.pi*Lch*n/Fs)
for n in np.arange(N)])
sinwaveR = scale * np.array([np.sin(2*np.pi*Rch*n/Fs)
for n in np.arange(N)])
# 16ビットに変換
waveL = np.array([int(x * 32767.0) for x in sinwaveL])
waveR = np.array([int(x * 32767.0) for x in sinwaveR])
# ステレオ形式のwavのデータ構造に合わせ込む
quantizeWave = np.array([[waveL[i], waveR[i]]
for i in range(int(N))]).flatten()
# バイナリ化
binwave = struct.pack("h" * len(waveL)*2, *quantizeWave)
w = wave.Wave_write(filename)
# (チャンネル数(1:モノラル,2:ステレオ)、サンプルサイズ(バイト)、サンプリング周波数、フレーム数、圧縮形式(今のところNONEのみ)、圧縮形式を人に判読可能な形にしたもの?通常、 'NONE' に対して 'not compressed' が返されます。)
# 参考:https://docs.python.org/ja/3/library/wave.html
p = (2, 2, Fs, len(binwave), 'NONE', 'not compressed')
w.setparams(p)
w.writeframes(binwave)
w.close()
if __name__ == '__main__':
createWavFile()
感想とか
Webで調べてもステレオでWAVファイルを生成する方法は見つからず途方にくれていましたが形になって良かったです