(Vizio Smart-)Cast All the Things

So the music system has been running really well with the various Chromecast Audio (and regular Chromecast) devices sprinkled throughout our house.  No complaints really on interaction, responsiveness, usefulness, etc.  However… Progress(tm).

I’ve probably alluded to my ongoing quest to reduce and de-clutter my living space.  This is and probably will forever be a source of intrigue, excitement, and cash drainage.  Technology marches forward and enables ever-smaller devices to fill the role that myriad other devices once filled – or at the very least, that much larger devices once filled.  And in some cases devices become virtualized and move into the realm of bits and bytes, losing their corporeal selves and existing in “the cloud”.

Riiiight.

Back to music.  When I first began the home audio aspect of my Home Automation ambitions 11 years ago, the unanswered question was: how to bridge the digital world and physical world?  Digital, in that I was writing the software that would form the basis of the home audio system, and physical in that you need hardware to produce the music – and also to control it.  It’s interesting reading the old articles chronicling those first steps, and then reading the machinations I went through as I struggled with concepts and financial constraints to realize the system I was aiming to build.  All of this reading is available on Piper’s Pages, if you’re interested.   Even then, the two big questions were: how to physically interact with the system? And: what will produce the music?

It’s the latter that I’m focusing on in this post.  The early system’s intentions were so cute, in retrospect.  Multiple sound cards, running outputs of cards into inputs of other cards, worrying about card addressing.  So quaint.  And then we moved to another house, and those sounds cards haven’t done a single DA conversion since.  Nope… the new, temporary solution was to use smartphones or tablets connected via AUX or Bluetooth.  The remote/renderer capability of the system made this a little more bearable, in that you could purpose a tablet as a renderer and have it tethered to an amp via AUX/Bluetooth, then control it with your smartphone running as a remote.  But again… so quaint.

This was certainly a stopgap solution.  I had envisioned a full-fledged Sonos setup for the move, a dream that was never realized due to cost and unanswered questions of how to get my music to Sonos.  Would I be back to utilizing sound cards and piping music to the Sonos network via AUX?

At some point we gained Cast integration, and that was a Good Thing(tm).  Cheap to implement, could repurpose existing amplifier/speaker hardware, and it brought with it the software challenge of how to integrate my 11-year-old software project with something that was both modern and surprisingly sensical in its approach (I’m speaking of the technology that underpins Cast).

But…… Progress(tm).

The system has certainly been capable.  Multiroom is a thing, mulitple audio streams is a thing, Bluetooth headaches are not a thing.  What became evident through is the divide between interaction models.  You can get as far as casting audio to a destination, but then you have to switch mindset and think of the destination itself: is the amp on? is it on the correct input? do I control the volume in software or hardware? is the Harmony remote in the right mode?  It’s a conceptual disconnect.

Still, Cast certainly seemed like the right way to go.  And Google eventually launched the Chromecast Built-in program, which seemed to address most or all of my problems.

Which brings us to the real reason for this post – my experience with Vizio’s SmartCast products.  Specifically, the Crave 360 and Crave Pro.  And I have to tell you, I’ve really been on the fence about the move to Chromecast Built-in, much less Vizio’s own implementation.  Truthfully, moving to built-in represents more of a sideways move than a forward move: same Cast technology, same Cast integration, same music in the same physical locations (probably).  You’re spending money but on the face of it the only thing you’re really addressing is the “disconnect” issue.  Unless, of course, the new hardware does better at music reproduction.

In my case the Sony bookshelf that the Crave Pro was to replace is a pretty good system.  It’s louder than the Pro, it has boomier bass.  What irks me is the “disconnect”.  And the wires.  Man, the wires.  Getting the Sony into the music ecosystem means four physical devices (1 amp, 2 speakers, 1 Chromecast Audio), 5 wires, and 2 power outlets.  In this age of appliances I really wanted a single integrated device with a single wire going to a single power outlet.

Sooo… Crave Pro.  It really is my first experience with the amplified-speaker age that we’re in now.  And… I was disappointed.  The Cast aspect was fine, really.  But the music reproduction was something altogether different from the Sony.  Again, the Sony is louder and has boomier bass.  But… but… does that make the Sony better?  Because, truthfully, the Pro actually has a wider soundstage and richer bass at moderate listening levels.  It can’t get as loud as the Sony while maintaining the same composure that the Sony can, but… it can get loud enough.

I’m aware of the danger in trying to convince yourself of something.  And I definitely vacillated on the Pro.  The 360, on the other hand, went through one night of uncertainty but then became a firm “yes” after applying a software update which solved strange Cast disconnect issues.  The 360, unlike the Pro, is a new entrant – having a portable speaker that can be used in the yard or the garage.  It fills that role and it fills it well, so it got to stay.  And so did the Pro, honestly, once I decided that insane volume no longer has a place in our house.

That’s right folks.  Apparently I’m maturing… who knew.  The Pro is the right answer for the intended application.  It’s different than the Sony – in all the ways previously mentioned – but it turns out that it’s the right answer for the particular application.

So ya… the march goes on.  The music system is evolving.  I’ll spare a paragraph to say that what I like about the Crave 360 and Crave Pro are their simplicity: an amplified speaker with a physical volume knob (actually a ring) which itself is very thoughtfully integrated into the design of the unit.  Whatever transport controls the speaker supports are hidden away as swipe and tap gestures within the ring.  Music reproduction is nice – and actually impressive on the 360 given its size – at anything below 75% volume.  Which, frankly, is just fine when you remember that these things are not meant to be concert speakers but rather are intended to fill a room with music.

I’m happy.  They can both stay.

What have I been up to? (“Home Automation” edition)

Apologies for the dearth of updates.  The silent masses have been wailing my name incessantly as a result.  I hear you, your screams are defeaning.

(WTF?)

