Autumn is Coming…

With summer nearly over a summary of my effort is in order. First up are the improvements to Banshee’s Media Transport Protocol support.

Please Try Again

I showed a similar screenshot to the one below some time ago. After some massaging by Andrés and I this is the final result, as depicted by an Ubuntu Trusty Tahl system. I’ll be proud indeed when this quite significant visual component appears in the public repositories!

In addition to the visual element, the same patch prevents Banshee from interfering with the desktop’s automatic mounting system and allows us to give the user quick feedback in cases where we’re not able to initialize his device.

There are a few other changes in the pipeline ranging from improving the feedback during an MTP device’s connection process [1] to a small but quite important revision in the way we deal with disconnection [2] but this one is by far the most important for every day use.

Device Unavailable

One Page to Rule Them All

Aside from a couple of patches required in dbus-sharp [3,4] to make this work, Bluetooth synchronisation is off the stove and cooling on the sideboard.

With respect to the project’s original goal I think we’ve succeeded, we do indeed provide the capability to synchronise a media player wirelessly and unsupervised. Unfortunately there’s not much to show, since I was able to re-use a whole lot of existing Banshee components.

I showed a screenshot of my connected GT-I9100 in a previous post where I talked about making the system ready for everyday use, to that end it has grown a retry mechanism employed when the connection fails and many improvements when identifying files that the user already has in his library, finished off with a sprinkle of concurrency.

So things are no different when the device is connected, but how exactly would one connect a Bluetooth Digital Audio Player? Simple enough, the below screenshot is a graphical hardware manager. I hadn’t thought about it much, but it’s design follows that of a Single Page Application. Status, configuration and control are bundled into the same display.

Bluetooth Manager Overview

Top left, in bold,
shows the names of your Bluetooth adapters.
whether any of your adapters are discovering.
as above but for powered status.
In yellow,
pair your device.
In red,
enable sheduled synchronisation.
In teal,
connect the device and view tracks.
In purple,
connect the device as an audio source.
In blue,
as above, but as a headset.
In green,
as above, but as speakers.

The following shot shows the interface in full swing, the reactive elements can be seen in the form of the emboldened device alias signifying that the device is connected, the toggled status of each of the connection buttons and presence of the time input control for entering the desired synchronisation time.

Bluetooth Manager Details

Last weekend, the folks at Gentoo declared Gnome 3.12 stable in portage. In the aftermath I noticed that Banshee’s volume control slider (GtkVolumeControl) is now implemented as a Popover and looks great, so I started looking to find where I could get at one in gtk-sharp.

After fruitlessly trying to regenerate my .NET bindings for GTK+ I spent many hours abusing the venerable GtkMenu before finally succumbing and doing the Platform Invoke, elliciting a roar of victory when one finally appeared on my screen…

To explain; your Bluetooth device presents an interface with which you can remotely control the media playing on it. Prior to using a Popover, the playback controls were in an ugly, long, left aligned line separated by a vast expanse of nothing until the right aligned volume up and down buttons, taking a whole lot of unnecessary space for something you might only use every now and again.

Hypothetical Questions and Some Answers

  • If I have more than one Bluetooth adapter, what does toggling the power and discovery buttons do?
  • They affect all of your adapters.
  • Why do you provide a button for pairing, but not for unpairing?
  • Because sometimes following pairing, the list of profiles reported by the device is updated so it’s handy to be able to do that from Banshee. If it weren’t for that fact the pair function would not be present.
  • What’s the point of the headset, speaker and microphone buttons?
  • They are shortcuts. You could open Gnome’s settings and do the same thing but if you’re listening to music anyway, why should you have to do that?
  • Scheduling sucks. Why don’t you connect to a device automatically when it’s in range?
  • Unless the device is visible, even in the case of Android devices which have Only visible to paired devices as their unannounced state, we have no way of knowing when a device is in range. Furthermore, we’d need to be discovering devices at all times for it to work which can only be detrimental to energy consumption.
  • The volume control buttons in the Popover don’t work, what gives?
  • Not a scoob, they don’t work for me either.

