이번에는 microphone과 python의 sounddevice 라이브러리를 이용한 소리 탐지 소스를 만들어 보았습니다.
우선 설치부터 해야지요~
운영체제마다 조금씩 다르지만 맥기준으로 설명하겠습니다.
우선 sounddevice를 microphone과 연결하기 위한 portaudio를 설치해줍니다.
brew install portaudio 명령을 통해 설치를 해줍니다.
그리고 자신의 파이썬 환경에 sounddevice설치를 위해 pip install sounddevice 를 통해 라이브러리를 설치해줍니다.
이제 제가 간단히 테스트해본 코드를 봅시다.
우선 필요한 라이브러리들을 임포트해줍니다.
import time import sounddevice as sd import numpy as np
그리고 몇 초단위로 코드를 진행할 것인지 duration을 정해줍니다.
duration = 3 # seconds
저는 3초로 했습니다.
while True: present_wave = [] compare_wave = [] def print_sound(indata, outdata, frames, time, status): volume_norm = np.linalg.norm(indata)*10 print("|" * int(volume_norm)) with sd.Stream(callback=print_sound): sd.sleep(duration * 1000)
그리고 반복문으로 반복해줍니다.
이렇게 하면
마이크로폰으로 들어오는 input stream을 파이프 기호로 표시해줍니다.
이런식으로 말이죠
여기에 여러분이 원하는 기능을 추가할 수 있습니다.
저는 3초동안 불규칙한 웨이브가 감지되면 udp 소켓으로 데이터를 보내도록 코드를 만들었습니다.
아래는 전체코드입니다.
# Print out realtime audio volume as ascii bars import time import sounddevice as sd import numpy as np import copy import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli = ("127.0.0.1", 9999) data = b'True' error_wave = '' gijunjum = 1000 duration = 3 # seconds prev_wave = [] init = True while True: present_wave = [] compare_wave = [] def print_sound(indata, outdata, frames, time, status): volume_norm = np.linalg.norm(indata)*10 print("|" * int(volume_norm)) present_wave.append(gijunjum - volume_norm) with sd.Stream(callback=print_sound): sd.sleep(duration * 1000) if init is True: prev_wave = copy.copy(present_wave) init = False try: for idx, each in enumerate(present_wave): compare_wave.append(each - prev_wave[idx]) except IndexError: pass temp = 0 total_change = 0 for cw in compare_wave: if abs(cw - temp) > 4: total_change = total_change + 1 temp = cw if total_change > 30: print("sound detect!!") client_socket.sendto(data, cli) time.sleep(0.01)
여기까지 마치겠습니다. 끝~!