User Tools

Site Tools


music_on_linux

Music on Linux

우분투 22.04부터는 음악 작업을 하기가 훨씬 수월해졌고(내 블로그의 관련 글 참조), DAW 역시 Tracktion의 Waveform Free를 즐겨 쓰게 되었으며, 2023년에 접어들어서는 음악 작업 환경을 Windows로 옮기게 되면서 이 위키 문서를 계속 업데이트하는 것이 무슨 의미가 있는지 고민을 하게 되었다. — 2023/09/08 05:23

이곳은 리눅스(우분투 스튜디오 20.04 기준)가 설치된 컴퓨터에서 음악과 MIDI 작업을 하는 요령을 기록하기 위한 위키 페이지이다. 우분투 스튜디오의 좋은 점은 멀티미디어 작업에 필요한 많은 프로그램이 기본적으로 포함되어 있고, low latency kernel로 구동된다는 것이다. 그러나 우분투 스튜디오가 아닌 '데스크탑'을 설치한 다음 필요한 소프트웨어를 추가적으로 설치해도 별로 불편한 점은 없다. 설치된 리눅스 배포판과 커널의 상세 정보는 다음 명령으로 확인해 보자.

$ cat /etc/lsb-release 
$ cat /etc/os-release | grep 'VERSION='
$ uname -a 

이 글은 초보자를 위한 친절한 tutorial 또는 step-by-step guide는 되지 못한다. 주된 목적은 나의 기억을 돕기 위해서 작성된 것이라고 봐야 한다. 글을 쓰면서 기본 개념을 잡기 위하여 다음 사이트를 주로 참고하였다.

위에서 소개한 Ted의 가이드에서는 JACK의 작동에 종종 방해가 되므로 PulseAudio를 아예 쓰지 말라고 하지만 그건 결코 바람직하지 않다. PulseAudio는 알게 모르게 오디오의 재생과 녹음 작업에 깊숙하게 관여하고 있어서 결코 피해 다녀서는 안된다는 것이 현재 나의 확고한 신념이다. 재생 위주의 작업을 하거나 웹캠을 이용한 음성 녹음 정도를 한다면 오히려 JACK을 쓰지 않는 것이 더 편할 수도 있다. PulseAudio는 ALSA보다는 좀 더 사용자에 가까운 레벨에서 조절을 담당하지만 그 기능이 매우 방대하고 이해하기에 썩 쉬운 것도 아니다.

PulseAudio는 일반인을, JACK은 전문가를 위해 특화된 것이다. 비슷하면서도 다른 두 프로그램의 특성은 PulseAudio and Jack이라는 웹문서의 표에 일목요연하게 잘 나타난다. 종종 PulseAudio와 JACK이 서로 충돌을 한다고 여겨지지만, 두 프로그램은 사용 목적이 조금 다르며, 영리한 설정을 통해서 조화롭게 사용할 수 있다. How use PulseAudio and JACK? 웹문서에서 두 프로그램이 공존하게 만드는 방법을 확인해 보라. PulseAudio의 작동 상태를 확인하거나 설정을 변경하려면 메뉴에서 PulseAudio Volume Control을 찾아서 실행하거나 명령행에서 pavucontrol을 입력하라. 또는 pactl이나 pacmd로 세밀한 부분을 건드릴 수도 있다.

나의 최종 목표는 원래 Rosegarden에서 미디 및 오디오 녹음 작업을 하는 것이었다. 일반적인 녹음 작업 및 후처리에서는 Audacity를 빼놓을 수 없다. Rosegarden은 우분투 스튜디오에 기본으로 포함되어 있지도 않고, 어떤 면에서는 ARDOUR가 DAW(Digital Audio Workstation) tool로는 더 나은 것 같다. 그러나 Rosegarden은 인터페이스가 간단하며 사용이 매우 편리하고 미디 작업에는 더욱 적합하다. Seq24는 그야말로 최소 수준의 미디 시퀀서일 뿐 DAW를 겸하고 있지 않으므로 오디오 녹음은 하지 못한다.

2022년 10월 현재 LMMS(Linux MultiMedia Studio)와 Waveform Free를 주력 DAW로 쓰는 것으로 방향을 선회하였다.

설치된 사운드 카드의 확인

명령행 인터페이스(CLI)

Behringer U-Control UCA200, Roland Sound Canvas SC-D70, 그리고 M-AUDIO Keystation 88es을 USB 단자에 꽂은 상태에서 'cat /proc/asound/cards' 명령을 실행해 보자. 내장 사운드카드뿐만 아니라 사운드와 관련된 모든 기기(마이크로폰, 마이크로폰 내장 웹캠, MIDI 키보드 콘트롤러, MIDI 사운드 모듈 등)가 전부 표시될 것이다.

$ cat /proc/asound/cards
 0 [Intel          ]: HDA-Intel - HDA Intel
                      HDA Intel at 0xd4500000 irq 27
 1 [CODEC          ]: USB-Audio - USB Audio CODEC
                      Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.0-1, full speed
 2 [SCD70          ]: USB-Audio - SC-D70
                    Roland SC-D70 at usb-0000:00:1a.7-4.4, full speed

맨 왼쪽에 보이는 숫자(card ID or card number)는 ALSA device name의 일부이다. '일부'라고 표현한 이유는, 실제 ALSA device name은 'hw:0' 또는 'hw:3,0'과 같은 형태로 쓰이기 때문이다. 각 카드에 대한 고유한 정보는 /proc/asound/cardX(X는 조금 전 설명한 card number로서 0..7) 디렉토리에 각각 수록된다. 컴퓨터 부팅 직후라면 내장 사운드 카드인 card0 디렉토리만 존재한다. 'Intel'은 card0의 심볼릭 링크이다. 여기에서 MXL Tempo 마이크는 오디오 인터페이스와 같은 회사의 칩을 사용하므로 단독으로 연결하면 CODEC, UCA200와 같이 연결된 상태에서는 순서에 따라 CODEC 및 CODEC_1이라는 식별자가 붙는다.