Life, Career, Love

Summer may be nearly over, but Banshee contributions will keep coming of course, the program has helped me learn C# thoroughly and has now allowed me to use a functional language in every day programming, as opposed to just within an abstract academic appliance.

If I could do Summer of Code over again, the one difference I would make is GUADEC attendance. The opportunities for networking within the Free software community would have been invaluable for the career I’ve managed to put off for so long.

Unfortunately I won’t be able to remedy the situation through Google next year as I managed to complete university with a pleasing result, so instead I’ll be slinging my hook, rather haphazardly, in the hope of catching employment.

That said, I hope to meet you all in years to come.

Dr G.T. von Kit or: How I Learned to Stop Worrying and Love SpinButton

As developers, sometimes we need to take input from the people using our software. In many cases, the choice of component to use when capturing it is obvious. If you need some text, you use a GtkEntry, if there’s a set of discrete values to choose from, a GtkComboBox is the ideal choice, and so on…

Some datum can be specific, but possibly ambiguous in representation. To illustrate with a contrived example; 1.23 metres is the same as 123cm, you could also say that’s just over 48 inches and again there’s steps up and down in magnitude and alternative ways of writing the same value.

This post deals specifically with Time, in the context of my Google Summer of Code project, as I’d like to specify when Banshee should try to synchronise my playlist. So, what component is the hot enchilada? The obvious choice is the GtkSpinButton. Here’s some highlights, it:

  • supports real numbers and integers;
  • allows the user to type for quick entry;
  • provides handy increment and decrement buttons;
  • can optionally wrap the value beyond the upper and lower bounds;
  • has customisable step and page amounts and, finally;
  • It. Looks. Fantastic.

And the following are my first two attempts at using it for our purpose. While the first is easy enough to use it’s a bit clumsy because it separates the two fields of our input data across two different controls, perhaps more importantly it is not immediately apparent that the controls are representing time or even that the values relate to one another apart from through proximity. The second suffers from a similar problem, what’s in that box doesn’t smell of time!

Time Input SpinButtons: Bad

What to do?! Readers of previous entries can probably guess that I’ll take a slightly circuitious route, known affectionately as scenic. In this instance that involves stepping back a little to GtkEntry, since it conveniently has areas designated for Primary and Secondary buttons. Here’s how that version turned out:

Time Input SpinButton: Good

Not too shabby, it looks pretty good and, apart from the bound wrapping ability, works in an equivalent way to the SpinButton. First some functions:

let inline (|Match|_|) rex text =
    let m = Regex.Match(text, rex)
    if m.Success then
        Some [ for i in m.Groups -> i.Value ]

let rex = @"^(\d{1,2}):(\d{2})$"

This is nothing new. If the regular expression is a match then the result is Some<string list>, otherwise None. For use with the Active Pattern is a regular expression to match two integers separated by a colon, allowing us to extract the hours and minutes from the user’s input, as shown in the following:

let inline to_value (hr,mn) = float hr * 60.0 + float mn

let inline from_text text =
    match text with
    | Match rex [full;hr;mn] -> to_value (hr,mn) |> Some
    | _ -> None

let inline from_value v =
    let hr = uint32 v / 60u
    let mn = uint32 v % 60u

let inline to_text (hr,mn) = sprintf "%d:%02d" hr mn

These four functions convert the decimal value stored in the GtkAdjustment to its text representation and back again. In our GtkEntry subclass they are connected to the signals emitted when the text entry area loses focus and when the value of the GtkAdjustment changes. Astute readers will notice that it would be fairly easy to include support for other time formats to the from_text function.

The code for the widget weighs in at around 40 lines. I’m not going to display it here, it’s long, boring and a lot was concerned with starting and stopping GLib timeouts to make the value scroll when one of the buttons was held down. Furthermore, the scrolling behaviour just wasn’t the same as SpinButton and required some tweaking of the repeat timings, in addition to a slightly hacky function to ensure that the appropriate timeout stops when the value reached either bound. Quite a bit of work for something that only sort of works like a SpinButton…

