Thursday, 12 April 2018

ALSA, PulseAudio, JACK - âm nhạc trên Ubuntu/Linux

Bình thường người dùng chỉ quan tâm đến việc cài máy xong:
- có mở được nhạc không
- chỉnh âm lượng to nhỏ được không
- cùng lắm là mic có hoạt động không

là xong.

Vậy còn bất thường?
Khi bạn muốn "sản xuất nhạc" trên Linux, cụ thể là đánh đàn, thu âm, ... nhu cầu ít phổ biến này thậm chí khiến Ubuntu sản xuất 1 phiên bản gọi là "Ubuntu Studio" với các software phục vụ mục đích trên cài sẵn.

(Như KaLi là Distro cài sẵn các tool để Pentest).

Trường hợp tốt nhất là bạn cài Ubuntu Studio, và lại không quan tâm.
Nhưng ít ai dùng bản này, vậy nên ta rơi vào trường hợp tốt nhì, đã cài Ubuntu (hay 1 Linux distro nào đó).

Các từ khóa liên quan:
- snd: viết tắt của sound
- pcm: Pulse-code modulation (PCM) - một phương pháp để biểu diễn tín hiệu analog dưới dạng số - đây là tiêu chuẩn cho digital audio, compact disk, ...

ALSA

The Advanced Linux Sound Architecture (ALSA) provides audio and MIDI functionality to the Linux operating system.

Alsa là viết tắt của "Advanced Linux Sound Architecture", với chữ "The" ở đầu ám chỉ nó là DUY NHẤT.
Theo wikipedia, ALSA là 1 software framework, 1 phần của Linux kernel, cung cấp 1 API cho các driver của thiết bị âm thanh.
Trước/ngoài ALSA, có một API khác cho các thiết bị âm thanh gọi là OSS (Open Sound System), OSS hiện là hệ thống sound API trên các OS không phải Linux khác, như FreeBSD



Vì là phần của kernel, nên mặc định thì trên hệ điều hành nhân Linux nào cũng có ALSA cả. Ngoài là một phần của kernel, ALSA đi kèm với các câu lệnh chạy ở phía người dùng:

$ dpkg -L alsa-utils | grep /bin/ | sort | xargs
/usr/bin/aconnect /usr/bin/alsabat /usr/bin/alsaloop /usr/bin/alsamixer /usr/bin/alsatplg /usr/bin/alsaucm /usr/bin/amidi /usr/bin/amixer /usr/bin/aplay /usr/bin/aplaymidi /usr/bin/arecord /usr/bin/arecordmidi /usr/bin/aseqdump /usr/bin/aseqnet /usr/bin/iecset /usr/bin/speaker-test

Chú ý mọi câu lệnh đều bắt đầu với chữ a (ALSA).

http://www.alsa-project.org/main/index.php/Main_Page

Card sound - card âm thanh (phần cứng) - driver

Khi xem thông tin về phần cứng, dmesg luôn hoàn thành nhiệm vụ, dù output có thể hơi khó giải thích vì đậm chất kỹ thuật:

$ dmesg | grep -i sound
[    3.040049] input: HDA Intel HDMI HDMI/DP,pcm=3 as /devices/pci0000:00/0000:00:03.0/sound/card0/input8
[    3.040112] input: HDA Intel HDMI HDMI/DP,pcm=7 as /devices/pci0000:00/0000:00:03.0/sound/card0/input9
[    3.040171] input: HDA Intel HDMI HDMI/DP,pcm=8 as /devices/pci0000:00/0000:00:03.0/sound/card0/input10
[    3.040227] input: HDA Intel HDMI HDMI/DP,pcm=9 as /devices/pci0000:00/0000:00:03.0/sound/card0/input11
[    3.040284] input: HDA Intel HDMI HDMI/DP,pcm=10 as /devices/pci0000:00/0000:00:03.0/sound/card0/input12
[    3.060920] input: HDA Intel PCH Dock Mic as /devices/pci0000:00/0000:00:1b.0/sound/card1/input14
[    3.060997] input: HDA Intel PCH Dock Line Out as /devices/pci0000:00/0000:00:1b.0/sound/card1/input15
[    3.061058] input: HDA Intel PCH Front Headphone as /devices/pci0000:00/0000:00:1b.0/sound/card1/input16

Đọc nội dung về các card sound ghi trên /proc thay vì đọc từ dmesg:
$ cat /proc/asound/cards
 0 [HDMI           ]: HDA-Intel - HDA Intel HDMI
                      HDA Intel HDMI at 0xf7e34000 irq 48
 1 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xf7e30000 irq 47