다음은 다른 종류의 컴퓨터(AMD Ryzen 5950X)에 UCA200과 RockFrog를 연결한 상태이다.

$ cat /proc/asound/cards
 0 [NVidia         ]: HDA-Intel - HDA NVidia
                      HDA NVidia at 0xfc080000 irq 117
 1 [CODEC          ]: USB-Audio - USB Audio CODEC
                      Burr-Brown from TI USB Audio CODEC at usb-0000:05:00.3-2.3, full speed
 2 [Generic        ]: HDA-Intel - HD-Audio Generic
                      HD-Audio Generic at 0xfca00000 irq 119
 3 [RockFrog       ]: USB-Audio - RockFrog
                      SIMS Corp. RockFrog at usb-0000:05:00.3-2.1, full speed

alsa-utils 패키지에 포함된 유틸리티 중 하나인 aplay를 사용해서 사운드 카드의 정보를 알아낼 수도 있다. USB 키보드 콘트롤러는 이 명령에서는 보이지 않는다. '-l/--list-devices'는 'list all soundcards and digital audio devices'인데 화면에는 'PLAYBACK 하드웨어 장치 목록'이라고 나오는 것이 넌센스이다. 맨 앞의 숫자는 /proc/asound/cards 파일에서 각 기기의 앞에 나오는 숫자와 동일하다.

$ aplay -l # or --list-devices; list all soundcards and digital audio devices 
  **** PLAYBACK 하드웨어 장치 목록 ****
0 카드: Intel [HDA Intel], 0 장치: 92HD75B2X5 Analog [92HD75B2X5 Analog]
  하위장치: 1/1
  하위장치 #0: subdevice #0
0 카드: Intel [HDA Intel], 3 장치: HDMI 0 [HDMI 0]
  하위장치: 1/1
  하위장치 #0: subdevice #0
1 카드: CODEC [USB Audio CODEC], 0 장치: USB Audio [USB Audio]
  하위장치: 1/1
  하위장치 #0: subdevice #0
2 카드: SCD70 [SC-D70], 0 장치: USB Audio [USB Audio]
  하위장치: 1/1
  하위장치 #0: subdevice #0

이로부터 내장 사운드카드의 디바이스 네임은 hw0,0임을 알 수 있다. ALSA device, subdevice 및 card에 대한 의미는 Understanding ALSA device, subdevice and cards를 읽어 보도록 하자.

내 사운드카드의 최대 샘플링 레이트는 얼마일까?

컴퓨터 내장 사운드카드를 예로 들어서 이를 알아보자. PulseAudio의 기본 동작에서는 44100 Hz로 작동한다. 기본 설정은 /etc/pulse/daemon.conf 파일에 수록되어 있다.

## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
## more information. Default values are commented out.  Use either ; or # for
## commenting...
; default-sample-format = s16le
; default-sample-rate = 44100
; alternate-sample-rate = 48000
; default-sample-channels = 2
; default-channel-map = front-left,front-right

고의로 60 kHz로 녹음을 시도한 뒤 명령행에 나오는 메시지를 통하여 내장 사운드카드가 지원하는 최대의 샘플링 레이트를 알아보자. '-f dat'는 16 bit little endian, 44.1 kHz, stereo를 의미한다.

$ arecord -f dat -r 60000 -D hw:0,0 -d 5 test.wav
녹음 WAVE 'test.wav' : Signed 16 bit Little Endian, 60000 Hz 비율, 스테레오
경고: 비율이 정확하지 않습니다(요청함 = 60000Hz, 가져옴 = 48000Hz)
       플러그인 를, 연결해보십시오

여기에서 플러그인이라는 다소 어려운 개념이 나온다. Plugin이란, PCM 디바이스의 기능이나 특성을 확장하는 역할을 한다. 예를 들어 디바이스 이름을 바꾸거나, 샘플 레이트를 바꾸고, 다른 채널 간에 복사를 하는 등의 일을 자동적으로 수행하는 것이다. 플러그인의 전체 목록과 옵션은 alsa-lib documentation에 나오지만 대단히 기술적이고 딱딱하며 이해하기 어려운 문서이므로 .asoundrc 파일 설명 문서를 보는 것이 나을 것이다.

PulseAudio Volume Control(GUI)을 이용한 사운드 카드의 확인 및 설정 변경

GUI 프로그램인 PulseAudio Volume Control(명령어: pavucontrol)을 실행하여 나타나는 설정 탭에서 설치된 사운드 카드 및 현재의 프로파일을 확인할 수 있다. 우분투 스튜디오가 아니라 그냥 우분투를 설치했다면 자동으로 깔리지 않는다. pavucontrol을 설치하지 않았다고 해서 PulseAudio 서비스가 돌아가지 않는 것은 아니니 걱정할 필요는 없다. 아마도 이 유틸리티는 우분투에서 음악 작업을 하면서 가장 자주 열어보는 프로그램이 될 것이다. 원하는 기기로 소리의 입출력이 되도록 변경하거나 녹음/재생 레벨을 맞출 때 등 쓸 일이 아주 많다. 영화를 보기 위해 HDMI 케이블을 이용하여 TV를 연결했는데 소리가 TV에서 나지 않는다면? 설정(configuration) 탭에서 내장 사운드 카드의 출력 프로파일을 바꾸면 된다. 즉, 다음 그림에서 '디지털 스테레오(HDMI) 출력'을 포함하는 것을 선택하면 된다.

