Friday, February 23, 2007

Stereo Bluetooth Profile (A2DP) on Mac OS X Tiger

This post is now obsolete, please check out the new instructions which use Jack Audio, here.

Using the following instructions will allow full use of stereo bluetooth headphones on a mac without waiting for Leopard! Unfortunately The audio is delayed by nearly a second because this is such an indirect method.

I have an old ibook with a D-link bluetooth adapter (with upgraded firmware for headsets). After following all the instructions (I am a novice, but I think everything's as it should be), when I run the a2dp.sh shell script in /usr/local/bin I get this message in terminal:a2dp.sh: line 5: sbcenc: command not founda2dp.sh: line 5: bttest: command not found

Any ideas? does this mean it won't work on PPC macs? are sbcenc and bttest compiled only for intel macs? Have I understood correctly that, after downloading btplay02.zip, I copy just the sbcenc and bttest executables into /usr/local/bin, and nothing else?

Great - that solved the issue, and the shell script now seems to try to start the stereo BT process correctly.

Unfortunately, I still can't get it to work. I'm going to keep fiddling with it tomorrow, and I'll post back if I can get it to work, or with the error messages - thanks for your help getting me this far.

I've tried to make sure that I've done everything right, but I still can't get it to work on a PPC 800MHz iBook, with the HT820 headset. I'm using an external BT adapter from Dlink (with updated firmware which supports headsets).When I run the script, the computer connects to the headset, and terminal returns this:

Activity monitor doesn't show the the processor being overloaded (I forgot to mention it is a G4), or any obvious problems with RAM (I have 640Mb). One day I may go to the trouble of booting from an external drive to see if faster disk access or usb hub power is an issue.Maybe someone has got it to work on an iBook with internal bluetooth?

I am so close, yet so far away. When I run my a2dp.sh I can only hear the sound from the microphone on my S805 looped back to me. That sounds to me like I've set the input wrong - but I am unsure how to specify to esdrec which audio device to pull from. Can anyone tell me what obvious step I am missing?

Just to let anyone who is interested know, I'm using a D-link BT adapter, "rev B3" model, with firmware updated to BT class 1.2 using Apple's updater. Terminal says "discover : try again", "Too short received data!" & "Can't open stream port" etc. (see my previous post above) when I use the D-link adapter.I swapped it with a regular BT adapter which is incompatible with headsets on a mac (i.e. class 1.1 bluetooth adapter - the one that comes bundled with the motorola stereo BT headsets) and terminal spits out the very same message about not being able to establish a stereo connection with the headset (even though the shell script succeeds in pairing the headset to the mac with either BT adapter). That seems to imply that my BT dongles can't interact with the mac and a stereo headset - right?Has anyone with a PPC mac and internal BT got it to work?

This worked excellently for me, although I am quite disappointed with the delay. I try to watch a video, and they delay makes me want to rip my hair out. And solution to this would be greatly appreciated. :)

I'm trying to get the Motorola S9 working on my MacBook Pro (Intel) and am having a strange problem - the only audio which will come through is via the build-in Mic. I think I have tried changing ALL the settings in Soundflowerbed, even tried running esd with -d /dev/audio, /dev/sound, /dev/mixer (which don't exist on the Mac anyway) to no avail. I can MUTE the mic and get no sound but I cannot get the actual audio playing in iTunes. I get no errors and other than the echo, it *does* work to play iTunes through the speakers, get picked up by the Mac mic, and then sent to the headphones, just sounds really bad and obviously the reason for headphones is so everyone else doesn't have to listen :).

Works well with Motorola HT820. But when attempting to connect to Motorola DC800 get the following screen outputTaifs-MacBook:~ Taif$ a2dp.shmkfifo: /tmp/mixer: File existsopening socket, format = 0x00002021 at 44100 HzBluetooth SBC player ver 0.1frm_len = 68

