Tuesday, 1 April 2014

A Bug report I helped write made Raymond’s blog!

This is probably as close as I’ll ever get to famous. The Visual C++ IDE bug Raymond mentions went like this (I’ve redacted the names of the other developers in case they’re super-serious now and don’t want to be associated with this silliness).

-------------------- ACTIVE - 01/30/95 – M******S -----------------------

Visual C++ makes an audible signal when a build completes.  When no developer is in the room, this signal doesn't make a sound.  To reproduce:

1) Start a build.

2) Leave the room.

3) Note that the chime does not make a sound.

We should find a way to make the build bell make a sound even if nobody is there to hear it.

This philosophical issue may need program management's attention before being resolved.

--------------- ASSIGNED to M******T - 01/30/95 – S***F -----------------

Can we use the telepathy support in Win95 to contact whomever is logged into the machine doing the build?

Maybe we should just detect when the developer is leaving the room and prompt for a phone number where s/he can be reached.

How about disabling leaving the room during a build?

--------------- RESOLVED - BY DESIGN - 01/31/95 – M******T --------------

-------------------- ACTIVE - 02/01/95 - MARKLAM ------------------------

Actually, we can't do this either. The problem is that while you're out of the room your build is neither finished nor unfinished. It stays in a state of flux until you return and collapse the quantum uncertainty by observing it.

Perhaps we could link the build finished event to a cat in a box?

--------------- ASSIGNED to HEISENBERG - 02/01/95 - MARKLAM -------------

--------------- RESOLVED - NOT REPRO - 02/03/95 - HEISENBERG ------------

I cannot repro this. I tried standing just outside my door and it made the beep.

Do I have to go further from my office? Would the mailroom do?

-------------------- ACTIVE - 02/03/95 – M******S -----------------------

The relative position of the mailroom and your office are relatively uncertain to me, Doctor.

Please try again:

1) start a build

2) leave your office

3) go down the hall

4) wait until you don't hear the beep

5) return to note that the build is done

I think this is how I first repro'ed the problem, but I can't remember what I was doing to make it happen.

The idea of disabling leaving the room might be the best possible solution, I think.  When a build starts, the IDE should pop up a message that says "There are no more Fritos" or "The kitchen has closed early" or "The bathroom is being cleaned" so the developer will not be tempted to get up and wander around.

With minimal rebuild in place, we should consider diversions that won't take as long to remedy: "You're expecting a phone call" or "Someone will stop by to see you soon".

We need to think of messages that are easy to localize for VC++3.0J.

--------------- ASSIGNED to M******S - 02/13/95 - MARKLAM ---------------

To do this we'll need to avoid messages about the bathrooms and vending machines for external releases.

Perhaps some customer research is needed to find out exactly *why* Visual C++ users leave their keyboards.

Some suggestions (including MB_ types)

Get a drink :

(i) You're out of coffee

(i) You're out of tea

(i)(i) YYoouuvv''ee  hhaadd  eennoouugghh

Get something to eat :

(?) You have no food, remember

/!\ You need to lose weight, fatso. Sit your ass down

Exercise etc :

(?) Did You Know - sunlight causes skin cancer

(i) With a Nordik Trak you can get a workout in front of your monitor. Call for home delivery

/!\ I didn't mean that about your weight

See family :

(i) They already know you love them

/!\ They'll only want money for something

/!\ Your in-laws have arrived

Call of nature :

This could be difficult. Consider supplying bed-pan or similar

--------------- ASSIGNED to M******S - 02/16/95 - HEISENBERG ------------

I attempted to repro this once more:

I placed my machine in the forest at the edge of the campus.

I started a 'rebuild all' and ran out of the forest towards my mailroom.

My build normally takes 3 minutes. After 5 minutes I had not heard anything, so I returned to my machine.

Unfortunately a tree had fallen on it. I had not heard that, either.

(If any of the people concerned recognise themselves and want their names put back, just let me know.)

Wednesday, 15 January 2014

Converting 20-bit PCM from a DVD soundtrack to FLAC on Windows

Almost everything refuses to work with this 20-bit format, but here’s a process I found to work.

DVDDecrypter can demultiplex the stream and split it into chapters.

  • In the settings, on the IFO tab choose splitting by chapter. On the Stream processing tab ensure Convert PCM to WAV is unchecked.
  • Choose IFO mode
  • Select the PGC in the Input tab
  • Enable stream processing, check only the LPCM stream
  • Choose Direct Stream Copy
  • Choose an output folder
  • Hit the decrypt button

