Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record from bluetooth device #7

Closed
ghost opened this issue Nov 5, 2016 · 15 comments
Closed

Record from bluetooth device #7

ghost opened this issue Nov 5, 2016 · 15 comments

Comments

@ghost
Copy link

ghost commented Nov 5, 2016

Do you know if it's possible to use arecord together with bluealsa? I managed to fix the problem from #6 by disabling pulseaudio-bluetooth and can now play music through my bluetooth headset with aplay, but arecord still gives me the same error. Would I have to set different parameters for device input than for output?

Again I try to provide a full log.

My /etc/asound.conf contains:

defaults.bluealsa.interface "hci0"
defaults.bluealsa.device "E4:22:A5:08:7B:FF"
defaults.bluealsa.profile "a2dp"

So let's start from a freshly booted system (# indicates root, ~ indicates user):

# systemctl start bluetooth
# bluealsa

Output so far:

bluealsa: ctl.c:353: Starting controller loop
bluealsa: bluez.c:677: Registering endpoint: 0000110A-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DP_MPEG24_Source
bluealsa: bluez.c:677: Registering endpoint: 0000110A-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DPSource
bluealsa: bluez.c:677: Registering endpoint: 0000110B-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DP_MPEG24_Sink
bluealsa: bluez.c:677: Registering endpoint: 0000110B-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DPSink
bluealsa: bluez.c:893: Registering profile: 00001108-0000-1000-8000-00805F9B34FB: /Profile/HSPHeadset
bluealsa: bluez.c:893: Registering profile: 00001112-0000-1000-8000-00805F9B34FB: /Profile/HSPAudioGateway
bluealsa: main.c:202: Starting main dispatching loop

Going on:

# bluetoothctl
> power on
> connect E4:22:A5:08:7B:FF

New output:

bluealsa: bluez.c:846: Profile method call: org.bluez.Profile1.NewConnection()
bluealsa: bluez.c:778: HSP Audio Gateway configured for device E4:22:A5:08:7B:FF
bluealsa: transport.c:399: State transition: 0 -> 2
bluealsa: transport.c:91: Created new IO thread: HSP Audio Gateway
bluealsa: io.c:960: Starting IO loop: HSP Audio Gateway
bluealsa: io.c:994: AT command: +VGS=08
bluealsa: io.c:994: AT command: +VGM=15
bluealsa: bluez.c:482: Endpoint method call: org.bluez.MediaEndpoint1.SelectConfiguration()
bluealsa: bluez.c:482: Endpoint method call: org.bluez.MediaEndpoint1.SetConfiguration()
bluealsa: bluez.c:416: A2DP Source (SBC) configured for device E4:22:A5:08:7B:FF
bluealsa: bluez.c:418: Configuration: channels: 2, sampling: 48000
bluealsa: transport.c:399: State transition: 0 -> 0

Headset tells me "PC connected".

Going on:

~ pactl list | grep Legend

no output, nice.

aplay -D bluealsa applause.wav

Gives the following output and plays the applause in my ear:

bluealsa-pcm.c:101: Getting transport for E4:22:A5:08:7B:FF profile 1
bluealsa-pcm.c:502: Setting constraints
Playing WAVE 'applause.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Warning: rate is not accurate (requested = 44100Hz, got = 48000Hz)
         please, try the plug plugin (-Dplug:bluealsa)
bluealsa-pcm.c:337: Initializing HW
bluealsa-pcm.c:137: Requesting PCM open for E4:22:A5:08:7B:FF
bluealsa-pcm.c:154: Opening PCM FIFO (mode: WR): /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-1
bluealsa-pcm.c:355: FIFO buffer size: 4096
bluealsa-pcm.c:359: Selected HW buffer: 23 periods x 4096 bytes
bluealsa-pcm.c:390: Prepared
bluealsa-pcm.c:296: Starting
bluealsa-pcm.c:238: Starting IO loop
^CAborted by signal Interrupt...
aplay: pcm_write:2004: write error: Interrupted system call
bluealsa-pcm.c:311: Stopping
bluealsa-pcm.c:366: Freeing HW
bluealsa-pcm.c:182: Closing PCM for E4:22:A5:08:7B:FF
bluealsa-pcm.c:327: Closing plugin

