wavファイルを作成し、その作成したwavファイルの情報を表示します。C#言語では、「C#によるWaveファイルの解析」「C#によるWaveデータの作成」ですでに作成しましたが、今回はPython3言語で行います。

wavファイル作成プログラムの作成

100、500、1000、8000hzのそれぞれの正弦波で波形を作成します。作成するWaveファイルの仕様を次に示します。

フォーマットID:リニアPCM
チャンネル数:ステレオ
サンプリングレート:44.1kHz
データ転送速度:176400byte/sec
バイト/サンプル:16bitステレオ
量子化ビット数:16

wavCreate.py

# encoding: utf-8
import numpy as np
import wave
import struct
 
fname = '100-500-1000-8000hz.wav'
wf = wave.open(fname, 'w')
ch = 1
width = 2
samplerate = 44100
wf.setnchannels(ch)
wf.setsampwidth(width)
wf.setframerate(samplerate)
 
time = 30
numsamples = time * samplerate
 
print( u"チャンネル数 = ", ch)
print( u"サンプル幅 (バイト数) = ", width)
print( u"サンプリングレート (Hz) =", samplerate)
print( u"サンプル数 =", numsamples)
print( u"録音時間 =", time)
 
# 信号データを作る
# 周波数 100,500,1000,8000 (Hz) の正弦波
freq = 500 # 周波数 freq を 500Hz にする
x=np.linspace(0, time, numsamples+1) # 0 ≦ t ≦ time を numsamples 等分
y=np.sin(2 * np.pi * freq * x)+ \
    np.sin(2 * np.pi * 2*freq * x)+ \
    np.sin(2 * np.pi * 16*freq * x)+ \
    np.sin(2 * np.pi * freq/5 * x)
  
y=np.rint(32767*y/max(abs(y))) # [-32767,32767] の範囲に収める
y=y.astype(np.int16) # 16 ビット整数に型変換する
y=y[0:numsamples] # numsamples 個のデータに打ち切る
 
# ndarray から bytes オブジェクトに変換
data=struct.pack("h" * numsamples , *y)
 
# データを書き出す
wf.writeframes(data)
wf.close()

wavファイル作成プログラムの実行

次のコマンドでwavファイル作成プログラムを実行します。

 
$ python3 wavCreate.py
チャンネル数 =  1
サンプル幅 (バイト数) =  2
サンプリングレート (Hz) = 44100
サンプル数 = 1323000
録音時間 = 30

次のwavファイル「100-500-1000-8000hz.wav」が作成されます。



audacityアプリを用いて作成した波形を確認します。

audacityアプリによる波形の確認

audacityアプリでFFT処理を行うと、100、500、1000、8000hzのそれぞれが含まれていることが確認できます。

audacityアプリによるFFT処理

wavファイル情報表示プログラムの作成

実行時に渡されたwavファイル名で示されたファイルの次の情報を表示します。

  • チャンネル数
  • サンプル幅 (バイト数)
  • サンプリングレート (Hz)
  • サンプル数
  • 録音時間(秒)
  • データ(4個)

wavDump.py

# -*- coding: utf-8 -*-
import wave
from scipy import fromstring, int16
import sys

args = sys.argv
wavfile = args[1]

# WAVファイルを開く
wr = wave.open(wavfile, "rb")

# WAVファイルの情報を表示(別にいらん)
print ("Channel num : ", wr.getnchannels())
print ("Sample size : ", wr.getsampwidth())
print ("Sampling rate : ", wr.getframerate())
print ("Frame num : ", wr.getnframes())
print ("Prams : ", wr.getparams())
print ("Sec : ", float(wr.getnframes()) / wr.getframerate())

# データの読み込み
data = wr.readframes(wr.getnframes())

# 文字型から数値型に
num_data = fromstring(data, dtype = int16)
print ("Data : ", hex(num_data[0])," ",hex(num_data[1])," ",hex(num_data[2])," ",hex(num_data[3])," ")
if (wr.getnchannels() == 2):
    # 左チャンネル
    left = num_data[::2]
    # 右チャンネル
    right = num_data[1::2]

wr.close()

wavファイル情報表示プログラムの実行

作成したWavファイルを引数にした次のコマンドでwavファイル情報表示プログラムを実行します。

$ python3 wavDump.py 100-500-1000-8000hz.wav
Channel num :  1
Sample size :  2
Sampling rate :  44100
Frame num :  1323000
Prams :  _wave_params(nchannels=1, sampwidth=2, framerate=44100, nframes=1323000, comptype='NONE', compname='not compressed')
Sec :  30.0
Data :  0x0   0x27d7   0x2a76   0xddb

バイナリエディタにより「100-500-1000-8000hz.wav」を開くと次のように表示され、強調表示した部分が実行結果の「Data : 」と一致することが確認できます(リトルインディアン表示になります)。

Wavファイルのバイナリエディタ表示