UCA200은 'PCM2902 Audio Codec', MXL Tempo 마이크는 'PCM2912A Audio Codec'로 나타날 것이다. /proc/asound/cards 파일에서는 이렇게 상세하게 사운드 카드 정보가 나타나지는 않는다.

여러 사운드 장비가 꽂혀 있을 때 원하는 장비에서 입출력이 이루어지게 만들려면 PulseAudio Volume Control의 설정 탭을 이용하는 것이 원칙이라고 보아도 무방하다. 예를 들어 USB 마이크가 연결되어 있지만 이는 입력만 담당하고 출력은 내장 사운드 카드에서 뽑고자 할 때가 있을 때 이 기능을 적절히 사용하면 된다. 명령어 환경에서는 'pactl list short sources|links'로 설정 상태를 확인하면 된다. 명령행에서 default device를 바꾸려면 pacmd 명령어를 사용해야 되는데, 상세한 요령은 이곳을 참조하라. 'pacmd list-cards'를 입력하면 정말 상세한 목록이 나올 것이다. 사운드 관련 장비의 정보를 출력하는 명령어는 다음과 같이 다양한 것이다!

  • cat /proc/asound/cards
  • aplay -l
  • pactl list short sources [sinks]
  • pacmd list-cards
  • pacmd list-sources [list-sinks]

다음 명령어는 default source/sink를 확인하기 위함이다.

  • pacmd list-sources [list-sinks] | grep -e 'index:' -e device.string -e 'name:'

오디오 파일의 재생

테스트 목적의 사운드 파일 생성 및 재생

SoX(Sound eXchange) 패키지를 구성하는 유틸리티인 sox/play/rec를 사용하여 440 Hz의 사인파를 WAV 파일로 녹음한 뒤 재생해 보자. 사용한 프로그램(sox & play)는 SoX package('the Swiss Army knife of audio manipulation')에 포함된 것이다. 녹음 및 재생은 USB 포트에 가장 나중에 꽂힌 장치(기본 장치, 즉 default device)를 통하여 이루어지며, 내장 사운드 카드가 기본 장치 역할을 하는 것이 아니다. 물론 이러한 기본 동작은 PulseAudio를 통하여 바꿀 수 있다. 여기에서는 명령행에서 aplay를 입력하여 재생하였지만, GUI에서 오디오 파일을 더블클릭하면 VLC 미디어 재생기가 작동할 것이다. parole도 미디어 재생기의 일종이다.

$ sudo apt install sox
$ sox -b 16 -n test.wav rate 44100 channels 2 synth 1 sine 440 gain -1
$ play test.wav # 기본 장치를 통한 재생
# USB 사운드 카드가 꽂힌 상태에서도 다음과 같이 입력하면 내장 사운드 카드에서 재생이 된다.
$ aplay -D hw:0 test.wav # /proc/asound/cards에서 나타나는 카드 번호 사용
$ aplay -D hw:Intel test.wav

Default 사운드 카드를 설정하는 다양한 방법에 대해서는 How do you set a default audio output device in Ubuntu 18.04? 또는 How to make Alsa pick a preferred sound device automatically?를 참조하도록 한다. 여러 개의 사운드 카드가 설치된 상태에서 특정 애플리케이션의 재생음을 원하는 사운드 카드로 나오게 하려면 PulseAudio Volume Control → Playback 탭에서 애플리케이션의 오디오 출력을 원하는대로 고치면 된다. 경험에 의하면 바로 직전의 설정 상황(각 애플리케이션에 따른)이 기억되어 이를 따르는 것으로 보인다. Configuration에서 설정한 사운드 카드 프로파일과도 잘 일치해야 함은 물론이다. 예를 들어 HDMI 출력을 위한 내장 오디오 프로파일을 설정해 놓은 상태에서 헤드폰 단자(이것 역시 내장 오디오의 일부)로 음성 출력이 나오도록 할 수는 없다. 별도의 USB 사운드 카드가 꽂인 상태라면 화면을 HDMI 단자를 통해 외부 모니터로 보내면서 USB 사운드 카드로 음성 출력을 보내는 것은 가능하다.

USB 마이크를 이용한 녹음과 재생

alsa-utils에서 제공하는 프로그램인 aplay/arecord를 이용하여 USB 마이크로부터 입력한 소리를 5초 동안 녹음해 본다. USB 마이크 입력을 어떻게 지정해야 하는지 'aplay -l' 명령으로 알아본다.

$ aplay -l
**** PLAYBACK 하드웨어 장치 목록 ****
2 카드: CODEC [USB audio CODEC], 0 장치: USB Audio [USB Audio]
  하위장치: 1/1
  하위장치 #0: subdevice #0
..(생략)

USB 마이크는 'hw:2,0'에 해당한다. '-f dat'는 스테레오 채널의 의미까지를 포함하고 있으므로, 모노 마이크 입력임을 감안하여 '-c 1' 옵션을 추가해야 된다.

$ arecord -f dat -c 1 -r 48000 --device="hw:2,0" -d 5 test.wav
녹음 WAVE 'test.wav' : Signed 16 bit Little Endian, 48000 Hz 비율, 모노
$ aplay test.wav

MIDI 파일의 재생(1): 외장 모듈의 이용