And then:

arecord -d 3 -D bluealsa test.wav

Gives the output:

bluealsa-pcm.c:101: Getting transport for E4:22:A5:08:7B:FF profile 2
ALSA lib bluealsa-pcm.c:619:(_snd_pcm_bluealsa_open) Couldn't get BlueALSA transport: No such device
arecord: main:786: audio open error: No such device

On the bluealsa output we now have the new output (for both aplay and arecord, I forgot to split them...):

bluealsa: ctl.c:411: New client accepted: 8
bluealsa: ctl.c:414: +-+-
bluealsa: ctl.c:414: +-+-
bluealsa: ctl.c:226: PCM requested for E4:22:A5:08:7B:FF profile 1
bluealsa: transport.c:481: New transport: 10 (MTU: R:672 W:672)
bluealsa: ctl.c:414: +-+-
bluealsa: bluez.c:990: Signal: PropertiesChanged: org.bluez.MediaTransport1
bluealsa: transport.c:399: State transition: 1 -> 2
bluealsa: transport.c:91: Created new IO thread: A2DP Source (SBC)
bluealsa: io.c:71: Opening FIFO for reading: /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-1
bluealsa: io.c:448: Starting IO loop: A2DP Source (SBC)
bluealsa: transport.c:616: Cleaning PCM FIFO: /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-1
bluealsa: transport.c:623: Closing PCM: 11
bluealsa: transport.c:528: Releasing transport: A2DP Source (SBC)
bluealsa: transport.c:556: Closing BT: 10
bluealsa: io.c:61: Exiting IO thread
bluealsa: ctl.c:414: +-+-
bluealsa: bluez.c:990: Signal: PropertiesChanged: org.bluez.MediaTransport1
bluealsa: transport.c:399: State transition: 0 -> 0
bluealsa: ctl.c:385: Client closed connection: 8
bluealsa: ctl.c:414: +-+-
bluealsa: ctl.c:411: New client accepted: 8
bluealsa: ctl.c:414: +-+-
bluealsa: ctl.c:414: +-+-
bluealsa: ctl.c:385: Client closed connection: 8
bluealsa: ctl.c:414: +-+-
@arkq
Copy link
Owner

arkq commented Nov 5, 2016

Unfortunately, it is not implemented yet. Recording (from the headset, aka accessing build in microphone) requires HSP/HFP profile support. Like I said in #6, currently I'm trying to make it work. However, it is not trivial with the current bluealsa architecture (my bad) - so I'm doing some refactoring.

The only possible way of recording with the current setup, it is to connect Bluetooth device, which will act as a source in the A2DP profile, e.g. iPhone or Android-powered smartphone.

Current master snapshot has one "glitch" - in the amixer there is a recording device for HSP, so one might think recoding is possible, unfortunately not yet.

@arkq
Copy link
Owner

arkq commented Nov 6, 2016

I've just pushed prototype implementation of the SCO audio transfer (for HSP), which should provide access to the headset microphone. Try something like this:

arecord -f S16_LE -D bluealsa:HCI=hci0,DEV=XX:XX:XX:XX:XX:XX,PROFILE=sco mic.wav

The crucial thing is the usage of the SCO profile (in the future I might change this profile name, though).

There is one important thing to mention. The behaviour of using A2DP and SCO simultaneously is headset dependent. On my headset it is not possible to listen to audio transferred with A2DP while the SCO connection is opened (recording and/or playing).

@ghost
Copy link
Author

ghost commented Nov 9, 2016

