Creative Stage Air

I bought a Creative Stage Air Bluetooth speaker. It's quite nice, but has a couple of annoying faults. Here's how to fix them!

Voice prompts are really, really loud

When you switch the speaker or disconnect a Bluetooth device, it says "Pairing mode! Waiting for device to connect!!" at a significantly higher volume I'd like. Creative provider firmware updates which can be installed using USB, so I downloaded this and had a look at the binary file. Running strings over it showed up text droppings from Adobe Soundbooth, which made me suspect that the messages are MP3s.

Run binwalk to search for MP3s (the identifier is "ID3")

   $ binwalk -R '\x49\x44\x33' app.bin

   DECIMAL       HEXADECIMAL     DESCRIPTION
   --------------------------------------------------------------------------------
   196608        0x30000         Raw signature (\x49\x44\x33)
   205312        0x32200         Raw signature (\x49\x44\x33)
   223232        0x36800         Raw signature (\x49\x44\x33)
   241152        0x3AE00         Raw signature (\x49\x44\x33)
   259072        0x3F400         Raw signature (\x49\x44\x33)
   266752        0x41200         Raw signature (\x49\x44\x33)
   275968        0x43600         Raw signature (\x49\x44\x33)
   286720        0x46000         Raw signature (\x49\x44\x33)

I wrote a shell script to extract these, reduce their volume using mp3gain (which can change MP3 volume without altering the file size), and put them back into the firmware image. I assumed that all files were laid out sequentially, and manually found the end of the final MP3 by examining the file in a hex editor - this is the final byte offset in the starts array.

#!/bin/bash

starts=( 196608   205312   223232   241152   259072   266752   275968   286720   300851 )

for i in ${!starts[@ ]}; do
this=${starts[$i]}
next=${starts[$i+1]}
if [[ ! -z $next ]]; then
    size=$(expr $next - $this)
    echo $size
    dd if=app.bin of=$i.mp3 skip=$this count=$size bs=1
fi
done

mp3gain -g -20 *.mp3

unset 'starts[${#starts[@ ]}-1]'

for i in ${!starts[@ ]}; do
  this=${starts[$i]}
  dd if=$i.mp3 of=app.bin seek=$this obs=1 conv=notrunc
done

Predictably, the device doesn't do any checksumming whatsoever, so this worked great!

Blue LED flashes continuously when Bluetooth is not connected

I don't usually have the speaker connected to anything, so it's annoying that the blue LED flashes constantly. This is relatively simple to fix by placing an opaque object in front of it, but a more elegant solution is to reverse engineer the firmware and patch it to not flash at all.

Speaker eventually switches itself off even when connected to power