Wednesday 30 July 2008

Problem Solved

I finally got the track length application working. Turns out it runs fine removing the database calls from the C application. These are replaced with a wrapper script written in Python (the first time I've used Python in such a way). The script makes all the database calls then uses fork-exec to run the length application. It seems to be working fine and is currently running in a screen session on one of STAR's machines.

You can view the Python script here. I will get onto packaging the rest of the source for your viewing some point in the near future.

EDIT: Full source code can be obtained here. Also, the application seems to use 100% CPU. I might want to put a sleep call in somewhere.

Monday 28 July 2008

Dropping Down A Level

Most of the programming discussed in this blog has been in managed languages (e.g. VB.NET, C#) where almost everything is done for you. Garbage collection, memory management. In most situations, it's great to have it all done for you and concentrating on the programming. However, this weekend, I decided to program in a bit of C.

The application in question is a small command line application that calculates accurite track lengths. Making use of the FMOD Ex API, it plays a track, constantly checking the levels. From this the actual end point is calculated. The result is no dead air on STAR.

It's not been without its problems though. I've completed the audio part of the application and most of the database side of things. However, I have run into the error "Could not connect to database. Reason: could not create socket: Too many open files" when trying to connect to the database. Annoying, and surprisingly the suggested fixes on google are no help.

So, I'm planning to test it on one of the STAR machines. Problem being I'll need to install the FMOD library on the machine. Thankfully not really an issue as it is supplied compiled. The installer just copies files over. So we should be ok without having make on the machines to run through the script.

I've also been informed I should be packaging the application. Specifically in a .deb package as we are running debian. Not really a priority in my book (I'm more interested in getting the application working and running) but would be nice. Though I should point out that the debian packaging documentation was not the easiest to find. Once there, it seems easy enough.

Friday 25 July 2008

Best Intentions

Working in customer services, my job consists of handling complaints from time to time. Some complaints are valid, need investigation and fixed. Others not so much.

There also exists a sub category of valid complaints. These are valid issues that need taken up and investigated, but are reported for the wrong reasons. Take the example of the allegation of staff at the fish counter not using gloves. That is something that will be taken up with the branch management. However, it was reported not because of *just* cross contamination (the reason I would have it investigated) but because this cross contamination may put vegetarians off eating the fish!!! I'm a bit lost by that one. Why would a vegetarian be eating fish (a meat)?

There are also the bizarre. I was reading on the internal notice boards system that a customer had complained about the refurbishment at one of the small, town centre stores. You would think it would be because of noise, disruption, works, etc. You'd be wrong. Turns out the food was being moved to different locations during the works and the customer insisted we hand out maps! This is for a store with about 3 isles in it.

And finally, a story was printed in the local press about hospital staff wearing uniforms on public transport. Not something they should really be doing. The paper quoted a person taking about contamination from the "unwashed masses". Bit full of yourself, eh? No wonder you asked to remain anonymous.

Sunday 20 July 2008

Get Voting

Now fully written and integrated into the website is STAR's track voting system. This originally spawned from the idea Phil had to have the playlists selected by user vote automatically. Not an entirely brilliant idea for a station carrying on average 3 listeners. However, the idea of voting for tracks was taken on board.

I decided to go ahead with allowing the user to vote on the last 5 played tracks. This currently includes jingles, promos and sweepers until I get the exceptions setup. However, the listeners are only choosing from tracks they have just heard. So, if it sounded rubbish, you vote it as rubbish.

The results are held displayed on the staff portal to all registered users. This could potentially allow presenters to integrate the voting into their shows.

There are a few restrictions in the system. You can only vote for each track a maximum of once per day and a vote will only hold weight for 1 week (this may be adjusted in the future). As the automatic logging system can only logs tracks on the playout system, only music played from the computer can be played. Though it should be noted that any playlisted music would have to be on the system anyway!

So, if you're eager to get voting, you'll have to wait until we launch again in the autumn. But when we do, you can vote by clicking on the "listen now" button then "click here" on the popup. Just follow the onscreen messages. (The overly eager can just click here).

Wednesday 16 July 2008

Wizard!

No, I'm not talking about the band and a certain Christmas song. I'm actually on about AllDay DJ.

After sending a few copies of the latest beta in the general direction of people, I was informed that the first steps were not obvious. So, to make them a little easier, I've put together a simple wizard. It talks you through importing tracks in various formats as well as locating your database in the first place!

Hopefully the process of setting up AllDay DJ should now be easier and a little more colourful.

ss_wizard.JPG

Saturday 12 July 2008

CDs - Playing, Ripping and XML?!?

A lot can happen in a weekend. But how about a complete CD ripper for a playout system? Not likely you'd think, but I managed to get a working CD ripper.

Ok, it's probably not the most robust of systems but it works quite nicely, even with CDs you make yourself! Though, most of the work was done for me. It actually makes use of the CD module from the BASS Audio Library. This provided me with a stream of decoded audio to throw in the general direction of oggenc2.

But there are some clever bits. For example, the track identification. I made use of the library to obtain the ISRC codes for the tracks and the identifying code to send to the Musicbrainz server.

But I mentioned XML, where does it fit in. Simple - Musicbrainz. Compared to the FreeDB system I though it would be overkill but it works quite nicely. There's also less screwing about with creating my own parser. In fact, the XmlTextReader class seemed happy enough to do the HTTP requests on my behalf.

For a CD, the tracks are return as a set of nodes, containing the title and artist in child nodes. This makes it simple to obtain the data I needed. There's actually very little code from myself processing the XML.

This makes it sound simple, right? Well, I did screw it up a bit. For a while I had an elusive bug that caused a stuttering effect in the ogg files. Turned out I had just used a wrong flag on oggenc. We all make silly mistakes from time to time... :)