There is a better way, the Input and Output signals of SpinButton are designed for conversion purposes. This is the result:

Time Input SpinButton: Better

It’s simple, short (13 lines, three of which are semantic constants, with even one superfluous extra for no other reason than completeness) and customisable. This, folks, is How I Learned to Stop Worrying and Love SpinButton.

type FormatSpinButton(adjust: Adjustment, climb, digits, get, set) as this =
    inherit SpinButton(adjust, climb, digits)
    let TRUE = 1
    let FALSE = 0
    let GTK_INPUT_ERROR = -1
    do this.Input.Add(fun o -> 
         match this.Text |> get with
         | Some v -> o.NewValue <- v
                     o.RetVal <- TRUE
         | None -> o.NewValue <- this.Value
                   o.RetVal <- GTK_INPUT_ERROR)
       this.Output.Add(fun o ->
         this.Text <- this.Value |> set
         o.RetVal <- TRUE)

Lair of the Beast

Dear Readers, it has been a fortnight since I last wrote. When I left you there was plenty of infrastructure but few visible artifacts and at the time I said I felt on the brink of something akin to an avalanche. So, take a seat as there’s quite a lot to get through. But first, I’ll tell you about my new toy!


Some weeks ago, I had asked Andrés about using third party libraries and in the discussion he remarked of his distaste for Inversion of Control containers. In a rebellious streak1 I went ahead and wrote one, but its design is around the ObjectManager interface so it sports a slight twist in that it can only give you things that already exist but it will tell you when new things appear.

If the evolving property wrappers were compared to the cheapest, flimsiest snowboard you could buy, then this was like… well, this analogy is going nowhere, but it would be comfortable; you could ride all Nine Circles and if you happened to run down Beelzebub you might not even notice until you got back and the cheering started.

As the last supporting DBus component it has been invaluable, saving time that I was able to apply on the secondary aspect of the project.

MTP Support

Banshee has provided support for MTP devices through libmtp for a long time but the increasing numbers of Android devices supporting it exclusively has hi-lighted some issues with how we handle them.

I’m quite proud to say that I’ve had my mother using Free Software for some years, she loves it and rarely has any problems, but whenever she wants to change her playlists one particular difficulty she has is getting her phone to connect. We had logged one of the major problems she was encountering already.

After a false start and some steering from Andrés I’d like to share a screenshot showing the result of the latest approach and while sparing you the technical details I have to stress that the patch this comes from is yet to be reviewed.

Presently, when Banshee is unable to connect to a DAP it is quite outwardly silent, unless you happen to be listening on a virtual terminal where it’s usually screaming loud enough to break plates. The patch attempts to solve the problem initially by providing a graphical component where Banshee can show the problematic device and then with a magic button for taking remedial action.

Device Unavailable

The approach is very simple, it works remarkably well and MTP devices, once slippery eels where Banshee was concerned, are easy to get a hold of. You can freely disconnect, use them in nautilus and then come back to Banshee.

Bluetooth DAP

For those of you bored until now, here it comes, Bluetooth synchronisation works! <applaud! />

Implementing it took me on an arduous quest into the dusty depths of Banshee’s synchronisation mechanism. I tried to make it bend to my will, alas, it was too strong a foe but with guile I emerged (mostly) victorious.

I saw it’s wrath when first stepping into it’s domain. Little did I know that a third of videos and double that proportion in songs would perish that day. If it weren’t for the fact that the beast also took with it that jaw gratingly annoying Facebook messenger notification sound I might have turned back, licked my wounds and spoke no more. As it was, the minor blessing intrigued and perplexed me.

It was cunning, and had lulled me into a false sense of security. Banshee feeds on metadata; it had the track names, numbers and in some cases the album title and artist name, but it wanted More.