Things have been… different… this year.  That’s about as much as I can say at the moment.  The lack of a stable “all systems OK” comfort zone has basically meant that I’m in maintenance mode more than anything else.  Hence – little in the way of blog updates and other reckless indulgences 🙂

Anyhoo, on to the subject of this particular post.  And this will likely be quick.

You may recall that, to-date, the home automation system consists primarily of surveillance, hvac, and music.  Much hasn’t changed in that respect, but I have been able to make some changes that have increased the reliability, efficiency and usefulness of the system.

Surveillance first.  The most notable change here has been the inclusion of HTML5-compatible transcoded video.  For some time I’ve relied on Flash to allow for remote viewing of archived surveillance video – but having upgraded my phone to Jelly Bean and settled on Chrome as my browser of choice, Flash is no longer an option on that particular device.  To that end, the backend transcodes video into both Flash and x264 formats.  The format available to you is in the browser is determined automagically.

Other small changes have been the regular code cleaning that occurs when you realize that the way you did something a year ago makes absolutely no sense and – there – this makes much more sense.  For now.

The next notable change/improvement actually touches on HVAC as well, so it’s a good segue.  You may recall (but probably don’t) that the automation system is occupant-aware.  When we’re home, certain things happen – like telling the thermostat to target a comfortable temperature, or telling the surviellance system not to pepper me with event notifications.  Previously, occupant detection relied on Bluetooth and its rather short range.  And while I had dreams of hacking unsightly 2.4Ghz antennas onto cheap USB Bluetooth adapters, I woke up recently and decided to use WiFi for the same purpose – which also makes sense since our phones are connected to WiFi whenever we’re home.  Well, Shelly’s Nokia wasn’t always connected, by her loaner phone (my Desire Z) is as is my Galaxy S III.  It was just a matter of course before – no changes in usage or increased battery consumption.

This has simplified matters greatly, in addition to greatly increasing the reliability of the detection code.  The method is actually straightforward – check the wireless access point’s association table to see if particular MAC addresses are connected.  C’est tout.

Also within the spherical roundness of occupant-detection (???) is the news that the system can now get updates from the alarm system.  This is very useful, as it leads to very dependable home/away information that is actually more reliable (in some cases) than the wireless detection method.  The automation system is also configured to simulate motion/audio events on all cameras if the alarm notifies it of a perimeter breach.

Now over to HVAC.

Again – more code cleaning.  I spent a little bit of time thinking I could simplify the “Smart Logic” – the stuff that determines if the system should be off or on and what mode and when to run the fan and blah blah blah – but that turned out to be more painful than just leaving it the way it was so left it I did.  However, the system now has the ability to pre-condition the house if the next program calls for it.  This is one end of a multi-month effort that involved the automated collection of efficiency information.  The system keeps track of how long it takes to heat/cool the house – and currently maintains these statistics seperately for various absolute inside temperatures as well as inside/outside temperature differences – and if the next program calls for more heating or cooling, the system will start doing just that so that we hit the desired temperature just as the next program becomes active.

Admittedly this is not a novel concept.  Some thermostats have been doing this for years.  Something they can’t do is take the efficiency data and determine when to start pre-conditioning the house once it has been determined that occupants are on the way home.  And in the name of openness – my system can’t do this either.  But presently that has more to do with niggling concerns rather than a dearth of information or ability.  Any claims to the contrary would be blasphemy – you’ve been warned.

???

Anyhoo, the reality is that the current pre-conditioning only happens once a day – and perhaps twice a day in the cooling season.  Mostly this is due do the fact that I’ve “flattened” my thermostat’s programs, so that we basically have an overnight setpoint and a not-overnight setpoint (like I talked about here).  I’ve been able to do this because:

  1. the HVAC is much more efficient now than it was before (since we’ve moved)
  2. occupant detection can lower/raise the setpoint appropriately
  3. occupant prediction can target the “home” setpoint before we get home

We tend to keep a “cool” house when we’re asleep, but it absolutely sucks to wake up in the morning to cold floors and cold everything-else-too.  Otherwise, there’s really no need to program the thermostat when the pieces are in place to make more effective decisions automatically.

So ya, that’s HVAC.  Last (and perhaps least?), Music.

Admittedly there hasn’t been much development there.  Not to say that I/we don’t use the system – in fact I used it this past Thanksgiving when we entertained family.  I just haven’t had occassion to spend oodles of time on it.  As it is now, it Just Works(tm).

What I have done, though, is to bring some HTML5 usefulness to the streaming aspect of the system.  As with video in the surviellance system, there has been a browser-embedded solution for some time to stream music via a Flash player.  Got the job done, but again – Flash’s days seem numbered and are basically done and done in the mobile world.

To that end I added HTML5 Audio, and it gets regular use when I’m at work.  Not so much in the car (also known as “not at all in the car”) but that’s because Chrome (and perhaps others) will not allow for background HTML5 audio.  If the screen turns off or the browser is pushed to the background: sayonara streaming audio.  So I still rely on a bonafied SHOUTcast client for streaming in the car, and truthfully I’d love to be able to run the browser-only solution as it requires much less in the way of security concessions.

Aaaaaaand….

….that’s it!

Server upgrade? [update: 2012-02-17]

Ah, the life of a consummate hardware tinkerer.

Blog devotees will know that my “Home” server is the guy whose job is to run the house – in-so-much as the house can be run by a computer, that is.  More commonly noted in these journals as “Home Automation”, the Home server is primarily responsible for surveillance, HVAC, Whole Home Audio, TV show transcoding, and a host of other support services.

Said server has had a long history of service, although the only original parts are probably the case, power supply, and some hard drives(!).  And after just over 3 years with its current hardware configuration, it would seem that a significant shift is about to occur.

So significant, in fact, that I’ve had to come up with a new “P”-prefixed name for said server.  Yes, *all* of my computers are named with a “P” as the first character…

