Pythonで* .wavファイルを読み取る


90

.wavファイルに書かれた音を分析する必要があります。そのためには、このファイルを一連の数値(配列など)に変換する必要があります。私はwaveパッケージを使用する必要があると思います。しかし、それがどのように正確に機能するかはわかりません。たとえば、私は次のことを行いました。

import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
    frame = w.readframes(i)
    print frame

このコードの結果として、私は音圧を時間の関数として見ることを期待していました。対照的に、私は多くの奇妙で神秘的な記号(16進数ではない)を目にします。誰か、お願い、それを手伝ってくれませんか?

回答:


109

ドキュメントによるとscipy.io.wavfile.read(somefile) 2つの項目のタプルを返します。1つ目は1秒あたりのサンプルでのサンプリングレート、2つ目はnumpyファイルから読み取られたすべてのデータを含む配列です。

from scipy.io import wavfile
samplerate, data = wavfile.read('./output/audio.wav')

これをコマンドライン変換ツールと組み合わせて、他の形式を開くことができます。
endolith 2010

11
ただし、チャネル数が大幅に不足しています。チャンネル数を知らずにオーディオをどのように扱うことになっていますか?
bastibe 2011年

私のコンピュータでいくつかの奇妙な構造体の解凍エラーをスローします。以下で使用するstruct.unpack( '<h'、data)nakの代わりにstruct.unpack( '<i'、data)を使用していると思います。
Alex S

1
このライブラリは機能しますか?いくつかの問題が発生しました:scipy.io.wavfile.read( '/ usr / lib / python2.7 / dist-packages / pygame / examples / data / house_lo.wav')->データがありません。scipy.io.wavfile.read( '/ USR / LIB / python2.7 / DIST-パッケージ/ pygameの/例/データ/ secosmic_lo.wav') - > ZeroDivisionError:ゼロによる整数除算や剰余
フィンARUPニールセン

6
@bastibedataは2次元のnumpy配列であるためdata.shape、(num_samples、num_channels)のタプルを返します
ホブ

63

structモジュールを使用すると、ウェーブフレーム(-32768と32767(つまりと)の間の2の相補バイナリにあります)を取得できます。これにより、MONO、16ビット、WAVEファイルが読み取られます。このWebページは、これを作成するのに非常に役立ちます。0x80000x7FFF

import wave, struct

wavefile = wave.open('sine.wav', 'r')

length = wavefile.getnframes()
for i in range(0, length):
    wavedata = wavefile.readframes(1)
    data = struct.unpack("<h", wavedata)
    print(int(data[0]))

このスニペットは1フレームを読み取ります。複数のフレーム(例:13)を読み取るには、

wavedata = wavefile.readframes(13)
data = struct.unpack("<13h", wavedata)

2
24ビットステレオファイルを処理する方法は?
Basj 2013年

14
これにより、次のエラーが発生します。「struct.error:unpackには長さ2の文字列引数が必要です」
Coder404 2014年

1
このコードを非常に大きなオーディオファイルで実行する場合。このプログラムによるメモリの必要性のために、コンピュータは死にます。大きなオーディオファイルの場合、ブロック
ごとに

@ Coder404おそらくステレオウェーブファイル、または異なるビット深度があります。
jmilloy 2015年

3
私のように、2の補数バイナリとは何か疑問に思っている人は、ここを参照してください
。stackoverflow.com/ questions / 1049722 / what

34

wavを読み取るためのさまざまなPythonモジュール:

ウェーブオーディオファイルを読み取るには、少なくとも次のライブラリがあります。

最も簡単な例:

これはSoundFileの簡単な例です。

import soundfile as sf
data, samplerate = sf.read('existing_file.wav') 

出力のフォーマット:

警告、データは常に同じ形式であるとは限りません。これはライブラリによって異なります。例えば:

from scikits import audiolab
from scipy.io import wavfile
from sys import argv
for filepath in argv[1:]:
    x, fs, nb_bits = audiolab.wavread(filepath)
    print('Reading with scikits.audiolab.wavread:', x)
    fs, x = wavfile.read(filepath)
    print('Reading with scipy.io.wavfile.read:', x)

出力:

Reading with scikits.audiolab.wavread: [ 0.          0.          0.         ..., -0.00097656 -0.00079346 -0.00097656]
Reading with scipy.io.wavfile.read: [  0   0   0 ..., -32 -26 -32]

SoundFileとAudiolabは、-1と1の間で浮動小数点数を返します(matabと同様に、これはオーディオ信号の規則です)。Scipyとwaveは整数を返します。これは、エンコードのビット数に応じて浮動小数点数に変換できます。次に例を示します。

from scipy.io.wavfile import read as wavread
samplerate, x = wavread(audiofilename)  # x is a numpy array of integers, representing the samples 
# scale to -1.0 -- 1.0
if x.dtype == 'int16':
    nb_bits = 16  # -> 16-bit wav files
elif x.dtype == 'int32':
    nb_bits = 32  # -> 32-bit wav files
max_nb_bit = float(2 ** (nb_bits - 1))
samples = x / (max_nb_bit + 1)  # samples is a numpy array of floats representing the samples 

14

IMHO、サウンドファイルからNumPy配列にオーディオデータを取得する最も簡単な方法はSoundFileです:

import soundfile as sf
data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')

これは、すぐに使用できる24ビットファイルもサポートします。

利用可能な多くのサウンドファイルライブラリがあります、私はあなたがいくつかの賛否両論を見ることができる概要を書きまし。またwaveモジュールを使用して24ビットのwavファイルを読み取る方法を説明するページもあります


注:soundfile.read()は、sandovalのscipy.io.wavfileの例のように2 ^(n_bits-1)で正規化されます
Quetzalcoatl