All I had to work with were file names so, fearing a repeat of our first encounter, I wove SQLite queries in the dead of night trying to find the best way to satiate its hunger. After an abortive attempt I was on the back foot, as some might say.

It was clear, the metadata-morsels obtained from Obex FTP would not be enough. Banshee wanted the genre and year, which only a foolhardy optimist would hope to find encoded in a file name, to calculate a unique value for each track. But I had discarded an assumption too early, and filling in the missing information by liberal matching against the local database keeps Banshee from belligerence. Thus, the day was won.

As you can see from the screenshots below, using a remote bluetooth device is identical to using it locally. Albeit without video support as I deemed those files generally too large to transfer over a slow connection.

Preferences View
Source View

Next Quest

With most of the battle behind us, there’s still a few things left to do. The first of which is to make the code resistant enough to its environment, it works but isn’t reliable enough to have Banshee do it without supervision. A few extra types to handle redundancy, some graphical components and a bit of data sorting, and we’ll be looking at providing that killer feature.


  1. Not really, but antagonism is good for stories.

Long Route to a Short Cut

With my last post a day over three weeks ago, I had not noted the passage of time until this weekend. I think the delay can be attributed to proficiency with F# after scaling some important parts of its learning curve. Since then, I’ve set about creating some components from the earlier examples.

The decorator pattern for DBus property support, discussed in an ealier post, has given way to an abstract generic base class which makes efficient use of the bus; rendering the property support that I had implemented redundant, if it weren’t for the unexpected benefit of correcting dbus-sharp’s event implementation for F# classes…

With some robust plumbing in place it was time to move on to integration. Starting with a Service for monitoring the state of adapters and devices, followed by a Source for displaying some basic information and controls within Banshee we’re able to provide some simple, but useful shortcuts to features already available to users under the hood of their system. For example, BlueZ and PulseAudio integrate beautifully; it is quite a simple matter of connecting bluetooth speakers and headsets. Users may now do this through Banshee, as the screenshot below shows:

Screenshot from 2014-06-22 20:16:45

It’s taken quite a bit of effort getting here, but the work on dbus-sharp and the invisible infrastructure that has been slowly evolving leaves me with a sense of big things, just about to happen, like a snowboarder hearing the rumble of an avalanche.

Day 3: Build Systems and Black Arts

Build Systems

After the prior experience of creating a template project some attention was applied to the build infrastructure. Banshee uses a combination of GNU Make, supported by Autotools, and xbuild. We happily go about development with the knowledge that MonoDevelop will keep them synchronised.

The presence of two systems is a headache for maintainers since there’s two sets of configurations that need to be considered (e.g. in templates) but also to developers using the Unix IDE since editing project files is an awful experience; I say this as a developer because looking at XML makes my stomach knot, even JSON files don’t evoke such a visceral reaction.

You can probably predict my response when my mentor, Andrés, suggested that the Makefile just call xbuild. “But then make depends on xbuild!” I cried; his response that doing so would reduce maintenance made sense, but made me think of how we can better use GNU Make.

To illustrate, although not proficient with Autotools, I have used Make to build software. One immediate difference I see in the makefiles I use compared to those you can find in any basic tutorial is the listing of source files verbatim instead of using make functions. This has an important consequence, changes like adding or removing a source file from a project means that you have no other option than to modify the makefile; used in this way a makefile is no better than its project file counterpart.

I’m also uncertain of how we can check dependencies if we were to move to a completely xbuild managed system, dependency information has the same duplicate representation and, although I love Make, project files are not optional, as most contributions come from people using MonoDevelop, while we could (arguably!) live without makefiles.

For what it’s worth, the basic tutorial I learnt Make with can be found here. It’s actually a really good one, providing a great base for extension and encouraging the reader to investigate further.

Black Arts

As I noted on Day 2 we had some issues accessing DBus properties for objects exported from none CLR languages. This was unforunate but had an easy workaround.

Since then, I took a long, hard look at dbus-sharp. It was an instructive experience to see how they use the Intermediate Language Generator class to create interface implementations on the fly, mapping those calls to the appropriate DBus methods, and figure out how to extend it to map CLR properties to DBus ones.