Anyhoo, this started about a week ago when I noticed some “previous system shutdown was unexpected” messages in the event log.  And some quick investigating led me to conclude that hardware was – again – the cause of the problem.

I was left with three choices:

  1. Retire the Home server and move all functionality to the remaining (“Internet”) server.
  2. Troubleshoot the problem and replace the failing component.
  3. Start from scratch with a new server

My “best practices” principles ruled out option #1.  And with time at a premium these days – and given that the Home server is based on technology that’s over a decade old – I decided to take the $$$ plunge and build a new system utilizing modern(ish) technologies.  Some things I’ve wanted for some time – like RAID1 drive redundancy – and other things I’ve had no experience with and wanted to have at least some passing familiarity (like SATA… yes, *all* of my drives are PATA!!!)

I also decided that I wanted to go with an Intel motherboard and processor solution.  In all of my professional and personal years dealing with computer hardware, I can’t recall one time that an Intel product has failed (especially motherboards).  I may be unique in this experience, but I decided to pay the extra money and go Genuine Intel.

Unfortunately I may have been too presumptuous during my decision-making process, as I opted for any old Intel board that had the hardware features I wanted (among them, 3 PCI slots) and didn’t spend too much time worrying about the “***DESKTOP***” branding that graced the packaging and product designation.  So it was that I came home, spent an untold amount of time putting the hardware together, and found myself unable to install my server software due to driver issues – all of which were arbitrary on Intel’s part, wanting their DESKTOP boards to have no business running SERVER software.

So it took a few nights and early mornings to finally get Windows Server 2003 installed and recognizing the DZ68DB board’s many features.  Thanks to Google and these pages for the invaluable assistance.

That was the first hurdle, and I knew that the software setup would be a multi-day affair.  Unfortunately I’ve run into another (temporary) roadblock, which is that the act of promoting this Windows 2003 Server to a Domain Controller has been foiled by Exchange 2000-related issues in my Windows 2000 AD schema.  Argh.  And while I value the learning experience, at this point I just want to get to the point where I can start moving services to this new “Home” server from the old “Home” server.  I’m really looking forward to the significant increase in speed that this server should bring, particularly with respect to show transcoding and database operations.

So I’ll update this post when I have more to report.

[update 2012-02-17]

So I’ve surmounted most (all?) of my AD-related issues, and the server is chugging along quite happily.  Girder gave me some issues – particularly in the area of launching processes – but this was resolved by changing the window parameter from “hide” to “show”.  Had to do it for both the open process and kill process (this is more a note to myself for future reference…)  I was also pulling my hair out over mixer issues until it dawned on me that the references to the hardware on the old server were probably causing Girder to get mired in some thick mud.

Anyhow I can say that services are smoking fast; DivX transcoding is limited by the speed of the network transfer from the PVR machine (which is currently the Internet server but will soon become the Home server).  The responsiveness of the whole-home audio interface is likewise much improved, as is the whole set of intranet pages (particularly noticeable when looking at archived HVAC and surveillance data).

I’m still in the process of moving my network-stored movie images from a local disk on the old Home server to a local disk on the new server.  This task’s painfulness is exacerbated by the insistence of the old server to spontaneously reboot whenever I try to initiate such a file transfer over the network – which certainly would seem to mimic the original problem which started this whole process in the first place.  The question still remains as to why this causes a server reboot.

Anyhow, I’m using the external 1TB drive (thanks Mark!) to sneaker-net the files from the old server.  However, we’re talking about something like 40GB of data (or is it 80GB?), which is very slow to transfer using the old server’s USB 1.1 ports…

Other than that, I’ve finally got full data redundancy thanks to Second Copy (thanks Daniel!) and that very same 1TB drive.  NTBackup is backing up the system and data drives on both servers, saving said backups to the external drive; and Second Copy is doing one-way replication to the external drive of all media on a nightly basis.  To Centered Systems – the cheque will soon be in the mail 🙂

DP and HTML5 – strange bedfellows

So a few days back I got my hands a bit dirty with HTML5’s CANVAS tag.  And some number of weeks ago I got into the history object and HTML5’s improvements to that.  Today I got my feet a little wet with the AUDIO tag.

It’s an interesting concept, really.  This most recent journey has been within the context of the home audio system, and I was just just just remarking to myself that development was at a virtual standstill for a number of months – and here it is that HTML5 is enabling a new coding push with real-world usability.

Well, that’s the theory.

The truth is that HTML5 and embedded media consumption are themselves strange bedfellows, and as a result, I find myself in the same position in my relationship with HTML5.

So forget about the abstracts.  My music collection is overwhelmingly encoded in the MP3 format.  And when I say overwhelmingly, I really mean completely – with the exception of perhaps 20 tracks, vs. the other 35,064 which are MP3’s.  The problem with MP3 – besides its lossy, yesteryear compression – is that it’s not in the public domain.  This doesn’t really mesh well with HTML5 – specifically, the AUDIO tag of HTML5 – which wants to work with open standards and hence is at odds with MP3.

So how does this affect me and my home audio system?  Glad you asked.

You may recall that the system consists of 2 physical zones, 4 general-purpose streaming zones and one special-purpose streaming zone.  It’s the general-purpose streaming zones that I use extensively when I’m not at home – ie, at work or in the car.  And despite advancements in the manner by which my intranet resources are made publicly “available”, the real truth is that using the streaming zones has always been a two-part affair; part one is to interact with the system using a browser, part two is to connect to the zone using a program on the client device.

Granted, quite often I can eschew part one, as the zone is loaded and good-to-go as soon as the client connects.  But one thing that really dogged me incessantly – besides security considerations that I won’t go into here – is the absence of any ability to play a single track without having to leave the web browser.

Yes, I’m talking about a desire to implement an audio client within the browser itself.

