Archive for September, 2013

Playing a CD with the Win32 Media Control Interface

A long time ago I wrote some code to play CD audio tracks for a game engine I was writing. CD audio (via mixed mode CDs) was popular for video game music at the time because it allowed for high quality music without having to deal with large un-compressed audio files (e.g. uncompressed WAV) or relatively expensive decompression algorithms with compressed files (e.g. MP3).

I cleaned up the code a bit and decided to post it here. It’s surprising simple code as it uses the very high-level Media Control Interface (MCI).

Compiling and Linking

You must link with winmm.lib

cdaudio.h

#ifndef __CDAUDIO__H__
#define __CDAUDIO__H__

bool cdaudio_open(void);
void cdaudio_play(int track);
void cdaudio_stop(void);
void cdaudio_close(void);

#endif

cdaudio.cpp

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include
<windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <mmsystem.h>

bool cdaudio_open(void)
{
    DWORD ret = mciSendString(L
"open cdaudio",NULL,NULL,NULL);
    mciSendString(L
"set cdaudio time format tmsf",NULL,NULL,NULL);

    
if (ret != 0) {
        
return false;
    }

    
return true;
}

void cdaudio_play(int track)
{
    
wchar_t tk_string[32];
    wsprintf(tk_string, L
"play cdaudio from %i to %i", track, track+1);
    mciSendString(tk_string,NULL,NULL,NULL);
}


void cdaudio_stop(void)
{
    mciSendString(L
"stop cdaudio",NULL,NULL,NULL);

}

void cdaudio_close(void)
{
    mciSendString(L
"stop cdaudio",NULL,NULL,NULL);
    mciSendString(L
"close cdaudio",NULL,NULL,NULL);
}

main.cpp (example showing how to use cdaudio functions to play track)

#include <stdio.h>
#include "cdaudio.h"

int main(int argc, char *argv[])
{
    
// setup MCI for CD audio
    
cdaudio_open();

    
// play track 8 on CD
    
cdaudio_play(8);

    wprintf(L
"Press any key to stop playing track...");
    getchar();
// wait for keypress

    // cleanup
    
cdaudio_close();


    
return 0;
}

Musei Civici Veneziani

Cleaning out old cards from my wallet and found my museum pass, for the Civic Museums of Venice, from a trip to Italy a few years ago.

musei-civici-veneziani-pass

Numbering items within groups in MySQL

In my previous post, I described computing row numbers for items within a result set. If items in the result set can be ordered into groups, you can use the same technique to number items within the groups. This is valuable as it allows you to get the top 3, top 5, top N … items within each group (note that GROUP BY isn’t appropriate here; we don’t want to aggregate items within a group, we want an ordering of all the items within a group).

Consider the following sample of data where we’ve done an ordering by the location and age fields (ORDER BY location DESC, age DESC). Every user’s email address is within a group (location) and within that group users are sorted by age in descending order.

SELECT mytable.*
FROM mytable
ORDER BY location DESC, age DESC

ordered data

By using two variables, one to keep track of the item number (@itm) and another to keep track of the current group (@grp), and incrementing the item number if the current group has not changed, else resetting it to 1, we get a numbering of each item within each group. In this example, the group item number tells us who is the 1st oldest, 2nd oldest, etc. user in each location.

SELECT

    
@itm := IF(@grp = location, @itm + 1, 1) AS group_item_number,
    
@grp := location,

    
mytable.*

FROM     mytable,
        (
SELECT @itm := 0) AS itm_num_init,
        (
SELECT @grp := NULL) AS grp_init

ORDER BY location DESC, age DESC

group item numbers

Row numbers in MySQL

Surprisingly straight-forward. Row numbers are useful is cases where you need the rank of a row within a result set.

SET @cur_row := 0;
SELECT mytable.*,
@cur_row := @cur_row + 1 AS row_num
FROM mytable
ORDER BY whatever;

The variable initialization can be done without a SET declaration by doing it as a JOIN:

SELECT mytable.*,
@cur_row := @cur_row + 1 AS row_num
FROM mytable, (SELECT @cur_row := 0) AS row_num_init
ORDER BY whatever;

Solution via Daniel Vassallo’s answer on StackOverflow. A comment mentioned the row numbers being calculated before ordering is done, but I haven’t found this to be the case.

While the above queries will give you the row numbers as expected, putting a HAVING or GROUP BY clause in the same statement might be dangerous. From Xaprb:

The result of assigning to a variable and using it in the same statement (in the HAVING, for example) depends on the query plan the server chooses, the phase of the moon, and probably other things too.

So, in such cases, a subquery is the safe bet:

SELECT sub.* FROM

    
(SELECT mytable.*,
            
@cur_row := @cur_row + 1 AS row_num
    
FROM mytable, (SELECT @cur_row := 0) AS row_num_init
    
ORDER BY whatever) AS sub

HAVING sub.row_num ... ;

Generating a random timestamp in MySQL

Random timestamps are fairly simple to generate and useful when creating test data or fake data for demos. The technique involves converting a MySQL timestamp into unix time, adding or subtracting a certain time range (in seconds), then converting back to a MySQL timestamp.

I’ve used this technique presented on underdog-projects.net before, where a starting timestamp is specified and a random time span is added to the timestamp. However, I wanted to try something slightly different and, in my opinion, a bit more robust. Instead of specifying a starting timestamp, I wanted a pivot timestamp from which a random time span is randomly added or subtracted.

SET @pivot_ts = '2013-01-15 22:15:45';
SET @max_span = 432000; /* 5 days in seconds */
SET @bias = SIGN(-0.5 + RAND());

SELECT FROM_UNIXTIME(
    
UNIX_TIMESTAMP(@pivot_ts) + ( @bias * (FLOOR(RAND()*@max_span)) )
);

Of course all the variables can be made part of the SELECT statement to make everything more succient.

Blog redesign

I’ve not posted anything in a while partly due to time constrains but mostly because I’ve been working on redesigning this blog and wanted my focus to be 100% on the redesign before publishing anything new. In addition to the redesign I also wanted to put this blog on it’s own domain and move away from aautar.digital-radiation.com/blog (when this blog was setup the digital radiation team was more than myself, hence the aautar subdomain, and I wanted other, non-Wordpress pages, to live in the root, hence the /blog folder). I snagged the semisignal.com domain a while back and thought it was a great choice for the blog and positioned it away from old or non-relevant content on digital radiation; this blog (and content linked to from this blog) have been the only things relevant on that site for quite a while.

With regards to the redesign, I had a few key goals in mind as I was working, which I’ll run through below.

semisignal blog redesign

  • Clean and consistent design: One of the big problems with the old blog was that it was hacked together from the default WordPress template at a time when I knew very little CSS. There was a lot of bad things both in the code I wrote and in the base code I was working from. I kept making minor improvements over time but there were still a lot of things that didn’t look good (unstyled input buttons, tags, etc.) and things that only looked good if additional inline styles were applied. There were also a number of inconsistencies in regards to link styling, tag styling, search input location, etc… a lot being due to different rendering code for single posts vs multiple posts in the archives and search. This redesign attempts to address these issues, while providing a cleaner, fresher look to the blog overall.
  • Bring content forward: At one of my first jobs, my boss mentioned that one of the design goals of our project was to “bring content forward”, pushing back superficial elements that took up real estate but had no real functional purpose. This has stuck with me since. With this redesign, I ditched the massive header, ditched the blurb and photo of myself, and increased the space given to posts.
  • Responsive: Admittedly this was not a goal when I started this redesign, but more and more I wanted something that would at least scale comfortably on a tablet and allow navigation via touch. I probably did responsive design wrong here (it’s not mobile first, styles are hacked in here and there to accommodate for different sections and breakpoints), but the new design was simple enough that I really only dealt with scaling elements and not with stacking them. For the lowest resolution breakpoints (for phones), I simply dropped the sidebar, betting that search was a better means of navigation on a phone, where a user’s intent is more directed towards a specific need, and they likely aren’t looking to browse the site.

semisignal blog redesign

  • Highlight projects & notable content: As with the old design, I wanted to keep a section in the sidebar to highlight my projects. Going forward I may add another section or expand this section to include notable posts as there are a handful of posts which are popular, but visitors really don’t have a way to find those easily.
  • Meaningful gateway to content: With the old design, you could browse through posts by going to a month in the Archives or selecting a specific Category. Neither of these really made sense. Category (in the way I use it) is generally way too broad to browse over and digging into the Archives gives you, essentially, a random set of posts given that the only context binding the posts is the date they were published and my posts are not time sensitive in nature.
  • Consistent gateway across all pages: With the old design there were 2 ways a post could be displayed: narrowcolumn where the post with listed with others and the sidebar content was displayed, and widecolumn where only a single post was displayed but the sidebar was empty (with a fixed width layout, going wider has always been preferable for me but I hated the layout of an article changing when you clicked to view a single post, so I had reduced the width on the widecolumn display as well). Search was also not available in the widecolumn display (I have no excuse for that). With the new design the sidebar (at non-mobile resolutions) and search field are consistent and visible across all pages.

semisignal blog redesign; old design

The old design served me well for a long time and, looking back, it’s surprising how well it held up, given that so much was hastily hacked together. That said, I’m excited to move forward with this new design and begin focusing on content again.