User Tools

Site Tools


blog:우분투_명령행_인터페이스_cli_에서_녹음하기

우분투 명령행 인터페이스(CLI)에서 녹음하기

이전부터 작성하던 글인 우분투(스튜디오) 18.04에서 음악과 MIDI 작업을 위한 설정이 너무 길고 복잡해져서 아예 위키사이트 윗단계에 새로운 기분으로 글을 쓰기로 한다. 여기에서 총정리를 한다고 생각하자. 새 글이 올라오면 뒤로 밀리겠지만… 기본 개념을 다지기 위해 자주 방문하는 사이트를 먼저 나열해 본다. 펄스오디오(PulseAudio) 사운드 서버를 잘 알면 세상이 정말 편해진다. 모든 것은 PulseAudio에서 시작해서 PulseAudio로 끝난다고 해도 과언이 아니다.

요즘 누가 CLI에서 녹음을 하느냐고? 바로 내가 한다. 사용할 사운드 카드는 무엇인가? 소스는 무엇인가? 소스를 동시에 여러 개 쓸 것인가? 이러한 것을 미리 파악해 두도록 한다. 내가 갖고 있는 USB 오디오 인터페이스(사운드 카드) 중 유일하게 복합 기능 - 여러 인풋을 입력하여 원하는 것을 녹음용으로 선별할 수 있으며 본체에서 직접 모니터링이 가능 - 을 갖는 사운드캔버스 SC-D70을 쓰면 아래에서 설명한 상황에서 보다 간편한 대처가 가능하다. 물론 SC-D70은 출시된지 20년이 넘은 제품이라서 MIDI 음원이 내장되어 있다는 점만 제외하면 요즘 나오는 웬만한 오디오 인터페이스보다 나을 것이 없다. 그럼에도 불구하고 단순한 오디오 기기를 써서 이렇게 복잡하게 작업을 하는 것은 그만큼 배울 것이 많기 때문이다. 이 글을 작성하기 위하여 사용한 장비는 다음과 같다.

  • Behringer U-Control UCA200: 이미 단종되어 Behringer 홈페이지에는 상세한 정보가 없다. 외관 매뉴얼 PDF
  • (HP 프리자리오 CQ61 노트북 + 컴퓨터 내장 사운드 카드)

녹음용 유틸리티는 arecord를 쓰는 것으로 가정한다. '-f cd'는 '-f S16_LE -c2 -r44100'를 뜻한다. 사용할 디바이스는 '-D NAME(select PCM by name)'으로 지정한다('aplay -L'로 확인 가능).

$ arecord -f cd -d 300 five-minutes-recording.wav
# mp3로 녹음하려면 lame을 거친다.
$ arecord -v -f cd -t raw | lame -r -b 192 - output.mp3

MP3 파일을 재생하는 명령어는 꽤 다양하다. How to play MP3 by command line in Linux distros (tutorial)을 방문해 보라. aplay로 mp3 파일이 재생되는 것이 맞는 것인지? 아리송하다.

수시로 PulseAudio의 디바이스와 스트림에 관한 Victor Gaydov의 그림을 클릭하여 기본 개념을 익혀야 한다. 소스는 녹음을 위한 것이고 싱크는 재생을 위한 것이다. 소스 아웃풋은 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 <파라미터>').

정해영의 source-sink diagram

단일 소스로부터 녹음하기

단일 애플리케이션

