컴퓨터/Python

Python (21) - 파이썬을 이용하여 Beep로 연주하기 (winsound)

달서비 2023. 10. 17. 00:23

라즈베리파이 부저로 예전에 음악처럼 만든 적이 있었습니다. 시간이 나서 한번 재현하려고 하다 파이썬을 이용하는 방법이 있어 게시글을 투고합니다.

앙상블 - pixabay

 

사용 방법

pip install winsound

우선 이번에 이용할 모듈은 winsound라는 모듈입니다. 해당 모듈은 윈도우용으로 기본 소리 재생 장치들을 조작할 수 있습니다. 맥이나 리눅스를 사용하는 분은 다른 모듈을 참조하면 될 것 같습니다.

 

아래 링크는 windsound 모듈에 가이드입니다.

https://docs.python.org/ko/3/library/winsound.html

 

winsound — Sound-playing interface for Windows

The winsound module provides access to the basic sound-playing machinery provided by Windows platforms. It includes functions and several constants.

docs.python.org

 

비프음을 예시 코드

imort winsound

winsound.Beep(440, 1000) # 440Hz, 1000ms

비프음을 사용하는 방법은 winsound 함수에 Beep 함수만 이용하면 됩니다. 여담으로 오케스트라가 악기를 맞추는 기준 음이 라(440Hz) 입니다.

 

음계별 주파수 (도레미파솔라시도)

음계 옥타브
1 2 3 4 5 6 7 8
C 32.7 65.41 130.81 261.63 523.25 1046.5 2093 4186.01
C# 34.65 69.3 138.59 277.18 554.37 1108.73 2217.46 4434.92
D 36.71 73.42 146.83 293.66 587.33 1174.66 2349.32 4698.64
D# 38.89 77.78 155.56 311.13 622.25 1244.51 2489.02 4978.03
E 41.2 82.41 164.81 329.63 659.26 1318.51 2637.02 5274.04
F 43.65 87.31 174.61 349.23 698.46 1396.91 2793.83 5587.65
F# 46.25 92.5 185 369.99 739.99 1479.98 2959.96 5919.91
G 49 98 196 392 783.99 1567.98 3135.96 6271.93
G# 51.91 103.83 207.65 415.3 830.61 1661.22 3322.44 6644.88
A 55 110 220 440 880 1760 3520 7040
A# 58.27 116.54 233.08 466.16 932.33 1864.66 3729.31 7458.62
B 61.74 123.47 246.94 493.88 987.77 1975.53 3951.07 7902.13

음계별 주파수 (단위 Hz)

 

우선 위의 표는 음계별 표준 주파수를 소수점 3번째 자리에서 반올림한 값입니다. 해당 표를 통해 알 수 있는 것은 각 옥타브로 넘어갈 때마다 주파수가 2배가 된다는 사실입니다. 또한 각 음계의 주파수는 아래의 규칙을 따른다는 것을 알 수 있습니다.

  • 440 * 2 ^ (1 / 12) ≒ 466.16

이것을 12음계라고 부릅니다.

프로젝트에 적용하기 전 사람들이 쉽게 사용할 수 있도록 이것을 함수화 하도록 하겠습니다. 쉽게 구현하기 위해 기준이 되는 옥타브의 주파수를 매핑했습니다. 그리고 편의상 C부터 매핑했습니다.

import winsound

# 음계와 주파수 매핑
note_frequency = {
    'C': 261.63,
    'C#': 277.18,
    'D': 293.66,
    'D#': 311.13,
    'E': 329.63,
    'F': 349.23,
    'F#': 369.99,
    'G': 392.00,
    'G#': 415.30,
    'A': 440.00,
    'A#': 466.16,
    'B': 493.88
}

def play_note(note, octave, duration):
    frequency = note_frequency[note]
    winsound.Beep(int(frequency*(2**(octave-4))), int(duration * 1000))

# A음계를 1초 동안 재생
play_note('A', 4, 1)

 

키보드로 연주해 보자

마지막으로 키보드로 연주하는 예시를 구현해 보겠습니다.

키보드는 키보드 자판 배열에 쉽게 맞출 수 있도록 아래와 같이 설정했습니다.

  W(C#4) E(D#4)   T(F#4)   I(G#4) O(A#4)  
A(C4) S(D4) D(E4) F(F4)   J(G4) K(A4) L(B4) :(C5)

 

위의 규칙을 바탕으로 키보드 모듈을 이용하여 소스 코드를 수정했습니다.

import winsound
import keyboard

# 음계와 주파수 매핑
note_frequency = {
    'C': 261.63,
    'C#': 277.18,
    'D': 293.66,
    'D#': 311.13,
    'E': 329.63,
    'F': 349.23,
    'F#': 369.99,
    'G': 392.00,
    'G#': 415.30,
    'A': 440.00,
    'A#': 466.16,
    'B': 493.88
}

def play_note(note, octave, duration):
    frequency = note_frequency[note]
    print(int(frequency*(2**(octave-4))))
    winsound.Beep(int(frequency*(2**(octave-4))), int(duration * 1000))

while True:
    if keyboard.is_pressed('A'):
        play_note('C', 4, 0.25)
    elif keyboard.is_pressed('S'):
        play_note('D', 4, 0.25)
    elif keyboard.is_pressed('D'):
        play_note('E', 4, 0.25)
    elif keyboard.is_pressed('F'):
        play_note('F', 4, 0.25)
    elif keyboard.is_pressed('J'):
        play_note('G', 4, 0.25)
    elif keyboard.is_pressed('K'):
        play_note('A', 4, 0.25)
    elif keyboard.is_pressed('L'):
        play_note('B', 4, 0.25)
    elif keyboard.is_pressed(':'):
        play_note('C', 5, 0.25)
    elif keyboard.is_pressed('W'):
        play_note('C#', 4, 0.25)
    elif keyboard.is_pressed('E'):
        play_note('D#', 4, 0.25)
    elif keyboard.is_pressed('T'):
        play_note('F#', 4, 0.25)
    elif keyboard.is_pressed('I'):
        play_note('G#', 4, 0.25)
    elif keyboard.is_presse('O'):
        play_note('A#', 4, 0.25)

여기서 keyboard.is_pressed 함수는 키보드가 눌렸을 때 True를 출력하는 함수입니다. 해당 함수를 이용하여 각각의 키보드 입력을 구현하였습니다.

 

마지막으로 제가 블로그에 적은 부분으로 간단하게 음계를 표현할 수 있습니다. 만약에 키보드로 본격적으로 곡을 연주 하고 싶다면 Multiplayer Piano라는 웹사이트에서 피아노를 직접 연주하시는 것을 추천합니다.

https://multiplayerpiano.com/

 

Multiplayer Piano

This site makes a lot of sound! You may want to adjust the volume before continuing. PLAY

multiplayerpiano.com