USB 케이블로 연결된 Sound Canvas SC-D70를 이용하여 MIDI 파일을 재생하는 방법을 알아보자. USB MIDI interface를 통하여 고전적인 사운드 모듈이 연결된 상황에서도 이와 비슷할 것이다. 원하는 MIDI output port를 알아낸 다음 aplaymidi 명령으로 MIDI 파일을 재생하면 된다.

$ aplaymidi -l # or --l (list all possible output ports)
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 20:0    SC-D70                           SC-D70 Part A
 20:1    SC-D70                           SC-D70 Part B
 20:2    SC-D70                           SC-D70 MIDI
 24:0    USB Keystation 88es              USB Keystation 88es MIDI 1
$ aplaymidi -p 20:2 cakewalk.mid # 또는 --port 20:2

MIDI 파일의 재생(2): 사운드 폰트의 이용(FluidSynth)

FluidSynth가 설치된 상태라면 사운드 폰트(.sf2 파일)를 이용하여 MIDI 파일을 직접 재생할 수 있다. FluidR3_GM.sf2는 용량이 142MB나 되는 매우 양질의 GM 사운드 폰트이다. 마스터 키보드를 연결해서 직접 실시간 연주를 할 수도 있다. Standalone mode로 FluidSynth를 실행해 보자. -a alsa[–audio-driver=alsa] 옵션을 지정하지 않으면 JACK이 기동한다. -i(--no-shell) 옵션을 주지 않으면 fluidsynth prompt에서 명령을 입력할 수 있고, 재생 후에도 prompt 상태가 된다.

$ fluidsynth --audio-driver=alsa /usr/share/sounds/sf2/FluidR3_GM.sf2 flourish.mid
> ...음악 재생...
> quit
cheers!
# JACK 사용. 그러나 설정이 완벽하게 되어 있어야 한다.
$ fluidsynth /usr/share/sounds/sf2/FluidR3_GM.sf2 flourish.mid

FluidSynth를 다른 스타일로 실행해 보자. -m alsa_seq[–midi-driver=alsa_seq]은 지정하지 않아도 된다.

$ fluidsynth -a alsa -m alsa_seq -l -i /usr/share/sounds/sf2/FluidR3_GM.sf2 passport.mid

FluidSynth를 서버로 작동시키면 다른 응용프로그램(예: aplaymidi)으로 하여금 MIDI 데이터를 FluidServer로 전송하게 만들 수 있다.

$ fluidsynth --server --audio-driver=alsa /usr/share/sounds/sf2/FluidR3_GM.sf2
$ aplaymidi -l
  Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 24:0    iCON iKeyboard 5 Nano V1.06      iCON iKeyboard 5 Nano V1.06 MID
128:0    FLUID Synth (5439)               Synth input port (5439:0)
$ aplaymidi -p 128:0 flourish.mid

FluidSynth의 몇가지 유용한 명령행 사례를 Example Command Lines to start fluidsynth 문서에서 확인해 보라.

키보드 콘트롤러를 연결하여 FluidSynth 연주하기

USB MIDI 키보드 콘트롤러를 연결한 다음 FluidSynth로 소리를 내어 보자. FluidSynth는 서버 모드(-s or --server)로 작동해도 되고, shell이 나타나도록('-i' 옵션을 주지 않음) 실행해도 된다. 후자의 경우라면 FluidSynth shell prompt에서 사운드 폰트 변경, 음색 변경 등 조절 작업을 할 수 있다. 키보드 콘트롤러로 MIDI soft synth를 제어하려면 MIDI IN과 OUT을 서로 연결해야 하므로 aconnect라는 유틸리티를 사용해야 한다.

$ aconnect -i
client 0: 'System' [type=커널]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=커널]
    0 'Midi Through Port-0'
client 24: 'iCON iKeyboard 5 Nano V1.06' [type=커널,card=2]
    0 'iCON iKeyboard 5 Nano V1.06 MID'
$ aconnect -o
client 14: 'Midi Through' [type=커널]
    0 'Midi Through Port-0'
client 24: 'iCON iKeyboard 5 Nano V1.06' [type=커널,card=2]
    0 'iCON iKeyboard 5 Nano V1.06 MID'
client 128: 'FLUID Synth (5439)' [type=사용자,pid=5439]
    0 'Synth input port (5439:0)'
$ aconnect 24:0 128:0  # 각 포트에 속한 디바이스가 하나뿐이므로 ':0'는 없어도 된다.

FluidSynth를 실행할 때 사운드 폰트를 여러 개 동시에 인수로 지정하면 shell prompt에서 선택할 수 있다. 각 채널에 할당된 프로그램을 확인하고 이를 바꾸어서 연주해 보자.

> fonts
ID  Name
 1  /usr/share/sounds/sf2/FluidR3_GM.sf2
> inst 1 # font ID를 입력한다. 프로그램 전체 목록을 보여준다(번호는 0부터 시작).
000-000 Yamaha Grand Piano
000-001 Bright Yamaha Grand
...
008-004 Detuned EP 1
008-005 Detuned EP 2
...
128-048 Orchestra Kit
> channels # 각 채널에 할당된 프로그램을 보여준다. 채널 번호는 01부터 시작한다.
chan 0, Yamaha Grand Piano
chan 1, Yamaha Grand Piano
...
chan 15, Yamaha Grand Piano
> prog 0 3 # 0번 채널의 프로그램을 3번('Honky Tonk')으로 바꾼다.
> channels
chan 0, Honky Tonk
...
> select 0 1 8 4 # 다른 뱅크에 속하는 프로그램으로 바꾼다(chan sfont bank prog)
> channels
chan 0, Detuned EP 1
...
chan 15, Yamaha Grand Piano