It does not give me an error, but also it does not seem to record anything and it seems arecord also does not start counting the recorder time. It gives me a beep in my headset to tell me that something becomes active (but I am not sure exactly when this occurs, I also heard this some times when playing around before you implemented sco)

Output on the arecord terminal is:

~ $ arecord -f S16_LE -D bluealsa:HCI=hci0,DEV=E4:22:A5:08:7B:FF,PROFILE=sco mic.wav
bluealsa-pcm.c:103: Getting transport for E4:22:A5:08:7B:FF type 2
bluealsa-pcm.c:507: Setting constraints
Recording WAVE 'mic.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
bluealsa-pcm.c:342: Initializing HW
bluealsa-pcm.c:140: Requesting PCM open for E4:22:A5:08:7B:FF
bluealsa-pcm.c:157: Opening PCM FIFO (mode: RO): /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-2-1
bluealsa-pcm.c:364: Selected HW buffer: 4 periods x 2000 bytes
bluealsa-pcm.c:395: Prepared
bluealsa-pcm.c:301: Starting
^CAborted by signal Interrupt...
arecord: pcm_read:2096: read error: Interrupted system call
bluealsa-pcm.c:316: Stopping
bluealsa-pcm.c:371: Freeing HW
bluealsa-pcm.c:186: Closing PCM for E4:22:A5:08:7B:FF
bluealsa-pcm.c:332: Closing plugin

And on the bluealsa terminal:

# bluealsa 
bluealsa: ctl.c:483: Starting controller loop
bluealsa: bluez.c:676: Registering endpoint: 0000110A-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DP_MPEG24_Source
bluealsa: bluez.c:676: Registering endpoint: 0000110A-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DPSource
bluealsa: bluez.c:676: Registering endpoint: 0000110B-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DP_MPEG24_Sink
bluealsa: bluez.c:676: Registering endpoint: 0000110B-0000-1000-8000-00805F9B34FB: /MediaEndpoint/A2DPSink
bluealsa: bluez.c:912: Registering profile: 00001108-0000-1000-8000-00805F9B34FB: /Profile/HSPHeadset
bluealsa: bluez.c:912: Registering profile: 00001112-0000-1000-8000-00805F9B34FB: /Profile/HSPAudioGateway
bluealsa: bluez.c:912: Registering profile: 0000111E-0000-1000-8000-00805F9B34FB: /Profile/HFPHandsFree
bluealsa: bluez.c:912: Registering profile: 0000111F-0000-1000-8000-00805F9B34FB: /Profile/HFPAudioGateway
bluealsa: main.c:201: Starting main dispatching loop
bluealsa: bluez.c:834: Profile method call: org.bluez.Profile1.NewConnection()
bluealsa: transport.c:553: State transition: 0 -> 2
bluealsa: transport.c:94: Created new IO thread: HSP Audio Gateway
bluealsa: bluez.c:773: HSP Audio Gateway configured for device E4:22:A5:08:7B:FF
bluealsa: transport.c:553: State transition: 0 -> 2
bluealsa: io.c:1151: Starting IO loop: HSP Audio Gateway
bluealsa: transport.c:94: Created new IO thread: HSP Audio Gateway
bluealsa: io.c:1009: Starting RFCOMM loop: HSP Audio Gateway
bluealsa: io.c:1064: AT command: +VGS=08
bluealsa: io.c:1064: AT command: +VGM=15
bluealsa: ctl.c:543: New client accepted: 8
bluealsa: ctl.c:546: +-+-
bluealsa: ctl.c:546: +-+-
bluealsa: ctl.c:326: PCM requested for E4:22:A5:08:7B:FF type 2 stream 1
bluealsa: ctl.c:546: +-+-
bluealsa: io.c:72: Opening FIFO for reading: (null)
bluealsa: io.c:93: Opening FIFO for writing: /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-2-1
bluealsa: transport.c:758: New SCO link: 13 (MTU: R:48 W:48)
bluealsa: ctl.c:401: PCM close for E4:22:A5:08:7B:FF type 2 stream 1
bluealsa: transport.c:791: Cleaning PCM FIFO: /var/run/bluealsa/hci0-E4:22:A5:08:7B:FF-2-1
bluealsa: transport.c:798: Closing PCM: 12
bluealsa: ctl.c:546: +-+-
bluealsa: io.c:72: Opening FIFO for reading: (null)
bluealsa: transport.c:768: Closing SCO: 13
bluealsa: ctl.c:515: Client closed connection: 8
bluealsa: ctl.c:546: +-+-