Vậy máy này có 2 card sound, một cái là HDMI, cái kia là PCH - tạm không biết là gì.

Dùng lệnh `aplay -l` (hoặc -L để chi tiết hơn):

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: HDMI [HDA Intel HDMI], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 8: HDMI 2 [HDMI 2]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 9: HDMI 3 [HDMI 3]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: HDMI [HDA Intel HDMI], device 10: HDMI 4 [HDMI 4]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: PCH [HDA Intel PCH], device 0: ALC3226 Analog [ALC3226 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0


HDA là viết tắt của High Definition Audio.
Ở đây có 2 card, đánh số lần lượt card 0: HDMI và card 1: PCH (xem ý nghĩa tại đây: https://unix.stackexchange.com/questions/122986/how-to-understand-list-of-soundcards-meaning-of-mid-hdmi-pch)

Ứng với mỗi card có các device (thiết bị) tương ứng - thực chất là các đầu vào và ra.
Các Playback device có thể kể tới: loa, headphone, microphone (chúng không gắn chặt vào máy tính mà phải cắm vào một đầu cắm in/ouput tương ứng), đầu ra HDMI (nếu bạn không biết, cổng HDMI vừa truyền được âm thanh lẫn hình ảnh).

Từ PLAYBACK: trong tiếng Anh nghĩa là:
> The reproduction of previously recorded sounds or moving images.
việc tái tạo lại (phát lại) âm thanh / hình ảnh đã thu trước đó.

PLAYBACK hardware chỉ thứ phần cứng có khả năng phát lại (trong trường hợp này là âm thanh). Một máy tính không có card sound sẽ không thể phát ra âm thanh (card này thường tích hợp sẵn/dính liền nên hầu như máy tính nào cũng có).

Nghĩ lại việc nghe nhạc hay xem film trên máy tính, tất cả đều là phát lại những bản nhạc / bộ phim đã thu thành file trước đó.

Playback thường xuất hiện với từ recording, hai công việc liên quan đến âm thanh: phát và thu.
Rõ ràng khi muốn thu âm hay cắm "midi controller" vào, ta sẽ KHÔNG làm việc với HDMI, mà sẽ dùng card còn lại, ở đây là PCH.

PusleAudio, JACK

Là 2 sound server nổi tiếng trong giới mã nguồn mở.
Nếu như  có HTTP server, mail server, FPT server ... thì đây là sound server, một phần mềm luôn chạy, và xử lý các yêu cầu mà "sound client" gửi tới.

- PulseAudio: khá phổ biến, mặc định trên Ubuntu, cùng tác giả với systemd
- JACK: low-latency (tức truyền tín hiệu vào thì nhận được nhanh, không phải đợi lâu), đẳng cấp chuyên nghiệp dùng trong chỉnh sửa, mix nhạc.

Vì 2 phần mềm này cùng chức năng, nên nếu CHẠY cùng lúc sẽ dẫn đến xung đột / lỗi. Trên Ubuntu, PulseAudio mặc định là luôn chạy, nên nếu dùng JACK, ta phải dùng câu lệnh: pasuspender để "tạm ngưng" PA khi chạy chương trình khác.

Cả 2 đều tương tác với kernel thông qua ALSA.

PulseAudio (viết tắt: PA)


package `pulseaudio` thường được cài sẵn trên máy Ubuntu:

$ dpkg -L pulseaudio | grep /bin/
/usr/bin/pulseaudio
/usr/bin/start-pulseaudio-x11

$ dpkg -l 'pulse*' | grep ^ii
ii  pulseaudio                  1:8.0-0ubuntu3.8 amd64        PulseAudio sound server
ii  pulseaudio-module-bluetooth 1:8.0-0ubuntu3.8 amd64        Bluetooth module for PulseAudio sound server
ii  pulseaudio-module-x11       1:8.0-0ubuntu3.8 amd64        X11 module for PulseAudio sound server
ii  pulseaudio-utils            1:8.0-0ubuntu3.8 amd64        Command line tools for the PulseAudio sound server

$ ps xau | grep pulse
hvn       6254  0.0  0.2 491968 11280 ?        S<l  21:15   0:00 /usr/bin/pulseaudio --start --log-target=syslog

Server đang chạy như thấy ở lệnh ps bên trên.
Phía client, có các "utils" sau:

$ for line in $(dpkg -L pulseaudio-utils | grep /bin/); do apropos $(echo $line | cut -d / -f4); done | sort | uniq
pacat (1)            - Play back or record raw or encoded audio streams on a PulseAudio sound server
pacmd (1)            - Reconfigure a PulseAudio sound server during runtime
pactl (1)            - Control a running PulseAudio sound server
padsp (1)            - PulseAudio OSS Wrapper
pamon (1)            - Play back or record raw or encoded audio streams on a PulseAudio sound server
paplay (1)           - Play back or record raw or encoded audio streams on a PulseAudio sound server
parec (1)            - Play back or record raw or encoded audio streams on a PulseAudio sound server
parecord (1)         - Play back or record raw or encoded audio streams on a PulseAudio sound server
pasuspender (1)      - Temporarily suspend PulseAudio
pax11publish (1)     - PulseAudio X11 Credential Utility

Tất cả các câu lệnh đều bắt đầu với `pa`, như
- pactl: client để điều khiển PA server
- parecord: ghi âm

$ parecord record.flac --file-format=flac --rate=16000
Hát vài câu rồi ctrl C để dừng chương trình, sau đó ta có file nhạc thu âm những gì vừa hát.

- paplay: play file nhạc được hỗ trợ trên PA server. Danh sách file hỗ trợ xem bởi output câu lệnh:
$ paplay --list-file-formats
Trong đó, chú ý không có MP3, nhưng có WAV, RAW và FLAC.
Mở file nhạc chỉ cần
$ paplay filename.wav
(Có thể tải file này https://freewavesamples.com/files/Roland-JV-2080-Pick-Bass-C2.wav về để thử)
hết bài, câu lệnh sẽ tự kết thúc.

JACK - JACK Audio Connection Kit

không được cài sẵn, phải tự cài:

 $ apt-cache search JACK | grep server
pulseaudio - PulseAudio sound server
jackd - JACK Audio Connection Kit (default server package)
jackd1 - JACK Audio Connection Kit (server and example clients)
jackd2 - JACK Audio Connection Kit (server and example clients)
pulseaudio-module-jack - jackd modules for PulseAudio sound server
qjackctl - User interface for controlling the JACK sound server

Thấy có đến 3 package để cài JACK,

$ apt-cache show jackd | grep depend -i
Depends: jackd2 | jackd1
 This dummy package depends on the current default JACK implementation.

như vậy package jackd chỉ tới jackd1 hoặc jackd2, hai chương trình này về mặt tính năng là tương tự nhau, nhưng jackd1 viết bằng C, jackd2 viết bằng C++, và nói chung sẽ khó có ngày gộp lại thành một - nên tồn tại song song. Ta có thể dùng jackd2 vì ... mới hơn.
https://wiki.archlinux.org/index.php/JACK_Audio_Connection_Kit


Package jackd2 đi kèm một đống câu lệnh:
$ dpkg -L jackd2 | grep  /bin/ | sed 's:/usr/bin/::' | sort |xargs
alsa_in alsa_out jack_alias jack_bufsize jack_connect jack_control jack_cpu jack_cpu_load jackd jackdbus jack_disconnect jack_evmon jack_freewheel jack_iodelay jack_latent_client jack_load jack_lsp jack_metro jack_midi_dump jack_midi_latency_test jack_midiseq jack_midisine jack_monitor_client jack_multiple_metro jack_net_master jack_net_slave jack_netsource jack_rec jack_samplerate jack_server_control jack_session_notify jack_showtime jack_simple_client jack_simple_session_client jack_test jack_thru jack_transport jack_unload jack_wait jack_zombie


jackd được điều khiển bởi câu lệnh jack_control

Đặc biệt chú ý câu lệnh: jack_dbus - ám chỉ gói đã cài đã tích hợp sẵn jack với DBus.

Cài thêm qjackctl - giao diện đồ hoạ:
$ dpkg -l '*jack*'
...
ii  qjackctl                    0.4.2-0ubuntu2     amd64              User interface for controlling the JACK sound server
$ dpkg -L qjackctl | grep /bin/
/usr/bin/qjackctl

Bật jackd - server:
Bởi công việc yêu cầu JACK chỉ làm theo phiên, ta không cần lúc nào cũng phải chạy jack server mà chỉ cần khi xử lý / thu âm nhạc. Sử dụng qjackctl sẽ tự bật JACK server lúc nó chạy và tắt đi lúc tắt qjackctl. Vì JACK sẽ dùng card sound - nên sẽ gây cạnh tranh với PA server, dùng lệnh sau để tạm dừng PA khi chạy JACK:

$ pasuspender qjackctl

Một giao diện đồ họa như sau sẽ hiện ra.



Nếu bấm vào nút play, thấy có vẻ như nó chạy không lỗi gì, chúc mừng.
Còn nếu các cửa sổ lỗi lần lượt phụt ra, ta phải chọn lại card sound:
Setup -> Settíng ->
Tại cửa sổ này chọn:
- Driver: alsa (cố định trên mọi máy)
- interface: hw:PCH (mặc định là default, nếu default ko chạy ta đổi lần lượt)
- Midi driver: chọn seq.
- Realtime: chọn hay không cũng được, realtime sẽ dùng tốn tài nguyên hơn để cho phép tín hiệu truyền tới với độ trễ thấp hơn.

Lệnh jack_control dùng để điều khiển JACK server bằng dòng lệnh, đây là thông số về cấu hình của JACK đang hoạt động trên máy mình:
$ jack_control dp
--- get driver parameters (type:isset:default:value)
              device: ALSA device name (str:set:hw:0:hw:PCH)
             capture: Provide capture ports.  Optionally set device (str:set:none:hw:PCH)
            playback: Provide playback ports.  Optionally set device (str:set:none:hw:PCH)
                rate: Sample rate (uint:set:48000:44100)
              period: Frames per period (uint:set:1024:1024)
            nperiods: Number of periods of playback latency (uint:set:2:2)
               hwmon: Hardware monitoring, if available (bool:set:False:False)
             hwmeter: Hardware metering, if available (bool:set:False:False)
              duplex: Provide both capture and playback ports (bool:set:True:True)
            softmode: Soft-mode, no xrun handling (bool:set:False:False)
             monitor: Provide monitor ports for the output (bool:set:False:False)
              dither: Dithering mode (char:set:n:n)
          inchannels: Number of capture channels (defaults to hardware max) (uint:notset:0:0)
         outchannels: Number of playback channels (defaults to hardware max) (uint:notset:0:0)
              shorts: Try 16-bit samples before 32-bit (bool:set:False:False)
       input-latency: Extra input latency (frames) (uint:notset:0:0)
      output-latency: Extra output latency (frames) (uint:notset:0:0)
         midi-driver: ALSA MIDI driver (str:set:none:seq)


midi controller

Dùng bàn phím đánh đàn được không?
Có, sẽ phải dùng một phần mềm để map tương ứng mỗi phím của bàn phím với một phím đàn - hay nói đúng hơn là với một "tín hiệu" phát ra mỗi khi ta gõ phím.
Midi controller là phần cứng có khả năng phát ra tín hiệu ứng với các nốt nhạc, thường có hình dạng như một cái đàn keyboard (piano ... với 25, 49 hay 61 phím). Thay vì dùng bàn phím, midi controller giải quyết vấn đề đánh đàn trên máy tính  - phần quan trọng khác biệt, là ngoài số phím / hình dáng tương ứng với phím piano, các phím trên một thiết bị midi controller có độ nhạy như một phím đàn (đánh nhẹ, đánh mạnh, giữ phím ...).
Midi controller sẽ cắm vào PCH input
https://www.amazon.com/midi-controller/s?ie=UTF8&page=1&rh=i%3Aaps%2Ck%3Amidi%20controller

qsynth


sau khi mỗi phím đàn được map với một tín hiệu, âm thanh phát ra sẽ có tiếng như thế nào?
Cùng một "nốt" nhạc, nhưng tiếng Piano, Guitar, violin là khác nhau. Ở đây xuất hiện khái nhiệm synthesizer, cho ta các bộ "sample" tiếng - hay gọi là soundfont (tương tự font chữ, cùng biểu diễn 1 nội dung, nhưng thể hiện khác nhau). Với các bộ soundfont khác nhau, ta tạo ra được các âm thanh khác nhau sử dụng midi controller.

TODO: chi tiết hơn về midi controller & synthesizer

==UPDATE 2018 Aug==

Để thu âm tiếng đàn mình đánh (nghe thấy), cài audacity bằng apt-get, bật audacity lên, hiện ngay màn hình phần menu, chọn:
- Audio host -> chọn Jack audio Connection Kit
- Recording device -> chọn qsynth
- Recording Channels -> chọn stereo
- Playback device -> Chọn system

Sau đó bấm nút record là  thu âm được.
# Tham khảo

https://rafalcieslak.wordpress.com/2012/08/29/usb-midi-controllers-and-making-music-with-ubuntu/
https://askubuntu.com/questions/19764/how-does-one-set-up-a-midi-keyboard
https://superuser.com/questions/144648/how-do-alsa-and-pulseaudio-relate/144649#144649