Raspberry pi

라즈베리파이 음성인식 - 블루투스 프로파일 변경

[혜안] 2017. 9. 4. 22:23
728x90

블루투스 스피커를 연결하고 단순 음악감상이 아닌, 음성 입출력으로 사용하고 싶다면

블루투스 프로파일에 대한 기본 지식은 있어야 한다.


처음 라즈베리파이에 블루투스 음성인식을 고안할때에 가장 궁금했던 부분이고, 

잠깐의 구글링으로 찾은 짧은 지식이지만,

너무 유용한 어플리케이션이라 생각되어 정리해본다.


라즈베리파이에서는 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



728x90