More bling from the Banshee front

Lots of new stuff has been going into HEAD lately, and I’ve been starting to review and polish plugins in the banshee-official-plugins module. We’re aiming for the first release in the 0.11.x development series in mid-August.

So here’s a short run-down of some nice new features…

Tiles: An upgrade from a linoleum music player

Inspired by “tiles” throughout the desktop in the excellent recently released SUSE Linux Enterprise Desktop 10, I began writing tile and tile view support in Banshee core. The first consumer of this new support is the Recommendations plugin, which shows similar artists and popular songs by the currently playing artist.

Tiles!

I will be adding lots of contextual and plugin-installable actions to various tile types in the future. Right now the default action for the recommended artist tile is to go to the last.fm artist page. I am also going to experiment with tile-based library/artist/album/tile views. Tiles are just hot.

Let me hear it my way!

Last week, Ivan N. Zlatev began working on equalization support for Banshee. He sent a patch to the list that added preset support and an equalization dialog, however, the presets were bound to the player engine. I had been wanting to implement equalization for some time, so I took his efforts as an opportunity to dive into it. My goal is to be able to assign equalization settings to tracks, playlists, and smart playlists and of course sync them to the iPod (please bug snorp for EQ support in ipod-sharp).

Today I committed the re-worked equalization/preset editor and will soon take the rest of Ivan’s patch and connect the support to the player engines, so you can actually hear the changes. The UI support for equalization supports 10 bands at fixed frequencies, which need to be transformed to whatever frequencies are supported by the active engine.

Ivan also added the equalizer support to the Helix Remote engine and helix-dbus-server, and to his Xine engine. A GStreamer plugin will be next.

Equalization

Oh, yes, speaking of Xine… Ivan also wrote a Xine engine a few weeks ago – it’s in Banshee subversion. We are not going to officially support it, but hey… it’s available for those who want it.

Some internal stuff

Today was a very productive day. I committed a lot of the equalization stuff, then I re-wrote most of the old and poor drag-and-drop selection support. Sending objects “over” drag and drop internally in Banshee is now insanely simple and much more efficient than it was previously.

For instance, here’s all that’s required to pull a collection of TrackInfo objects out of a Gtk.SelectionData:

protected override void OnDragDataReceived(Gdk.DragContext context, 
    int x, int y, Gtk.SelectionData selectionData, uint info, uint time)
{
    DragDropList<TrackInfo> dnd_tracks = selectionData;
    foreach(TrackInfo track in dnd_tracks) {
        ...
    }
    ...
}

“Sending” the selection is as equally simple.

And a drum roll please…

Tonight I implemented one of the most requested features for Banshee: support importing of songs from DAP devices. That’s right. You can now drag songs from your iPod onto the Banshee library and they will be copied to the library directory and imported to the database.

You can also create locally-saved playlists of imported DAP tracks just as you would from the library – just drag them to the source view and let go, or drop on an existing playlist… all directly from your DAP!

iPod to Library

The import support is not specific to the iPod, so it should work just fine for those with USB mass storage audio players. It works quite well with the iPod. It does not work with NJB/MTP. They will need to implement IImportable and provide importing based on the respective transfer protocol.

This is all committed and ready for a beating. I’d really like to hear from those with mass storage players.

A smörgåsbord of text and an erratum

The History Channel Presents: gst-sharp

On the heels of my last post regarding GStreamer C# bindings, Alp Toker, original author of the first generation gst-sharp binding, provided me with a little more history regarding his binding.

“The ‘valiant effort’ to bind GStreamer in C# wasn’t just a couple of years ago, it was in 2002, and it targeted not GStreamer 0.8 but 0.4.1, making it one of the earliest GStreamer language bindings in use.”

I had thought the original binding started against 0.6.x, not 0.4.1, which is really cool and just one more reason why the new binding must become on par with other language bindings (PyGst).

Oh, yes, and some photos

I have posted some of my [less incriminating] photos from GUADEC. It was an absolute blast, and was wonderful to meet everyone in person finally. You can find my photos in the guadec2006 group on Flickr or in my F-Spot exported gallery. There’s way too much to write about on this subject, so I’ll reserve that for my thoughts.

Has anyone had problems listening to “Jono’s World of Metal”? For the record, Jono, Ted had everything to do with it. (actually, that’s completely false)

Just one more question: just who will have the honor of removing it? :-D

On the platter today…

