20160821

Pythonで.wavファイルを出力(標準のwaveとscipy.io.wavfileの速度比較)

タイトルの通り、速度を比較した。
中に入れるデータの作成も含めた時間を計測したら、圧倒的にscipyの方が有利になった。

また、詰まって、一日潰してしまった。
本当なら、ちゃっちゃと終わっちゃうはずだったのに。
http://www.non-fiction.jp/2015/08/17/sin_wave/とか、
Qiitaとかスタックオーバーフローが役に立ったけど、自分のやりたい事が直接載っていたわけではなかったので、かなり苦労した。
中に入れるデータ型が、かなり面倒だった。



numpy arrayで作ったデータを、wavファイルにする。
wavのフォーマットは、pcmのint16。
http://docs.scipy.org/doc/scipy/reference/generated/scipy.io.wavfile.write.html

中に入れるデータ型が、かなりの曲者だった。

waveは、標準ライブラリなので、何もしないでもpython上で使用できるけれど、中に入れるデータの型が難しかった。(int16のnumpy arrayを入れると曲の長さが半分になるのは、もしかして自分だけだろうか?)
np.sin →x = dtype int16にする。(ここまではscipyと共通) → np.reshape()の引数に、order='F'を入れて、RL交互に入れる → struct(要import struct)で、pythonの整数型を、Cで言うshortに変換。大変。
ただ、ここまですれば、scipyのやつと、同じサイズのファイルが作れる。
途中をサボると、高低が変わった音とか、ノイズがでたりとか、音は出るけど、scipyの数十倍のファイルサイズだったりとかになる。

scipyの方は、int16のnumpy arrayをそのままぶち込んでも全く平気。
scipyは、標準ライブラリではないけど、入れるよね?
numpy, scipy, matplotlib(自分は入れないがpandas)は、絶対入れるよね?
int16でなくても、−1〜+1のfloatでも読んだ。(ただし、この状態だとpcmでないため、Soundenfginefreeで読んでくれない模様。)
integerにせずstringで入れてしまうと、
・ファイルサイズが大きくなったりする、
・wavのフォーマットがPCM対応でなくなる。(なぜかは不明)



import numpy as np
import time
import wave as wv
import struct

stop = 60
Srate = 44100
frq = 1000
rad = np.linspace(0, 2 * np.pi * frq * stop, Srate * stop)

filename = str(frq) +"Hz-frequency_" + str(Srate) + "Hz-Srate_"+ str(stop) +"seconds-duration_sin-1.wav"



t = time.clock()

y1 = np.sin(rad) * 0.5
int16amp=32768
y2 = np.array([y1 * int16amp],dtype = "int16")[0]
y3 = np.reshape([y2,y2],len(y2)*2,order='F')
y4 = struct.pack("h" * len(y3), *y3)

w = wv.Wave_write(filename)
w.setparams((
2, # channel
2, # byte width
44100, # sampling rate
len(y4), # number of frames
"NONE", "NONE" # no compression
))
w.writeframesraw(y4)
w.close()
print("wave.Wave_write.write: time" + str(time.clock() - t))









import numpy as np
import scipy.io.wavfile as siw
import time
import struct


stop = 60
Srate = 44100
frq = 1000
rad = np.linspace(0, 2 * np.pi * frq * stop, Srate * stop)

filename = str(frq) +"Hz-frequency_" + str(Srate) + "Hz-Srate_"+ str(stop) +"seconds-duration_sin-1.wav"


t = time.clock()

y1 = np.sin(rad) * 0.5

int16amp=32768
y2 = np.array([y1 * int16amp],dtype = "int16")[0]
y3 =np.array(np.c_[y2, y2])

siw.write("1"+filename, Srate, y3)

print("scipy.io.wavfile.write: time" + str(time.clock() - t))

posted by yuchan at 12:00 | Comment(0) | python
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: