summaryrefslogtreecommitdiff
path: root/posts/2013-08-11-hacking-the-wavedrum.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'posts/2013-08-11-hacking-the-wavedrum.markdown')
-rw-r--r--posts/2013-08-11-hacking-the-wavedrum.markdown400
1 files changed, 400 insertions, 0 deletions
diff --git a/posts/2013-08-11-hacking-the-wavedrum.markdown b/posts/2013-08-11-hacking-the-wavedrum.markdown
new file mode 100644
index 0000000..aafd1a6
--- /dev/null
+++ b/posts/2013-08-11-hacking-the-wavedrum.markdown
@@ -0,0 +1,400 @@
+---
+title: Hacking the Wavedrum
+tags: DIY,electronics,music,hacking
+---
+
+The Wavedrum Oriental is a wonderful electronic instrument. Unlike an
+electronic drum set or drum machines with touch sensitive pads, this
+drum synthesizer's sensors don't merely trigger samples. The sensors
+rather behave like microphones or the pickup in an electric guitar;
+the signals of the four sensors---one sensor for the drum head, one
+sensor on the left and another on the right of the metal rim, and a
+pressure sensor in the centre of the drum---are used to control drum
+synthesizer algorithms whose output can be mixed with PCM samples. As
+a result, the instrument feels a lot like a real drum, a feat that
+cannot easily be achieved with devices that use simple
+velocity-sensitive sample triggers.
+
+For all its magic, the Wavedrum also has a number of flaws. Most
+prominently, all editing is done through five buttons and an endless
+rotary encoder. What parameters can be selected by the buttons and
+thus manipulated by the encoder depends entirely on context; one
+button is used to jump to the next parameter page; simultaneously
+pressing a pair of buttons switches between the two edit modes (why
+two?), "global" mode and "live" mode; as one navigates through this
+confusing environment, a three-character seven-segment display
+conjures up magic strings that occasionally resemble abbreviations of
+what appear to be parameter names. Without a copy of the manual lying
+next to the device, any attempt at deciphering the cryptic
+three-character hints is doomed to fail.
+
+Another painful flaw is the lack of connectivity. There is no way to
+export these precious custom programmes that were edited with so much
+difficulty. There is no way to back up the programmes, nor can one
+share programmes with another Wavedrum. When the device dies, all
+custom patches go down with it. Or so it seemed.
+
+
+# A look inside the Wavedrum
+
+Not really knowing what to look for I opened up the Wavedrum in the
+hopes of finding *something* that would allow me to extend the feature
+set of the instrument. I first took off the control panel. Only
+three screws have to be loosened to lift the front panel and look
+underneath. The PCB, however, does not offer much of interest.
+
+Much more interesting is the main board which is located right
+underneath the drum head. Removing the rim and the drum head
+apparently is a permitted activity which does not void the
+warranty---the manual includes instructions on how to change the drum
+head.
+
+<img class="full stretch" src="/images/posts/2013/wavedrum-opened.jpg" alt="After removing the rim and the drum head" />
+
+Once the rim and drum head are out of the way, one can already
+see much of the main board, but access is denied by a transparent
+plastic disk. In my instrument the plastic disk was only screwed to
+two posts although there are holes for seven screws. The heads of the
+two screws are covered with adhesive pads that can easily be removed
+to undo the screws. (Don't worry, the glue on the pads is strong
+enough to put them back on when you're done.)
+
+<warning>
+**Warning:** if you are following these instructions, at this point, I
+ believe, you might be voiding your warranty. If you're careful and
+ you don't tell anyone, nobody should ever notice. Note that I
+ cannot be made responsible for any damage to your device that may
+ result from following these instructions.
+</warning>
+
+With this warning out of the way, let's move on.
+
+The main board is very tidy making it easy to understand what's going
+on. The densely packed section on the right appears to be power
+supply and rim sensor amplification logic. On the left you can see
+two medium-sized chips, a bulky capacitor and something covered with a
+black, textured tape. The two chips are RAM (ESMT) and flash memory
+(cFeon), respectively. The big capacitor buffers the power for the
+two memory chips and the massive DSP on the back of the board. The
+back side of the board is rather boring as it really only holds the
+DSP chip (ADSP-21375 by Analog Devices). The board has a somewhat
+unusually great number of test pads (most of which are connected to
+ground, used for automated testing) and quite a few connector pads,
+possibly allowing a hardware debugger to be connected to debug the
+DSP's firmware *in situ*.
+
+<img class="full stretch" src="/images/posts/2013/wavedrum-mainboard.jpg" alt="The mainboard of the Wavedrum Oriental" />
+
+
+# The treasure trove
+
+What is underneath that black tape on the front, though? This is
+where things get really interesting (well, to people like me, at
+least). As I carefully removed the tape I was pleasently surprised to
+see a micro SD card reader underneath. The card is locked to the
+reading interface to make sure it stays in place during operation.
+Unlock it by shifting the metal brace to the right whereupon it can be
+lifted.
+
+![The taped-over SD card](/images/posts/2013/wavedrum-card-tape.jpg)
+
+The 2GB micro SD card is a standard card formatted with a FAT32
+filesystem, making it possible to read it out with a standard card
+reader. My netbook has a built-in SD card reader only, so I first
+needed to buy an adapter to connect the micro SD card. This reader is
+a little weird. It seems that the adapter must be in the reader slot
+on boot or the micro SD card won't be recognised. (If you're unsure
+whether the card is recognised by your system check the output of
+`dmesg`.) Eventually, the card was recognised as `/dev/sdb1`.
+(`/dev/sdb` is the SD card reader device itself.) As this is my only
+Wavedrum and I intend to use it for years to come I decided to be
+especially careful this time and only operate on a *copy* of the card.
+To create a block level copy of the card I *did not* mount the
+filesystem and simply executed the following command:
+
+ dd if=/dev/sdb1 of=wavedrum.img
+
+This instructs `dd` to copy all blocks from the input device file
+(`if`, i.e. `/dev/sdb1`) to the output file (`of`) of the name
+`wavedrum.img`. Dependent on the number of disks on your system, the
+input device file may have a different name. Check the output of
+`dmesg | tail` as you connect the card reader to see which device node
+is created for the micro SD card. Note that this blindly copies
+*everything* on the micro SD card, not just files that are available
+through the FAT32 filesystem. Hence, the size of the image is quite a
+bit larger than the sum of all files on the mounted image (502,145,536
+bytes vs 234,479,878 bytes).
+
+Before continuing, please put the micro SD card back into the
+Wavedrum's card reader and lock it to prevent it from being damaged
+(things can get messy, you know). Going forward, we only need to
+mount the image to access the data stored on the card. Run the following as
+root to mount the card image as a read-only filesystem:
+
+ mkdir wavedrum
+ mount -o loop,ro wavedrum.img wavedrum/
+
+Let's take a look at the files on the card:
+
+<ul class="tree">
+<li><b class="NORM">/</b></li>
+<li>├── [&nbsp;&nbsp;16]&nbsp;&nbsp;<b class="EXEC">CALIB.BOR</b></li>
+<li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">Factory</b></li>
+<li>│   ├── [192K]&nbsp;&nbsp;<b class="EXEC">F_INFO.BOR</b></li>
+<li>│   ├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">F_INST_H.BOR</b></li>
+<li>│   ├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">F_INST_R.BOR</b></li>
+<li>│   ├── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">F_PROG.BOR</b></li>
+<li>│   └── [&nbsp;&nbsp;88]&nbsp;&nbsp;<b class="EXEC">F_USER.BOR</b></li>
+<li>├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">INST_H.BOR</b></li>
+<li>├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">INST_R.BOR</b></li>
+<li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">LOOP</b></li>
+<li>│   ├── [744K]&nbsp;&nbsp;<b class="EXEC">LOOP0001.BIN</b></li>
+<li>│   ├── [402K]&nbsp;&nbsp;<b class="EXEC">LOOP0002.BIN</b></li>
+<li>│   ├── [750K]&nbsp;&nbsp;<b class="EXEC">LOOP0003.BIN</b></li>
+<li>&#x22ee;</li>
+<li>│   ├── [173K]&nbsp;&nbsp;<b class="EXEC">LOOP0138.BIN</b></li>
+<li>│   ├── [173K]&nbsp;&nbsp;<b class="EXEC">LOOP0139.BIN</b></li>
+<li>│   └── [234K]&nbsp;&nbsp;<b class="EXEC">LOOP0140.BIN</b></li>
+<li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">PRE_PROG.BOR</b></li>
+<li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">SYSTEM</b></li>
+<li>│   ├── [&nbsp;&nbsp;16]&nbsp;&nbsp;<b class="EXEC">VERSION.INF</b></li>
+<li>│   ├── [1.0M]&nbsp;&nbsp;<b class="EXEC">WDORM202.BIN</b></li>
+<li>│   └── [8.0K]&nbsp;&nbsp;<b class="EXEC">WDORS110.BIN</b></li>
+<li>├── [&nbsp;&nbsp;88]&nbsp;&nbsp;<b class="EXEC">USER.BOR</b></li>
+<li>├── [157M]&nbsp;&nbsp;<b class="EXEC">WD2_DATA.BOR</b></li>
+<li>├── [192K]&nbsp;&nbsp;<b class="EXEC">WD2_INFO.BOR</b></li>
+<li>└── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">WD2_PROG.BOR</b></li>
+</ul>
+
+The files in the `Factory` directory contain initialisation data.
+When a factory reset is performed, the customised versions of these
+files in the root directory are overwritten with the versions
+contained in the `Factory` directory. All initial programmes that
+come with the Wavedrum are stored in `Factory/F_PROG.BOR`; once
+programmes have been edited `PROG.BOR` in the root directory will
+differ from `Factory/F_PROG.BOR`. (More about the nature of these
+differences later.) `PRE_PROG.BOR` is the same as
+`Factory/F_PROG.BOR` and is probably used to make the original factory
+presets available in addition to custom programmes, starting at
+position `P.00`, the programme slot after `149`.
+
+The initial mapping of presets to any of the 12 slots (3 banks with 4
+slots each) is stored in `Factory/F_USER.BOR`. Initially, `USER.BOR`
+in the root directory will be identical to this file. The format of
+this file is rather simple:
+
+ 00000000 | 00 00 00 64 00 00 00 67 00 00 00 7b 00 00 00 6c
+ 00000010 | 00 00 00 65 00 00 00 68 00 00 00 71 00 00 00 7a
+ 00000020 | 00 00 00 84 00 00 00 8c 00 00 00 8b 00 00 00 95
+ 00000030 | 00 00 00 00 00 00 00 00 00 00 00 75 00 00 00 26
+ 00000040 | 00 00 00 07 00 00 00 14 00 00 00 07 00 00 00 14
+ 00000050 | 00 00 00 05 00 00 00 64
+
+Every 8 digit block (4 byte) is used for one slot. We can see that
+the first slot in bank A is set to programme 100 (0x64 hex), the
+second to programme 103 (0x67 hex) and so on. As the Wavedrum only
+allows for 12 slots to store programme identifiers, only the first 48
+bytes are used for programmes. The remaining 40 bytes (starting at
+0x30) are used for global parameters that can be adjusted in "global"
+editing mode. The global parameters are stored in this order:
+
+ - delay pan
+ - aux input level
+ - loop phrase select
+ - loop play mode (off=38)
+ - head sensor threshold
+ - head sensor sensitivity
+ - rim sensor threshold
+ - rim sensor sensitivity
+ - pressure sensor threshold
+ - pressure maximum
+
+I don't know yet what purpose `F_INST_H.BOR` and `F_INST_R.BOR`
+fulfil, but it is clear that the former relates to settings for the
+drum head while the latter contains similar settings for the rim.
+Even after editing a few programmes, `INST_H.BOR` and `INST_R.BOR` in
+the root directory were still identical to their counterparts in the
+`Factory` directory.
+
+The `CALIB.BOR` appears to contain calibration information for the
+head and rim sensors. This is different from the calibration
+performed by adjusting the four global paramaters for sensor threshold
+and sensitivity. I have not been able to edit these settings through
+the Wavedrum so far, so these probably are factory settings.
+
+
+## Audio data
+
+All files in the `LOOP` directory as well as `WD2_DATA.BOR` contain
+raw audio data. Unfortunately, I haven't quite figured out the format
+yet, but you can listen to the clearly recognisable loop patterns with
+`play` (part of the [SoX](http://sox.sourceforge.net) applications):
+
+ find LOOP -name "*.BIN" -print |\
+ xargs -I XXX \
+ play -t raw -r 48k -b 32 -e unsigned-integer -c 2 XXX speed 0.3
+
+Obviously, this isn't quite correct. I'm interpreting every 32 bits
+as a sample in unsigned integer format, but assuming a sample rate of
+48kHz and two channel output results in extremely fast playback which
+I then artificially slow down again. This really is the same effect
+as playing back the data at a lower sample rate. Even at the correct
+speed, the sound is distorted and far from the realistic instrument
+sound when playing back the loops through the Wavedrum. Clearly, more
+work is required to figure out the correct format. Once this is
+understood we could use custom loops with the Wavedrum.
+
+The raw audio data in `WD2_DATA.BOR` suffers from the same problems.
+Although the data can be interpreted as raw audio, the sound is
+distorted and playback is unnaturally fast.
+
+
+## System files
+
+I don't know what `SYSTEM/WDORS110.BIN` is used for. The only useful
+string contained in the file is "BOOTABLE". Your guess is as good as
+mine as to what it does.
+
+`SYSTEM/VERSION.INF` is only 16 bytes short and pretty boring as it
+contains just what the name implies: version numbers.
+
+ 02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00
+
+This string of numbers is interpreted as follows: firmware version
+2.02, sub-version 1.10, data version 2.02 (followed by two empty
+bytes); 57 44 4f 52 (hex for "WDOR") stands for "Wavedrum Oriental"
+(followed by four empty bytes). You can have the Wavedrum display all
+its version numbers by pressing the button labelled "Global" when
+powering on the device. Note that the file name `WDORS110.BIN`
+references the version number 1.10, while `WDORM202.BIN` references
+the firmware version number 2.02.
+
+`SYSTEM/WDORM202.BIN` contains the firmware of the Wavedrum Oriental.
+There are many interesting strings and binary patterns in the file,
+but I'm still a long way from *understanding* how it works. To view
+the strings with the `strings` command, you have to specify the
+encoding as 32-bit little endian:
+
+ strings --encoding L SYSTEM/WDORM202.BIN
+
+Some of the strings embedded in the firmware are file names, some of
+which are not available on the micro SD card. This includes the
+following files: SYS00000.BIN, SYS00100.BIN, SYSTEM/WDORS100.BIN,
+SYSTEM/WDX_M100.BIN, SYSTEM/WDX_S100.BIN, and SUBXXXXX.BIN (a
+pattern?).
+
+
+# The programme format
+
+Looking at the hexdump of the file `PROG.BOR` which holds all custom
+presets, I couldn't find any obvious patterns in the file, so I
+resorted to editing a single programme, setting particular consecutive
+parameters to easily recognisable sequences of values (such as 100,
+99, 98, and 97 for hd1, hd2, hd3, and hd4) and locating the changes in
+the hexdump.
+
+<img class="full stretch" src="/images/posts/2013/wavedrum-diff.png" alt="Analysing the programme format by changing values and looking at the differences" />
+
+This procedure has allowed me to figure out in what order the
+parameters are stored in the file. Each programme is exactly 54
+16-bit words long; each parameter takes up exactly 16 bits. Negative
+values are stored in [two's
+complement](https://en.wikipedia.org/wiki/Two%27s_complement) format
+(e.g. negative six is stored as 0xFFFA). The file is exactly 16200
+bytes long which is just enough to hold 150 custom programmes, each
+taking up 108 bytes.
+
+The parameters are stored in this order:
+
+ identifier | mode | target | name
+ -----------+--------+---------------------+------------------------------
+ 07.1 | Edit 1 | head algorithm | Pressure curve
+ type | Edit 2 | -- | Pre EQ
+ -----------+--------+---------------------+------------------------------
+ 01.1 | Edit 1 | head algorithm | Tune
+ 02.1 | Edit 1 | head algorithm | Decay
+ 03.1 | Edit 1 | head algorithm | Level
+ 04.1 | Edit 1 | head algorithm | Pan
+ 05.1 | Edit 1 | head algorithm | Algorithm select
+ hd.1 | Edit 2 | head algorithm | Algorithm parameter 1
+ hd.2 | Edit 2 | head algorithm | Algorithm parameter 2
+ hd.3 | Edit 2 | head algorithm | Algorithm parameter 3
+ hd.4 | Edit 2 | head algorithm | Algorithm parameter 4
+ hd.5 | Edit 2 | head algorithm | Algorithm parameter 5
+ hd.6 | Edit 2 | head algorithm | Algorithm parameter 6
+ hd.7 | Edit 2 | head algorithm | Algorithm parameter 7
+ hd.8 | Edit 2 | head algorithm | Algorithm parameter 8
+ -----------+--------+---------------------+------------------------------
+ 01.3 | Edit 1 | rim algorithm | Tune
+ 02.3 | Edit 1 | rim algorithm | Decay
+ 03.3 | Edit 1 | rim algorithm | Level
+ 04.3 | Edit 1 | rim algorithm | Pan
+ 05.3 | Edit 1 | rim algorithm | Algorithm select
+ rm.1 | Edit 2 | rim algorithm | Algorithm parameter 1
+ rm.2 | Edit 2 | rim algorithm | Algorithm parameter 2
+ rm.3 | Edit 2 | rim algorithm | Algorithm parameter 3
+ rm.4 | Edit 2 | rim algorithm | Algorithm parameter 4
+ rm.5 | Edit 2 | rim algorithm | Algorithm parameter 5
+ rm.6 | Edit 2 | rim algorithm | Algorithm parameter 6
+ rm.7 | Edit 2 | rim algorithm | Algorithm parameter 7
+ rm.8 | Edit 2 | rim algorithm | Algorithm parameter 8
+ -----------+--------+---------------------+------------------------------
+ 01.2 | Edit 1 | head PCM instrument | Tune
+ 02.2 | Edit 1 | head PCM instrument | Decay
+ 03.2 | Edit 1 | head PCM instrument | Level
+ 04.2 | Edit 1 | head PCM instrument | Pan
+ 05.2 | Edit 1 | head PCM instrument | PCM instrument select
+ 06.2 | Edit 1 | head PCM instrument | Velocity curve
+ 07.2 | Edit 1 | head PCM instrument | Pressure curve
+ 08.2 | Edit 1 | head PCM instrument | Pressure tune
+ 09.2 | Edit 1 | head PCM instrument | Pressure decay
+ -----------+--------+---------------------+------------------------------
+ 01.4 | Edit 1 | rim PCM instrument | Tune
+ 02.4 | Edit 1 | rim PCM instrument | Decay
+ 03.4 | Edit 1 | rim PCM instrument | Level
+ 04.4 | Edit 1 | rim PCM instrument | Pan
+ 05.4 | Edit 1 | rim PCM instrument | PCM instrument select
+ 06.4 | Edit 1 | rim PCM instrument | Velocity curve
+ 07.4 | Edit 1 | rim PCM instrument | Pressure curve
+ 08.4 | Edit 1 | rim PCM instrument | Pressure tune
+ 09.4 | Edit 1 | rim PCM instrument | Pressure decay
+ -----------+--------+---------------------+------------------------------
+ 10.1 | Edit 1 | -- | Reverb type
+ 10.2 | Edit 1 | -- | Reverb effect level
+ 10.3 | Edit 1 | -- | Reverb decay time
+ 10.4 | Edit 1 | -- | Reverb frequency damping
+ 11.3 | Edit 1 | -- | Delay feedback
+ 11.2 | Edit 1 | -- | Delay effect level
+ 11.1 | Edit 1 | -- | Delay time
+ 11.4 | Edit 1 | -- | Delay frequency damping
+
+
+# Thanks
+
+The following tools have proven indispensable in the analysis:
+
+- [`calc`](http://www.isthe.com/chongo/tech/comp/calc/), a calculator
+ for the command line supporting hexadecimal representations of
+ numbers (both input and output using the `base` and `base2`
+ functions)
+
+- [`vbindiff`](http://www.cjmweb.net/vbindiff/), a tool to visualise
+ differences between two binary files with a split-screen hexadecimal
+ display
+
+- [`ghex`](https://wiki.gnome.org/Ghex), a simple hexadecimal editor
+ supporting pattern search and highlighting
+
+
+# Call for help
+
+If you own an earlier model of the Wavedrum or the latest Wavedrum
+Global Edition, I would be *very* happy if you could send me a
+block-level copy of the SD card (see above for instructions). This
+would allow me to understand the firmware better and maybe even make
+it possible to upgrade an older Wavedrum to the latest version (taking
+into account possible hardware differences, such as differing memory
+size).
+
+Please send a link to the micro SD card image to
+<span class="obfuscated">sflbep,xbwfesvnAfmfqimz/ofu</span>.