While the above experience had an inexpressible value of fun and was definitely rewarding, the time from patch submission, through review and the new version reaching users probably means that I’ll be writing those decorators anyway! A perfect job for the early hours when I can safely limit any thinking to muscle memory…

Day 2: Poke and Destroy!

After yesterday’s small success we take a break from the big picture and
focus on harassing bluez into doing some work for us.

open System
open System.Collections.Generic
open DBus

Will I ever remove these lines of pre-amble? Perhaps, but first I’ll try
snipping out any mundane ones if it’s more than say, 5 lines… I think they’re
useful, the reader can be sure he’s not missing anything important if he wants
to run the examples and has these.

let IFDEV = "org.bluez.Device1"

This is cool! People who’ve done some C++ template programming will recognise
this as a constexpr. It’s used later, you’ll see. Minor difference in the Attribute style compared with C# vis-á-vis the <> symbols either side of the attribute name.

[<Interface ("org.freedesktop.DBus.Properties")>]
type IProperties =
    abstract member Get : string -> string -> obj 
    abstract member Set : string -> string -> obj -> unit
    abstract member GetAll : string -> IDictionary<string,obj>

The obligatory interface definiton for accessing properties, I’m not really worried about signals at this point. As an aside, why is this interface not built into DBus bindings, it wasn’t when I worked with it in Java either?

I was hoping to get some use out of F#’s built in map types but obviously we’re limited to the intersection of types available in all IL languages when working with dbus-sharp, hence the IDictionary. If you’re wondering, obj is just a type definition equivalent to System.Object.

[<Interface (IFDEV)>]
type IBluetoothDev =
    abstract Disconnect : unit -> unit
    abstract Connect : unit -> unit
    abstract ConnectProfile : string -> unit
    abstract DisconnectProfile : string -> unit
    abstract Pair : unit -> unit
    abstract CancelPairing : unit -> unit
    abstract Address : string with get
    abstract Name : string with get
    // Other Properties ommited for brevity

Spot the Literal?

Yes, I skipped the adapter since it wasn’t interesting and moved straight to the Device API. In yesterday and today’s examples there were a few unit type declarations, the concept is identical to void in other C-family languages.

At this point, we can actually grab a remote object and do some work with it. Unfortunately accessing properties doesn’t work the way I was expecting them to, generating a DBus error stating that we attempted to invoke a method which does not exist.

With some testing, in the form of stripping the MediaPlayer2 interface definition out of Banshee and making a small self contained example, it can be shown that DBus objects exported from IL langauges have accessible properties. I hypothesize that since the exported objects contain methods covered by the property system, that these methods are exported (although they do not appear in introspection data) and grant access to the properties.

The solution is nothing fancy, below is a slightly mangled decorator pattern covering the properties with the correct DBus call. In lieu of the problem being addressed in dbus-sharp, a reflecting proxy (I have only used these indirectly) may save hand-rolling a decorator for each interface that is needed.

type DevProxy (bus: Connection, name: string, obj: ObjectPath) =
    let dev = bus.GetObject<IBluetoothDev>(name, obj)
    let props = bus.GetObject<IProperties>(name, obj)
    interface IBluetoothDev with
        member x.Disconnect () = dev.Disconnect ()
        member x.Connect () = dev.Connect ()
        member x.ConnectProfile y = dev.ConnectProfile y
        member x.DisconnectProfile y = dev.DisconnectProfile y
        member x.Pair () = dev.Pair ()
        member x.CancelPairing () = dev.CancelPairing ()
        member x.Address = (props.Get IFDEV "Address").ToString ()
        member x.Name = (props.Get IFDEV "Name").ToString ()

printfn "Hello, Bluez"

