Table of Contents
명령행 인터페이스에서 녹음하는 요령
- 이 위키 페이지에 대한 short URL: https://bit.ly/3f3UsTl
- 유튜브에 올린 설명 동영상: https://youtu.be/RGMNEaGYytw
요즘 누가 리눅스, 그것도 명령행 인터페이스(CLI)에서 녹음을 하느냐고? 바로 내가 한다. 사용할 사운드 카드는 무엇인가? 소스는 무엇인가? 소스를 동시에 여러 개 쓸 것인가? 이러한 것을 미리 파악해 두도록 한다. 내가 갖고 있는 USB 오디오 인터페이스(사운드 카드) 중 유일하게 복합 기능 - 여러 인풋을 입력하여 원하는 것을 녹음용으로 선별할 수 있으며 본체에서 직접 모니터링이 가능 - 을 갖는 사운드캔버스 SC-D70을 쓰면 아래에서 설명한 상황에서 보다 간편한 대처가 가능하다. 물론 SC-D70은 출시된지 20년이 넘은 제품이라서 MIDI 음원이 내장되어 있다는 점만 제외하면 요즘 나오는 웬만한 오디오 인터페이스보다 나을 것이 없다. 그럼에도 불구하고 단순한 오디오 기기를 써서 이렇게 복잡하게 작업을 하는 것은 그만큼 배울 것이 많기 때문이다.
펄스오디오(PulseAudio) 사운드 서버를 잘 알면 세상이 정말 편해진다. 모든 것은 PulseAudio에서 시작해서 PulseAudio로 끝난다고 해도 과언이 아니다. 컴퓨터를 켠 다음에는 일단 PulseAudio Volume Control(명령행: pavucontrol)을 실행힌 뒤 '설정' 탭으로 가서 각 사운드 관련 기기의 프로필이 제대로 선택되었는지를 확인한다. 예를 들어 USB 마이크로 입력을 하면서 재생음은 컴퓨터 본체 사운드 카드의 출력을 통해 듣고 싶을 때도 있을 것이다. 이럴 때에는 어떻게 프로필을 설정하는 것이 옳겠는가? 이 글의 제목은 '명령행 인터페이스'를 말하고 있지만, PulseAudio Volume Control을 위해서는 GUI를 쓰지 않을 수가 없다.
녹음용 유틸리티는 ALSA가 제공하는 arecord를 쓰는 것으로 가정한다. 녹음이 진행되는 상태를 시작적으로 보면서 즐기고 싶다면 GUI 프로그램인 Audacity만한 것이 없다. PulseAudio의 유틸리티 parec을 사용한 녹음 방법은 별도의 위키 페이지 PulseAudio 설정 및 활용에서 따로 다루었다. 다음에 보인 명령어 사례에서 '-f cd' 파라미터는 '-f S16_LE -c2 -r44100'를 뜻한다. 다음이 format shortcut은 기억해둘 만하다.
- -f cd (16 bit little endian, 44100, stereo) [-f S16_LE -c2 -r44100]
- -f cdr (16 bit big endian, 44100, stereo) [-f S16_BE -c2 -f44100]
- -f dat (16 bit little endian, 48000, stereo) [-f S16_LE -c2 -r48000]
사용할 디바이스는 '-D NAME(select PCM by name)'으로 지정한다1). '-d 60'은 60초, 즉 1분 동안 녹음을 함을 의미한다. 정해진 시간보다 일찍 녹음을 끝내려면 도중에 Ctrl+C를 입력한다. 다이나믹 마이크를 믹싱 콘솔(예: Behringer Xenyx 802)에 연결하여 녹음하려면 레벨을 잘 맞추는 것이 중요하다. 믹싱콘솔의 입력 레벨 셋업(게인 조정)을 참조하도록 한다.
# 헤드셋을 연결하고 마이크로 녹음을 하는 것이 가장 간단할 것이다. $ arecord -f cd -d 60 one-minute-recording.wav $ aplay one-minute-recording.wav # mp3로 녹음하려면 lame을 거친다. $ arecord -v -f cd -t raw | lame -r -b 192 - output.mp3
SoX(play)로 MP3 파일을 포함한 모든 포맷의 오디오 파일을 재생하려면 libsox-fmt-all 패키지를 추가로 설치해야 한다. MP3 파일만 재생하려면 libsox-fmt-mp3를 설치해야 한다. aplay로는 MP3 파일 재생이 불가능하다.
$ sudo apt install libsox-fmt-mp3 $ play music.mp3
play 명령 외에도 명령행 인터페이스에서 MP3 파일을 재생하는 방법은 mpg123 등 꽤 다양하다. How to play MP3 by command line in Linux distros (tutorial)을 방문해 보라.
기본 개념 다지기
수시로 Victor Gaydov의 PulseAudio under the hood 웹문서에서 기본 개념을 탐독하기 바란다.
소스는 녹음을 위한 것이고 싱크는 재생을 위한 것이다. 소스 아웃풋은 recording stream, 싱크 인풋은 playback system이다. 따라서 특별히 손을 대지 않는다면 녹음을 할 때 마이크 입력은 스피커에서 들리지 않고, 유튜브 재생음은 녹음이 되지 않는 것이다. 소스와 싱크를 직접 연결하려면 루프백(loopback) 기능이 필요하다. 단, 모든 싱크는 자동적으로 monitor source를 갖는다(PulseAudio FAQ - How do I record other programs' output?. Monitor source는 sink로 들어오는 모든 소리에 대한 복제가 아니라, playback을 출발하여 sink로 들어오는 소리의 복제본이다. 이를 녹음하려면 루프백을 쓰지 않고 PulseAudio Volume Control의 Recording 탭에서 설정을 고치는 것만으로 된다.
Gaydov의 그림을 고쳐서 그려 보았다. 이를 정해영의 source-sink diagram이라 부르겠다. 소스와 싱크를 연결하려면 module-loopback을 로드해야 한다(명령행에서 'pactl load-module module-loopback <파라미터>' 실행). 아래의 그림에서는 루프백 연결이 표현되지 않았다.
단일 소스의 녹음
단일 애플리케이션의 재생음
강조하지만 근본적으로 녹음이란 마이크로폰으로 들어오는 소리를 기록하는 것이다. 따라서 컴퓨터의 애플리케이션이 재생하는 소리를 녹음하려면 약간의 수고를 해야 된다. 윈도우 계열에서는 이를 흔히 스테레오 믹스라 부른다. 윈도우 쪽에서는 스테레오 믹스가 되지 않는 것이 기본 설정이고, 사운드 카드에 따라서는 아예 되지 않는 제품도 있다. 이는 저작권이 있는 음원을 일반 컴퓨터 사용자가 기록하여 문제가 되는 것을 방지하는 차원에서 운영체계 또는 하드웨어 제작사가 어쩔 수 없이 택한 현실인 것 같다. 리눅스에서는 컴퓨터의 재생음을 녹음하는게 그렇게 어렵지 않다.
웹브라우저에서 유튜브를 재생하면서 나오는 소리를 녹음하고 싶다면? 아마 가장 흔하게 벌어지는 일일 것이다. VLC Media Player에서 유튜브의 스트리밍 비디오를 MP4(오디오만 MP3로 저장하는 것도 가능)로 저장한 뒤, 적절한 프로그램을 써서 MP3로 전환하면 된다. 그러나 CLI를 이용한 녹음은 단순하고 직관적이다! 재생용 애플리케이션과 arecord가 실행되는 동안 PulseAudio Volume Control에서 다음을 제대로 설정하면 된다.
- Playback 탭: Application name: AudioStream on XYZ(사용하는 디바이스 이름). 여기에서는 고를 수 있는 것은 없다.
- Recording 탭: ALSA plug-in [aplay]: ALSA Capture from 'Monitor of XYZ'를 선택한다. 이 행위는 아래 그림에서 빨간색 화살표를 연결하는 것에 해당한다(이는 루프백이 아니다!). 실제로 녹음이 시작되어야 'ALSA plug-in…'이 나타난다. Audacity를 쓰고 있다면, 녹음 버튼을 클릭하고 나서야 보인다는 뜻이다.
- Configuration을 제외한 모든 탭에서 해당 디바이스 혹은 애플리케이션에 대하여 'Mute audio' 버튼이 눌리지 않았는지 확인하라.
아날로그 입력을 녹음과 동시에 모니터링
U-Control UCA202처럼 모니터링용 헤드폰 단자가 있는 오디오 인터페이스를 쓴다면 이런 고생을 할 일은 없을 것이다!
PulseAudio의 module-loopback을 사용하면 입력 장치로 들어오는 외부의 소리(컴퓨터 내부의 애플리케이션에서 나는 소리를 뜻하는 것이 아님)를 default sink로 보내어 모니터링을 할 수 있다. 모니터링용 출력 단자가 없는 오디오 인터페이스인 UCA200을 사용하는 상황에 대해서 생각해 보자. 입력되는 신호를 녹음 중에는 들을 수 없다. 해결 방법은 입력 신호가 UCA200의 아날로그 출력으로도 나가게 만들고, 이를 외부 스피커에 연결하면 된다. 조금 더 공부하면 이를 컴퓨터의 내장 사운드카드로 보내고, 컴퓨터의 헤드폰 단자를 이용하여 듣게 만드는 방법도 알 수 있을 것이다. 이는 바로 다음에 소개하는 '모니터 출력을 내장 사운드 카드로 보내려면' 항목을 참조하라. pacmd list-sources/list-sinks는 PulseAudio Volume Control의 설정 변경 사항을 즉시 반영한다.
# UCA200의 아날로그 입력이 어떤 이름인지 알아보자. 인덱스 2번에 해당한다('*'표시는 default를 의미). $ pacmd list-sources | grep -e 'name:' -e 'index:' index: 0 name: <alsa_output.pci-0000_00_1b.0.analog-stereo.monitor> index: 1 name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.monitor> * index: 2 name: <alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo> $ pactl load-module module-loopback source=alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo 28 # 모듈 변호를 알면 나중에 해제하기 편리하다.
PulseAudio Volume Control을 실행하여 Recording 탭을 열면 'Loopback to PCM2902 Audio Codec 아날로그 스테레오 from'에 'PCM2902 Audio Codec 아날로그 스테레오'가 연결되어 있을 것이다. 위의 사례에서 인덱스 1번은 loopback하면 소용이 없다. 비록 “…monitor'라는 이름이 붙어있다고 해도 말이다. 인덱스 1번은 UCA-200으로 들어오는 아날로그 입력에 대한 모니터가 아니라, UCA-200을 통해 재생되는 클라이언트의 모니터를 말한다.
모듈을 해제하려면 다음을 입력한다.
# 로드된 모듈을 확인한다. $ pacmd list-modules | grep -e 'index:' -e 'name:' -e 'argument:' $ pactl unload-module 28
모니터 출력을 내장 사운드 카드(not default sink)로 보내려면
UCA-200의 아날로그 출력을 오디오 앰프에 연결하기 여러운 경우 여기에 RCA to 3.5 mm stereo female 젠더를 써서 헤드폰을 연결하기도 하는데 음량이 아무래도 부족하다. 모니터 출력을 내장 사운드 카드로 보내게 되면 컴퓨터 본체의 헤드폰 단자를 쓰면서 볼륨 조절이 가능하므로 조금 더 큰 음량으로 모니터링을 할 수 있다. 이는 내장 audio를 sink로 설정하면 간단히 해결된다.
# source의 확인. 결과는 위에서 보인 것과 같다. $ pacmd list-sources | grep -e 'name:' -e 'index:' # sink를 확인한다. $ pacmd list-sinks | grep -e 'name:' -e 'index:' index: 0 name: <alsa_output.pci-0000_00_1b.0.analog-stereo> * index: 1 name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo> # default sink(UCA-200)가 아닌 내장 사운드 카드로 루프백한다. $ pactl load-module module-loopback sink=alsa_output.pci-0000_00_1b.0.analog-stereo 26
아날로그 입력을 녹음과 동시에 듣기. 마이크로 들어 오는 소리도 같은 방법으로 들을 수 있다. 단, pactl load-module을 실행할 때 latency_msec=5 정도를 주어야 레이턴시가 느껴지지 않는다.
마이크 입력을 녹음과 동시에 모니터링
설정을 전혀 건드리지 않아도 마이크 입력을 녹음하는 데에는 지장이 없다. 그러나 녹음 중에 마이크로 입력되는 소리를 직접 듣고 싶다면 루프백 기능을 쓰면 된다. Sink-source diagram 상에서는 바로 위의 사례와 근본적으로 같다. 단, 스피커에서 나오는 소리가 마이크로 다시 들어가면 매우 듣기 거북한 피드백이 발생할 수 있으므로 헤드폰을 쓰는 것이 좋다. module-loopback을 로드할 때 'latency_msec=5' 정도로 지정해야 헤드폰으로 듣는 소리에 지연이 없을 것이다. 기본은 200 msec이므로 그대로 실행한다면 레이턴시를 느낄 수 있다. 아래 방법에서는 default sink로 모니터 출력이 나간다. 내장 사운드 카드(헤드폰 연결)로 보낼 수도 있고, MXL Tempo 마이크의 헤드폰 단자로 보낼 수도 있다.
$ pacmd list-sources | grep -e 'name:' -e 'index:' index: 0 name: <alsa_output.pci-0000_00_1b.0.analog-stereo.monitor> index: 1 name: <alsa_output.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-stereo.monitor> * index: 2 name: <alsa_input.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-mono> $ pactl load-module module-loopback source=alsa_input.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-mono latency_msec=5
이 상태로 마이크 녹음 중에 유튜브를 재생한다면?
마이크 입력과 애플리케이션의 동시 녹음이라는 점에서 아래에 보인 D-MA와 결과적으로 같은 상황이 된다. 아래에 보인 PulseAudio Volume Control의 Recording 탭에서 두 번째에 나타난 설정대로 하면 유튜브의 재생음이 같이 녹음될 것이다.
.
듀얼 소스의 동시 녹음
[D-MA] 마이크 + 애플리케이션
유튜브에서 재생되는 음악에 맞추어 마이크 입력을 동시에 녹음하고 싶다. 상세한 방법은 나의 구글 블로그에 올렸던 글을 링크하는 것으로 대신한다.
[우분투의 사운드와 MIDI] PulseAudio 루프백(loopback)의 활용
마이크 + 애플리케이션의 동시 녹음이라는 측면에서는 바로 위에 소개한 것과 결과적으로 같다(실제 녹음을 하여 확인하였음). 그런데 구현 방법은 아주 약간 다르다. 기본 소스(마이크)가 기본 싱크로 연결되도록 한다는 기본 골자는 동일하다. 첫 번째 방법, 즉 위에서 소개한 방법은 소스를 지정하여 기본 싱크로 연결하는 것이고, 두 번째 방법(구글 블로그)은 기본 소스를 지정된 싱크로 보내는 것이다. 'latency_msec=5'는 공통으로 적용되므로 생략하였다.
- pactl load-module module-loopback source=alsa_input.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-mono
- pactl load-module module-loopback sink=alsa_output.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-stereo
이 소스와 싱크는 module-loopback을 적용하지 못하면 서로 만나지 못하는 기구한 운명인 것이다!
Virtual sink를 쓰지 않아도 모니터링을 포함한 마이크+애플리케이션의 동시 녹음은 잘 된다
애플리케이션 1 + 애플리케이션 2(녹음은 뒤의 것만)
메트로놈 앱에서 나오는 소리를 들으면서 키보드 콘트롤러로 FluidSynth를 연주한다. 너무나 당연한 이야기지만 메트로놈 소리는 제외하고 FluidSynth의 소리만 녹음을 하고 싶다. 이러한 상황에서는 탁월한 스크립트인 pulse-recorder.bash를 사용한다. 이 스크립트의 사용법 및 내부에서 돌아가는 명령어인 parec에 대해서는 parec으로_애플리케이션_출력을_녹음하기를 참조하라.
Virtual sink를 이용한 멋진 해결책 소개
guvcview로 웹캠을 이용한 녹화를 하면서 USB 마이크 입력과 컴퓨터에서 재생되는 소리를 한꺼번에 녹음하는 방법을 궁리해 보았다. Virtual sink가 여기에서 대단한 위력을 발휘한다! 입력하려는 디바이스 혹은 애플리케이션이 몇 개이든 상관이 없다(내가 이해한 것이 맞다면). 마이크와 애플리케이션이라는 두 가지를 가상의 sink에 연결하는 것이므로 module-loopback 명령을 두 번 실행해야 한다.
$ pactl load-module module-null-sink sink_name=input # 한 번만 실행해라! $ pactl load-module module-loopback sink=input $ pactl load-module module-loopback sink=input
PulseAudio Volume Control의 Recording 탭에서는 다음과 같이 설정한다. 'Loopback to 빈 출력'에 두 가지의 인풋을 각각 연결하고, 녹음을 위한 애플리케이션에서는 'Monitor of 빈 출력'을 연결하면 된다. 마이크 입력을 녹음할 때에 실시간으로 들으려면 어떻게 해야 하는지 이미 잘 알 것이다. Null sink와 loopback을 잘 이용하면 복수의 소스와 애플리케이션 재생음 중 원하는 것만을 거두어서 녹음을 하거나 다른 애플리케이션으로 보낼 수 있다.
JACK을 사용하여 녹음을 한다면
적어놓고 보니 제목이 적절하지 않다. JACK 자체는 녹음용 유틸리티가 아니다. 이 서브섹션에서 설명하려는 것은, PulseAudio가 아니라 JACK을 오디오 드라이버이자 신호 연결 도구로서 사용하는 것이다. 특히 DAW 프로그램을 다루는 것처럼 여러 장비(물리적 장비 또는 가상)를 오고가는 신호를 원하는대로 연결하려면 JACK이 필수적이라 해도 과언이 아니다.
단일 오디오 스트림에 대한 녹음에서도 CLI 명령어인 arecord를 쓰는 것보다는 GUI를 갖춘 Audacity를 녹음용 유틸리티로 택하는 것이 보다 정교하고도 '프로페셔널한 작업'을 하기에 적합하다. Audacity는 acrecord로 기록한 오디오 파일의 후처리에도 꼭 필요한 도구이다. Audacity를 사용한 녹음에 관해서는 별도의 페이지에서 다룬다.
복수의 오디오 디바이스를 서로 연결하려면 alsa_in/alsa_out 유틸리티가 편리하다. 역시 상세한 방법은 나의 구글 블로그에 올렸던 글을 링크하는 것으로 대신한다.
명령행 환경에서 jack_capture 유틸리티를 이용한 녹음
JACK을 적극적으로 쓰기 시작한 것은 우분투 스튜디오 20.04로 업그레이드를 한 다음의 일이다. 따라서 이에 대한 설명은 우분투 스튜디오 20.04 LTS는 얼마나 다른가?의 별도 섹션에서 다루기로 한다.