I've gotten this to work with a Plantronics Pulsar 260. It took me a while to get it to work, however, as I had to change the Audio format to 44100.0 Hz for the various audio devices before esd would work.

I'm using a Jensen WBT212 headset with a new MacBook (built-in bluetooth). I know my esd is fine, since it produces sounds upon startup if I direct the output to the internal speakers instead of SoundFlower. I know the Bluetooth connection is fine because I can send over (horrible sounding) audio by selecting the headset directly in the Sound part of System Prefs.

When I run the script, though, I get the same output as Taif reported above (mine is pasted below). Suggestions would be most welcome, I'd really love to get this working!

same here. running on a macbook. I've had mplayer working for fairly long periods before the "delayed = ..." error and also noticed that the sound sampling rate varies... sound slooooowwwwsss ddooooowwwwwnnnnn before the delayed error kicks in. (mplayer is great since it allows you to vary the audio offset and remove that delay through this method). Itunes however just kills this pretty much immediately for me.

I just purchased a Jabra BT 620s stereo headphones, to my disappointment i found out that osx does not support stero sound over BT and my Palm LifeDrive does not support BT headphones period!I found a hack for my pda just about the time I found this postI'm listining to stereo heavy rock music on my headphones from iTunes as I'm hacking my palm to have the same feature.

I cannot get this to work on my iMac G5. Since no PPC user has reported this working, I'm assuming it likely does not work on a PPC Mac. I get the same error as Kamon. It appears that it never can hook up with the 'phones. The discovery does not appear to work. I am using the iLuv i903 headphones.

Re: PPC, it doesn't work. It works fine on a Intel Mac Mini, but not on a PPC iBook G4.

I messed around with the code for bttest for a while and found that swapping bitfields around allowed the iBook to connect to the device (a Jabra BT320s) when it wouldn't discover it previously (error was "discover: try again"), but still only silence.

I get the feeling it is very nearly "there" but there's a final hurdle.

I now have it working on PPC (and Intel). I'm not sure who to contact to have the changes integrated into the btplay zip download, anyone know?

It looks like the core part of btttest needs to be run using realtime scheduling, I find that the slightest use of the computer while it is transmitting to my Jabra BT320s causes gaps in the music, and the music pitch can "wow" presumably because the device is receiving the audio packets at an uneven rate. This iis the same for both Intel and PPC.

BTW the Jabra 320s sounds great, the best thing being that it is a receiver which is separated from the headphones, meaning that you can plug in your own favourite 'phones instead of having to put up with what you're given.

Great news about updating sbcenc and bttest for PPC, but I still can't get it to work. Like Justen, I'm getting static, though it comes and goes and doesn't seem to correspond with anything in particular.

Hey David, it's syperium@gmail.com. I now know why it wasn't working... and I was very stupid for not figuring it out before. My headset was paired with my cell phone. But... you were right still. It doesn't work with PPC.

So... even with help from David, the Motorola HT820 does not work with and iBook G4. All I get is static.

The PPC "static" issue is very strange as the current download works fine on my iBook G4 (as well as my Intel Mac Mini) with the Jabra BT320s. The only difference is that I wasn't using esd (it won't start up on either my iBook or Mini, it errors with "unsupported device.").

This leaves me wondering if esd doesn't work properly on PPC, as I've been using sbcenc and bttest fine on PPC.

I'm a bit confused with what I'm suppose to do with the SBC sample. Do I replace a file with it...? Or... do I put it somewhere? And, the command line edit. Do I change it in the 'a2dp.sh' file? Or... a different file?

I also tried your altered line of code, and instead of static, I now get snippets of sound! Sometimes up to about 10 seconds of a track, but quite often there are long gaps of silence. When it works, it actually sounds pretty good - it's close!

My setup is ibook G4, a slow 800mHz, with the motorola HT820 headphones. The processor doesn't seem to be overtaxed. But another factor in the mix is that I'm using a D-Link adapter - maybe your altered line of code will be enough for PPC Macs with built in bluetooth 2.0+EDR modules ... (like Justen?). Any other ideas or tweaks would of course be welcome - thanks.