The file size of mic.wav does not change at all, it's always 44 bytes no matter how long I wait. I also tried to add -d 3 to the arecord command, so it stops after three seconds, but this never gets reached. I have the feeling that arecord is waiting for something to start counting. When I try to play the 44 bytes mic.wav, it returns immediately without playing anything.

On the other hand when I do arecord -f S16_LE -d 3 mic.wav it will stop after 3 seconds with a mic.wav with size 47k, playing for 3 seconds in aplay.

Can I try or post anything else to help?

@arkq
Copy link
Owner

arkq commented Nov 9, 2016

In logs everything looks OK (except one thing, A2DP profile seems not to be connected, which is odd, however is happens with my setup from time to time - try issuing connect (from the bluetoothctl) and see if A2DP will connect).

44 bytes in the WAV file is a header, so there will be no sound :)

So the question is, if your Bluetooth headset is compatible with bluez. I might try to make some adjustments, so you will be able to test it. However, if you are sure that the microphone works (e.g. it works with PulseAudio) you might try to insert few debug statements in the io.c in these places:

Simple fprintf(stderr, "1"); will do. just put different numbers in "" every time, so you will see from where is the print. So when you connect to the SCO profile in the capture mode (arecord), every print except line 1202 should print like crazy - 8kHz mono with 48 bytes per read with sample width 2 bytes, so the iteration should be at exactly 333.(3) prints per second. If there is no output, make sure that your headset is "supported" by your kernel and bluez.

EDIT:

For more thorough investigation you might try using tcpdump like this. Before connecting headset, run tcpdump as follows:

# tcpdump -pn -i bluetooth0  -w /tmp/bluetooth.tcpdump

then connect device, and try to record audio - wait for few (3-5) seconds. Then see what is in logs using wireshark. There should be A LOT of packets from headset, which will indicate incoming audio, so the the problem is somewhere between kernel and HCI (or something). You might also try to use hcitop (shipped with bluez-alsa in the utils directory), just run it, and you should see incoming bandwidth (reported by the HCI).

@ghost
Copy link
Author

ghost commented Nov 12, 2016

With PulseAudio I didn't even manage to play music to my headset. I have the feeling it uses a call protocol and I should answer the call from my headset, but that also did not work.

I'm having the idea that when I want to record through bluez-alsa it might also be recognized as an incoming call somehow, because it always plays three beep sounds when I want to do this recording connection (SCO). Tried to hit the answer button, this lead to bluealsa: io.c:1064: AT command: +CKPD=200 in the bluealsa output.

The headset has three options to answer calls:

  1. click button
  2. take headset and put on ear (if not already worn)
  3. say "answer"

Number 1. and 2. both lead to the signal bluealsa: io.c:1064: AT command: +CKPD=200, saying "answer" did nothing (but who knows if I did it right, never tried this before). So I am pretty positive, that this has something to do with the phone call functionality.

I'm just not sure if you can do it or if bluez guys would have to do it and did not do yet. As said, I tried to play some music with PulseAudio, which also lead to this incoming call beep in my headset. So I pushed the button and nothing happened...

Edit:
From the hcitop output, I would say that my headset does not send any data yet. It's at

HCI       RX       TX     RX/s     TX/s
hci0    15 KB    14 KB      1 B      0 B

