2014-02-10 · in Tech Notes · 511 words

I've got a couple of SanDisk Sansa Clip+ MP3 players — available refurbished these days for less than £25 — upon which I've installed the Rockbox open-source firmware. These players have good-quality audio output, and in combination with Rockbox can play all the audio formats I generally use.

The Clip+ also makes a reasonably good audio recorder, hampered mostly by the case design and AGC limitations, and I've used mine several times to record music when I didn't have anything better with me. However, recently I recorded an evening's set when my Clip+ was running low on battery — and got home to find the battery completely flat, and a 0-byte-long WAV file on the Clip+'s FAT filesystem.

Hrmph. Well, it was recording for most of the evening; the data must be somewhere...

WAV files start with a RIFF header, which contains the length of the file as one of the fields; tools that do live recording generally need to write a dummy header, and then go back and fill in the length later. Searching the raw filesystem using Tweak found a likely-looking RIFF header with a zero length field:

5A70E800  52 49 46 46 00 00 00 00 57 41 56 45 66 6D 74 20  RIFF....WAVEfmt
5A70E810  10 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  ................
5A70E820  00 00 10 00 64 61 74 61 00 00 00 00 40 FD 52 FD  ....data....@.R.

And this was at the start of a chain of blocks allocated in the FAT which ended without an end-of-file marker (FF FF 0F 7F or similar), suggesting it'd not been closed properly:

0005C1D0  75 60 01 00 76 60 01 00 77 60 01 00 78 60 01 00  u`..v`..w`..x`..
0005C1E0  79 60 01 00 7A 60 01 00 7B 60 01 00 7C 60 01 00  y`..z`..{`..|`..
0005C1F0  7D 60 01 00 7E 60 01 00 7F 60 01 00 80 60 01 00  }`..~`...`...`..
0005C200  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

So my recording was there — it just didn't have a filename attached to it, and the header hadn't been filled in properly.

The dosfsck tool from dosfstools has a -f option, which makes it look for unused cluster chains and attach a filename to them. I made an image of the filesystem with dd, and ran:

$ dosfsck -v -a -f rockbox-int2.img
...
Reclaiming unconnected clusters.
Reclaimed 39842 unused clusters (1305542656 bytes) in 1 chain.
...
$ mcopy -i rockbox-int2.img ::fsck0000.rec rescued.wav

Next I needed to fill in the missing fields in the header, since no tools would open the file without them. Most of the fields could be completed by making another recording with the same settings, and copying the header from the new file over the recovered one:

$ dd if=R_MIC_140117-193045.wav of=rescued.wav bs=48 count=1 conv=notrunc

Finally I needed to correct the length field to match the size of the file — and I'd already written the fix-wav-length script to do that a few years ago:

$ fix-wav-length rescued.wav

Success — four hours of audio!