9

これは、scikits.audiolabを使用して実現できますモジュールます。機能するにはNumPyとSciPyが必要であり、libsndfileも必要です。

注意してください、私はそれをUbunutuでのみ動作させることができ、OSXでは動作させることができませんでした。

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

これでwavデータができました


scikits.audiolab2010年以降更新されておらずおそらくPython2のみです。
ボリス

4

オーディオをブロックごとに処理したい場合、与えられた解決策のいくつかは、オーディオ全体をメモリにロードすることを意味し、多くのキャッシュミスを引き起こし、プログラムの速度を低下させるという意味で非常にひどいものです。python- wavefileは、ジェネレーターによる効率的で透過的なブロック管理を使用してNumPyブロックごとの処理を行うためのいくつかのpythonic構造を提供します。他のPythonの優れた点は、ファイルのコンテキストマネージャー、プロパティとしてのメタデータです。ファイルインターフェイス全体が必要な場合は、迅速なプロトタイプを開発していて効率を気にしないため、ファイルインターフェイス全体が引き続き存在します。

処理の簡単な例は次のとおりです。

import sys
from wavefile import WaveReader, WaveWriter

with WaveReader(sys.argv[1]) as r :
    with WaveWriter(
            'output.wav',
            channels=r.channels,
            samplerate=r.samplerate,
            ) as w :

        # Just to set the metadata
        w.metadata.title = r.metadata.title + " II"
        w.metadata.artist = r.metadata.artist

        # This is the prodessing loop
        for data in r.read_iter(size=512) :
            data[1] *= .8     # lower volume on the second channel
            w.write(data)

この例では、通常必要なサイズよりも小さい最後のブロックの場合でも、同じブロックを再利用してファイル全体を読み取ります。この場合、ブロックのスライスを取得します。したがって、ハードコードされた512サイズを使用するのではなく、返されたブロック長を信頼してください。


1

あなたは波形データに転送を実行するつもりなら、おそらくあなたは使うべきscipyのダウンロードを具体的には、scipy.io.wavfile


2
OK。SciPyをインストールしたばかりですが、scipy.io.wavfileの使用例が見つかりません。
ローマ

6
物事がどのように機能するかを理解するためのインタラクティブなインタプリタのようなものはありません!大志を抱け!
Ignacio Vazquez-Abrams

1

1チャンネルの24ビットWAVファイルを読み取る必要がありました。Nakによる上記の投稿は非常に役に立ちました。ただし、basjが前述したように、24ビットは単純ではありません。私はついに次のスニペットを使用してそれを機能させました:

from scipy.io import wavfile
TheFile = 'example24bit1channelFile.wav'
[fs, x] = wavfile.read(TheFile)

# convert the loaded data into a 24bit signal

nx = len(x)
ny = nx/3*4    # four 3-byte samples are contained in three int32 words

y = np.zeros((ny,), dtype=np.int32)    # initialise array

# build the data left aligned in order to keep the sign bit operational.
# result will be factor 256 too high

y[0:ny:4] = ((x[0:nx:3] & 0x000000FF) << 8) | \
  ((x[0:nx:3] & 0x0000FF00) << 8) | ((x[0:nx:3] & 0x00FF0000) << 8)
y[1:ny:4] = ((x[0:nx:3] & 0xFF000000) >> 16) | \
  ((x[1:nx:3] & 0x000000FF) << 16) | ((x[1:nx:3] & 0x0000FF00) << 16)
y[2:ny:4] = ((x[1:nx:3] & 0x00FF0000) >> 8) | \
  ((x[1:nx:3] & 0xFF000000) >> 8) | ((x[2:nx:3] & 0x000000FF) << 24)
y[3:ny:4] = (x[2:nx:3] & 0x0000FF00) | \
  (x[2:nx:3] & 0x00FF0000) | (x[2:nx:3] & 0xFF000000)

y = y/256   # correct for building 24 bit data left aligned in 32bit words

-1から+1の間の結果が必要な場合は、追加のスケーリングが必要です。たぶんあなたの何人かはこれが役に立つと思うかもしれません


0

ファイルが2つだけで、サンプルレートが非常に高い場合は、それらをインターリーブするだけで済みます。

from scipy.io import wavfile
rate1,dat1 = wavfile.read(File1)
rate2,dat2 = wavfile.read(File2)

if len(dat2) > len(dat1):#swap shortest
    temp = dat2
    dat2 = dat1
    dat1 = temp

output = dat1
for i in range(len(dat2)/2): output[i*2]=dat2[i*2]

wavfile.write(OUTPUT,rate,dat)

0

簡単なimport wavioライブラリを使用することもできます。サウンドの基本的な知識も必要です。


0

PyDubhttp://pydub.com/)は言及されていないため、修正する必要があります。IMOこれは、Pythonでオーディオファイルを読み取るための最も包括的なライブラリですが、欠点がないわけではありません。wavファイルの読み取り:

from pydub import AudioSegment

audio_file = AudioSegment.from_wav('path_to.wav')
# or
audio_file = AudioSegment.from_file('path_to.wav')

# do whatever you want with the audio, change bitrate, export, convert, read info, etc.
# Check out the API docs http://pydub.com/

PS。この例はwavファイルの読み取りに関するものですが、PyDubは箱から出してさまざまな形式を処理できます。注意点は、ネイティブのPython wavサポートとffmpegの両方に基づいているため、ffmpegをインストールする必要があり、多くのpydub機能がffmpegバージョンに依存していることです。通常、ffmpegがそれを実行できる場合は、pydub(非常に強力です)も実行できます。

免責事項:私はプロジェクトとは関係ありませんが、ヘビーユーザーです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.