quite stable, just the received and transmitted bytes per second sometimes go up/down a bit (but not connected to when I speak; but connected to when I push a button). E.g. when I push the answer button, it shortly goes up to 30 Bytes/s and then drops again. Every few seconds it goes to 6 Bytes/s.

So does not really look as if any audio is transmitted.

If I on the other hand play some music to my headset with A2DP then the transmission goes up a lot:

HCI       RX       TX     RX/s     TX/s
 hci0    16 KB   113 KB    166 B  29620 B

I assume if there was some transfer of audio when recording, the RX should also be in the area of 20kB/s.

@ghost
Copy link
Author

ghost commented Nov 12, 2016

I tried adding debug outputs, but everytime I add some debug code to your code, I get this error message on execution later:

$ arecord -f S16_LE -D bluealsa:HCI=hci0,DEV=E4:22:A5:08:7B:FF,PROFILE=sco mic.wav
bluealsa-pcm.c:102: Getting transport for E4:22:A5:08:7B:FF type 2
ALSA lib bluealsa-pcm.c:636:(_snd_pcm_bluealsa_open) Couldn't get BlueALSA transport: No such device
arecord: main:786: audio open error: No such device

I'm using the arch linux AUR package as base. At first, I tried adjusting it inline with sed - worked fine according to the code, but error above.