You should now have a folder with PCM files in, which nothing understands. Except Twen.

For each PCM file in turn:

  • Press open, select the PCM file.
  • Press Process.

That should create a WAV file for each chapter, which nothing understands. Except ffmpeg.

From a command prompt in the folder with the WAVs,

for %f in (*.wav) do "path-to-ffmpeg.exe" -i "%f" -acodec flac "%~nf.flac"

You can now get rid of everything except the FLAC files in that folder. They should be playable in your favourite music app, as 24-bit 48kHz FLAC.

Monday, 6 January 2014

Setting up a DLNA renderer with decent line out on a Raspberry Pi

GMediaRenderer/GMRender-Resurrect with a USB soundcard on Raspbian Wheezy (as of January 2014).
I could only get rid of the choppy sound by lowering the USB speed, so if that’s a problem for you then these instructions won’t help…
I’m not claiming any of this is groundbreaking or even original. This is basically me pulling together all the information I found on various blogs and forum posts into one set of steps that seemed to be ‘current’. I hope I have given everyone the appropriate credit for their hard work, if not please let me know and I’ll fix it.

Install Raspbian (Wheezy) using NOOBS

Available from the Raspberry Pi downloads page.

Get a USB soundcard

But check that it works with the Raspberry Pi. This is the one I used (because on of the reviewers had it working): Dynamode USB Sound Card 7.1

Install gstreamer-1.0

Add the custom repository line
deb http://vontaene.de/raspbian-updates/ . main
to /etc/apt/sources.list as described in this forum post, where Defiant has compiled gstreamer-1.0 for Raspbian.
Update the package information and install the upnp and gstreamer libraries.
sudo apt-get update
sudo apt-get install libupnp-dev \
libgstreamer1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \

Get and build gmrender-resurrect

From Henner Zeller’s  instructions in the gmrender-resurrect repository
sudo apt-get install autoconf automake libtool git
git clone https://github.com/hzeller/gmrender-resurrect.git
cd gmrender-resurrect
sudo make install

Set up alsa and tweak the USB settings

I made the USB soundcard the default sound following the instructions in atom’s forum post:
In /etc/modprobe.d/alsa-base.conf, comment out the line that prevents usb-audio from being loaded first, and add the line to prevent the on-board sound being loaded first:
#options snd-usb-audio index=-2
options snd_bcm2835 index =-2
options snd-usb-audio nrpacks=1
Then configure the volume to be full using
sudo alsamixer

sudo alsactl store
I tried enabling fiq_split (whatever that is), but I still couldn’t get the playback to not stutter, until I lowered the usb speed to USB 1. Edit /boot/cmdline.txt to add
dwc_otg.fiq_split_enable=0 dwc_otg.speed=1

Install gmrender-resurrect

From inside the gmrender-resurrect folder
sudo make install
And then create a script to run at startup with some appropriate settings. Save this script as /etc/init.d/gmediarenderer (from Stephen C Phillips’ post on Making gmediarender start on boot - but with the command line changed for ALSA instead of pulseaudio). You’ll need a guid, which you can generate using your favourite guid generating tool (what? you don’t have a favourite guid generating tool – try http://www.random-guid.com/).
# Provides: gmediarender
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start GMediaRender at boot time
# Description: Start GMediaRender at boot time.
export USER HOME
case "$1" in
echo "Starting GMediaRender"
start-stop-daemon -x /usr/local/bin/gmediarender -S -- -d --gstout-audiosink=alsasink --gstout-audiodevice=sysdefault --uuid insert-your-guid-here -f "name-your-media-renderer" --logfile /dev/null
echo "Stopping GMediaRender"
start-stop-daemon -x /usr/local/bin/gmediarender -K
echo "Usage: /etc/init.d/gmediarender {start|stop}"
exit 1
exit 0
And then install the service with
sudo update-rc.d gmediarenderer defaults
And reboot.

Android remote control

To play audio from my DLNA server (Buffalo LinkStation Live NAS) on the newly running renderer, I had good success with MediaHouse on Android (which has a free and pro version)

See? simple :-)

I hope I’ve managed to capture all the steps I did to get that working. If you try it and find anything wrong, let me know in the comments and I’ll at least try to update these instructions.

Tuesday, 16 July 2013

Non-obvious behaviour in the C# compiler with params array

