[python] Python에서 * .wav 파일 읽기

.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 진수가 아닌)를 많이 본다. 누구든지 저를 도와 줄 수 있습니까?



답변

문서 , scipy.io.wavfile.read(somefile)두 항목의 튜플 결과 : 처음 인 샘플링 레이트 는 초당 샘플은, 제는 인 numpy데이터 파일로부터 판독 된 모든으로 배열 :

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


답변

struct모듈을 사용하면 웨이브 프레임 ( -32768과 32767 사이 의 2의 보완 바이너리 (예 : 0x8000and 0x7FFF)) 을 가져올 수 있습니다 . 이것은 MONO, 16-BIT, WAVE 파일을 읽습니다. 이 웹 페이지 는 다음을 공식화하는 데 매우 유용하다는 것을 알았습니다 .

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)


답변

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 


답변

IMHO, 사운드 파일의 오디오 데이터를 NumPy 배열로 가져 오는 가장 쉬운 방법은 SoundFile입니다 .

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

이것은 또한 24 비트 파일을 즉시 지원합니다.

많은 사운드 파일 라이브러리를 사용할 수 있으며 몇 가지 장단점을 볼 수 있는 개요를 작성 했습니다 . 또한 모듈을 사용하여 24 비트 wav 파일을 읽는 방법을wave 설명 하는 페이지가 있습니다.


답변

scikits.audiolab을 사용하여이를 수행 할 수 있습니다. 모듈을 . NumPy와 SciPy가 작동하려면 libsndfile도 필요합니다.

참고로 OSX가 아닌 Ubunutu에서만 작동하도록 할 수있었습니다.

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

이제 wav 데이터가 있습니다.


답변

블록별로 오디오를 처리하려는 경우 주어진 솔루션 중 일부는 전체 오디오를 메모리에로드하여 많은 캐시 미스를 생성하고 프로그램 속도를 느리게한다는 점에서 상당히 끔찍합니다. python-wavefile 은 생성기를 사용하여 효율적이고 투명한 블록 관리를 사용하여 NumPy 블록 별 처리를 수행하는 일부 파이썬 구조를 제공합니다. 다른 파이썬적인 장점은 파일에 대한 컨텍스트 관리자, 속성으로서의 메타 데이터 … 그리고 전체 파일 인터페이스를 원한다면 빠른 프로토 타입을 개발하고 효율성에 신경 쓰지 않기 때문에 전체 파일 인터페이스가 여전히 존재합니다.

처리의 간단한 예는 다음과 같습니다.

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 크기를 사용하는 대신 반환 된 블록 길이를 신뢰하십시오.


답변

파형 데이터에 대한 전송을 수행하려면 SciPy , 특히 scipy.io.wavfile.