The State of Bluetooth Headset in Linux

A few days ago, I bought a shiny Sony SBH80 bluetooth headset. This is my first bluetooth headset ever, so I thought I’d share my experience in setting it up.

Android

Yes, Android is Linux, just not the regular one ๐Ÿ™‚
I have a Nexus 5 phone and since it comes with KitKat, the headset is fully supported. Audio quality is superb (both for streaming music and making calls). The only annoyance I experienced is that the headset need to be disconnected from the phone first before connecting it with PC. When the connection with the PC is established, you can then reconnect it with the phone (yes, it supports multiple connections).

Gentoo

I’m running the unstable Gentoo Linux, so I always have the (relatively) latest packages available. I have BlueDevil 2.0_rc1 installed as part of my KDE desktop, along with BlueZ 5.18 as its dependency. BlueDevil easily established the connection with the headset but I couldn’t use it as audio output/sink.

After a quick research, I found out that BlueZ needs to have PulseAudio support to make use of the headset functionalities. I then rebuilt it (along with some multimedia packages) with PulseAudio support. After logging in back to KDE, the headset worked. All I needed to do was giving the headset the highest priority in KDE Phonon settings, so when it’s available, Phonon will use that as the output, otherwise it will revert back to the other available devices.

However, I couldn’t make the microphone work. After some digging, I found out that HSP & HFP support were removed from Bluez 5.0, so until oFono provide those profiles, there’s no way to use the microphone ๐Ÿ™

I was curious and downgraded BlueDevil, Bluez and some other packages to their previous versions that support HFP & HSP profiles. I also removed PulseAudio support from my system since it’s not required. I had to add the following lines to /etc/asound.conf to make the headset recognized by ALSA:

pcm.sbh80 {
        type plug
        slave {
                pcm {
                        type bluetooth
                        device xx:xx:xx:xx:xx:xx
                        profile "auto"
                }
        }
        hint {
                show on
                description "Sony SBH80"
        }
}

ctl.sbh80 {
        type bluetooth
}

After that, the headset worked as audio sink but the microphone was not working still. I then found out that to make use of the microphone, the audio sink service need to be disabled. Enabling only the HFP/HSP profile without A2DP profile with BlueDevil wasn’t possible, so I installed BlueMan and it worked!

However, the sound quality was terrible and often times, Phonon won’t switch to the headset when it’s availabe, and won’t revert back to the built-in sound card when it’s disconnected. Ouch!

I figured, if I added PulseAudio support, the switching should be smooth, and I did. For the most part, it worked, but there’s this delay when the system is making an event sound which was really annoying.

Finally, I reverted back to Bluez5 with PulseAudio support and ‘sacrificed’ the microphone (I don’t do audio chat that often and my built-in mic is working fine anyway). It’s not what I really wanted, but it’s the best option I got and I’m quite happy with it.

PulseAudio Equalizer

pulseaudio-eq

Finally got PulseAudio’s equalizer working. It consumes 1-4% of my 2.30GHz i5 CPU (Clementine’s built-in equalizer consumes 4-7%, btw), and sounds really good ๐Ÿ™‚

In Gentoo, all you need to do to get this working is to install pulseaudio with equalizer USE-flag enabled (may need to unmask the unstable ebuild) and append this line to /etc/pulse/default.pa or ~/.pulse/default.pa (you can change the sink name to your liking) :

load-module module-equalizer-sink sink_name=equalized

After that, quit all applications that use pulseadio and restart pulseaudio:

pulseaudio --kill && pulseaudio --start

Now you should be able to use the equalized sink name for your multimedia application. For example, in Clementine, go to Tools ยป Preferences ยป Playback and change the Output plugin to PulseAudio Sink and fill the Output device field with your equalized sink name (equalized in the above example).

While Clementine’s playing, adjust the equalizer levels by running qpaeq. All done! ๐Ÿ˜‰

KDE 4.8 Taskbar

I’m not really sure if this feature is part of KDE SC 4.8, but it’s so cool and I feel like I have to write about it here ๐Ÿ™‚

kde-taskbar-4.8

See the screenshot above? KDE’s default taskbar is now more powerful than ever! Right clicking on a taskbar item now gives you the ability to start a new instance of that application, and add a launcher of that application to the taskbar when it’s not running.

I know, it’s pretty similar to what Windows 7 offers, except (IMO) it’s waay cooler. In Windows 7, if you pinned an application to the taskbar, it will only show an icon, without the application name/window title, no matter the state of the application is (running or not). In KDE, well, you guessed it, if the application is not currently running, an icon will be added to the taskbar, and it will disappear when it’s launched.

If you really want Windows 7’s taskbar in KDE, you can install this plugin ๐Ÿ™‚

Move Cursor to the Next/Previous Paragraph in Kate

It kind of irritates me that Kate doesn’t have a builtin functionality to move cursor to the next/previous paragraph. Fortunately, as with most KDE SC applications, Kate is extendable with custom scripts. So here’s my solution for the mentioned problem.

/**
 * kate-script
 * author: Dzikri Aziz <kucrut@kucrut.org>
 * license: GPLv2
 * revision: 3
 * kate-version: 3.4
 * type: commands
 * functions: jumpUp, jumpDown
 *
 * Move cursor to next/previous paragraph
 */

function jumpDown() {
  return _jump();
}


function jumpUp() {
  return _jump( true );
}


function action( cmd ) {
  var a = new Object();
  if ( cmd == 'jumpUp' ) {
    a.text = i18n('Move cursor to previous paragraph');
    a.shortcut = 'Alt+Up';
    a.icon = "";
    a.category = "";
    a.interactive = false;
  }
  else if ( cmd == 'jumpDown' ) {
    a.text = i18n('Move cursor to next paragraph');
    a.shortcut = 'Alt+Down';
    a.icon = "";
    a.category = "";
    a.interactive = false;
  }

  return a;
}


function help( cmd ) {
  if (cmd == 'jumpUp') {
    return i18n('Move cursor to previous paragraph');
  }
  else if (cmd == 'jumpDown') {
    return i18n('Move cursor to next paragraph');
  }
}


function _jump( up ) {
  var init   = curPos = view.cursorPosition().line,
      lines  = document.lines(),
      target;

  if ( document.firstColumn(curPos) == -1 )
    curPos = document.prevNonEmptyLine(curPos);

  if ( up === true ) {
    target = 0;
    while ( curPos-- > 0 ) {
      if ( document.firstColumn(curPos) == -1 && document.nextNonEmptyLine(curPos) != init ) {
        target = document.nextNonEmptyLine(curPos);
        break;
      }
    }
  }

  else {
    lines--;
    target = lines;
    while ( curPos++ < lines ) {
      if ( document.firstColumn(curPos) == -1 && document.nextNonEmptyLine(curPos) != init ) {
        target = document.nextNonEmptyLine(curPos);
        break;
      }
    }
  }

  view.setCursorPosition(target, 0);
}

Save this script as jump.js inside katepart directory in your KDE user directory, eg: $KDEHOME/share/apps/katepart/script (just create the sub-directories if they don’t exist yet) and relaunch Kate. Now you can move the cursor to the next paragraph by pressing Alt+Up or the previous one by pressing Alt+Down. You can freely customize the shortcut from Settings ยป Configure Shortcuts.

Any improvements are welcome!

As a bonus, here’s the scripting guide I printed from Google cache.

Smart Firefox

I just love the fact that Firefox remembers the directory/folder you last used to save a downloaded file from a particular site. Just select Always ask me where to save files in Preference » General » Downloads and you’re set.

NOT in that thing called Chrom(e|ium) ๐Ÿ˜›