Regarding the audio gaps, I suffer the same problem on my 1.33GHz iBook G4 and 1.5GHz Intel Mini with the current download. The problem is that the Bluetooth A2DP audio transmission is very time-sensitive and if the Mac decides it has to do something else then you get gaps.

MacOS provides a way to give a process priority and I've been experimenting and have something which is working pretty reliably (using real-time scheduling, if interested).

This has only been done for bttest so far when really it needs to be done for the whole command chain starting with esdrec. Ideally it would all be integrated into one command and if we can get it working with JackOSX it'll be worth the effort to do it.

To try the current effort at a real-time bttest, download it from here:

http://www.coolatoola.com/bttest.zip

Incidentally it looks like sbcenc already provides a byte swap function, meaning that you can get rid of the new PPC "dd conv=swab" command and simply add the '-b' option to sbcenc.

I am trying to use this on a MacBook Pro with Jensen WBT212 headphones. It is connecting and is able to output sound, but the sound is messed up. When I play music, it makes a short noise every 5-10 seconds. When I do not play music, it makes no noise, so I think it is actually trying to play the audio. I have tried every bttest you've linked to, and it is the same.

Unfortunately I can't test using esd as it won't work on either of my Macs. It's beginning to look as if the entire record/SBC encode/bttest command chain is going to have to be integrated into one high priority command. Fortunately I've found a recording application which doesn't need esd AND which works with Jack and it may not be too much work to create a single process as mentioned above.

