Python에서 마이크 입력을 받으려면?
이라는 질문에 답을 찾다 찾은 해결책이 pyaudio라는 module입니다.
이 모듈을 이용하면 녹음장치와 스피커에 파일처럼 접근을 하여 소리를 녹음하고 출력 할 수있습니다.
""" Record a few seconds of audio and save to a WAVE file. """
import pyaudio
import wave
import sys
chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
frames_per_buffer = chunk)
print "* recording"
all = []
for i in range(0, RATE / chunk * RECORD_SECONDS):
data = stream.read(chunk)
all.append(data)
print "* done recording"
stream.close()
p.terminate()
# write data to WAVE file
data = ''.join(all)
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()
우리가 하고 싶은 것은 mic로 소리를 받고 이 소리가 얼마 만큼의 값을 갖는지를 알고 싶습니다. 여기서 key는 struct라는 module의 unpack입니다. 장치에서 소리를 binary형태로 읽어 오는데 이 읽어온 소리를 출력 자료 형태에 따라서 다시 조합을 해야 합니다. binary형태의 값을 재조합하여 원하는 형태의 자료 형태로 만드는 것이 unpack입니다.
import pyaudio
import struct
from pylab import plot, subplot, show
f = open("mic.txt", "w")
p = pyaudio.PyAudio()
mic_stream = p.open(format = pyaudio.paInt16, channels = 1, rate = 44100/10, input = True, frames_per_buffer = 1)
prev_mic_value = 0
mic_value = 0
def ReadMic():
data = mic_stream.read(1) #we can read long period, it should be same as frames_per_buffer
result = struct.unpack("h", data) #binary data to short data conversion, 2byte -> short
return result[0]
print "rec start"
mic_data =[]
mic_gap_data =[]
mic_gap_abs_data =[]
FILTER_NUM = 10
for i in range(0, 10000):
prev_mic_value = mic_value
"""
sum = 0.0
for n in range(FILTER_NUM):
sum += ReadMic()
mic_value = sum/FILTER_NUM
"""
mic_value = ReadMic()
mic_value_gap = mic_value - prev_mic_value
mic_data.append(mic_value)
mic_gap_data.append(mic_value_gap)
mic_gap_abs_data.append(abs(mic_value_gap))
#f.write(str(abs(mic_value_gap)) + '\n')
f.write(str(mic_value) + '\n')
print "rec end"
mic_stream.close()
p.terminate()
f.close()
subplot(311)
plot(mic_data)
subplot(312)
plot(mic_gap_data)
subplot(313)
plot(mic_gap_abs_data)
show()
위의 예를 보면 마이크에서 값을 읽어 온후 이 값을 2바이트 씩 붙여서 short형으로 만들고 이것을 출력 하고 있습니다.
이제 이 입력 받은 소리 값을 처리해 봅시당 ㅎㅎ