Now, Flash is capable of doing this.  And while Shelly’s phone doesn’t support Flash (argh), the truth is that Flash isn’t completely suited to the next logical step in this thought process – which is, replacing the streaming zones with a webpage and embedded player.  I mean, I could code a Flash app, but trust me when I say that that’s not going to happen.

But would could happen – and indeed, what I really, really, really want to happen – is to code an HTML5 “app” that can do this.  This would actually solve all sorts of niggling problems, like the issue of transport control that I talked about here.  The truth is that it could actually serve as a bonafied mobile music app, optimally designed for the small screen.

It could, if… MP3 and HTML5 played nicely together in all modern browsers.

And that’s the problem I’m having right now.  I’ve worked out the interaction, I’ve figured out that the current home audio system can easily support the types of XHR calls I’d need to make, I’ve got some working knowledge of JSON… heck, I’ve even got a working implementation now of an embedded player for playing single tracks.  But to make this all work I need HTML5 and it’s DOM-accessible AUDIO element, and I need cross-browser support of MP3 files via that same AUDIO element.

Desktop support is sketchy – as is mobile support.  I find it strange that Opera on Windows doesn’t support MP3 but Opera on Android does…?  And the native Android browser is supposed to support MP3 but it actually doesn’t.  <sigh>  The truth is that there’s no point burning the proverbial midnight oil on an HTML5 music player app for my audio system if support is hit-and-miss – across the devices that I actually use.

So as much as I’d love to cuddle up close to HTML5, the unfortunate truth is that it’s playing hard to get.

Universal Search in the Home Audio interface

Development has been slow on the Home Audio system lately.  Which isn’t to say that it’s not getting used; rather, I’ve been busy doing other things – some technology related, some not – and the system is quite mature at this stage after many years of development.

Nonetheless, ideas pop up every now and then and they’re compelling enough that it’s worth it to dust off the code and Make It Happen(tm).

Such is the case with “universal search”.  Regular followers of this blog will know that the search function is already quite powerful, so much so in fact that you can get lost in the features – and possibly become turned off from search completely if you’re trying to do something simple.

It dawned on me the other day that it would be really nice if I could simply search for a string without having to specify the field to search on.  So for example, I want to search for “lounge”, but I don’t necessarily want to give the system any more information than that.  With “universal search”, the system will search:

  • artist
  • title
  • category
  • genres
  • year

… for your particular search text.  You enter your text once and the system searches all of these fields.

In hindsight – and from your perspective – this is one of those “well duh!” sort of things.  But again, it’s easy to get caught up in gee-whiz features and completely neglect the stuff that seems obvious.  So pardon moi, but at least the feature is there now <g>

Back to where we came from

I’ve had a small, but noticeable problem with my home audio interface.

Yes, I’m well aware that I often seem to have small problems just begging for a resolution, but neglected nonetheless for some period of time until… a blog post is finally written.

Anyhow, this particular problem stems from the dynamic tables that are oh-so-cool in giving us super-long tables that are filled dynamically by the backend.  It’s somewhat of a good problem to have, in fact.

Here’s the deal.  You execute a search and you’re staring at your results.  Were you to press F5 now, you’d see the exact same page starting back at you (provided you hadn’t scrolled down at all).  This is the case because a search always refreshes the whole page, or more specifically, requests a new URL in the browser’s address bar.

That’s great and all, but then you decide that you want to sort on a different field.  So you do.  And because the table is dynamic, the sort occurs without refreshing the entire page.  Now, if you were to press F5, you’d be looking at the same search results but the original sort order would be restored.

The truth is that this situation still occurs today, and pretty much occurs in many DHTML apps unless you do some cool work to alleviate it (like I did at work, for a different but similar situation).  However, there’s more to the story.

Now, some links are smart enough to (essentially) ask the table about its condition and then make a request to the server based on the table’s answer.  So for example, if you click a link to add the results to a playlist, then the results will get added with the correct sort order.  And this could be done for every link on the page.

Except… they would have to become javascript links, vs. the straight HREF’s they are now.

Why does this matter?  Well let’s take allmusic.com as an example.  It used to be that some links – particularly those that were presented in list format – were javascript links.  If you attempted to open them in a new tab, well, any number of things could happen.  Recently allmusic made some changes and now many of their links are straight HREF’s, meaning you can open in a new window or new tab or whatever and it works as expected.

In our home audio interface we have the similar, occasional requirement of wanting to open a link in a new tab.  But if the link is a JS link, then you’ve got a problem.

It’s because of this that I decided that I didn’t want to present all of links as JS links.  But I still wanted to be able have the links reflect the state of the main table.

The solution I came up with is creative, though not the prettiest.

Basically, we leave the links as they are.  But, if the table changes for whatever reason, then we go out and explicitely rewrite links to reflect the changes.  This isn’t an ideal solution since it involves some overhead on the client.  But I can’t think of any other way to have regular HREF links which reflect changing properties elsewhere in the page.

So the act of initiating this update is fired by the table’s scroll handler.  I decided that this was the best place to start the update, as the scroll handler has the singular task of determing which rows/tiles are in the viewport and hence need to be brought in from the backend.  Recall that every time you scroll, it’s necessary to make sure that you’re actually looking at something.  This is the job of the scroll handler; he does some calculations, determines what should be there, then starts to calls to put those things “there”.  Since the scroll handler is so integral to the operation of our dynamic tables, I thought he should be the guy who starts the HREF updates.

Now, it’s entirely possible that there are hundreds, even thousands of links on a page at any point in time.  Fortunately, the majority of those links are contained in the scrolling table itself.  It’s on oversimplification, but I can say that those links are already aware of the state the table is in.

That leaves a handful of other links scattered around the interface.  Meaning, the actual process of updating those links is not particularly CPU intensive.  And I even have some nifty “process control” code that makes sure that only one update process can run at a time, and only the most recent one will run.