As a test, try recording SBC into a file (replace "| bttest $ADDR -" with "> FILE.sbc" (replace FILE with a filename of your choice) - this will record into a file in SBC format instead of sending to the headphones. Once you have recorded a decent amount of audio to test with, do control-C and then "bttest ADDR FILE.sbc" to play the file out to the headphones. Make sure you use the bttest version from the location given in my previous post rather than the standard one included in the download.

Doing this should give you stable audio and it should usually survive you using the Mac of other things at the same time.

Tim, I've tried the latest bttest version, and there are far less gaps in playback. But still too many to make it useable, and you're right about the gaps occuring when the computer is asked to do something.

I also did a test recording, outputting an .sbc file, and playing it back - there doesn't seem to be any gaps. But in the recording, I'm starting to hear what you call the pitch 'wow' much more. And the tempo 'wows' too - in the recording (or at least when playing it back) it is very marked.

But, I do have another problem that I don't know how to fix. When I try to open the 'a2dp.sh' file in Terminal, I get this annoying message that terminates the command. It says 'This is not an SBC file'. I have no idea what the problem could be...

Tim, I downloaded the new bttest again, copied it to my local bin folder, and recorded another 2 minutes of music. Playing it back is totally gapless, and I can do other things at the same time, like type this comment (of course if I really tax the processor, I can produce gaps). But every now and again the recording stutters, speeds up, slows down, and messes around with pitch and tempo (I've listened over and over again to check whether it was the recording itself or the process of playing it back which contained the 'wow' effects). Really all of that is only minor though - it has no gaps and is already a great improvement on the live process. My machine and BT dongle are very old technology - maybe they have too many additional bottlenecks compared to your PPC machine ...

I've just realised that Soundflower doesn't need (or no longer needs) to be selected as the input device for this to work ... It only needs to be set as the output device.

This all at least proves that reliably transmitting A2DP is fundamentally possible even on a 800MHz G4 using a USB 1.1 Bluetooth device. The pitch deviation and gaps were probably caused by hard disk delays reading the SBC file - even high priority processes have no choice but to wait for hard drives :-) . Also you can get pitch issues if radio noise causes the headphones to lose contact with the Mac temporarily (or if you go out of range etc.) and then recover.

I'm expecting that hard disk delays will disappear with a process which integrates recording, SBC encoding and A2DP transmission, since the entire process will keep the data in RAM.

I'm working on that and feel it isn't too far away. So far I've had a process which has recorded from JackOSX, piped that to sbcenc in the same way as esdrec and played it out to the headphones with a delay of about 0.5 seconds. The delay should come right down to the SBC framelength (plus whatever Jack adds) which amounts to 1-2ms, or the PCM frame size received from Jack which is 256 stereo 16 bit samples - about 6ms. Those are low latency figures. It could happen...

Here is an integrated process for Mac A2DP which works with Jack (on PPC at least). I can't get it working with Jack on Intel at the moment, not sure why yet although recording from the built-in audio device works fine.

I have renamed the tool from bttest to a2dpcast.

What it now does is to record from the current sound input device as set in System Preferences, convert it to SBC and transmit that to the headphones. If you want to use JackOSX as the sound input, just select it in System Preferences as usual. To listen to iTunes, use the Jack router window to connect iTunes to a2dpcast (on PPC only as mentioned, though your Intel mileage may vary).

Then run it using "a2dpcast ADDR", replacing ADDR with your device's address as previously. No need for the old shell script as everything is now integrated into a2dpcast.

The tool does detect the incoming sample rate and adapt the SBC encoder and headphones to suit, but if the rate changes (as it can do by itself for Macs with optical digital inputs) you need to restart a2dpcast to have it adapt.

Lipsync is very good (i.e. audio latency is very low), at least if you use the built-in audio input device, but any radio glitch or other loss of contact between the headphones and Mac can cause this to be lost, at least for a time (I've seen it recover). At its best the lipsync is so good that you can't tell that your 'phones aren't directly connected. Also assuming decent reception, the pitch wow is minimal and resistance to the Mac being used for other things is high.

In addition to my last post, and as credit, this work has been very much piggy-backed on top of Apple's AudioFileTools example in /Developer/Examples, in fact there is a lot still there which isn't needed...

The creator of bttest (i.e. "bkc") will still recognise his code in spite of the severe mangling needed to have it all integrate.

I don't know what the set_config error is but mine does it too. I don't know why you're not getting audio, do you use the headphones right next to the Mac? From those logs everything is looking good, or normal at least.

I'm going to go back to the Linux roots of the bttest source and see how well it works with that. I'm suspicious of how well the tinny/mono audio that MacOS X System Preferences sends directly to the 'phones works when the phones go to the limit of the range - there's crackle and glitches but no huge gaps. If that behaviour can be transferred to the A2DP code then we're cooking, and it would be interesting to see how well Linux manages.

I tried to follow all instructions and succeeded insofar that from the bluetooth setup assistant I cannot pair. iStumbler allowed me to pair the Jabra BT320s via the A320s dongle. Upon running a2dp.sh both with bttest 1 and 2, I get the following result:opening socket, format = 0x00002021 at 44100 HzBluetooth SBC player ver 0.1frm_len = 69open : control channnelFailed to open connectionconnectBTdevice : ngI copied the device ADDR from iStumbler, using both notation $00-16-8f-etc as well as $00168fetc. Any hints?

Running Powerbook G4, using bttest2, entering the device address as a series of 0-9a-f without preceding $ or 0x, I managed to pair a BT320S via an A320s dongle. The device was unpaired at that moment, I discovered its address through iStumbler as the Bluetooth configuration assistand told me 'headsets are not supported on your Bluetooth hardware'. The result is a purple breathing jabra BT dongle and an intermittant hissing when an audio source (eg. iTunes) is activated. 8 sec silence, 2 sec hiss, processor load is neglegtible. From the hissing one can deduce that someone is speaking (podcast). This is the output of the terminal at that time:

I'm using the Jabra BT320s using an iBook G4 1.33GHz and Intel Mac Mini 1.5GHz, both running OS 10.4.9. It paired fine using the Bluetooth pane of System Preferences with it set to search for headsets. Perhaps you are using an older version of OS X?

The best way to enter the device address is to copy/paste it from the device listing in System Preferences.

In attempting to pair using the bluetooth assistant assistant, the very second I click 'continue' in the step to search for bluetooth headsets, I get a dialog 'Failed to setup the headset. Headsets are not supported on your bluetooth hardware'. I'm running 10.4.9, on a 1 GHz TiBook G4. The bluetooth hardware is the A320s dongle on the USB 1.0 bus in the back of the TiBook.When I start a2dp.sh, I get a 'seemingly BlueTooth setup assistant' dialog that asks for a passphrase. After that, the headset is showing up in the Bluetooth Devices list of the system preferences.I cannot configure however, the bluetooth setup assistant says 'therre were no supported services found on your device'. Continuing the setup congratulates me with my computer now being setup to use my bluetooth headset.The headset is now blinking purple and is quiet until I start an audio source. The processor load (using menu meters) shows less than 25% load.Switching on the SoundFlower output and starting to play iTunes gives a continuous hiss. The sunfower input input level jumps up and down wildly.Pausing iTunes both stops the hiss and seemingly unrelated motion in the input devices input level.

Pairing is no evidence of working apparently. When changin ghe A320S Jabra dongle for a D-link DBT-120, the BT320S could be paired with without a hitch. The system preferences 'sound' now show both soundflower and Jabra BT320s. The soundflower still sends the hissing. It sounds as if 16-bit sound is sent, but is clipped to 8-bit sound; silence is OK, the moment a person starts to speak in the podcast you can hear them breath in and start speaking the first vowel, then hissing follows and this is repeated in every spoken word.When one switches to the Jabra BT320s sound output in the system preferences 'sound' however, the sound is reasonable. Not HiFi stereo, but clearly one can hear the music and the spoken text, both overlayd with a substantial amount of noise.It seems that I have had quite a workout to discover that the A320s is not supported and the audio quality of the BT320s is, well, not hifi.

Don't select the Jabra in the System Preferences Sound pane as this is for mono telephony quality only (hands free profile). Instead choose your normal sound input and use the a2dpcast program, this will record from the sound input and transmit it to the headphones, and will have hifi stereo quality.

I followed your recommendation and indeed, audio quality now is as it should be. Occasionally the audio is dropped (processor load only reaches 50%) but quality is certainly hifi. Now I guess I just have to find the software to operate the mac via Bluetooth using the BT320s controls ;-)

I have a macbook pro and a Scosche BTHPK headset and now that i have this fix it's clearer than using the dongle that it came with.

For awhile I was hearing noise from both my headphones AND my speakers until I clicked the "routing" button in jackpilot, clicked "itunes" under send ports, and after made sure to double-click "a2dpcast" ALSO made sure to double click "aggregate device". The latter turned off the laptop speakers.

I just found this conversation. I have a new Macbook with the Motorola HT820 headphones. The phones are "paired" and working fine but the sound is bad (like I'm in a tin box). Is this the problem for which you all are providing the remedy? I'm a bit of a novice. So if I follow your directions, my ears will be "happy"? Thanks in advance.

Metal: MacBook Core Duo Headset: Dell BH200Tips: Make sure you d/l the XCode first. Let it run, and dont do any sound configs in the meantime. Install Soundflower. It took me about 10 minutes to run the process. D/L the bttest and go to your bin directory - which is hidden - unlock it by typing this in the terminal: defaults write com.apple.finder AppleShowAllFiles -bool TRUE . Now edit the a2dp.sh file in the desktop then transfer it over. Apple protects itself from the user so it's not going to keep asking you for your pass along the way, and this is the path of least resistance.

Now: Specify i/o as soundflower in the sys prefs. Run the process. Does it work? For me it didn't, however when I switched to my headset from the sys prefs afterwards, it did. So follow the instructions above, and do a little debugging, and you should be good.