let bus  = Bus.System
let name = "org.bluez"
let mac  = "<Bluetooth MAC Here>"
let path = new ObjectPath ("/org/bluez/hci0/dev_" + mac)
printfn "Requesting Remote Objects"
let dev = DevProxy(bus, name, path) :> IBluetoothDev
let props = bus.GetObject<IProperties>(name, path)
printfn "Got Remote Objects"

    printfn "Device: [%s] - %s" dev.Address dev.Name
    | ex -> printfn "%s\n%s" ex.Message ex.StackTrace
dev.Connect ()
dev.Disconnect ()

printfn "Bluez, Goodbye"

Finally, we grab a handle to the paired device and introduce ourselves by prodding it in a couple of places, like a teenager on IRC. Tomorrow we’ll most likely investigate some bluez interfaces available through the session bus.

Parting Concern

Prototyping like this is great, quickly displaying and importantly testing functionality that will be used in the eventual concrete implementation. But, what of that key word; one difficulty I encountered while working with a similar Java system was that since functionality depended on variables originating from a live system I found it impossible to rigourously test the system, relying on an ad-hoc approach not much different from the example above. Not only did this reduce my confidence, it also stopped me documenting the steps necessary to correct the issues. Comments and advice on how to combat this problem are welcome and appreciated.

Supper: Porting my Comfort Zone

It was late, I was bored, this was the result… I think it’s equivalent to its C# counterpart. I’ve modified some lines for illustrative purposes and swallowed a line break here and there for brevity. A few lines at a time:

namespace Banshee.Template
open Banshee.ServiceStack
open Banshee.Sources
open Hyena
open Hyena.Data
open Mono.Addins

Nothing new here, just declaring a namespace and using some others. Dot notation is identical. I was unable to find an equivalent for C# and Java’s static import system but there appears to be a reason.

module Constants =
    let SORT = 190
    let NAME = "Banshee.Template"

No let expressions or values in a namespace so they’re wrapped in a module. Modules get compiled to classes with static values. I’m guessing this is for compatibility with other IL languages. For what it’s worth, I’ve always wondered why you can’t declare constants in a C++ namespace.

type Source() as this = 
    inherit Banshee.Sources.Source (AddinManager.CurrentLocalizer.GetString (Constants.NAME),
                                    AddinManager.CurrentLocalizer.GetString (Constants.NAME),
    let name = Constants.NAME + ".Source"
        this.Properties.SetStringList ("Icon.Name", "multimedia-player")
        Log.DebugFormat ("Instantiating {0}", name)

This (can’t resist a pun…) is interesting, the line after do caused me some time of confusion, apparently this was not defined until the addition of the self-identifier (“as this”) before the body of the type.

The do and let statements are also of interest.

In C#, these would be member variables, in F# they are immutable by default but can be declared otherwise.
Roughly equivalent to the default constructor.

Last, we can see the familiar addition operator overloaded for string concatenation. F# also allows use of the caret, `^’ in this capacity.

type Service(name: string) as self =
    do Log.DebugFormat ("Instantiating {0}", name)
    interface IExtensionService with
        member x.Dispose () = ()
        member x.ServiceName = name
        member x.Initialize () = Log.DebugFormat ("Initializing {0}", (self :> IExtensionService).ServiceName)
    new() = new Service (Constants.NAME + ".Service")

This one’s a bit more juicy; we can see some of the power of functional programming here in the form of the name value, no need to store it anywhere. Especially useful is the enforcement of constructor chaining, since you only really have one, chaining is the only option. The language also allows specialized constructors to have specific continuations, more information here.

Casting syntax is slightly different, shown in the Initialize interface member override, I quite like this style, it’s very easy to read. It’s possibly not surprising, considering the nature of the language, interface methods must be accessed explicitly.

Notes and Other Thoughts

Order is important; inherit, let, do, interfaces, members. The syntax has a few optional elements, for example class and end markers which can, no doubt, be used for hinting when necessary. Coupled with the already terse syntax F# makes for an interesting hybrid, it feels like scripting until you make a mistake, which is when the type system steps in.

Porting something you already know is great for building momentum in a new language. After this, poking bluez via DBus becomes the next step.