블루투스 스피커를 연결하고 단순 음악감상이 아닌, 음성 입출력으로 사용하고 싶다면
블루투스 프로파일에 대한 기본 지식은 있어야 한다.
처음 라즈베리파이에 블루투스 음성인식을 고안할때에 가장 궁금했던 부분이고,
잠깐의 구글링으로 찾은 짧은 지식이지만,
너무 유용한 어플리케이션이라 생각되어 정리해본다.
라즈베리파이에서는 pulseaudio를 이용해 사운드 시스템을 제어할 수 있다.
pulseaudio 설치는 이전 포스팅 참고
2017/08/29 - [Raspberry pi] - 라즈베리파이 음성인식 - 블루투스 스피커 연결
pulseaudio를 설치하고, pactl 커맨드를 참고하면 기본적인 설정이 가능하다.
pactl 사용법은 아래 참고
https://manpages.debian.org/jessie/pulseaudio-utils/pactl.1.en.html
우선 헬프
$ pactl -h
pactl [options] stat
pactl [options] info
pactl [options] list [short] [TYPE]
pactl [options] exit
pactl [options] upload-sample FILENAME [NAME]
pactl [options] play-sample NAME [SINK]
pactl [options] remove-sample NAME
pactl [options] load-module NAME [ARGS ...]
pactl [options] unload-module NAME|#N
pactl [options] move-(sink-input|source-output) #N SINK|SOURCE
pactl [options] suspend-(sink|source) NAME|#N 1|0
pactl [options] set-card-profile CARD PROFILE
pactl [options] set-default-(sink|source) NAME
pactl [options] set-(sink|source)-port NAME|#N PORT
pactl [options] set-(sink|source)-volume NAME|#N VOLUME [VOLUME ...]
pactl [options] set-(sink-input|source-output)-volume #N VOLUME [VOLUME ...]
pactl [options] set-(sink|source)-mute NAME|#N 1|0|toggle
pactl [options] set-(sink-input|source-output)-mute #N 1|0|toggle
pactl [options] set-sink-formats #N FORMATS
pactl [options] set-port-latency-offset CARD-NAME|CARD-#N PORT OFFSET
pactl [options] subscribe
The special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@
can be used to specify the default sink, source and monitor.
-h, --help Show this help
--version Show version
-s, --server=SERVER The name of the server to connect to
-n, --client-name=NAME How to call this client on the server
꽤 여러가지를 지원해주는 것 같지만 사실 별거 없다.
알아야 할 것은, sink, source, profile 정도..
sink는 수신자, source 는 송신자, profile은 스테레오 고음질 모드로 연결할지, 헤드셋 모드로 연결할지에 대한 정의 정도로 이해하면 된다.
스테레오 고음질 모드는 A2DP, 헤드셋 모드는 HSP 라고 줄여서 사용하곤 한다.
라즈베리파이에 블루투스 스피커를 연결하여 대화를 하고 싶다면 스테레오 고음질 모드가 아니라 헤드셋 모드로 연결해야 한다.
pactl 로 그걸 설정할 수 있다.
우선 sink를 조회해보자.
$ pactl list sinks
Sink #0
State: SUSPENDED
Name: alsa_output.0.analog-stereo
Description: bcm2835 ALSA Analog Stereo
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 6
Mute: no
Volume: front-left: 26090 / 40% / -24.00 dB, front-right: 26090 / 40% / -24.00 dB
balance 0.00
Base Volume: 56210 / 86% / -4.00 dB
Monitor Source: alsa_output.0.analog-stereo.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "bcm2835 ALSA"
alsa.id = "bcm2835 ALSA"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "bcm2835 ALSA"
alsa.long_card_name = "bcm2835 ALSA"
device.bus_path = "/devices/virtual/sound/card0"
sysfs.path = "/devices/virtual/sound/card0"
device.string = "hw:0"
device.buffering.buffer_size = "65536"
device.buffering.fragment_size = "65536"
device.access_mode = "mmap+timer"
device.profile.name = "analog-stereo"
device.profile.description = "Analog Stereo"
device.description = "bcm2835 ALSA Analog Stereo"
alsa.mixer_name = "Broadcom Mixer"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card"
Ports:
analog-output: Analog Output (priority: 9900)
Active Port: analog-output
Formats:
pcm
Sink #4
State: SUSPENDED
Name: bluez_sink.F0_13_C3_63_1B_B7
Description: HUAWEI AM08
Driver: module-bluez5-device.c
Sample Specification: s16le 1ch 8000Hz
Channel Map: mono
Owner Module: 24
Mute: no
Volume: mono: 43691 / 67%
balance 0.00
Base Volume: 65536 / 100%
Monitor Source: bluez_sink.F0_13_C3_63_1B_B7.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
bluetooth.protocol = "headset_head_unit"
device.intended_roles = "phone"
device.description = "HUAWEI AM08"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
Ports:
headset-output: Headset (priority: 0)
Active Port: headset-output
Formats:
pcm
블루투스로 아무것도 연결하지 않았다면, Sink #0 만 있다.
Sink #4가 조회된 건 화웨이 블루투스 스피커가 연결되어 있기 때문이다.
Sink라는건 수신자, 현재 블루투스 스피커가 수신자로, 헤드셋 모드로, 연결되어 있고, 샘플레이트가 8000Hz로 매우 낮다는 걸 알 수있다.
Sample Specification: s16le 1ch 8000Hz
Channel Map: mono
Properties:
bluetooth.protocol = "headset_head_unit"
즉, 양방향이지만 저품질이라는 뜻.
양방향인건 source를 조회해 보아야 확실하다.
$ pactl list sources
Source #0
State: SUSPENDED
Name: alsa_output.0.analog-stereo.monitor
Description: Monitor of bcm2835 ALSA Analog Stereo
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 6
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor of Sink: alsa_output.0.analog-stereo
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Monitor of bcm2835 ALSA Analog Stereo"
device.class = "monitor"
alsa.card = "0"
alsa.card_name = "bcm2835 ALSA"
alsa.long_card_name = "bcm2835 ALSA"
device.bus_path = "/devices/virtual/sound/card0"
sysfs.path = "/devices/virtual/sound/card0"
device.string = "0"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card"
Formats:
pcm
Source #6
State: SUSPENDED
Name: bluez_sink.F0_13_C3_63_1B_B7.monitor
Description: Monitor of HUAWEI AM08
Driver: module-bluez5-device.c
Sample Specification: s16le 1ch 8000Hz
Channel Map: mono
Owner Module: 24
Mute: no
Volume: mono: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor of Sink: bluez_sink.F0_13_C3_63_1B_B7
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Monitor of HUAWEI AM08"
device.class = "monitor"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Formats:
pcm
Source #7
State: SUSPENDED
Name: bluez_source.F0_13_C3_63_1B_B7
Description: HUAWEI AM08
Driver: module-bluez5-device.c
Sample Specification: s16le 1ch 8000Hz
Channel Map: mono
Owner Module: 24
Mute: no
Volume: mono: 65536 / 100%
balance 0.00
Base Volume: 65536 / 100%
Monitor of Sink: n/a
Latency: 0 usec, configured 0 usec
Flags: HARDWARE HW_VOLUME_CTRL LATENCY
Properties:
bluetooth.protocol = "headset_head_unit"
device.intended_roles = "phone"
device.description = "HUAWEI AM08"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
Ports:
headset-input: Headset (priority: 0)
Active Port: headset-input
Formats:
pcm
Source #7에 bluez_source.F0_13_C3_63_1B_B7 가 조회된다.
만약 A2DP 와 같은 단방향으로 설정을 했다면 source #7과 같은 bluez_source.F0_13_C3_63_1B_B7은 보이지 않는다.
주의할 것은, bluez_sink.F0_13_C3_63_1B_B7.monitor가 source 목록에서 조회되지만 Description에서 설명되듯이 sink를 모니터하는 용도일 뿐 source가 아니라는 점이다.
만약 A2DP로 연결되어 있다면 source와 sink가 아래와 같이 나올 것이다.
$ pactl list sinks
...
Sink #5
State: SUSPENDED
Name: bluez_sink.F0_13_C3_63_1B_B7
Description: HUAWEI AM08
Driver: module-bluez5-device.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 24
Mute: no
Volume: front-left: 43691 / 67% / -10.57 dB, front-right: 43691 / 67% / -10.57 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor Source: bluez_sink.F0_13_C3_63_1B_B7.monitor
Latency: 0 usec, configured 0 usec
Flags: HARDWARE DECIBEL_VOLUME LATENCY
Properties:
bluetooth.protocol = "a2dp_sink"
device.description = "HUAWEI AM08"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Ports:
headset-output: Headset (priority: 0)
Active Port: headset-output
Formats:
pcm
$ pactl list sources
...
Source #5
State: SUSPENDED
Name: bluez_sink.F0_13_C3_63_1B_B7.monitor
Description: Monitor of HUAWEI AM08
Driver: module-bluez5-device.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 24
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor of Sink: bluez_sink.F0_13_C3_63_1B_B7
Latency: 0 usec, configured 0 usec
Flags: DECIBEL_VOLUME LATENCY
Properties:
device.description = "Monitor of HUAWEI AM08"
device.class = "monitor"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Formats:
pcm
프로파일을 바꾸고 싶으면 아래와 같이 하면 된다.
#헤드셋 모드로 바꾸어서 양방향 스트림을 하고자 하면...
$ pactl set-card-profile bluez_card.F0_13_C3_63_1B_B7 headset_head_unit
#A2DP로 바꾸어서 단방향이지만 스테레오 고음질을 스트리밍하고자 하면...
$ pactl set-card-profile bluez_card.F0_13_C3_63_1B_B7 a2dp_sink
그러면,
현재 연결된 블루투스 장치가 지원하는 프로파일을 모두 보고싶으면?
조회해보면 된다.
$ pactl list cards
Card #0
Name: alsa_card.0
Driver: module-alsa-card.c
Owner Module: 6
Properties:
alsa.card = "0"
alsa.card_name = "bcm2835 ALSA"
alsa.long_card_name = "bcm2835 ALSA"
device.bus_path = "/devices/virtual/sound/card0"
sysfs.path = "/devices/virtual/sound/card0"
device.string = "0"
device.description = "bcm2835 ALSA"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card"
Profiles:
output:analog-mono: Analog Mono Output (sinks: 1, sources: 0, priority: 200, available: yes)
output:analog-stereo: Analog Stereo Output (sinks: 1, sources: 0, priority: 6000, available: yes)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: output:analog-stereo
Ports:
analog-output: Analog Output (priority: 9900, latency offset: 0 usec)
Part of profile(s): output:analog-mono, output:analog-stereo
Card #2
Name: bluez_card.F0_13_C3_63_1B_B7
Driver: module-bluez5-device.c
Owner Module: 24
Properties:
device.description = "HUAWEI AM08"
device.string = "F0:13:C3:63:1B:B7"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_F0_13_C3_63_1B_B7"
bluez.class = "0x240404"
bluez.alias = "HUAWEI AM08"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Profiles:
headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
off: Off (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: headset_head_unit
Ports:
headset-output: Headset (priority: 0, latency offset: 0 usec)
Part of profile(s): headset_head_unit, a2dp_sink
headset-input: Headset (priority: 0, latency offset: 0 usec)
Part of profile(s): headset_head_unit
Card #2 에서 현재 연결된 블루투스 장치가 지원하는 프로파일과 활성화된 프로파일을 조회할 수 있다.
라즈베리파이에 연결한 화웨이 스피커의 경우 헤드셋 모드와, A2DP 모드 두가지를 지원한다.
추가로, 나의 경우에는 연결된 블루투스 장치가 기본 사운드 장치로 인식되어서 문제가 없었지만, 혹시 그렇지 않다면 아래 명령어로 기본 sink와 source를 블루투스 장치로 바꿀 수 있다.
$ pactl set-default-sink bluez_sink.F0_13_C3_63_1B_B7
$ pactl set-default-source bluez_source.F0_13_C3_63_1B_B7
'Raspberry pi' 카테고리의 다른 글
Wake on LAN으로 PC 켜기 (0) | 2017.10.24 |
---|---|
라즈베리파이 음성인식 - Google API nodejs sample 실행 (7) | 2017.09.10 |
라즈베리파이 음성인식 - 블루투스 스피커 연결 (3) | 2017.08.29 |
Swap 늘리기 (0) | 2017.06.15 |
4편 PLEX 최적화 - 자막 일괄변환 (0) | 2017.05.21 |