bonkora 님이 제공해 주신 글입니다.
확장 패키지 snack을 이용하여 음과 화음을 만들어 보겠습니다. 사운드를 만드는 명령은 snack::sound, 그 사운드를 구성하는 음의 정보를 만드는 명령은 snack::filter입니다. snack::filter 명령을 사용하여 음의 정보를 만들어 보겠습니다. 형식은 아래와 같습니다.
snack::filter generator frequency ?amplitude? ?shape? ?type? ?ntot?
- frequency: 음의 진동수(주파수) 필수적인 옵션
- amplitude: 음의 고저, 즉 음의 볼륨이라고 생각하면 되겠습니다. 필수적인 옵션은 아니지만 amplitude 값을 넣지 않으면 소리가 작아서 들리지 않으니 frequency와 amplitude은 기본적으로 필요하다고 알고 있으면 되겠습니다.
- shape: 번역하자면 음의 모양이 되겠지만 스피커에 달려있는 tone 스위치의 기능을 생각하면 되겠습니다. 값은 0.0부터 1.0 사이의 수치를 선택할 수 있습니다. rectangle, triangle, sine 형에서만 효력이 있습니다.
- type: rectangle, triangle, sine, noise, sample의 형이 있습니다. 각각 들어보면 조금씩 다르게 들립니다. 이론적으로 차이가 뭔지는 잘 모르겠습니다.
- ntot: 만들 사운드의 정보에 몇개의 샘플이 포함되어 있는가를 지적해 줍니다. 이 숫자가 커지면 음의 길이가 늘어납니다. 기본값은 -1이고 이것은 무한정 재생한다는 뜻입니다.
콘솔에서 명령어를 넣어서 이렇게 해 봅니다.
package require snack
set f [snack::filter generator 440.0 30000 0.5 sine 8000]
set s [snack::sound]
$s play -filter $f
짧게 소리가 납니다. 길게 소리를 내려면 8000을 더 크게 입력하면 되고 계속 나게 하려면 -1을 넣습니다. 두 개의 필터에 각각의 음의 정보를 입력한 후 두 개의 소리를 같이 나게 해 봅니다. 콘솔에서 아래의 명령들을 써 봅니다.
set f1 [snack::filter generator 440.0 30000]
set f2 [snack::filter generator 220.0 30000]
set s [snack::sound]
# A음을 연주한다
$s play -filter $f1
# A음을 멈추게 한다
$s stop
# 이번엔 낮은 A음을 연주한다
$s play -filter $f2
# 멈춘다
$s stop
# 두개의 음을 한꺼번에 낸다
$s play -filter $f1
$s play -filter $f2
$s stop
stop 명령을 쓰면 소리는 안 나더라도 사운드와 필터가 기억장소를 차지하고 있으니까 작업이 완전히 끝나고 나면 소리와 필터를 없앱니다.
$s destroy
$f1 destroy
$f2 destroy
마지막으로 snack 홈페이지에서 본 예제를 보겠습니다.
proc beep {freq} {
set len 8000
set f [snack::filter generator $freq 30000 0.0 sine $len]
set s [snack::sound -rate 22050]
$s play -filter $f -command "$s destroy;$f destroy"
}
"beep 440" 이렇게 명령했을 때 그 진동수에 해당하는 음을 내 주는 프로시져입니다. 음과 화음을 한번만 내는 것은 간단한데 멜로디가 만들려면 이건 조금 복잡해지는 모양입니다. 매뉴얼과 튜토리얼을 봐도 아직 정확히 모르겠는데 아시는 분이 올려주시면 도움이 되겠고 제가 다음에 정리가 된다면 그 때 올리겠습니다.