Wednesday 9 July 2008

VB.NET Niceties

It's not often you hear about VB.NET in a good light. That's mainly for the reason it's a mainly misused tool. It works well for prototyping but not so brilliantly as a RAD tool. However, there are projects I have had to make use of it in and suprisingly there are some good bits.


 


Drag And Drop Made Easy


 


In VB6 (yes, I had to suffer it at school), doing anything remotely interesting required an obtuse call to some DLL. There was also a lot of hoping an praying over file version numbers as well. This made me think it would be excedingly difficult to do drag and drop in VB.NET. Fortunately, I was wrong.


 


To start, you will need both controls to have drag and drop enabled. You'll find the option in the properties box.


 


Secondly, you will need two methods. One for the "from" control. This example is from AllDay DJ's drag and drop player:


 


Private Sub lvResults_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lvResults.MouseDown

            lvResults.HitTest(e.X, e.Y).Item.Selected = True
            lvResults.DoDragDrop(Me.selected_item, DragDropEffects.Copy)

End Sub


 


The HitTest call is only there to the item in the listview is selected on mouse down, before doing the drag and drop. You will need to replace Me.selected_item with the object you wish to send to the other control. You'll also need a receiver:


 


Private Sub dndPlayerDragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles btnBackDND.DragEnter...

        ' Check the source

        If (e.Data.GetDataPresent("AllDayDJ2.AudioItem")) Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.None
        End If

End Sub


 


In the above code, the object is type checked then a "copy" is allowed. Note that you could also use move or some other option but they must match.


 


Finally, you will need a third method to perform any action after the drop. Here we simply add the item to the playlist:


 


Private Sub dndPlayerDragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles btnBackDND.DragDrop...

        ' Load the item

        Dim item As AudioItem = DirectCast(e.Data.GetData("AllDayDJ2.AudioItem"), AudioItem)
        item = New AudioItem(item.getTrackId.ToString, item.getDbTable, True)
        Me.loadDNDPlayer(item)

End Sub



