107

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

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進数ではない)を目にします。誰か、罪状認否、それを手伝ってくれませんか?

4

13 に答える 13

133

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

from scipy.io import wavfile
samplerate, data = wavfile.read('./output/audio.wav')
于 2010-01-13T23:44:48.550 に答える
64

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)
于 2011-03-12T07:21:08.023 に答える
39

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は整数を返します。これは、エンコードのビット数に応じてfloatに変換できます。次に例を示します。

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 
于 2014-11-03T14:13:58.797 に答える
17

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

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

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

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

于 2015-09-17T12:09:43.277 に答える
9

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

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

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

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

于 2011-06-17T22:10:32.073 に答える
5

オーディオをブロックごとに処理する場合、指定されたソリューションのいくつかは、オーディオ全体をメモリにロードして多くのキャッシュミスを生成し、プログラムの速度を低下させるという意味で非常にひどいものです。python- wavefileは、ジェネレーターによる効率的で透過的なブロック管理を使用してNumPyブロックごとの処理を行うためのいくつかのpythonic構造を提供します。他の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サイズを使用するのではなく、返されたブロック長を信頼してください。

于 2014-09-16T09:54:36.253 に答える
2

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

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

于 2015-06-14T17:01:48.907 に答える
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)
于 2013-08-23T16:51:36.263 に答える
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(非常に強力です)も実行できます。

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

于 2020-04-22T11:07:39.683 に答える
0

これは、組み込みのwaveモジュール[1]を使用したPython 3ソリューションで、nチャネルと8,16,24...ビットで機能します。

import sys
import wave

def read_wav(path):
    with wave.open(path, "rb") as wav:
        nchannels, sampwidth, framerate, nframes, _, _ = wav.getparams()
        print(wav.getparams(), "\nBits per sample =", sampwidth * 8)

        signed = sampwidth > 1  # 8 bit wavs are unsigned
        byteorder = sys.byteorder  # wave module uses sys.byteorder for bytes

        values = []  # e.g. for stereo, values[i] = [left_val, right_val]
        for _ in range(nframes):
            frame = wav.readframes(1)  # read next frame
            channel_vals = []  # mono has 1 channel, stereo 2, etc.
            for channel in range(nchannels):
                as_bytes = frame[channel * sampwidth: (channel + 1) * sampwidth]
                as_int = int.from_bytes(as_bytes, byteorder, signed=signed)
                channel_vals.append(as_int)
            values.append(channel_vals)

    return values, framerate

結果をNumPy配列に変換できます。

import numpy as np

data, rate = read_wav(path)
data = np.array(data)

注意してください、私はそれを速くではなく読みやすくしようとしました。すべてのデータを一度に読み取る方がほぼ2倍高速であることがわかりました。例えば

with wave.open(path, "rb") as wav:
    nchannels, sampwidth, framerate, nframes, _, _ = wav.getparams()
    all_bytes = wav.readframes(-1)

framewidth = sampwidth * nchannels
frames = (all_bytes[i * framewidth: (i + 1) * framewidth]
            for i in range(nframes))

for frame in frames:
    ...

python-soundfileは約2桁高速ですが(純粋なCPythonでこの速度に近づくのは困難です)。

[1] https://docs.python.org/3/library/wave.html

于 2020-12-20T09:32:18.540 に答える
0

私の愛する人、あなたが探しているものを理解している限り、あなたはデジタル信号処理(DSP)と呼ばれる理論分野に入っています。このエンジニアリング領域は、離散時間信号の単純な分析から複雑な適応フィルターに由来します。良いアイデアは、離散時間信号をベクトルと考えることです。このベクトルの各要素は、元の連続時間信号のサンプル値です。ベクトル形式でサンプルを取得したら、このベクトルにさまざまなデジタル信号技術を適用できます。

残念ながら、Pythonでは、オーディオファイルからNumPy配列ベクトルへの移行は、お気づきのとおり、かなり面倒です...あるプログラミング言語を他の言語よりも偶像化しない場合は、MatLab/Octaveを試してみることを強くお勧めします。Matlabを使用すると、ファイルからサンプルに簡単にアクセスできます。audioread()このタスクをあなたに任せます:)そしてDSPのために特別に設計されたツールボックスがたくさんあります。

それでも、もしあなたが本当にこれのためにPythonに入るつもりなら、私はあなたをガイドするためのステップバイステップをあなたに与えるでしょう。


1.サンプルを入手する

.wavファイルからサンプルを取得する最も簡単な方法は次のとおりです。

from scipy.io import wavfile

sampling_rate, samples = wavfile.read(f'/path/to/file.wav')


または、waveandstructパッケージを使用してサンプルを取得することもできます。

import numpy as np
import wave, struct

wav_file = wave.open(f'/path/to/file.wav', 'rb')
# from .wav file to binary data in hexadecimal
binary_data = wav_file.readframes(wav_file.getnframes())
# from binary file to samples
s = np.array(struct.unpack('{n}h'.format(n=wav_file.getnframes()*wav_file.getnchannels()), binary_data))

あなたの質問に答える:人間binary_databytes読める形式ではなく、機械にしか意味をなさないオブジェクトです。を入力して、このステートメントを検証できますtype(binary_data)。この奇妙なキャラクターの束についてもう少し詳しく知りたい場合は、ここをクリックしてください

オーディオがステレオの場合(つまり、2つのチャネルがある場合)、この信号の形状を変更して、で得られるのと同じフォーマットを実現できます。scipy.io

s_like_scipy = s.reshape(-1, wav_file.getnchannels())

各列はシャネルです。.wavどちらの方法でも、ファイルから取得したサンプルを使用して、信号の時間的動作をプロットおよび理解できます。

どちらの方法でも、ファイルから取得したサンプルは、線形パルス符号変調(LPCM)で表されます。


2.オーディオサンプルにデジタル信号処理を実行します

その部分はあなたに任せます:)しかし、これはDSPを通してあなたを連れて行くための素晴らしい本です。残念ながら、Pythonを使った良い本はわかりません。通常、恐ろしい本です...しかし、心配しないでください。プログラミング言語をドメイン化する限り、その言語を使用しても理論はまったく同じように適用できます。

どんな本を手に取っても、プロアキスやオッペンハイムなどの古典的な作家に固執してください...彼らが使用する言語プログラミングについては気にしないでください。Pythonを使用したオーディオ用のDPSのより実用的なガイドについては、このページを参照してください。

3.フィルタリングされたオーディオサンプルを再生します

import pyaudio

p = pyaudio.PyAudio()
stream = p.open(format = p.get_format_from_width(wav_file.getsampwidth()),
                channels = wav_file.getnchannels(),
                rate = wav_file.getframerate(),
                output = True)
# from samples to the new binary file
new_binary_data = struct.pack('{}h'.format(len(s)), *s)
stream.write(new_binary_data)

ここwav_file.getsampwidth()で、はサンプルあたりのバイト数、wav_file.getframerate()はサンプリングレートです。入力オーディオと同じパラメータを使用するだけです。


4.結果を新しい.wavファイルに保存します

wav_file=wave.open('/phat/to/new_file.wav', 'w')

wav_file.setparams((nchannels, sampwidth, sampling_rate, nframes, "NONE", "not compressed"))

for sample in s:
   wav_file.writeframes(struct.pack('h', int(sample)))

ここnchannelsで、はチャネル数、sampwidthはサンプルあたりのバイト数、sampling_rateはサンプリングレート、nframesはサンプルの総数です。

于 2022-02-09T19:46:41.980 に答える
-1

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

于 2018-01-27T05:50:18.233 に答える