python wav output

num2snd(python)を書き直して、ちょっと使いやすくした。

サンプリングレートとか長さを変えられるようにした。グローバル変数を使うのはあんましよくない的な文章を読んだのもある。prepare_list()関数をなくして、変数名、関数名の記法を統一。だいぶすっきりしたけど、何かまだスパゲッティな感じ。最近やっとコーディングの仕方がわかってきた気がする。今まではパズル感覚で適当に組み替えてただけ。

使うときは例えばこのコードをsinewave.pyと名前を付けて同じ階層に移動し、

python

と入力して対話モードにする。

>>>import sinewave

とし、

>>>sinewave.sineWave('test.wav', 2000, 44100, 1)

とすればサンプリングレート44100Hz、高さ2000Hz、1秒のサイン波が録音されたtest.wavというwavファイルが生成される。

import wave, math

def waveInit(fileName, sampFreq):
 file = wave.open(fileName, 'w')
 file.setnchannels(1)
 file.setsampwidth(2)
 file.setframerate(sampFreq)
 file.setcomptype('NONE', 'not compressed')
 return file
 
def waveWrite(out, samples):
 out.writeframesraw(samples)
 out.close()
 
def sineWave(fileName, freq, sampFreq, length):
 out = waveInit(fileName, sampFreq)
 samples = range(sampFreq * length)
 a = math.pi * 2.0 * float(freq) / float(sampFreq)
 for i in range(sampFreq * length):
  samples[i]  = int(math.sin(a * float(i)) * 30000.0)
 waveWrite(out, samples)

  • hysysk 別の環境でやったらエラーになった。wave.pyのwriteframesrawに渡す引数のせいみたい。もーよくわからん。

    TypeError: argument 1 must be string or read-only buffer, not list

    • 2007-04-15 15:47
  • hysysk これはできた。

    • 2007-04-15 15:53
  • hysysk samples = range(int(sampFreq * length))
    とすると音の長さを0.2秒とか小数点でも指定できるようになる。前のだとできなくはないけど警告される。

    あと、for文の中に
    env = (sampFreq * float(length) - i) / sampFreq * float(length)
    samples[i] = int(math.sin(a * float(i)) * env * 30000.0)
    を入れてあげるとエンヴェロープがかかるみたい。なるほどね。単純に周波数を右肩下がりにしてるだけ。

    んで、for文はfor i in range(len(samples)):
    としたら若干スマートかな。

    • 2007-04-17 08:16