FluidSynth shell prompt에서 입력 가능한 명령어를 알고 싶다면 'help'를 입력하라.

FluidSynth 명령어에서 직접 키보드 연결하기

alsa-utils의 일부인 amidi를 사용하여 MIDI 키보드의 주소를 알아낸다.

$ amidi
Please specify at least one of --send, --receive, --send-hex, or --dump.
$ amidi -l
Dir Device    Name
IO  hw:1,0,0  iCON iKeyboard 5 Nano V1.06 MID

FluidSynth를 실행한다. '-s'는 서버 모드로 실행함을 뜻한다.

$ fluidsynth -s -a alsa -m alsa_raw -o midi.alsa.device=hw:1,0,0 ~/sf2/FluidR3_GM.sf2

FluidSynth with PulseAudio

MIDI Keyboard controller가 연결되어 있다면 특별한 설정을 더 하지 않아도 다음과 같이 최소한의 명령으로 연주를 할 수 있다. 참고 사이트는 여기이다. 이렇게 간단한 명령행으로 키보드를 통한 연주를 할 수 있으므로, 아래에 소개한 run_fluidsynth 스크립트는 무슨 소용인가 싶다.

$ fluidsynth -a pulseaudio -m alsa_seq -o midi.autoconnect=1 -g 1.0 /usr/share/sounds/sf2/FluidR3_GM.sf2

run_fluidsynth script

run_fluidsynth 스크립트는 ~/sf2에 보관 중인 여러 사운드폰트 파일의 목록 중에서 원하는 것을 골라서 FluidSynth를 실행하게 만드는 스크립트이다. 대부분의 사운드폰트 파일은 Soundfonts 4U에서 입수하였다. '-a' 또는 '-alsa' 옵션을 주면 ALSA를 통하여 작동하며, 지정하지 않은 경우 JACK sound server가 필요하다. 이 스크립트를 실행한 뒤 aconnect 명령을 이용하여 MIDI 콘트롤러 키보드를 연결하여 실시간 연주를 즐기도록 한다.

$ run_fluidsynth 
Run JACK server prior to running FluidiSynth!
$ run_fluidsynth -a

ALSA audio driver will be used (default: JACK)

Soundfonts installed in /home/hyjeong/sf2: 
[0]: FluidR3_GM.sf2 - 142M
[1]: Nice-Keys-Complete-JNv2.0.sf2 - 750M
[2]: Chateau_Grand-v1.8.sf2 - 259M
[3]: Nice-Keys-Ultimate-V2.3.sf2 - 1.2G
[4]: Essential_Pianos-bs16i-v1.0.sf2 - 668M

Select sf2 index number: 1
FluidSynth version 1.1.9
Copyright (C) 2000-2018 Peter Hanappe and others.
Distributed under the LGPL license.
SoundFont(R) is a registered trademark of E-mu Systems, Inc.

JACK을 활용하려면, run_fluidsynth 스트립트 구동 전에 다음 명령어를 실행한다. 디바이스명은 상황에 맞게 제공하여라. 이 명령어는 JACK을 구동하는 여러 방법 중에서 가장 단순한 편에 든다.

$ jackd -d alsa --device hw:Intel --rate 44100 --period 128

웹 서핑 중에 발견한 piano.sh라는 스크립트는 JACK 서버 구동을 위한 명령어를 내장하고 있다. 그런데 어제는 되고 오늘은 안 되는 일은 대관절 무슨 조화인가?

JACK, a low-latency audio server

드디어 JACK이 등장하였다. JACK은 음악 프로덕션 등 심각한(?) 수준의 음악 작업을 하려는 사람에게 매우 유용한 사운드 서버이다. 공식 명칭은 JACK Audio Connection Kit이다. 버전 번호가 1 미만인 것이 JACK1, 2 미만인 것이 JACK2이다. JACK2를 기동하려면 jackd 명령어를 이용하거나, 또는 뒤에서 소개한 D-Bus 기반의 jack_control 명령어를 이용하는 두 가지 방법이 있다. 일반적으로 후자가 더 나은 방법이라고는 하나, jackd 명령어를 쓰는 방법이 좀 더 이해하기 쉬운 것 같다. jack_control은 온라인 매뉴얼은커녕 '-h' 옵션을 줘 봐야 간단한 설명조차 나오지 않을 정도로 관련 문서가 부실한 것으로 잘 알려져 있다. 우선 설치된 jackd의 버전을 확인해 보자.

$ jackd --version
jackdmp version 1.9.12 tmpdir /dev/shm protocol 8

컴퓨터를 켠 직후라면 jackdbus manager인 autojack만이 백그라운드에 돌고 있을 것이다.

$ pgrep -l jack
1500 autojack

jackd와 jackdbus의 차이점은 이 문서를 참고하라. 다음은 jackd를 구동하는 아주 간단한 명령행 사례이다. JACK_PLAY_CONNECT_TO 환경변수는 jack-play 명령(jack-tools 패키지를 설치해야 함)을 쓸 때 이외에는 필요한 것 같지 않다. JACK 서버를 이런 방식으로 쓸 일은 사실 거의 없을 것이다.

$ jackd -d alsa --device hw:0 --rate 44100 --period 128
$ export JACK_PLAY_CONNECT_TO=system:playback_%d
$ jack-play test.wav

사운드카드가 지원하지 않는 높은 샘플링 레이트를 지정했다 하더라도 JACK은 지원 기능한 최상의 샘플링 레이트로 장치를 구동한다. jack_bufsize 명령을 다음과 같인 인수 없이 실행하면 현재의 buffer size를 출력한다.