(fine, I’ll explain how it’s done.  The scroll handler starts the update process as an async process (using a JS timer).  It’s entirely possible that the scroll handler will fire again while the update process is still running – unlikely, but still possible.  So before an update process is started, a random process ID is generated and stored with the table’s other properties.  The update process is then “launched” and is told its process ID.  Once the update process starts to run (and while it’s running) it checks that the table’s record of the update process ID matches the processes own ID.  If there’s a mismatch – which will occur if a newer process is spawned – then the process halts and exits).

Anyhow, the end result is that a few things happen:

  • you can move to another page (zones, lists) and return to your browse results and the table will be positioned where you left it
  • you can resort your results, move to another page, then return to your browse results and the table will be positioned where you left it

Probably the only things that’s left, then, is to store the selections.  Sometimes you make some selections, but then you want to drill into a record and get more info.  This requires you to abandon your selections, or perhaps open the drill details in a new tab.  It would be nice, perhaps, if you could move around and not worry about your selections, knowing they will be there when you return to the browse results.  This is much harder to do though… I mean, there are ways around it using cookies, but I’m trying to avoid those methods.

Artists – What many names can do

(this title brought to courtesy of Beres Hammond, who’s “What One Dance Can Do” bubbled to the front when coming up with names for this post)

I’ve had a recurring problem ladies and gentlemen, in that artist names have been driving me crazy.

Here’s the situation.  An artist is named “artist”, and she publishes albums in this name.  Then the artist decides to change her name to “artois”, and publishes further names under this new name.  And so on and so forth.

The problem, then, is trying to determine which albums belong to a particular artist, regardless of pseudonym.  The problem can even crop up when, say, a gospel artist works with a choir and publishes an album with the choir’s name.  You want to give credit where credit is due, so the album artist field dutifully contains both the primary artist and the contributing choir.  But what happens when the artist publishes a solo album?

I’ve turned this one around in my mind for some time.  It becomes a problem when listing artists, in which case a single artist can be listed 2, 3, even 4 times.  Or when trying to browse an artist’s discography.

Part 1 of the solution was to introduce an “artist alias” field into the backend database, which is intended to contain the most recent pseudonym for that artist.  This isn’t the same as “TLC” vs. “Left Eye”; rather, it’s intended for people like “Puff Daddy”, aka “P. Diddy” aka “Puff Daddy” aka “P. Diddy and the Bad Boy Family”, etc.

OK, so we then had the ability to search on alias.  And the alias field is a calculated field, in that it will return the value of the artist field if the alias is empty.  Groovy.

However there was still the problem of listing and browsing.  You’d think that the artist alias would be enough, but you’d be wrong.  Take Bobby Valentino, aka Bobby V., aka Bobby Wilson.  I don’t believe he’s published any names under Bobby Wilson, yet that’s his current psuedonym (in this case, his real name).

Now, it would be fine – I think – to browse Bobby’s discography using nothing other than the Bobby Wilson alias.  However, we get into major problems when we want to see all songs where Bobby Wilson is the primary artist.  Those songs may exist on albums that are not Bobby Wilson albums at all – ie, soundtracks – or he may have still been going by Bobby Valentino at the time.

Basically, you’d need to search by all known aliases in those cases.

So after much consternation, I finally put together the code to make this happen.  Works a treat.  You have to take some care when putting together a manual search, as you have to understand exactly what it is you’re searching.  This is a fairly standard condition though, I think.  Otherwise, use the plethora of buttons and links which will do the heavy lifting for you.

While I was at it, I decided to tackle another dilemma: handling artist names that contain quotes.

Quotes are Bad News(tm) in the programming world.  You have to escape them, which isn’t bad.  But still, they can cause major problems.  Take the following example:

Give me all albums by Damian "Junion Gong" Marley, or by Lisa "Left Eye" Lopes.

Those are both valid artist pseudonyms.  And, if you construct the search with two artist fields OR’d together, you’re fine.

But in some cases – and this is true for our discography browsing code – you use a search specified like this:

artist is "Lisa "Left Eye" Lopes" or "Damian "Junior Gong" Marley"

There may be any number of reasons why you have to use this format versus the one above.  In my case it’s due to restrictions in the code and how parms are passed around.

Regardless, what you’ve got there are nested quotes.  And previously, my code would spit it out and give some unknown result.

No longer.  There are some basic assumptions that you can make:

  • a quote followed by a non-whitespace character is an opening quote
  • a quote followed by a whitespace character (or end-of-line) is a closing quote

There may be more, and more complexity, but you get the picture.  And indeed, these may be rules that you enforce rather than simply assume to be true.  With those rules in place, the code can now track nesting levels.  Escaping is another simple step away.

Wifey say, wifey do: zone drag/drop active

I don’t really know what to say about the titles that I come up with.  I mean, they’re my ideas, so I can’t sit here and shake my head in disbelief or some mild form of pity.  But really, what the heck does this one mean?

Well, at least the second part is fairly self-explanatory – to a degree.  It’s now possible to drag-and-drop an album or song directly onto a zone while in the browse view.  The idea is that you can queue up – or begin playing – an album/song without going through the steps that previously existed (and still exist) to perform this apparently arduous task.

Yes – “apparently” – and this is where the first part of our interesting title is explained.  One day, a long long time ago, Shelly said that it really should be possible to drag-and-drop an album onto a zone.  I believe that I was in the midst of showing her the ability to drag-and-drop an album/song onto the working list and have the item added to the list.

I’m not sure what prompted her to make this suggestion.  The thing is, the drag/drop facility is only available on platforms that support dragging – like a laptop or desktop – and not at all on platforms like smartphones which have no concept of how to perform a drag/drop action.  And – you guessed it – Shelly users her smartphone to interact with the system.

