파이썬 표준 라이브러리의 wave 모듈은 WAV 오디오 포맷을 손쉽게 다룰 수 있는 인터페이스를 제공합니다. 이 모듈의 함수들을 활용하면 원시(raw) 형식의 오디오 데이터를 파일 객체에 기록하거나, WAV 파일의 각종 속성 정보를 읽어올 수 있습니다.
내장 open() 함수와 마찬가지로 파일을 '쓰기' 또는 '읽기' 모드로 열지만, wave 모듈에서는 전용 open 함수인 wave.open()을 사용합니다.
wave.open()
wave.open() 함수는 오디오 데이터를 읽거나 쓰기 위해 파일을 열 때 사용합니다. 두 개의 매개변수가 필요한데, 첫 번째는 파일 이름, 두 번째는 모드입니다.
- 'wb' : 오디오 데이터를 기록(쓰기)할 때
- 'rb' : 오디오 데이터를 읽어올 때
obj = wave.open('sound.wav', 'wb')
모드가 'rb'이면 Wave_read 객체가, 'wb'이면 Wave_write 객체가 반환됩니다.
Wave_write 객체의 주요 메서드
| close() | wave 모듈로 연 파일을 닫습니다. |
| setnchannels() | 채널 수를 설정합니다. 1은 모노, 2는 스테레오입니다. |
| setsampwidth() | 샘플 폭을 n 바이트로 설정합니다. |
| setframerate() | 프레임 레이트(샘플링 주파수)를 n으로 설정합니다. |
| setnframes() | 프레임 수를 n으로 설정합니다. |
| setcomptype() | 압축 유형과 설명을 설정합니다. 현재는 NONE(무압축)만 지원됩니다. |
| setparams() | (nchannels, sampwidth, framerate, nframes, comptype, compname) 튜플을 한 번에 지정합니다. |
| tell() | 파일 내 현재 위치를 반환합니다. |
| writeframesraw() | 보정 과정 없이 오디오 프레임을 그대로 기록합니다. |
| writeframes() | 오디오 프레임을 기록하고 헤더 정보가 올바르도록 보정합니다. |
다음 예제 코드는 무작위 short 정수값으로 구성된 WAV 파일을 생성하는 코드입니다. 44.1kHz 샘플링 레이트의 모노 채널로 사운드를 만들며, 440Hz(A4음) 기준으로 설정되어 있습니다.
import wave, struct, math, random
sampleRate = 44100.0 # 헤르츠
duration = 1.0 # 초
frequency = 440.0 # 헤르츠
obj = wave.open('sound.wav', 'w')
obj.setnchannels(1) # 모노
obj.setsampwidth(2)
obj.setframerate(sampleRate)
for i in range(99999):
value = random.randint(-32767, 32767)
data = struct.pack('<h', value)
obj.writeframesraw(data)
obj.close()
Wave_read 객체의 주요 메서드
| close() | wave 모듈로 연 스트림을 닫습니다. |
| getnchannels() | 오디오 채널 수를 반환합니다(모노는 1, 스테레오는 2). |
| getsampwidth() | 샘플 폭을 바이트 단위로 반환합니다. |
| getframerate() | 샘플링 주파수를 반환합니다. |
| getnframes() | 오디오 프레임 수를 반환합니다. |
| getcomptype() | 압축 유형을 반환합니다(NONE만 지원됩니다). |
| getparams() | (nchannels, sampwidth, framerate, nframes, comptype, compname) namedtuple을 반환하며, get*() 메서드들의 출력과 동일한 정보를 담습니다. |
| readframes(n) | 최대 n개의 오디오 프레임을 bytes 객체로 읽어 반환합니다. |
| rewind() | 파일 포인터를 오디오 스트림의 처음으로 되돌립니다. |
아래 코드는 WAV 파일의 파라미터 정보를 읽어 출력하는 예제입니다.
import wave
obj = wave.open('sound.wav', 'r')
print("Number of channels", obj.getnchannels())
print("Sample width", obj.getsampwidth())
print("Frame rate.", obj.getframerate())
print("Number of frames", obj.getnframes())
print("parameters:", obj.getparams())
obj.close()
실행 결과
Number of channels 1 Sample width 2 Frame rate. 44100 Number of frames 99999 parameters: _wave_params(nchannels=1, sampwidth=2, framerate=44100, nframes=99999, comptype='NONE', compname='not compressed')