My new head Sporting the ultra-sexy Fluendo hat, Christian delivered my new head for planet use. I like it very much. To whomever updates hackergotchi’s on various planets: would you mind doing me the honor?

GStreamer C# Binding Update

As many may know, there was once a valiant attempt to bind GStreamer in C# a couple of years ago against 0.8. However, this binding was never complete and had a number of problems, but it was nonetheless promising. That is until it eventually found itself without a maintainer.

For over a year it sat in Mono subversion, and during that time, a number of third-party developers assumed it was a working GStreamer binding for their beloved development platform. Unfortunately this was not the case, and a number of times myself and others had to explain that the binding was not complete and that the best thing to do was to develop the required GStreamer functionality in C, expose it in a simple P/Invokable API, and privately bind that. That’s what I do in Banshee, and it works very, very well.

I eventually moved the gst-sharp module out of the main source trunk to keep it from being “discovered” by new developers to save them the pain and excitement of seeing the apparent binding, and that worked well. After doing that, I found myself no longer having to explain the situation. But still, this was sub-optimal.

Now fast forward to just a couple of months ago. After Peter Johanson and I started talking about it, he managed to find a few hours spread over a few weeks to resurrect the old gst-sharp binding, and began fixing up its GAPI component. We then agreed that it might be a good idea to make it a Google Summer of Code project.

Now enter Khaled Abdul Karim Mohammed (who needs a blog): enthusiastic SoC student destined to deliver working GStreamer CLR bindings. We laid out a few goals for the summer project including extensive unit tests, runtime-bound GObject signal support, GAPI cleanup, sample porting, and some other minor tasks.

#region technical mumbo-jumbo

So now the personally most exciting and compelling reason for writing today: after a few weeks of hard work by Khaled, we now have one of the biggest goals for the binding essentially complete. Khaled took two ideas of mine that I had been toying with a few months ago and turned the best one into a working solution for supporting GObject signal binding at runtime.

This may sound a little weird, but it’s the best phrase I can come up with to describe it. In C, to connect to a signal you do something like g_signal_connect(object, "signal", callback). This isn’t so possible in the CLR without a decent amount of work, and it’s a major requirement for a GStreamer binding because elements aren’t targeted for binding, and thus GAPI doesn’t touch them, and can’t know what signals to bind.

GAPI-bound signals introduce an insane (but necessary) amount of code overhead to transform CLR events into a GObject signal binding. It’s not the kind of overhead you want to pass on to consumers of your binding :-).

Now what I mean by “GObject signal binding at runtime” is this:

Element typefind = ElementFactory.Make("typefind", "typefind");
typefind.Connect("have-type", delegate(object o, DynamicSignalArgs args) {
 Console.WriteLine("MimeType: {0}", args[1] as Gst.Caps);            
});

In C#, connecting to a signal is very much like how you would do it in C. A number of things had to happen under the hood to make this possible, but it’s much like it’s done in Python (or so Edward says). There’s a default C handler that is connected with G_CONNECT_SWAPPED, and the argument stack is walked to collect the arguments as GValues. There’s one caveat with GstMiniObject however, but we handle this with minimal overhead because GstMiniObject-derived types in the CLR binding are GLib.Opaque-derived. Subsequent Connect/Disconnect calls on the same signal and object then take advantage of multicast-delegate support in the CLR instead of having to manage multiple callbacks for a object-signal in GObject land.

This also means that adding by-hand bindings of common/base elements like decodebin or typefind to get C# event syntax is much easier.

All of this “dynamic signal” stuff is fully generic to glib-sharp, so it is my hope that after we fine-tune it and test drive it in gstreamer-sharp that it will end up in glib-sharp itself. It is an immensely useful feature to have if you need quick signal support on a GObject-based binding and can’t bring GAPI into the equation.

#endregion

That all being said, and technical jargon aside, we are hard at work (Khaled for the most part right now) on a working, usable, sexy, GStreamer 0.10 binding for Mono/.NET/C#/Boo/VB.NET/IronPython/WhateverLanguageThatTargetsTheCLR. Much of it is already working now, but there is still much to do. Eventually I will port all of the Banshee backends to this lovely new binding.

To avoid the messy situation we lived with for almost a year with the first iteration of the GStreamer CLR binding for 0.8, I am currently not going to directly disclose where the new bindings are located, but for the adventurous at heart, I’m sure they can be found :-). Expect a first release in the coming months.

And, oh boy… I just can’t *wait* to see GStreamer apps written in VB.NET! (ahhh!!!H!!OMG!)