Then I went as far as downloading the code from git and storing it to a zip file and adjusting the source path in PKGBUILD. First time I kept everything in original, makepkg -si. Execution is ok (just no sound recorded). Then I copied one of your debug lines so that it should get executed twice (src/io.c#72). Same procedure, error above. Ok, so I deleted my line again from the code, again makepkg, works.

Before each execution of the newly installed package I stopped and restarted bluealsa and reconnected the device.

md5sum for the main code is set to SKIP in PKGBUILD, so that should be fine (would have give me an error on package build process otherwise, I assume).

Confusion completed...

@arkq
Copy link
Owner

arkq commented Nov 12, 2016

Wow, pretty bit of a struggle you've got there :)

But seriously now.

it might also be recognized as an incoming call somehow,

The 3 beeps sound (I guess) indicates that the audio gateway (e.g. phone) has initialized SCO link - the audio is about to be transferred. Incoming call might be indicated by the special RING message sent to the headset (I'm not supporting it right now), or playing "ring" tone. Please, try using aplay with the SCO profile as follows:

aplay -f S16_LE -D bluealsa:HCI=hci0,DEV=E4:22:A5:08:7B:FF,PROFILE=sco test.wav

but make sure, that the test.wav is a 8000 Hz mono (this should eliminate necessary audio conversion, because the SCO link supports only monophonic sound with 8000 Hz sampling rate). If there is no sound in the earpiece, it is definitely something wrong. Also check hcitop and tcpdump if possible. It should allow to narrow the possible cause of this malfunction.

Number 1. and 2. both lead to the signal bluealsa: io.c:1064: AT command: +CKPD=200, saying "answer" did nothing (but who knows if I did it right, never tried this before).

The debug line showing "+CKPD=200" is a good thing. It is a signal (with a compliance to HSP) transferred from the headset to the audio gateway (in this case bluealsa), which indicates "button pressed". The HSP standard has only this one message (it is not possible to distinguish buttons or any other user actions) available to notify that one wants to answer the call. After this message, audio gateway should start transferring audio, however bluealsa is playing (in the HSP mode) without waiting - which is OK according to the HSP standard. Buuuut, I'm not sure if it is mandatory to transfer the sound from the headset to the audio gateway (in this case, a sound picked up by the microphone) just after the SCO has been established. So, the cause of this "issue" might lay somewhere here.

I assume if there was some transfer of audio when recording, the RX should also be in the area of 20kB/s.

The transfer rate for SCO should be about 15000 bytes/s in both directions - RX/s TX/s. Though, the TX/s should only be "activated" when one is using playback device (aplay ... PROFILE=sco ...). For A2DP with SBC encoding, it is about 30000 bytes/s.

And just one question, are you able to use this earpiece with a smarphone (preferable Android-based) or any other device or OS?

And for testing, it might be better to compile bluealsa from the source code all the way up. Just compile it (without make install) and use created executable. There is no need to modify ALSA modules, so running bluealse from the build/src directory will do. I'm not an Arch user, so I don't know the best practices for debugging on such a distro, but compilation from the source has been always good for me :D.

@arkq
Copy link
Owner

arkq commented Feb 12, 2017

Hi,

I don't know if you are still using bluez-alsa, but if yes, you might try to use a fresh master snapshot. Recently there was "exterminated" one bug (#22) which might have been related to this issue.

@morrolinux
Copy link

Hello, I've tried the above:
arecord -f S16_LE -D bluealsa:HCI=hci0,DEV=FC:58:FA:12:7A:7E,PROFILE=sco mic.wav
but still no audio is captured, is there any chance I might have gone wrong with something?
I need to capture audio form a Bluetooth speaker's microphone as well

@NA-Dev
Copy link

NA-Dev commented May 26, 2018

I also need to know how to get arecord working with a bluetooth device. With the following in .asoundrc, aplay works and arecord starts, but ignores duration and never stops.

pcm.!default {
	type asym
	capture.pcm "btmic"
	playback.pcm "btspeaker"
}

pcm.btspeaker {
	type plug
	slave.pcm {
		type bluealsa
		device "XX:XX:XX:XX:XX:XX"
		profile "a2dp"
	}
}

pcm.btmic {
	type plug
	slave.pcm {
		type bluealsa
		device "XX:XX:XX:XX:XX:XX"
		profile "sco"
	}
}

@kunupat
Copy link

kunupat commented Jul 10, 2018

@NA-Dev I am facing the same problem. Did you get it resolved?

@arkq
Copy link
Owner

arkq commented Dec 15, 2018

Please, use oFono backend for HFP profile - #172. Internal HFP support is not "production ready".

@saiedt
Copy link

saiedt commented Aug 21, 2020

I have a device that has both mic and speaker. bluetoothctl says that the device can act as both audio source and audio sink (but it does not show headset or handsfree). I have started bluealsa with both -p a2dp-source and -p a2dp-sink. Nevertheless, I am not able to get the audio stream from the mic (the device audio source profile).
Am I right when I assume that it is bluealsa that is lacking the feature to access mics over a2dp-source profile?

@arkq
Copy link
Owner

arkq commented Aug 22, 2020

bluetoothctl says that the device can act as both audio source and audio sink (but it does not show headset or handsfree)

@saiedt please, post the output of bluetoothctl which shows profile listing (preferably in new github issue).

Am I right when I assume that it is bluealsa that is lacking the feature to access mics over a2dp-source profile?

Yes, you are right, accessing backchannel is not yet supported in bluez-alsa master branch.

@lorenzever
Copy link

After a lot of head scratching, I think I found what was going wrong. I saw some key aspects are missing when bluealsa service is getting started.

By default, the bluealsa service is starting with only with "a2dp-source" profile. This is only for playback of audio. But for recording audio, it needs "a2dp-sink", "hfp-ag", and "hsp-ag" profiles.

Use below command if you are using any raspberry or ubuntu based distributions. "systemctl cat bluealsa" This shows the unit file for "bluealsa" service. it should have the below line for ExecStart. ExecStart=/usr/bin/bluealsa -p a2dp-sink -p a2dp-source -p hfp-ag -p hsp-ag

3.Usually what I have observed is with out any -p options passed to it. change the unit file and restart the service. Note: whenever any systemctl unit files are changed, the below command must be executed to take changes into effect.

  1. "systemctl daemon-reload"
  2. systemctl restart bluealsa
    4.Another thing to note is: using profile "sco" in asounrc file.

recording audio should work after these changes! This is what worked for me! after a long ordeal!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants