iPod Work

I started working on a generic iPod device class that provides lots of information about the iPod and will work with Snorp’s ipod-sharp. It provides things like the name of the iPod (not the volume name, but the assigned name), the model/type (shuffle, regular, mini, photo), version info, serial numbers, capacity, used space, etc. It also supports safe ejection of the iPod. Initially I was doing this by just calling ‘eject’ on the device.

However, I decided I’d try doing this by making an ioctl call on the device. Not giving much thought to it, I came up with a few lines of code to eject a CD-ROM drive. It didn’t dawn on me until after the CD ejection code was working that the iPod is not a CD-ROM drive (it’s okay, you can smack me). It needs to be ejected as a SCSI device. The ioctl call[s] for this task are much more complicated (a structure must be passed to the device instead of a plain integer), and I’m not sure how to do this easily in C#. I’m not sure that it’s even worth it, and will probably go back to just execing ‘eject.’

Anyway, if anyone wants to eject a CD-ROM drive in C#, here you go. This may be useful for making basic ioctls in C# for other reasons. I’ve never seen an example of ioctl from C#, so maybe this is new.

<br /> using System;<br /> using System.Runtime.InteropServices;<br /> using Mono.Unix;</p> <p>public class SimpleEject<br /> {<br /> public static void Main(string [] args)<br /> {<br /> if(args.Length &lt;= 0) {<br /> Console.WriteLine(&#8220;Usage: mono-eject.exe [-t] <device>&#8220;);<br /> return;<br /> }</p> <p> string device = args[0];<br /> bool open = true;</p> <p> if(args.Length > 1 &#038;&#038; args[0].Equals(&#8220;-t&#8221;)) {<br /> device = args[1];<br /> open = false;<br /> }</p> <p> Console.WriteLine(Eject(device, open)<br /> ? String.Format(&#8220;Device {0} {1} successfully&#8221;, device,<br /> open ? &#8220;opened&#8221; : &#8220;closed&#8221;)<br /> : &#8220;Error ejecting device &#8221; + device);<br /> }</p> <p> [DllImport(&#8220;libc&#8221;)]<br /> static extern int ioctl(int device, EjectOperation request); </p> <p> private enum EjectOperation {<br /> Open = 0x5309,<br /> Close = 0x5319<br /> }</p> <p> public static bool Eject(string devicePath, bool open)<br /> {<br /> try {<br /> using(UnixStream stream = UnixFile.Open(devicePath,<br /> OpenFlags.O_RDONLY | OpenFlags.O_NONBLOCK)) {<br /> return ioctl(stream.Handle, open<br /> ? EjectOperation.Open<br /> : EjectOperation.Close) == 0;<br /> }<br /> } catch {<br /> return false;<br /> }<br /> }<br /> }<br /> </device>

And with that we have a simple Mono eject replacement for basic opening/closing CD-ROM trays. Woo-hoo!

Smooth Music and the LTM

It’s been a while since the last entry, but at least I’ve been up to some good. There have been some exciting happenings regarding Sonance, too numerous and exciting to post here, right now. However, lately I’ve been enjoying iTunes while developing Sonance. I now have an iPod, and am loving it – but it’s not just for play. Currently I am performing five concurrent tasks in iTunes, and am happy to say that Sonance’s backend is ready to handle the same tasks soon. All at once I am Ripping a CD, Importing music to the iPod, Downloading purchased music, Burning a CD, and listening to music. This task load started as me re-ripping most of my CD collection to AAC (vs OGG) in order to actually have content to fill the iPod. In many ways this is a shame – I’ve been using OGG for years, and the only reason to drop it is because the iPod doesn’t support it, and that really needs to change.

Anyway, Sonance handles all of its extensive IO tasks with no lag in the interface at all, like iTunes. This is due to the Library Transaction Manager (LTM). IO tasks are handled through Library Transactions, all which extend a base class, so the LTM can manage the actual transactions. Transactions of the same type cannot be executed concurrently, and are therefore executed in a queue (For instance, you couldn’t burn two CDs at once). However, transactions that are not of the same type can be executed concurrently (I can import, burn, rip, and listen all at once). Additionally, the LTM provides access to the top-most transaction (usually the last transaction initiated), and then an array of the top-most transactions of each type. The interface can then query each transaction for status information. This allows the UI to provide status pages like iTunes – the top-most transaction’s status is displayed first, with the option of cycling to other transactions.

Development for Sonance over the next three months is going to be extremely exciting. A few major target features are iPod support, CD Burning, and CD Ripping. More details on this are soon to follow, when I can find a spare moment.

In somewhat other news, I’ve implemented a nice test case for all sorts of common Drag-n-Drop functionality desired for GtkTreeViews, including multi-row DnD, drag reordering, drop between rows, and drop on a row (both vs. the default drop between or on). This functionality will be included in Sonance, but I wanted to iron out a test case for other projects and make sure the code might not suffer from unrelated factors. I’ll make this available when it’s a little more polished off, and I have another spare moment.

F-Spot, Server Monitoring, ASP.NET, and Crazy Dancing

Today I relaxed a little bit and decided to organize ~/Photos, which has been an all purpose photo dumping grounds for the last year or so. I don’t take many photos, mainly because I have a horrible 2MP camera with awful focus and lighting, so I only had about 400 photos to organize. I built F-Spot for the first time today, and am extremely impressed. However, I did this after manually cropping and rotating about 80 photos using The Gimp. I am extremely impressed with F-Spot – it makes me even more inclined to finally purchase a nice camera.

I love the simple photo touch up tools and the fact that it doesn’t overwrite the original, and of course tagging photos like “Favorites.” The timeline widget is amazing – too bad only a few of my images have EXIF information, because about 90% of my photos, as reported by F-Spot, were taken today, when I copied many of them to a new location. Not much can be done about that I guess.

Anywhoo, I started writing a simple standalone HTTP server in C# today to serve status information regarding the health of my server and its applications and services. It is made up of a simple multi-threaded HTTP server that sends XML “ResponsePackets” containing status information (like uptime, system load, process listings, whether a given service is actually running, memory usage, etc). Each ResponsePacket is handled in code by extending a base ResponseHandler class. These extended classes are then registered with the server at startup in a Hashtable. When a client sends a GET request in the form of “/a:b:c”, “a”, “b”, “c” are parsed out and used to look up the proper ResponseHandler to execute. It’s kinda nifty. I’ll write a simple front end client for it that can email and text message my phone if/when a service goes down.

Of course I’ll release the whole thing in a few weeks when it actually becomes useful.

I also finally managed to build Mono 1.1.7 under my Linode UML server. Before today, Mono would segfault and/or throw a NullReferenceException during compile of mcs. I found out today that it was TLS that was causing the problem, as it’s not well supported under UML. All is well, and I now have mod_mono setup and working, and I look forward to learning ASP.NET (I never thought I would say that!)

Modern Music Management Experience: In Linux

With Sonance gaining much attention, and development gaining steady ground (though sometimes slow, due to trumping obligations that pay my bills), it is starting to unfold into a more modern environment for managing and playing music.

I am overjoyed with how well Jon Lech Johansen’s SharpMusique works. I purchased my first song through it today. Beautiful. There are plans to integrate it into Sonance for the ultimate music experience yet to be seen under Linux. I can’t wait until I can search for new music in iTms, purchase it, and have it appear shortly thereafter in my Sonance library. Yes, it is sick.

I made an SVN commit today that shows off some of the new functionality/widgets in Sonance, but I’m sure I’ve broken somethings, specifically adding tracks to a playlist. The next SVN commit will be more pleasing and feature complete. After a few more SVN commits, the next public release will be available.

One snag though, regarding which I am rather upset. It appears that you can’t drag-n-drop multiple selected rows in a Gtk.TreeView. This is upsetting because to add new songs to a playlist from the library, I wanted to be able to select them, and drag them onto a playlist in the sources TreeView. Apparently the problem is in GTK, not gtk-sharp. I read there is a hack for the problem in egg, so I’ll investigate that, and see what I can do. It’ll need to be wrapped, which is annoying. It seems like this should be supported in GTK itself. If I am misinformed, or if anyone has suggestions, I’d be glad to hear them!

Sonance Is Going Places

I’ve been actively working on Sonance for the past two weeks, and I have some major developments to report. The new interface is really working out, and since implementing it, I have been able to more easily implement some of the cool features that I have been planning for the last few months. I’m not promising a release date, since there is so much still to do, but at least development is moving smoothly, quickly, and it’s starting to show.

Today the Smart Playlist/Search interface (“Query Builder”) completely fell into place, and generated SQL to be used for smart playlists and searching.

The Query Builder (screenshot) generated this SQL today:

SELECT * FROM Tracks WHERE Artist LIKE '%Matthews%' AND (DateAdded >= '2005-04-11' AND DateAdded <= '2005-04-11') ORDER BY RAND() LIMIT 15

Also, the Library is now loaded automatically in the background when Sonance starts, which takes about 3 seconds for ~4500 songs. Loading the Library into the active view/playlist after that takes under a second. Sonance now has reorderable/toggleable/resizable column headers too, and their state is saved/restored.

The Query Builder uses a custom GTK Date Button widget I wrote, and the whole thing is composed of a few custom widget classes, and a few model classes. Ultimately, the Query Builder widgets/model can be used in other projects with the need of having a semi-complex interface to generating any type of query for searching. It doesn’t have to be SQL. I will publish the Query Builder separate from Sonance at some point for reuse in other projects. If anyone is interested in looking at it now, just contact me.

Finally, I’d like to thank Christian Hergert for letting me on Monologue! I’ve loved reading it over the past few months, and now I look forward to posting on it.

Change of Sonance Plans

After a few posts about Remix (now named Sonance), and getting ready for the first public release, I had a sudden life changing experience as a developer. I discoverd development under Mono. After quickly learning C# and exploring the .NET libraries and the GNOME/GTK bindings for Mono, I wrote a few test programs, and started rewiriting/porting Sonance to C#. Amazingly, the power of the language and bindings are allowing me to more efficiently develop Sonance, and in much less time. In just one week, I have re-developed Sonance with less code, to the same point that the C version was developed in about a month.

The major struggle was the lack of good documentation on the GStreamer bindings for C#, gst-sharp. I have been able to find about three gst-sharp applications. And honestly, and with no disrespect to their developers, their implementations are not very solid, nor featurefull. So in addition to porting Sonance, and developing a much better code base, I have developed a strong gst-sharp player with metadata support.

I am really excited about the rewrite, and new beginnings with the Mono platform. I still love C, but welcome the ease and power of this new platform. It is clearly the new path for GNOME, and I am glad to be a part of it.

The Day of New Stuff: Sonance, SQLite, GOCBuilder

I’m checking in again with some status reports and two new pages on the site. First, I have decided to name my previously mentioned Remix player to Sonance. I am very happy to report that development is going very strong, and I hope to make the first public release by the end of this week. I came to the conclusion that redeveloping yet another GStreamer backend is futile. I have decided to use the GStreamer playback and metadata code from the RhythmBox project. I have also decided to use SQLite as the library database backend. I’ll post with more details when I make the first release.

I am also happy to report that I have written a small article on embedding SQLite within a GNU/Linux autobuild C project. Documentation was not to be found on this matter, and after spending a few hours tinkering with SQLite, I managed to embed the entire engine in Sonance.

Finally, because Sonance is growing rapidly, I was finding myself constantly copying and pasting GObject Class templates from other sources in the project, only to perform many search/replace actions on certain strings to create a new class framework. I decided to take a few hour break from Sonance, and write GObject Class Builder, a very small, ugly Glade/C hack to produce a basic GObject Class template, based on a few levels of input. I added GOCBuilder to my Anjuta Tool Set, and now it’s just a matter of Project|GObject Class Builder, and a few fields to generate a base GObject Class.

That’s all for now. I’ll write next when Sonance makes its debut!

Remixing Life

After spending 24 hours in the air or in an airport, I finally arrived in Santa Barbara, California on Tuesday morning. I flew out of Raleigh (NC) at 3:30 to Chicago. My flight was delayed in Chicago by an hour. I arrived in Los Angeles at the same time my flight from LA departed for Santa Barbara. Needless to say, I wasn’t happy. We sat on the tarmack for another 15 minutes. I checked in with American Airlines (AA) support/ticketing center at LAX. They were great. I had already been automatically rebooked on the first flight to SBA for the next morning (my original flight to SBA Monday night was the last one for that evening). AA gave me a hotel reservation for the LAX Marriott along with two meal vouchers! It was a painless process to get to my free room and then back to LAX the next morning. So, as of Tuesday morning, I’ve been having fun in California.

I haven’t yet managed to purchase a new laptop. I’m torn between three models. A Sharp Actius MM20, some ultra-mobile Sony Vaio, and… gulp… an Apple PowerBook (12″). I’m currently on a iBook G3, using OS X 10.3. I love it. There’s so much innovation in this operating system. I’m just not totally comfortable using it. Though it’s smooth and beautiful, it really does feel “closed” (as in source code). I’m installing XTools from Apple, which apparently include gcc and other open-source tools. If I do get a PowerBook, I’ll be putting a PPC Linux distro on it.

I think I like OS X so much because I see basically what’s coming to GNOME, and what I’d love to one day contribute. For example… I’d love to write Sherlock for GNOME.

I’ve also been enjoying playing with iTunes. This inspires me because I am in the middle of writing an ultra-powerful Music playback/library program for GNOME. iTunes has some of the features that I have in mind for my program, but I have much planned that isn’t implemented in iTunes.

I’ll be writing code like crazy when I return home, but for now, I’m relaxing in beautiful Carpinteria/Santa Barbara California.

Happy Holidays!