# jackd가 구동 중인 상태여야 함.
$ jack_bufsize 
buffer size = 256  sample rate = 44100

JACK을 오디오 드라이버로 하여 FluidSynth를 구동하려면 다음의 명령을 입력한다.

$ fluidsynth --server --audio-driver=jack --connect-jack-outputs /usr/share/sounds/sf2/FluidR3_GM.sf2

그러고 나서 aplaymidi -p <port>를 이용하여 MIDI 파일을 재생할 수 있다. 포트 번호는 aplaymidi -l 명령으로 확인한다.

Ted's audio script

Ted's Linux MIDI Guide에서는 pasuspender를 이용하여 PulseAudio의 작동을 잠시 멈춘 다음 JACK 서버(jackd 명령어 사용)를 구동하고 FluidSynth를 로드하는 스크립트인 audio를 소개하였다(복사본).사용법은 다음과 같다.

$ audio start
$ audio stop

JACK이 실행된 다음에는 설정 변경을 위해 Qt GUI인 QjackCtl을 사용해도 좋다. 이 유틸리티는 JACK의 파라미터 변경뿐만이 아니라 패치베이 형태의 손쉬운 연결을 위한 인터페이스를 제공한다. 2005년 리눅스 저널에 나온 오래 된 글이지만 Dave Phillips의 At the Sounding Edge: Using QSynth and QJackCtl을 한 번 읽어 볼 것을 권한다.

정해영의 audio.qsynth script

Ted의 original audio 스크립트에서는 사운드 카드에 대한 파라미터로 '--device hw:0'를 제공하므로 내장 오디오 장치를 그대로 쓰게 해 놓았다. 이를 CODEC이나 SCD70처럼 현재 USB 포트에 연결된 장치로 바꿀 수 있어야 할 것이다. 또한 Qsynth가 항상 필요한 것이 아니니 스크립트 실행 단계에서 선택할 수 있게 만드는 것이 좋을 것 같다. 이러한 점을 반영하여 새로운 스크립트인 audio.qsynth를 만들어 보았다. Ted의 원본 audio와 나의 audio.qsynth 스크립트는 audio 관련 스크립트 모음을 참조하라. audio.qsynth의 사용법은 다음과 같다. 'Press Esc key within 3 seconds to skip Qsynth:' 메시지가 나온 뒤 3초 내에 ESC 키를 누르면 Qsynth 실행을 건너뛴다.

$ audio.qsynth start CODEC
Audio device CODEC found!
Starting JACK using CODEC...
Press Esc key within 3 seconds to skip Qsynth:
Starting Qsynth...
5692 jackd
5688 audio.qsynth
5699 qsynth
Audio servers running.
You may start qjackctl and PulseAudioJackSink (post_jack).
Please run a2jmidid -e if you have hardware MIDI devices connected.
You may use a2j -e instead.

$ audio.qsynth stop
5699 qsynth
5715 audio.qsynth
Audio servers stopped.

PulseAudio JACK Sink란?

Firefox에서 유튜브 동영상을 재생하면서 audio.qsynth 스크립트를 실행해 보라. 재생이 멈추고 더 이상 Firefox application의 소리가 나지 않을 것이다. 이는 PulseAudio가 관리하던 오디오 신호를 JACK이 전부 가져가 버렸기 때문이다. audio 스크립트 앞부분의 'pasuspender' 명령이 바로 그 역할을 한 것이다. JACK을 실행하면서도 다른 application의 소리를 잘 활용(재생 또는 녹음)하고 싶다면, PulseAudio의 출력을 JACK으로 보내도록 만들면 된다. 이것이 바로 PulseAudio Jack Sink라는 기능이다. 이를 위해서는 다음의 post_jack 스크립트를 [qjackctl GUI] JACK Setup → Options → Scripting에서 Execute script on Shutdown에 지정하여 JACK 서버에 이어서 실행되게 만든다. 혹은 다음에 보인 심플한 post_jack 스크립트를 직접 명령행에서 입력해도 된다. 이를 실행하면 PulseAudio의 출력이 JACK으로 들어가게 된다. 이를 가능하게 하려면 pulseaudio-module-jack 패키지가 설치되어 있어야 한다(Ubuntu Focal Fossa(20.04 LTS)의 pulseaudio-module-jack 패키지 내용물).

$ cat ~/bin/post_jack
pactl load-module module-jack-sink channels=2
pactl load-module module-jack-source channels=2
pacmd set-default-sink jack_out

모듈이 로드되었는지의 여부는 'pactl list modules' 명령으로 확인할 수 있다. JACK 서버 실행 전에는 modules-jackdbus-detect만 보일 것이다.

$ pactl list modules # 약 30개 모듈의 상세한 목록을 출력
# JACK을 실행하고 있는 도중에 확인하기
$ pactl list modules | grep jack
	이름: module-jackdbus-detect
	이름: module-jack-sink
	이름: module-jack-source

PulseAudio Volume Control의 출력 장치 탭에서는 다음과 같이 나타날 것이다. 뒤에서 설명할 jack_control을 사용하면 post_jack 스트립트를 사용하지 않아도 sink의 전환이 저절로 일어나는 것 같다.

어찌보면 PulseAudio와 JACK은 ALSA 드라이버를 놓고 서로 경쟁하는 것처럼 보인다. 일반적인 consumer 수준이라면 JACK을 전혀 쓰지 않고 음악 감상 등을 충분히 즐길 수 있다. 그러나 music producer 수준의 작업을 하려면 JACK을 전혀 쓰지 않을 수는 없는 노릇이다. PulseAudio와 JACK이 같이 설치된 시스템을 평화롭게 운용하려면 JACK 공식 문서 사이트의 How use PulseAudio and JACK?을 꼼꼼히 읽어보기 바란다.