I recently changed a function I was using inside a test, to take a params string[] parameter instead of a plain string[].

The change of behaviour surprised me at first, although after tracing the exception I could see why it happened.

Here’s an example (inside a test class, using NUnit and FluentAssertions)

private static int HowManyStrings(params string[] y)
return y.Length;

public void TestHowManyStrings()
HowManyStrings("foo", "bar").Should().Be(2);

string myNullString = null;

The last test causes an exception, because it’s OK to pass a string[] as the parameter, and the null (of unknown type) matches the string[] better than making a string[] { null } out of it.

It does feel like passing an untyped null to a params array parameter should produce a warning, either in the compiler or something like ReSharper – but neither flagged it up (C#5, ReSharper 7).

The Wildhearts Fishing For Luckies lenticular CD cover

Apropos of nothing…

My copy of “Fishing For Luckies” by The Wildhearts has a lenticular cover that flicks between two pictures. I decided to make an animated gif that alternates between the two to use as the cover art when I ripped it. Whether anything renders the animation is a different matter, but just so I never have to do it again, I’m recording the image here.


I scanned the inlay at 300dpi and then wrote some code to split the image into odd and even sets of (3-line-high) blocks, repeating each row twice. I then saved out the two images formed from the odd and even sets and used UnFREEz to make the animated gif.

Anyway, it’s a good album and you can buy it with the lenticular cover, or with a normal cover but with bonus disc, or ready-ripped but with some static cover art .

Thursday, 11 July 2013

Checkboxes Beside Labels in ASP.Net MVC4

This had me stumped for a while, so here’s what you need to do:

Inside your form,

@Html.CheckBoxFor(m => m.XX)
@Html.LabelFor(m => m.XX, new {@class="checkbox"})

This is for a boolean XX in the model, marked with the appropriate attributes to get the label text. The important thing is the class attribute for the label, because that applies the style defined in the default css:

label.checkbox { display: inline;}

To make it appear on the same line as the checkbox itself.

Tuesday, 14 May 2013

XPS Observations

All these observations were made printing an XPS document which seems to have a problem with the embedded subsetted font. The printer was a non-XPS printer (the Xerox Phaser 8560) but the problems affected the Microsoft PostScript driver as much as the Xerox driver.

Code to test printing XPS using the native API can be found on Logos Bible Software Code Blog

If your text looks blurry / fuzzy in print, it could be because the print path has converted your text to bitmaps.

The font problem which hadn’t upset .net 3.5 caused .net 4.5 to render each word rasterized as an individual png.

Try printing to the Microsoft Xps Document Writer and looking inside the XPS document (below).

.net 4.5 is more fussy than .net 3.5

Compiling the same code for a different target framework can change the results you’ll get.

The native API (with raw spooling) is fussier still

A problematic XPS document could cause reams of pages with random junk at the top, or event have documents be reordered in the print queue.

The native API (with metafile spooling) behaves unpredictably with bad input

You might get pages of junk, you might get a complete document, you might get nothing at all.

The XPS format is pretty easy to mess with manually, once you’ve generated your document

  • Make a test harness that can print the XPS document, using

LocalPrintServer.GetDefaultPrintQueue().AddJob("PrintJob", file, false);

or the native code referenced above.

  • Extract the files from the XPS package by treating it as a zip (I used 7zip to extract the contents into a folder).

  • Have a look around the extracted Resource folders for images (.png) and embedded obfuscated fonts (.odttf).

  • Document text and references to the resources can be changed by editing the xml format file.

  • Select all the files and subfolders in the top level of the extracted package, and add them to a zip file named like “MyHackedUpDocument.xps” (i.e. use the zip format, but .xps extension).

  • You’ve got a new XPS document to try printing.

The obfuscated fonts can be deobfuscated if you want to see what they were originally, using code like this StackOverflow answer but be aware that they will usually have had any unused glyphs stripped out (subsetted).

XPS Packages can contain multiple documents with different (per-document) print tickets

But the .net API ignores them.

You need to feed the tickets to the print job’s document writer.

  • Pick the tickets out of the fixed documents using its FixedDocumentSequenceReader.

  • Create a writer with System.Printing.PrintQueue.CreateXpsDocumentWriter(queue) and handle WritingPrintTicketRequired to supply the ticket based on CurrentPrintTicketLevel and Sequence (which is 1-based).

  • Use MergeAndValidatePrintTicket with the queue’s DefaultPrintTicket to get a valid ticket with the settings for that document.