본문으로 바로가기

snack을 이용한 음 만들기

category 카테고리 없음 2025. 3. 6. 15:41

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" 이렇게 명령했을 때 그 진동수에 해당하는 음을 내 주는 프로시져입니다. 음과 화음을 한번만 내는 것은 간단한데 멜로디가 만들려면 이건 조금 복잡해지는 모양입니다. 매뉴얼과 튜토리얼을 봐도 아직 정확히 모르겠는데 아시는 분이 올려주시면 도움이 되겠고 제가 다음에 정리가 된다면 그 때 올리겠습니다.