JACK basic setting 이해하기

레이턴시란 실시간 오디오 프로세싱에서 일어나는 시간 지연을 뜻한다. 건반으로 가상악기를 연주하면서 실시간 녹음을 하는데 실제 입력보다 소리가 늦게 들리면 상당히 짜증이 난다. 설정을 잘 조정해야 레이턴시도 적고 잡음도 줄어든다. Buffer size, sample rate, 그리고 period/buffer를 컴퓨터 환경에 맞도록 최적화하는 것이 중요하다.

Buffer size(frames per period라고도 부름)

Buffer size란 컴퓨터가 오디오 신호를 처리할 때 허용되는 시간의 길이이다(시간을 실제 단위로 하지는 않는다). 작은 값일수록 monitoring latency가 줄어든다. 그러나 낮게 잡으면 CPU를 많이 쓰게 되고 'glitchy audio' 혹은 'drop-out'을 유발한다. 보통 64-256 사이의 값을 쓰게 될 것이다. 'jackd [-p|--period] ###' 또는 'jack_control dps period ###'로 설정한다. Default 값은 1024이다.

Sample rate

다음과 같은 단순 공식(Nyquist theorem)에 따르면 높을수록 좋다.

Sample rate ÷ 2 = maximum frequency that can be correctly captured

44.1kHz는 CD 수준의 음질이다. 48kHz를 쓰려면 오디오 장비가 이를 지원하는지 확인해 보라. 지나치게 높으면 CPU 사용량이 높아지고, xrun(pops and clicks)을 초래할 것이다.

Periods/buffer(=nperiod)

USB 장비는 3으로 하면 더욱 안정적인 low latency를 얻을 것이다. 그 밖의 장비(motherboard, PCI, PCI-X 등)는 default 값인 2를 써라. 'jackd [-n|--nperiod] ###' 또는 'jack_control dps nperiod ###'로 설정한다.

Frames/Period 256 & Periods/Buffer: 2 results in 23.2 msec latency which is pretty good for a usb 2.0 sound board.

jakcd 명령어 매뉴얼을 그대로 소개한다.

a2midid (JACK MIDI daemon for ALSA MIDI)

ARDOUR의 매뉴얼의 JACK MIDI Configuration 문서에 의하면, JACK은 기본적으로 MIDI 포트를 검출하지 못하므로 native MIDI frameworks와 (e.g. CoreMIDI or ALSA) and JACK MIDI를 연결할 방편을 마련해야 한다고 한다. 그 방법은 현재 사용하는 JACK의 버전에 따라 달라진다고 한다. Arch Linux 웹사이트의 JACK Audio Connection Kit - MIDI 항목(대단히 중요한 설명이 많으니 잘 읽어보기 바람)에 의하면 jack2의 경우 a2jmidid를 쓰는게 필수적이라고 한다.

$ a2jmidid -e # 'a2midid --export-hw' 명령과 같다.

jack_control을 이용한 JACK 구동

위키백과에 의하면 D-Bus(desktop bus)란 '같은 머신에서 동시에 실행 중인 여러 컴퓨터 프로그램(즉, 프로세스) 간의 통신을 가능케 하는 소프트웨어 버스, 프로세스 간 통신 (IPC), 원격 프로시저 호출 (RPC) 매커니즘'이라고 한다. JACK2는 D-Bus를 통한 구동이 가능하다. 이에 대한 좋은 문서 자료는 Arch Linux의 JACK Audio Connection Kit 항목의 Basic Configuration에 나온다. 여기서 소개하는 start_jack.sh 스크립트가 매우 유용하다. 나는 이것을 살짝 변형한 스크립트 start_jack_uca200을 만들어 보았다. 원본 스크립트에서는 qjackctl 실행으로 끝을 맺지만, 나의 수정 스크립트에서는 마지막 부분에서 PulseAudio Volume Control을 자동으로 실행하게 하였다. 'jack_control dps device hw:CODEC' 라인만 적절히 수정하면 어떤 USB 사운드 카드라도 구동할 수 있다. audio.qsynth를 응용하여 만든 범용 스크립트 start_jack_generic에서는 사운드 카드 이름을 명령행 인자로 공급할 수 있다. 아래의 사례에서 DBus exception 에러에 대처하는 방법을 잘 보아두기 바란다. JACK을 이용한 작업이 끝났다면 'jack_control stop' 명령어를 실행하여 깨끗하게 종료하는 것을 권장한다.

$ start_jack_uca200 
--- start
DBus exception: org.jackaudio.Error.Generic: Failed to open server
# 이러한 에러가 발생하면 다음 설정 파일을 지우고 jackdbus를 죽인 뒤 재실행한다.
$ rm ~/.jackdrc ~/.config/jack/conf.xml ~/.config/rncbc.org/QjackCtl.conf
$ killall -9 jackdbus
$ start_jack_uca200 
--- start
--- driver select "alsa"
--- driver param set "device" -> "hw:CODEC"
--- driver param set "rate" -> "48000"
--- driver param set "nperiods" -> "3"
--- driver param set "period" -> "128"
$ jack_control stop
--- stop
# QjackCtl은 GUI에서 직접 종료하거나 명령행에서 'killall -9 qjackctl'을 실행한다.
$ jack_control exit # 'jackdbus' process까지 완전히 없앤다.
--- exit

스크립트 시작 부분의 'echo “suspend 1” | pacmd'은 코멘트 아웃 처리를 해도 작동에 영향을 미치지 않는 것 같다.

