ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PyAudio
    카테고리 없음 2009. 10. 13. 00:32
    Python에서 마이크 입력을 받으려면?
    이라는 질문에 답을 찾다 찾은 해결책이 pyaudio라는 module입니다.
    이 모듈을 이용하면 녹음장치와 스피커에 파일처럼 접근을 하여 소리를 녹음하고 출력 할 수있습니다.

    다음은 http://people.csail.mit.edu/hubert/pyaudio/에 있는 예제 인데 마이크 입력을 5초간 받고 이것을 wave파일로 저장을 합니다.
    """ 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형으로 만들고 이것을 출력 하고 있습니다.

    이제 이 입력 받은 소리 값을 처리해 봅시당 ㅎㅎ
Designed by Tistory.