Nevertheless, I said “yes ma’am” and eventually got to work.  And the fruits were fully realized today (well, a couple of days ago but polished a bit today) with code that makes Shelly’s suggestion a reality.  As I said, from the browse view, you can drag an album/song over the existing play icon, which will cause a popup to be dynamically created containing all of the zones.  Finish the drag/drop operation by dropping the album/song on one of these zones, et voila, Something Happens(tm).

That “something” is dependent on a few things.  For an unloaded/unlinked zone, the operation will always end with the zone being shown and playback started.  Depending on your prefs, you may be asked if you want the zone to be linked.

For a zone that is already linked, the operation will cause the dragged item to be added to the linked list.  You remain on the browse view, but there is a helpful popup that says “Added” just to confirm that, indeed, Something Was Done(tm).

Now, the 5-billion-dollar question is: is this really necessary?

Well let’s look at the title for the most obvious answer: Wifey say, wifey do.  Wifey said “Do it”, and now wifey can do it.  Easy breezy.

Okay, how about a more general discussion?

I’ll oblige.  If you have the ability to perform this drag/drop operation, then you have the ability to use the other nifty features presented by the interface – most notably, the ability to take advantage of dynamically-loaded popups and inline information.  Previously – and currently – the steps to play an album or song (we’ll just say an “entry”) could most easily be performed by clicking the popup icon for that entry, clicking the play icon in the resulting popup, and then clicking the zone in the resulting zone list that got dynamically loaded into the popup.  This operation would always result in you getting transferred to the zone, where playback would have been started.  In the case of a zone that was previously linked, the linked list would be overwritten (unless the list was not an auto-generated linked list – in which case you’d get an error).

So if anything, that’s three clicks and waiting around for two dynamic operations to complete (the popup and the inline zone list) before anything could happen.

With the new drag/drop ability, you really only click once and you have to wait for one dynamic operation to complete – ie, the popup containing the zone list.

So from that point of view, I suppose I can agree that the new method is indeed more efficient.  I have to wonder how many times in one session a user is likely to load an entry to a zone – or in other words, how much impact this increased efficiency would have in the real world – but I suppose one can’t argue when it comes to the inherent goodness that is “increasing efficiency”.

But wait… perhaps there’s more to this.

What really makes this worthwhile is that the code is linked-status-aware.  Meaning, it does different things depending on the linked status of the destination zone.  This was alluded to earlier, but allow me to focus on it in more detail.

While it’s all well and good to drop an album on a zone and call it a day for the next 60 minutes, what happens if you’re putting together a 4-hour playlist of albums – or a 60-minute playlist of songs?  Now we’re no longer talking about loading a single entry to a list.

The previous (and still existent) optimal method for doing this would have been to create a new playlist and select it as the working list – or perhaps to load the first entry to the zone, then select the resulting list as the working list.  This doesn’t always work well if you’re working with albums, as the system isn’t guaranteed to create a linked list for a single album depending on how your prefs are set.  But supposing that it’s set appropriately, either of these methods would get you pointed in the correct direction.

Then, you could drag/drop additional entries to the list – or use a pulldown, or a checkmark,  or whatever other method you liked.  But the point is that you’d want to select the list that ended up getting linked to the zone of interest.  Or, if you manually created the list, then you’d select this list as the one that you will eventually load to the zone of interest.

With this new method, the only thing you need to know is what zone you want to work with.  You could have an entirely different list selected, or no list at all.  The list is not important – only the zone.  So the new sequence of events becomes: drag/drop an entry to the zone, return to your browse results, and drag/drop more entries to the zone.  The backend will take those additional entries and add them to the list associated with the zone.

You can see that this method offers clear benefits.  Again, there’s no need to work with or even know which list is linked to the zone.  This is especially useful if your current working list was used as part of the criteria in your current search.  Changing your working list to become the linked list would alter your search results, which may make it difficult to select more entries to add to the working list.

But most crucially, you get to take advantage of the increased efficiency that we discovered previously.  Yes, you could already drag/drop entries onto your working list – ie, the same efficiency that drag/drop onto a zone offers (better efficiency in fact, since there’s even less dynamic loading going on) but again, this only factors in if you select the linked list as your working list.  Now, even without selecting the relevant linked list, you can drag/drop and end up at the same place.

So ya, that’s cool.  I did some initial work in the backend to allow the user to drop a search result onto a zone as well.  I don’t have  draggable defined for this, but once I define one then it should Just Work(tm).  Truthfully it would also be nice to be able to drag/drop multiple items at once.   This may be straightforward for the backend to handle, but I imagine the frontend would need some serious work.  I’ll hold off on getting that going, but I suppose it is a project to look forward to.

From a technical point of view, I will say that getting this to work took a few days, but the hooks were mostly present to make it all go.  The stuff that I added amounted to handling a new breed of popups, which are non-modal and presented more as a menu anchored by an element on the page.  This comes with the need to define a relationship to that anchor, manage timers (which close the menu appropriately), clean up everything when a drop occurs or a drag is cancelled, and defined special “action” elements to overcome z-index issues.  The action elements – “actionables”, as I call them – were already necessary for regular drag/drop operations (again, due to z-index issues) but needed to be extended to work with menu-ish popups.

C’est tout.

A proper zone in the master bedroom

So here’s the scenario.

We’ve got this handy system called the Whole Home Audio system, and it allows us to play networked music to a number of physical and virtual zones.  We can use it to play music in the basement, or in the family room, or even in a car doing 100+ km/h on the highway.

Without question the physical zones are cool.  The family room zone is the coolest, since I can use my (dying) Harmony universal remote to issue transport controls and the system will respond accordingly.  That’s a pretty nice example of bridging hardware and software; in the family room, the nature of the audio system is completely* hidden.

* (the caveat is that, currently, you can’t select anything to play if nothing is loaded on that zone.  Minor issue, but I’m mentioning it in the interest of full disclosure).