Qsynth(JACK) 사용하기

Qsynth는 Qt GUI를 입힌 FluidSynth이다. ALSA를 쓸 수도 있지만 기본 sound driver는 JACK이므로 이 섹션에서 설명하고자 한다. 직전의 Qsynth 실행에서 변경한 설정 사항은 ~/.config/rncbc.org/Qsynth.conf에 기록되며, 명령행 옵션으로 지정되지 않은 것은 설정 파일의 것을 불러온다. 설정 파일은 실행 때마다 매번 새롭게 기록되므로 일반적인 상황에서는 편집할 필요가 없다.

$ grep Driver ~/.config/rncbc.org/Qsynth.conf
AudioDriver=jack
MidiDriver=alsa_seq

만약 설정 파일에 AudioDriver=jack라 기록되어 있고 명령행에서 '-a jack'a jack(또는 '--audio-driver=jack') 파라미터를 제공하지 않았다면 Qsynth 실행시 자동으로 JACK 데몬이 실행되고 종료와 더불어 끝난다. 이때에는 $HOME/.jackdrc 또는 /etc/jackdrc 설정 파일의 첫 줄에 따라서 JACK이 실행된다. 여기에서 약간의 모순을 발견할 수 있다. 왜냐하면 $HOME/.jackdrc 파일은 jack_control 명령을 이용할 때 에러를 유발할 수 있기 때문이다. 백업 파일을 만들어 두고 적절히 처신하는 수밖에 없다. 다음은 ALSA audio driver를 사용하는 사례이다.

$ qsynth -m alsa_seq -a alsa
# GUI 설정 창에서 사운드폰트를 로드했는지 확인한다.
$ aplaymidi -p 128:0 song.mid

물론 aplaymidi를 쓰지 않고 Qsynth의 인수로 MIDI 파일을 직접 제공하여 재생하는 것도 가능하다.

$ qsynth -m alsa_seq flourish.mid

가상 키보드인 vmpk를 실행하고 Edit→Connection→Output MIDI Connection을 FLUID Synth로 설정한 다음 키보드를 클릭하여 소리를 들어 본다. vmpk는 명령행에서 실행하거나 또는 패널의 프로그램→Audio Production→MIDI Utilities에서 선택해도 된다.

$ vmpk

이번에는 Yamaha DX7 modeling software synthesizer인 Hexter를 실행해 본다. 이것은 Qsynth처럼 명령행에서 실행할 수 있는 것이 아니며, 패널의 프로그램→Audio Production→Instruments에서 선택하여 실행해야 한다. Hexter는 JACK을 통하여 구동된다. Hexter를 실행했다 하여도 VMPK에서 연결가능한 MIDI 출력쪽에 보이지 않을 것이다. 이제 명령행에서 aconnect(ALSA sequencer connection manager)를 사용하여 키보드와 악기를 원하는대로 연결할 수 있다.

$ aconnect -x # 기존의 연결을 끊는다.
$ aconnect -i
client 0: 'System' [type=커널]
    0 'Timer           '
    1 'Announce        '
client 14: 'Midi Through' [type=커널]
    0 'Midi Through Port-0'
client 129: 'VMPK Output' [type=사용자,pid=2789]
    0 'VMPK Output     '
$ aconnect -o
client 14: 'Midi Through' [type=커널]
    0 'Midi Through Port-0'(
client 130: 'VMPK Input' [type=사용자,pid=2789]
    0 'VMPK Input      '
client 131: 'FLUID Synth (2554)' [type=사용자,pid=2554]
    0 'Synth input port (2554:0)'
client 132: 'hexter DX7 emulation (v1.0.2)' [type=사용자,pid=2607]
    0 'hexter DX7 emulation (v1.0.2)'
$ aconnect 129:0 132:0 #원하는 MIDI sender(키보드)와 receiver(악기)를 연결한다.

만약 컴퓨터에 하드웨어 키보드를 연결하였다면 aconnect -i 명령을 실행했을 때 나타날 것이다. 그러면 aconnect 명령으로 원하는 악기와 연결하여 연주하면 된다. 만약 이 과정이 번거롭게 느껴진다면, 그것은 JACK을 사용할 때가 되었다는 것이다.

설치된 모든 software synthesizer가 Hexter처럼 단독 실행이 가능한 것은 아니다. JACK이 없으면 안되는 것도 있다.

명령행 인터페이스에서 녹음하는 요령

녹음 작업의 신호원은 기본적으로 마이크로폰이다. 컴퓨터에서 실행되는 응용프로그램의 재생음을 녹음하려면 약간의 설정 변경이 필요하다. PulseAudio와 달리 JACK은 하나의 사운드 카드만에 대해서 작동하므로, JACK을 구동한 환경에서 USB 마이크로폰으로 입력한 음성 신호를 녹음하려면 이 역시 간단하게 되지는 않는다.

다음에 소개한 링크에서는 CLI 명령어인 arecord를 사용하여 녹음하는 방법을 알아보자. 녹음시 마이크로 입력되는 소리를 직접 모니터링하려면 어떻게 할까? 여러 입력을 동시에 녹음하려면 어떻게 할까? PulseAudio의 loopback을 이용하는 요령과 parecpulse-record.bash 스크립트를 사용하는 방법도 다음의 글을 통해서 알아보도록 한다.

다른 응용프로그램을 사용하여 녹음하기

기타 정보

Music on Linux 네임스페이스 내의 모든 문서

기타 문서

music_on_linux.txt · Last modified: 2023/09/18 06:30 by hyjeong