Here we simply cast the object (we have already type checked) then use it. The important line in this block of code is the first one. The others simply make a clean copy of an the item dragged over and load it into the player.

 


Feel free to use these examples. It's not too hard to find other examples. Just be sure not to use the AllDayDJ2 namespace for your own classes!


 


Documentation


 


 If you look at the C# examples in previous entries, you'll find comments starting with 3 slashes. These act kind of like the double star (*) comment in Java (aka JavaDocs).


 


However, based on my experience with VB6, I did not expect such a thing from VB.NET. Turns out I was wrong. Just start the comment with 3 apostrophes ('). From there, the Visual Studio IDE will auto-complete a comment section. It's then a matter of filling in the blanks.


 


The up-shot to this over normal comments is that proper documentation can be generated in a similar stye to JavaDocs. Also, just like in Netbeans and Eclipse, the IDE will display the documentation info in a tooltip. Very useful.


The down side. Redocumenting AllDay DJ 2.

Saturday 5 July 2008

When Local Gets National

Call your local supermarket. Go on, I dare you. If it's a national chain, likely the phone will never be answered or somebody from another part of the country will answer. Sounds a bit odd? Not really.

My job currently involves answering phones on behalf of local stores. So if you call the Poole branch, a guy in Scotland may answer.

Sounds a bit daft really, until you think about it. Personal experience tells me retail outlets will rarely answer their own phones. Usually because most calls are pointless. Yeah, most calls are checking if we have a specific item in stock.

Ok... I'll check it for you. But really, did you need to call to check we had butter in stock? Get real, get over it and make the trip next time. I can see the point for big items (e.g. a BBQ set) but not for a loaf of bread.

This will probably give away who I work for but they are currently running an offer on wine. 25% off when you buy X amount. As I said before, I'll check if an item is in stock. However, I am not getting a small city centre store to keep their entire stock of a particular wine back for you. Remember, other people buy wine as well. Anyway, most of the smaller stores have "bulk buy" policies limiting you to 6 bottles, so you can't get 25. (WTF do you do with 25 bottles between 2 people anyway?).


Ok, I'll admit some issues will require me to speak to the store on your behalf (if I can get a hold of them that is...). For example, lost property. However, some issues can easily be handled by the call centre.

Take the example of being overcharged. Now, you certainly will not get any money back over the phone. So when I tell you that you will need to re-visit the store to get the money back, please don't argue that you need to speak to the store. I'll put you through but it will not get you anywhere.

Bad calls are part of the fun of the job. However, there are a staggering number of people who will refuse to speak to me and demand a direct number to the store. Unfortunately, you're out of luck there. Not only the 0845... numbers but the 01... and 02... numbers now get redirected to the call centre. We can then transfer you to an internal line but you cannot skip us.

Surprisingly, it's not only customers complaining about that one. Staff have had a good moan to me about it too.

Though the classic has to be job vacancy enquiries. You actually have to physically go to the store to check vacancies. Get over it, you will need to do that when you work there. I did it with previous retail jobs, and you will need to now. So when I tell you this, please don't get all huffy and demand personnel on the phone (some sneaky ones try it without mentioning they are enquiring about vacancies). I'm not allowed to and probably won't even try for you.

Thankfully, I haven't yet had too many issues with "you're not local". Though I had one guy with the cheek to say "I can't understand a word you're saying". All I said was "...<my employer> customer services, steelegbr speaking...". Not too many people happy with the Scottish accent. It also gets a few annoyed that Poole store is not answering, even though I can sort out most issues without involving them!

But with all these issues, is it worth it? Well it means the phones actually get answered and most issues never actually reach the store (most of them don't really need to). It also means we can look into stuff on your behalf and solve most problems within about 30 seconds.

Also, having just done a week of solid overtime in this call queue, most calls are not this bad. Most go well enough.

Though I have found another disadvantage to doing solid overtime. Working my way through the wired inbox after a week of not using it. A couple of hundred automated messages and almost 200 spam messages. It hurt working my way through them.