본문 바로가기

Programming/Python_Etc

Python 키보드로 소리내기 피아노 연주하기

반응형

키보드 입력에 맞추어 비프음을 내도록 하겠습니다. 이번 프로그램을 위해서는 비프음을 내도록 하는 windsound 모듈과 키보드 인풋을 받아들이는 pynput 모듈이 필요합니다. 그 중 windwound 모듈은 기본으로 내장되어있으니 pynput 모듈만 설치해주도록 합니다.

 

1. 라이브러리 설치

pip install pynput

 

2. pynput모듈

pynput 모듈에서는 on_press 이벤트와 on_release 이벤트에 대해 리스너를 통해 입력받는 방법이 있습니다.

from pynput import keyboard

def on_press(key):
    print('Pressed Key: %s' % key)

def on_release(key):
    print('Pressed Key: %s' % key)
    if key == keyboard.Key.esc: #esc 키가 입력되면 종료
        return False
        
 # 리스너 등록방법1
listener = keyboard.Listener(
     on_press=on_press,
     on_release=on_release)
listener.start()
listener.join()

# 리스너 등록방법2
with keyboard.Listener(
    on_press=on_press,
    on_release=on_release) as listener:
    listener.join()

이런식으로 이용하면 되지만, 이번에는 동기화 방식에 의한 방법으로

from pynput import keyboard
 
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            print("Exit!!")
            break
        if event.key == keyboard.KeyCode(char='a'):
            print("Pressed:", keyboard.KeyCode(char='a'))

와 같이 사용하려고 합니다. 이벤트의 종류와 상관없이 처리를 하게 됩니다.

 

3. winsound 모듈

winsound.Beep(음계주파수, 지속시간)

와 같이 사용합니다. 연주를 위해서는 음계에 대한 정확한 주파수를 입력해야합니다. 다행스러운 것은 한 옥타브 위의 음에 대해서는 2배의 Frequency에 해당하는 주파수를 갖고 있습니다.

 

4. 전체 소스코드

from pynput import keyboard
import winsound

# 1옥타브: C, C#, D, D#, E, F, F#, G, G#, A, A#, B
pitch = {'c_': 523, 'cs': 554, 'd_': 587, 'ds': 622, 'e_': 659,
         'f_': 698, 'fs': 740, 'g_': 784, 'gs': 831, 'a_': 880,
         'as': 932, 'b_': 988}
# 2옥타브
pitch2={}
for key, value in pitch.items():
    pitch2[key] = value * 2  # 한옥타브 위는 주파수가 2배.
print(pitch2)

# 지속시간
lasting = 100

# The event listener will be running in this block
with keyboard.Events() as events:
    for event in events:
        if event.key == keyboard.Key.esc:
            print("Exit!!")
            break
        elif event.key == keyboard.KeyCode(char='q'):
            winsound.Beep(494, lasting)
        elif event.key == keyboard.KeyCode(char='a'):
            winsound.Beep(pitch['c_'], lasting)
        elif event.key == keyboard.KeyCode(char='w'):
            winsound.Beep(pitch['cs'], lasting)
        elif event.key == keyboard.KeyCode(char='s'):
            winsound.Beep(pitch['d_'], lasting)
        elif event.key == keyboard.KeyCode(char='e'):
            winsound.Beep(pitch['ds'], lasting)
        elif (event.key == keyboard.KeyCode(char='d')) | (event.key == keyboard.KeyCode(char='r')):
            winsound.Beep(pitch['e_'], lasting)
        elif event.key == keyboard.KeyCode(char='f'):
            winsound.Beep(pitch['f_'], lasting)
        elif event.key == keyboard.KeyCode(char='t'):
            winsound.Beep(pitch['fs'], lasting)
        elif event.key == keyboard.KeyCode(char='g'):
            winsound.Beep(pitch['g_'], lasting)
        elif event.key == keyboard.KeyCode(char='y'):
            winsound.Beep(pitch['gs'], lasting)
        elif event.key == keyboard.KeyCode(char='h'):
            winsound.Beep(pitch['a_'], lasting)
        elif event.key == keyboard.KeyCode(char='u'):
            winsound.Beep(pitch['as'], lasting)
        elif (event.key == keyboard.KeyCode(char='j')) | (event.key == keyboard.KeyCode(char='i')):
            winsound.Beep(pitch['b_'], lasting)
        elif event.key == keyboard.KeyCode(char='k'):
            winsound.Beep(pitch2['c_'], lasting)
        elif event.key == keyboard.KeyCode(char='o'):
            winsound.Beep(pitch2['cs'], lasting)
        elif event.key == keyboard.KeyCode(char='l'):
            winsound.Beep(pitch2['d_'], lasting)
        elif event.key == keyboard.KeyCode(char='p'):
            winsound.Beep(pitch2['ds'], lasting)
        elif (event.key == keyboard.KeyCode(char=';')) | (event.key == keyboard.KeyCode(char='[')):
            winsound.Beep(pitch2['e_'], lasting)
        elif event.key == keyboard.KeyCode(char="'"):
            winsound.Beep(pitch2['f_'], lasting)
        elif event.key == keyboard.KeyCode(char="]"):
            winsound.Beep(pitch2['fs'], lasting)

# 빈 키(z,x,c,v... ) 에 대해 추가로 음계 할당
        elif event.key == keyboard.KeyCode(char="z"):
            winsound.Beep(pitch['c_'], lasting)
        elif event.key == keyboard.KeyCode(char="x"):
            winsound.Beep(pitch['d_'], lasting)
        elif event.key == keyboard.KeyCode(char="c"):
            winsound.Beep(pitch['e_'], lasting)
        elif event.key == keyboard.KeyCode(char="v"):
            winsound.Beep(pitch['f_'], lasting)
        elif event.key == keyboard.KeyCode(char="b"):
            winsound.Beep(pitch['g_'], lasting)
        elif event.key == keyboard.KeyCode(char="n"):
            winsound.Beep(pitch['a_'], lasting)
        elif event.key == keyboard.KeyCode(char="m"):
            winsound.Beep(pitch['b_'], lasting)
        elif event.key == keyboard.KeyCode(char=","):
            winsound.Beep(pitch2['c_'], lasting)
        elif event.key == keyboard.KeyCode(char="."):
            winsound.Beep(pitch2['d_'], lasting)
        elif event.key == keyboard.KeyCode(char="/"):
            winsound.Beep(pitch2['e_'], lasting)

 

이상으로 연주 가능한 키보드를 만들어보았습니다.

 

~~끝~~

반응형