Python에서 * .wav 파일 읽기


90

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

답변:


109

문서 , scipy.io.wavfile.read(somefile)두 항목의 튜플 결과 : 처음 인 샘플링 레이트 는 초당 샘플은, 제는 인 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-packages / pygame / examples / data / secosmic_lo.wav')-> ZeroDivisionError : 정수 나누기 또는 0으로 모듈로
Finn Årup Nielsen

6
@bastibe가 data되도록 2 차원 배열이다 NumPy와 data.shape(num_samples, NUM_CHANNELS)의 튜플 반환
호브

63

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)

2
24 비트 스테레오 파일을 처리하는 방법?
Basj 2013

14
이렇게하면 "struct.error : unpack에 길이 2의 문자열 인수가 필요합니다."라는 오류 메시지가 표시됩니다.
Coder404

1
매우 큰 오디오 파일로이 코드를 실행하면. 이 프로그램의 메모리 필요로 인해 컴퓨터가 죽을 것입니다. 큰 오디오 파일을 위해 블록별로 오디오 파일을 처리해야 함
ArthurLambert 2015-04-28

@ Coder404 아마도 스테레오 웨이브 파일이거나 다른 비트 심도를 가지고있을 것입니다.
jmilloy

3
저처럼 2s 보완 바이너리가 무엇인지 궁금한 사람들은 여기 stackoverflow.com/questions/1049722/what-is-2s-complement
Dennis Golomazov

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 비트 파일을 즉시 지원합니다.

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


참고 : soundfile.read ()는 sandoval의 scipy.io.wavfile 예제에서와 같이 2 ^ (n_bits-1)로 정규화됩니다.
Quetzalcoatl

9

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

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

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

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


scikits.audiolab2010 년 이후 로 업데이트되지 않았으며 아마도 Python 2 일 것입니다.
Boris

4

블록별로 오디오를 처리하려는 경우 주어진 솔루션 중 일부는 전체 오디오를 메모리에로드하여 많은 캐시 미스를 생성하고 프로그램 속도를 느리게한다는 점에서 상당히 끔찍합니다. 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 크기를 사용하는 대신 반환 된 블록 길이를 신뢰하십시오.



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

파일이 두 개이고 샘플 속도가 상당히 높으면 파일을 인터리브 할 수 있습니다.

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

u는 또한 간단한 import wavio라이브러리를 사용할 수 있습니다 u 또한 사운드에 대한 몇 가지 기본 지식이 필요합니다.


0

PyDub ( http://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/

추신. 예제는 wav 파일 읽기에 관한 것이지만 PyDub는 다양한 형식을 즉시 처리 할 수 ​​있습니다. 주의 할 점은 기본 Python wav 지원과 ffmpeg 모두를 기반으로하므로 ffmpeg를 설치해야하고 많은 pydub 기능이 ffmpeg 버전에 의존한다는 것입니다. 보통 ffmpeg가 할 수 있다면 pydub도 할 수 있습니다.

면책 조항 없음 : 나는 프로젝트와 관련이 없지만 무거운 사용자입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.