The basement is somewhat unique in that the volume controls exist in the home audio interface, so you mash buttons on the interface page to increase/decrease volume.

In both cases, being physical zones, the requirement exists that we have sound hardware in the server to pump analog audio to the zones, and obviously, that there’s a physical connection between this sound hardware and the amplifying sound hardware at the destination.  This has worked for the basement and the family room, due to their proximity to the server.

The master bedroom, on the other hand, has never gotten to enjoy this sort of seamless/impressive hardware/software bridge.  It has always relied on a streaming client – functionally equivalent to my phone, or WinAMP on my work computer – to stream music through the floors and walls.  The streaming client in this case is GSPlayer running on a no-longer-used-but-still-loved PocketPC PDA, which itself is connected to a 2.1 speaker setup.

So playing anything to the master bedroom has meant:

  1. Play something to a particular zone – usually streaming zone 3
  2. Turn on the PDA and mash the play button repeatedly until WiFi connects and GSPlayer connects to the streaming zone
  3. When your musical enjoyment has ended, power off the PDA

This works, but it’s less than convenient.  And as you can imagine, I wouldn’t be posting about it here if I didn’t come up with a solution.

And so, fresh off of my success with GSPlayer modifications, I once again delved into GSPlayer’s inner workings and gave it the ability to accept incoming TCP/IP connections.  That was part 1.  Part 2, was to give the home audio system the ability to connect to said GSPlayer and tell it to Do The Damned Thing(tm).

Okay, I’ll explain.  The idea here is that the user should only ever have to interact with the home audio interface/system when it comes to selecting joints and loading a zone.  You can use controls at the zone to control playback, once started, but starting playback should itself be a homogeneous process.  So obviously, pressing play on a home audio interface page, then powering on a PDA and pressing play repeatedly… well, that didn’t cut it.

The fact is that it’s the home audio system which receives your request to load a zone, so armed with that knowledge, it should be able to do Whatever Is Necessary(tm) to complete that request.  For the family room and the basement, this culminates in WinAMP being loaded with relevant song data and audio suddenly starts to stream out of the respective speakers.  Streaming zones will always* require a two-step process, and that’s to be expected given their nature.

* (there may be exceptions to this in the future; see this post for one example)

So yes, it’s true that the master bedroom needs to rely on a streaming zone since its physical proximity to the server can’t be (easily) overcome.  However, as a user of the system, your perception is that you’re at home, you’re in a static environment (ie, a room) and therefore you consider it a physical zone and hence you want it to behave as such.

Back to the technical stuff.  The GSPlayer modification allows the home audio system to tell the PDA to connect to the streaming zone and start playing.  And in a nutshell, that’s the crux of it.  You load the master bedroom zone using the home audio interface, and the system loads WinAMP and tells the master bedroom to connect.  The PDA must stay powered on all the time in order for this to work, but that’s trivial – much as the basement amp must be powered on to play music in the basement (it’s always left turned on).

Now, in practice, there were many considerations that had to be dealt with in order for this to work as expected.  A third component had to be modified – specifically, the WinAMP general purpose plugin that’s currently used to give certain feedback to the home audio system.  That plugin, being intimately tied to the guy that actually plays music, is the ultimate source for information on what’s happening.  And for the master bedroom, I decided that we wanted the “start playing darnit!” notification to be event driven and fired by the guy who knows when playback has actually started – ie, WinAMP, ie – the WinAMP plugin.

There are timing issues that help to lead one to this logical conclusion as well – as I said, there were many considerations.  But conceptually, the event-driven (ie, WinAMP-plugin-driven) approach it makes the most sense.  And the things that make the most sense are usually the things that are easily capable of resolving related, niggling issues.

So here’s what happens.  You select some Brian McKnight and send it to the Master Bedroom zone.  The home audio system goes through the motions of sending a playlist down to WinAMP.  WinAMP may churn and burn for a while, but we don’t care – nothing happens until WinAMP starts playing.  Once WinAMP does start playing, the plugin fires an event back in to the home audio system.  The system parses this, determines that the Master Bedroom has an “RPC-capable” client, and sends a suitable command to said client.  The client – GSPlayer in the master bedroom – gets the command to start playing and connects to the appropriate streaming zone.

And Bob is your uncle.

Once playback stops on the zone, GSPlayer will disconnect since the stream has stopped.  Or, if you’re no longer jonesing for Mr. McKnight, you press stop in a home audio interface page, and the system sends a command to GSPlayer to stop playback immediately – vs. waiting for the streaming buffer to empty.

So most of this has been tested successfully.  Today I cleaned it up and “properized”  it, so I’ve still got to make sure it works exactly as expected.  I may – or may not – post back here with my results 🙂

In-car USB flash drive vs. in-car A2DP

Last time I was here I talked about a custom modification that I had made to GSPlayer – an MP3 player on my WinMo smartphone – to allow limited, transparent control of a Home Audio streaming zone from within GSPlayer itself.  And it has proven quite handy.  The first trial went well, but then I was dismayed to discover that the stream was skipping.  It wasn’t happening regularly, and it would only skip for about 0.5 seconds each time… but it was enough to be noticeable.

I was beginning to wonder if perhaps this was the main reason why I had switched from GSPlayer to PocketMusic.

Perhaps I’d have to dig into the code.  But after thinking about it overnight it dawned on me that this may be a simple buffering issue.  It wasn’t behaving strictly like a buffering issue – the display wasn’t showing that the player was rebuffering, and it wouldn’t make sense that it would take 0.5 seconds to rebuffer each and every time – but what the hey, I figured it was worth a shot.

So I up’d the buffer from 128k to 1024k (1MB) and that seems to have fixed it 🙂  The prebuffer is still 32k so playback begins just as quickly as before.

Anyhow, everything up to this point has been a digression.  But I mentioned it all because; 1) it’s related, and (2) when taken with the real intent of this article, it serves as a nice illustration of the logical progression of this sort of project.

