web-dev-qa-db-ja.com

Pythonの* .wavファイルの読み取り

.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進数ではありません)を見ます。誰か、私を助けてくれますか?

72
Roman

ソースscipy.io.wavfile.read(somefile)ごとに2つの項目のタプルを返します。1つ目は1秒あたりのサンプル数のサンプリングレート、2つ目はすべてのデータが読み込まれるnumpy配列ですファイル。とても使いやすいようです!

例えば:

from scipy.io import wavfile
fs, data = wavfile.read('./output/audio.wav')
80
Alex Martelli

私は今晩いくつかの研究を行い、これを理解しました:

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]))

このスニペットが誰かを助けることを願っています。詳細: struct module を使用すると、waveフレーム(-32768、0x8000と32767、0x7FFFの間の2の補数バイナリ)を取得できます。これにより、MONO、16-BIT、WAVEファイルが読み取られます。 このウェブページ これを定式化するのに非常に役立つことがわかりました。

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

waveData = waveFile.readframes(13)
data = struct.unpack("<13h", waveData)
60
nak

wavを読み込むための異なるpythonモジュール:

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

最も単純な例:

これはPysoundfileを使用した簡単な例です。

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 filetest in argv[1:]:
    [x, fs, nbBits] = audiolab.wavread(filePath)
    print '\nReading with scikits.audiolab.wavread: ', x
    [fs, x] = wavfile.read(filetest)
    print '\nReading with scipy.io.wavfile.read: ', x

scikits.audiolab.wavreadを使用した読み取り:[0. 0. 0. ...、-0.00097656 -0.00079346 -0.00097656] scipy.io.wavfile.readを使用した読み取り:[0 0 0 ... 、-32 -26 -32]

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

例えば:

from scipy.io.wavfile import read as wavread
[samplerate, x] = wavread(audiofilename) # x is a numpy array of integer, 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.0) # samples is a numpy array of float representing the samples 
28
PatriceG

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

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

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

多くのサウンドファイルライブラリを利用できます。私は 概要 を作成しました。ここには、いくつかの長所と短所があります。また、 waveモジュールで24ビットwavファイルを読み取る方法 を説明するページも備えています。

12
Matthias

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

注、Ubunutuでしか動作せず、OSXでは動作しませんでした。

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

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

8
ch3rryc0ke

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

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

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サイズを使用する代わりに、返されたブロック長を信頼してください。

4
vokimon

1チャネルの24ビットWAVファイルを読み取る必要がありました。 Nak による上記の投稿は非常に役に立ちました。ただし、上記で basj 24-bitで述べたように簡単ではありません。私は最終的に次のスニペットを使用して動作させました:

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の結果が必要な場合は、追加のスケーリングが必要です。たぶんあなたの何人かはこれが役に立つと思うかもしれません

1
ProgJos

波形データで転送を実行する場合は、おそらく SciPy 、特に scipy.io.wavfile を使用する必要があります。

ファイルが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
leec

uは、シンプルなimport wavioライブラリも使用できます。また、サウンドに関する基本的な知識も必要です。

0
yunus