web-dev-qa-db-ja.com

SciPyのwavfile.writeでPythonにwavファイルを書き込む

私はこのコードを持っています:

import numpy as np
import scipy.io.wavfile
import math

rate, data = scipy.io.wavfile.read('xenencounter_23.wav')

data2 = []

for i in range(len(data)):
    data2.append([int(round(math.sin(data[i][0])*3000)), int(round(math.sin(data[i][1])*3000))])

data2 = np.asarray(data2)

print data2

scipy.io.wavfile.write('xenencounter_23sin3.wav',rate,data2)

これは出力します(切り捨て):

[[-2524  2728]
 [ -423 -2270]
 [ 2270   423]
 ..., 
 [-2524     0]
 [ 2524 -2728]
 [-2270   838]]

WavファイルはWindows Media Playerで開いて再生するため、少なくとも適切な形式です。ただし、それをAudacityで開いて個々のサンプルを見ると、それらはすべて0であり、ファイルはまったく音を再生しません。

私が理解していないのは、上記のnumpy配列がすべて0になる方法です。サンプルの最大値を下回る必要があります(または、負の場合は上回ります)。

14
JVE999

私はscipy.io.wavfile.write()が16ビット整数で書き込むことを発見しました。これは、代わりに32ビット整数(デフォルト)を使用しようとした場合のより大きなファイルサイズを説明しています。 wavfile.writeでこれを変更する方法を見つけることができませんでしたが、変更することでそれを見つけました。

data2 = np.asarray(data2)

data2 = np.asarray(data2, dtype=np.int16)

作業ファイルを書き込むことができました。

13
JVE999

さまざまなポイントで出力を印刷し、最初にロードしたものを再保存することで発見したように、data2.append([int(round(math.sin(data[i][0])*3000)), int(round(math.sin(data[i][1])*3000))])という行が問題の原因です。

3000は振幅が大きすぎると思います。 1を試してください。

1
Mike Vella

Scipy.io.wavfile.write()を使用してwavファイルを作成する際、振幅が非常に重要であることがわかりました。振幅150の正弦波を作成すると、VLCで再生すると無音のように聞こえます。振幅が100の場合、歪んだ正弦波のように聞こえ、80にすると、通常のファイルのように聞こえます。

ウェーブファイルを作成するときは、振幅に注意する必要がありますが、クリッピングまたは非表示になる前の最大レベルは今のところわかりません。

1
Milothicus