So… here’s what happened last Friday.

I left work, and decided to play some songs off the flash drive.  But after 5 minutes or so I decided that I would rather listen to the queued tracks on a streaming zone.  So I connected my phone to home and started playback, only to realize that music was coming out of the phone’s speaker itself…???  As it turns out, the USB drive was still plugged in under the armrest meaning the Bluetooth music gateway was not.

Well that certainly sucked.  And while it would have been physically possible to remove one and insert the other, there were two overriding thoughts which nagged me incessantly:

1) Those cables are inconvenient to reach, especially when driving

2) Why should I have to physically switch anything???

So on that Friday I decided to listen to nothing at all for the duration.  But the experience served to solidify and accelerate an idea I had from the very moment I decided to power the gateway off the USB port – which was, to split the port so I could power the gateway and leave a flash drive connected at the same time.

Normally you’ll find USB cables that wire two ports in parallel for the purposes of drawing combined current from both ports.  Only the power wires are connected together; the data wires are connected to one port only.  This allows you to connect devices that might exceed the 500mA that a single USB port can provide.

In my case, I needed a cable that could take one port and split the power to two USB devices, while again providing data connectivity to only one of those devices.  And I figured I’d be okay in the power department, since people regularly power USB hard drives off their BMW USB ports without issue; certainly a lowly flash drive and bluetooth A2DP adapter would be less power-hungry than a hard drive.

After looking around for a suitable cable it became apparent I wouldn’t find one.  I would have to make one myself.  And while I had a spare USB-to-mini-USB cable that I could hack (which would provide power to the A2DP adapter via mini-USB) I had no USB cable with a male plug on one end and a female receptacle on the other.

As luck would have it, I found just such a cable this weekend… for $2!  Perfect price.

So I spliced in my other cable and I’ve now got a 6″ USB extension with a spliced-in 2.5′ cable ending in a mini-USB connector.  I did multiple tests along the way to make sure that everything would work.  And once in the car, everything worked.

One comment I have to make – the wires inside said cables are t-i-n-y.  I had to use an X-acto knife to slice the sheathing off, and in 10 cuts I think I managed to sever one strand.  And because the wires were made up of 5 or 6 such tiny strands, I had to tin them with solder.  After twisting them together I soldered them again to solidify the splices, wrapped each splice individually in electrical tape, and then wrapped the whole shebang with more tape.

So there it is – I can play tunage off the flash drive or off the phone without having to reach under the armrest.

The particular flash drive I’m using – an 8GB Kingston C10 that I scored for $20 off Dell – is loaded with all the tracks from my “fav’s” list on the Home Audio system.  Syncing the two is fairly trivial, and in the process the system generates genre playlists since… well, I’ll explain.

Some of my tracks have “compound” genres.  For example: “R&B/Reggae”.  While the car has the ability to read these genres, the problem occurs when such a track is not listed in the R&B genre or the Reggae genre.  Personally, I’d want it to be listed in both.

The solution therefore was to gen my own playlists – which the car can read – and make sure that the track is listed in both playlists.  Done – this occurs during the syncing process.  This also allows me to group other genres – Dance, House, Techno, Electronica all get grouped as Dance – so that I can play them all while still keeping the original genres intact (and indeed, the sync will gen playlists for the original genres but name the playlist as, say, “Dance (House)” for house tracks)

So that’s cool.  But you know me, always wondering what the next step can be.

Here’s the thing – the car can control iPod’s and, apparently, certain other MP3 players.  How does this work, this “control”?  For the iPod I believe it’s a special set of code specifically designed to work with the iPod and act as an interface for the iPod.  But for all other devices, the car looks at the device as a storage container housing tracks.  Those devices can either be a Mass Storage device – so, a USB flash drive – or they can be a Media Transfer Protocol compliant device.

The difference between the two is  down to semantics, at the higher level at least.  Again, the car sees both as a storage of files.  In the case of Mass Storage, the device is a drive that the car mounts.  When you want to play a track the car opens the file and reads the data off the drive.  In the case of MTP, the car queries the device via MTP commands; when you want to play a track, the car asks the device for the data and the device sends it over.

So you can see that, to the end user, they both seem to operate the same way.  And indeed, the iPod appears to as well.  But the iPod’s interface is proprietary, and there may be more going on than I’m aware.

Actually I’m guessing about MTP as well, but it’s an educated guess.  And here’s where the magic would happen:

Unlike Mass Storage, there’s no reason why the files on an MTP device have to be on the device itself.  When the car queries for a list of tracks, or genres, or whatever, the MTP device can act as a mere proxy and query some other device for that info, then report back to the car.  When the car wants to play a track, the MTP device proxies the file from some other device and feeds the data back to the car.

Surely you see where I’m heading.  A full blown, customized implementation of this protocol would have me plug my phone into the USB port, then have an application that talks to the car via MTP on one “side” and on the other “side” it talks to my Home Audio system via VPN over 3G.  All of the constructs – albums, songs, playlists – exist on the Home Audio system.

That’s not the approach I’d take though, if only because I can just imagine what would happen trying to proxy metadata for 30,000 tracks.  Rather, you’d likely proxy metadata for a single playlist, or perhaps for the playlists only.  Something like that.

But the whole point of the exercise would be to provide a seamless way to connect back to the Home Audio system and use the car’s media system to playback songs and browse the collection.  Imagine seeing my list of fav tracks on my I-Drive screen, being pulled in realtime from my network at home.  With MTP this would be possible!

How much work is required?  Well, I can wrap my head around the concept and interaction of all the moving parts.  The good news is that we wouldn’t need to worry about decoding/encoding MP3 in the app, since we’d just be proxying song data.  The great unknown is the amount of work (or feasibility) of coding a WinMo app that can take over the USB port.