웹브라우저에서 유튜브를 재생하면서 나오는 소리를 녹음하고 싶다면? 아마 가장 흔하게 벌어지는 일일 것이다. VLC Media Player에서 유튜브의 스트리밍 비디오를 MP4(오디오만 MP3로 저장하는 것도 가능)로 저장한 뒤, 적절한 프로그램을 써서 MP3로 전환하면 된다(방법). 그러나 CLI를 이용한 녹음은 단순하고 직관적이다! arecord가 실행되는 동안 PulseAudio Volume Control에서 다음을 제대로 설정하면 된다.

  1. Playback 탭: XYZ(사용하는 디바이스 이름)
  2. Recording 탭: 내장 사운드카드 외에 연결된 것이 없으면 Input Devices 탭에서는 자동으로 'Monitor of 내장 오디오 아날로스 스테레오'가, Recording tab에서는 ALSA plug-in [aplay]: ALSA Capture XYZ'가 선택된다(다른 옵션은 나타나지 않는다) ⇐ 다른 사운드카드를 연결하지 않은 경우 선택할 수 있는 것은 없다. 그러나 USB 사운드 카드(예: UCA-200)을 연결하면 선택할 수 있는 것이 늘어난다. Recording 탭에서 'Monitor of XYZ'를 정확히 선택해야 한다. 이 행위는 아래 그림에서 빨간색 화살표를 연결하는 것에 해당한다(이는 루프백이 아니다!).
  3. Output Devices와 Input Devices 탭에서는 해당 디바이스의 'Mute audio' 버튼이 눌리지 않았는지 확인하라.

단일 애플리케이션 재생음의 녹음

아날로그 입력과 함께 모니터링

U-Control UCA202처럼 모니터링용 헤드폰 단자가 있는 오디오 인터페이스를 쓴다면 이런 고생을 할 일은 없을 것이다!

PulseAudio의 module-loopback을 사용하면 입력 장치로 들어오는 외부의 소리(컴퓨터 내부의 애플리케이션에서 나는 소리를 뜻하는 것이 아님)를 default sink로 보내어 모니터링을 할 수 있다. UCA200을 사용하는 상황에 대해서 생각해 보자. UCA200에는 모니터링용 출력 단자가 없다. 따라서 입력되는 신호를 녹음 과정에는 들을 수 없다. 입력 신호가 UCA200의 아날로그 출력으로도 나가게 만들고, 이를 외부 스피커에 연결하면 된다. 조금 더 공부하면 이를 컴퓨터의 내장 사운드카드로 보내고, 컴퓨터의 헤드폰 단자를 이용하여 듣게 만들 수 있다. 이는 바로 다음에 소개하는 '모니터 출력을 내장 사운드 카드로 보내려면' 항목을 참조하라.

# 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을 통해 재생되는 클라이언트의 모니터를 말한다. 아날로그 입력을 녹음과 동시에 듣기. 마이크로 들어 오는 소리도 같은 방법으로 들을 수 있다. 단, pactl load-module을 실행할 때 latency_msec=5 정도를 주어야 레이턴시가 느껴지지 않는다.

모듈을 해제하려면 다음을 입력한다.

# 로드된 모듈을 확인한다.
$ pacmd list-modules | grep -e 'index:' -e 'name:' -e 'argument:'
$ pactl unload-module 28

모니터 출력을 내장 사운드 카드로 보내려면

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

마이크 입력과 함께 모니터링

설정을 전혀 건드리지 않아도 마이크 입력을 녹음하는 데에는 지장이 없다. 그러나 녹음 중에 마이크로 입력되는 소리를 직접 듣고 싶다면 루프백 기능을 쓰면 된다. 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'는 공통으로 적용되므로 생략하였다.

  1. pactl load-module module-loopback source=alsa_input.usb-Burr-Brown_from_TI_USB_audio_CODEC-00.analog-mono
  2. 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에 대해서 좀 더 공부해 두면 좋을 것이다.

최선의 해결책 - 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을 사용한다면

녹음용 유틸리티로는 Audacity를 사용하는 것이 자연스럽다. 복수의 오디오 디바이스를 서로 연결하려면 alsa_in/alsa_out 유틸리티가 편리하다. 역시 상세한 방법은 나의 구글 블로그에 올렸던 글을 링크하는 것으로 대신한다.

https://blog.genoglobe.com/2021/01/midi-usb-usb.html

[부록] 녹음과 관계없는 오디오 라우팅

blog/우분투_명령행_인터페이스_cli_에서_녹음하기.txt · Last modified: 2021/02/28 03:33 by hyjeong