new post: hacking the wavedrum
[software/elephly-net.git] / posts / 2013-08-11-hacking-the-wavedrum.markdown
1 ---
2 title: Hacking the Wavedrum
3 tags: DIY,electronics,music,hacking
4 ---
5
6 The Wavedrum Oriental is a wonderful electronic instrument. Unlike an
7 electronic drum set or drum machines with touch sensitive pads, this
8 drum synthesizer's sensors don't merely trigger samples. The sensors
9 rather behave like microphones or the pickup in an electric guitar;
10 the signals of the four sensors---one sensor for the drum head, one
11 sensor on the left and another on the right of the metal rim, and a
12 pressure sensor in the centre of the drum---are used to control drum
13 synthesizer algorithms whose output can be mixed with PCM samples. As
14 a result, the instrument feels a lot like a real drum, a feat that
15 cannot easily be achieved with devices that use simple
16 velocity-sensitive sample triggers.
17
18 For all its magic, the Wavedrum also has a number of flaws. Most
19 prominently, all editing is done through five buttons and an endless
20 rotary encoder. What parameters can be selected by the buttons and
21 thus manipulated by the encoder depends entirely on context; one
22 button is used to jump to the next parameter page; simultaneously
23 pressing a pair of buttons switches between the two edit modes (why
24 two?), "global" mode and "live" mode; as one navigates through this
25 confusing environment, a three-character seven-segment display
26 conjures up magic strings that occasionally resemble abbreviations of
27 what appear to be parameter names. Without a copy of the manual lying
28 next to the device, any attempt at deciphering the cryptic
29 three-character hints is doomed to fail.
30
31 Another painful flaw is the lack of connectivity. There is no way to
32 export these precious custom programmes that were edited with so much
33 difficulty. There is no way to back up the programmes, nor can one
34 share programmes with another Wavedrum. When the device dies, all
35 custom patches go down with it. Or so it seemed.
36
37
38 # A look inside the Wavedrum
39
40 Not really knowing what to look for I opened up the Wavedrum in the
41 hopes of finding *something* that would allow me to extend the feature
42 set of the instrument. I first took off the control panel. Only
43 three screws have to be loosened to lift the front panel and look
44 underneath. The PCB, however, does not offer much of interest.
45
46 Much more interesting is the main board which is located right
47 underneath the drum head. Removing the rim and the drum head
48 apparently is a permitted activity which does not void the
49 warranty---the manual includes instructions on how to change the drum
50 head.
51
52 <img class="full stretch" src="/images/posts/2013/wavedrum-opened.jpg" alt="After removing the rim and the drum head" />
53
54 Once the rim and drum head are out of the way, one can already
55 see much of the main board, but access is denied by a transparent
56 plastic disk. In my instrument the plastic disk was only screwed to
57 two posts although there are holes for seven screws. The heads of the
58 two screws are covered with adhesive pads that can easily be removed
59 to undo the screws. (Don't worry, the glue on the pads is strong
60 enough to put them back on when you're done.)
61
62 <warning>
63 **Warning:** if you are following these instructions, at this point, I
64 believe, you might be voiding your warranty. If you're careful and
65 you don't tell anyone, nobody should ever notice. Note that I
66 cannot be made responsible for any damage to your device that may
67 result from following these instructions.
68 </warning>
69
70 With this warning out of the way, let's move on.
71
72 The main board is very tidy making it easy to understand what's going
73 on. The densely packed section on the right appears to be power
74 supply and rim sensor amplification logic. On the left you can see
75 two medium-sized chips, a bulky capacitor and something covered with a
76 black, textured tape. The two chips are RAM (ESMT) and flash memory
77 (cFeon), respectively. The big capacitor buffers the power for the
78 two memory chips and the massive DSP on the back of the board. The
79 back side of the board is rather boring as it really only holds the
80 DSP chip (ADSP-21375 by Analog Devices). The board has a somewhat
81 unusually great number of test pads (most of which are connected to
82 ground, used for automated testing) and quite a few connector pads,
83 possibly allowing a hardware debugger to be connected to debug the
84 DSP's firmware *in situ*.
85
86 <img class="full stretch" src="/images/posts/2013/wavedrum-mainboard.jpg" alt="The mainboard of the Wavedrum Oriental" />
87
88
89 # The treasure trove
90
91 What is underneath that black tape on the front, though? This is
92 where things get really interesting (well, to people like me, at
93 least). As I carefully removed the tape I was pleasently surprised to
94 see a micro SD card reader underneath. The card is locked to the
95 reading interface to make sure it stays in place during operation.
96 Unlock it by shifting the metal brace to the right whereupon it can be
97 lifted.
98
99 ![The taped-over SD card](/images/posts/2013/wavedrum-card-tape.jpg)
100
101 The 2GB micro SD card is a standard card formatted with a FAT32
102 filesystem, making it possible to read it out with a standard card
103 reader. My netbook has a built-in SD card reader only, so I first
104 needed to buy an adapter to connect the micro SD card. This reader is
105 a little weird. It seems that the adapter must be in the reader slot
106 on boot or the micro SD card won't be recognised. (If you're unsure
107 whether the card is recognised by your system check the output of
108 `dmesg`.) Eventually, the card was recognised as `/dev/sdb1`.
109 (`/dev/sdb` is the SD card reader device itself.) As this is my only
110 Wavedrum and I intend to use it for years to come I decided to be
111 especially careful this time and only operate on a *copy* of the card.
112 To create a block level copy of the card I *did not* mount the
113 filesystem and simply executed the following command:
114
115 dd if=/dev/sdb1 of=wavedrum.img
116
117 This instructs `dd` to copy all blocks from the input device file
118 (`if`, i.e. `/dev/sdb1`) to the output file (`of`) of the name
119 `wavedrum.img`. Dependent on the number of disks on your system, the
120 input device file may have a different name. Check the output of
121 `dmesg | tail` as you connect the card reader to see which device node
122 is created for the micro SD card. Note that this blindly copies
123 *everything* on the micro SD card, not just files that are available
124 through the FAT32 filesystem. Hence, the size of the image is quite a
125 bit larger than the sum of all files on the mounted image (502,145,536
126 bytes vs 234,479,878 bytes).
127
128 Before continuing, please put the micro SD card back into the
129 Wavedrum's card reader and lock it to prevent it from being damaged
130 (things can get messy, you know). Going forward, we only need to
131 mount the image to access the data stored on the card. Run the following as
132 root to mount the card image as a read-only filesystem:
133
134 mkdir wavedrum
135 mount -o loop,ro wavedrum.img wavedrum/
136
137 Let's take a look at the files on the card:
138
139 <ul class="tree">
140 <li><b class="NORM">/</b></li>
141 <li>├── [&nbsp;&nbsp;16]&nbsp;&nbsp;<b class="EXEC">CALIB.BOR</b></li>
142 <li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">Factory</b></li>
143 <li>│   ├── [192K]&nbsp;&nbsp;<b class="EXEC">F_INFO.BOR</b></li>
144 <li>│   ├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">F_INST_H.BOR</b></li>
145 <li>│   ├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">F_INST_R.BOR</b></li>
146 <li>│   ├── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">F_PROG.BOR</b></li>
147 <li>│   └── [&nbsp;&nbsp;88]&nbsp;&nbsp;<b class="EXEC">F_USER.BOR</b></li>
148 <li>├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">INST_H.BOR</b></li>
149 <li>├── [&nbsp;57K]&nbsp;&nbsp;<b class="EXEC">INST_R.BOR</b></li>
150 <li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">LOOP</b></li>
151 <li>│   ├── [744K]&nbsp;&nbsp;<b class="EXEC">LOOP0001.BIN</b></li>
152 <li>│   ├── [402K]&nbsp;&nbsp;<b class="EXEC">LOOP0002.BIN</b></li>
153 <li>│   ├── [750K]&nbsp;&nbsp;<b class="EXEC">LOOP0003.BIN</b></li>
154 <li>&#x22ee;</li>
155 <li>│   ├── [173K]&nbsp;&nbsp;<b class="EXEC">LOOP0138.BIN</b></li>
156 <li>│   ├── [173K]&nbsp;&nbsp;<b class="EXEC">LOOP0139.BIN</b></li>
157 <li>│   └── [234K]&nbsp;&nbsp;<b class="EXEC">LOOP0140.BIN</b></li>
158 <li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">PRE_PROG.BOR</b></li>
159 <li>├── [&nbsp;16K]&nbsp;&nbsp;<b class="DIR">SYSTEM</b></li>
160 <li>│   ├── [&nbsp;&nbsp;16]&nbsp;&nbsp;<b class="EXEC">VERSION.INF</b></li>
161 <li>│   ├── [1.0M]&nbsp;&nbsp;<b class="EXEC">WDORM202.BIN</b></li>
162 <li>│   └── [8.0K]&nbsp;&nbsp;<b class="EXEC">WDORS110.BIN</b></li>
163 <li>├── [&nbsp;&nbsp;88]&nbsp;&nbsp;<b class="EXEC">USER.BOR</b></li>
164 <li>├── [157M]&nbsp;&nbsp;<b class="EXEC">WD2_DATA.BOR</b></li>
165 <li>├── [192K]&nbsp;&nbsp;<b class="EXEC">WD2_INFO.BOR</b></li>
166 <li>└── [&nbsp;16K]&nbsp;&nbsp;<b class="EXEC">WD2_PROG.BOR</b></li>
167 </ul>
168
169 The files in the `Factory` directory contain initialisation data.
170 When a factory reset is performed, the customised versions of these
171 files in the root directory are overwritten with the versions
172 contained in the `Factory` directory. All initial programmes that
173 come with the Wavedrum are stored in `Factory/F_PROG.BOR`; once
174 programmes have been edited `PROG.BOR` in the root directory will
175 differ from `Factory/F_PROG.BOR`. (More about the nature of these
176 differences later.) `PRE_PROG.BOR` is the same as
177 `Factory/F_PROG.BOR` and is probably used to make the original factory
178 presets available in addition to custom programmes, starting at
179 position `P.00`, the programme slot after `149`.
180
181 The initial mapping of presets to any of the 12 slots (3 banks with 4
182 slots each) is stored in `Factory/F_USER.BOR`. Initially, `USER.BOR`
183 in the root directory will be identical to this file. The format of
184 this file is rather simple:
185
186 00000000 | 00 00 00 64 00 00 00 67 00 00 00 7b 00 00 00 6c
187 00000010 | 00 00 00 65 00 00 00 68 00 00 00 71 00 00 00 7a
188 00000020 | 00 00 00 84 00 00 00 8c 00 00 00 8b 00 00 00 95
189 00000030 | 00 00 00 00 00 00 00 00 00 00 00 75 00 00 00 26
190 00000040 | 00 00 00 07 00 00 00 14 00 00 00 07 00 00 00 14
191 00000050 | 00 00 00 05 00 00 00 64
192
193 Every 8 digit block (4 byte) is used for one slot. We can see that
194 the first slot in bank A is set to programme 100 (0x64 hex), the
195 second to programme 103 (0x67 hex) and so on. As the Wavedrum only
196 allows for 12 slots to store programme identifiers, only the first 48
197 bytes are used for programmes. The remaining 40 bytes (starting at
198 0x30) are used for global parameters that can be adjusted in "global"
199 editing mode. The global parameters are stored in this order:
200
201 - delay pan
202 - aux input level
203 - loop phrase select
204 - loop play mode (off=38)
205 - head sensor threshold
206 - head sensor sensitivity
207 - rim sensor threshold
208 - rim sensor sensitivity
209 - pressure sensor threshold
210 - pressure maximum
211
212 I don't know yet what purpose `F_INST_H.BOR` and `F_INST_R.BOR`
213 fulfil, but it is clear that the former relates to settings for the
214 drum head while the latter contains similar settings for the rim.
215 Even after editing a few programmes, `INST_H.BOR` and `INST_R.BOR` in
216 the root directory were still identical to their counterparts in the
217 `Factory` directory.
218
219 The `CALIB.BOR` appears to contain calibration information for the
220 head and rim sensors. This is different from the calibration
221 performed by adjusting the four global paramaters for sensor threshold
222 and sensitivity. I have not been able to edit these settings through
223 the Wavedrum so far, so these probably are factory settings.
224
225
226 ## Audio data
227
228 All files in the `LOOP` directory as well as `WD2_DATA.BOR` contain
229 raw audio data. Unfortunately, I haven't quite figured out the format
230 yet, but you can listen to the clearly recognisable loop patterns with
231 `play` (part of the [SoX](http://sox.sourceforge.net) applications):
232
233 find LOOP -name "*.BIN" -print |\
234 xargs -I XXX \
235 play -t raw -r 48k -b 32 -e unsigned-integer -c 2 XXX speed 0.3
236
237 Obviously, this isn't quite correct. I'm interpreting every 32 bits
238 as a sample in unsigned integer format, but assuming a sample rate of
239 48kHz and two channel output results in extremely fast playback which
240 I then artificially slow down again. This really is the same effect
241 as playing back the data at a lower sample rate. Even at the correct
242 speed, the sound is distorted and far from the realistic instrument
243 sound when playing back the loops through the Wavedrum. Clearly, more
244 work is required to figure out the correct format. Once this is
245 understood we could use custom loops with the Wavedrum.
246
247 The raw audio data in `WD2_DATA.BOR` suffers from the same problems.
248 Although the data can be interpreted as raw audio, the sound is
249 distorted and playback is unnaturally fast.
250
251
252 ## System files
253
254 I don't know what `SYSTEM/WDORS110.BIN` is used for. The only useful
255 string contained in the file is "BOOTABLE". Your guess is as good as
256 mine as to what it does.
257
258 `SYSTEM/VERSION.INF` is only 16 bytes short and pretty boring as it
259 contains just what the name implies: version numbers.
260
261 02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00
262
263 This string of numbers is interpreted as follows: firmware version
264 2.02, sub-version 1.10, data version 2.02 (followed by two empty
265 bytes); 57 44 4f 52 (hex for "WDOR") stands for "Wavedrum Oriental"
266 (followed by four empty bytes). You can have the Wavedrum display all
267 its version numbers by pressing the button labelled "Global" when
268 powering on the device. Note that the file name `WDORS110.BIN`
269 references the version number 1.10, while `WDORM202.BIN` references
270 the firmware version number 2.02.
271
272 `SYSTEM/WDORM202.BIN` contains the firmware of the Wavedrum Oriental.
273 There are many interesting strings and binary patterns in the file,
274 but I'm still a long way from *understanding* how it works. To view
275 the strings with the `strings` command, you have to specify the
276 encoding as 32-bit little endian:
277
278 strings --encoding L SYSTEM/WDORM202.BIN
279
280 Some of the strings embedded in the firmware are file names, some of
281 which are not available on the micro SD card. This includes the
282 following files: SYS00000.BIN, SYS00100.BIN, SYSTEM/WDORS100.BIN,
283 SYSTEM/WDX_M100.BIN, SYSTEM/WDX_S100.BIN, and SUBXXXXX.BIN (a
284 pattern?).
285
286
287 # The programme format
288
289 Looking at the hexdump of the file `PROG.BOR` which holds all custom
290 presets, I couldn't find any obvious patterns in the file, so I
291 resorted to editing a single programme, setting particular consecutive
292 parameters to easily recognisable sequences of values (such as 100,
293 99, 98, and 97 for hd1, hd2, hd3, and hd4) and locating the changes in
294 the hexdump.
295
296 <img class="full stretch" src="/images/posts/2013/wavedrum-diff.png" alt="Analysing the programme format by changing values and looking at the differences" />
297
298 This procedure has allowed me to figure out in what order the
299 parameters are stored in the file. Each programme is exactly 54
300 16-bit words long; each parameter takes up exactly 16 bits. Negative
301 values are stored in [two's
302 complement](https://en.wikipedia.org/wiki/Two%27s_complement) format
303 (e.g. negative six is stored as 0xFFFA). The file is exactly 16200
304 bytes long which is just enough to hold 150 custom programmes, each
305 taking up 108 bytes.
306
307 The parameters are stored in this order:
308
309 identifier | mode | target | name
310 -----------+--------+---------------------+------------------------------
311 07.1 | Edit 1 | head algorithm | Pressure curve
312 type | Edit 2 | -- | Pre EQ
313 -----------+--------+---------------------+------------------------------
314 01.1 | Edit 1 | head algorithm | Tune
315 02.1 | Edit 1 | head algorithm | Decay
316 03.1 | Edit 1 | head algorithm | Level
317 04.1 | Edit 1 | head algorithm | Pan
318 05.1 | Edit 1 | head algorithm | Algorithm select
319 hd.1 | Edit 2 | head algorithm | Algorithm parameter 1
320 hd.2 | Edit 2 | head algorithm | Algorithm parameter 2
321 hd.3 | Edit 2 | head algorithm | Algorithm parameter 3
322 hd.4 | Edit 2 | head algorithm | Algorithm parameter 4
323 hd.5 | Edit 2 | head algorithm | Algorithm parameter 5
324 hd.6 | Edit 2 | head algorithm | Algorithm parameter 6
325 hd.7 | Edit 2 | head algorithm | Algorithm parameter 7
326 hd.8 | Edit 2 | head algorithm | Algorithm parameter 8
327 -----------+--------+---------------------+------------------------------
328 01.3 | Edit 1 | rim algorithm | Tune
329 02.3 | Edit 1 | rim algorithm | Decay
330 03.3 | Edit 1 | rim algorithm | Level
331 04.3 | Edit 1 | rim algorithm | Pan
332 05.3 | Edit 1 | rim algorithm | Algorithm select
333 rm.1 | Edit 2 | rim algorithm | Algorithm parameter 1
334 rm.2 | Edit 2 | rim algorithm | Algorithm parameter 2
335 rm.3 | Edit 2 | rim algorithm | Algorithm parameter 3
336 rm.4 | Edit 2 | rim algorithm | Algorithm parameter 4
337 rm.5 | Edit 2 | rim algorithm | Algorithm parameter 5
338 rm.6 | Edit 2 | rim algorithm | Algorithm parameter 6
339 rm.7 | Edit 2 | rim algorithm | Algorithm parameter 7
340 rm.8 | Edit 2 | rim algorithm | Algorithm parameter 8
341 -----------+--------+---------------------+------------------------------
342 01.2 | Edit 1 | head PCM instrument | Tune
343 02.2 | Edit 1 | head PCM instrument | Decay
344 03.2 | Edit 1 | head PCM instrument | Level
345 04.2 | Edit 1 | head PCM instrument | Pan
346 05.2 | Edit 1 | head PCM instrument | PCM instrument select
347 06.2 | Edit 1 | head PCM instrument | Velocity curve
348 07.2 | Edit 1 | head PCM instrument | Pressure curve
349 08.2 | Edit 1 | head PCM instrument | Pressure tune
350 09.2 | Edit 1 | head PCM instrument | Pressure decay
351 -----------+--------+---------------------+------------------------------
352 01.4 | Edit 1 | rim PCM instrument | Tune
353 02.4 | Edit 1 | rim PCM instrument | Decay
354 03.4 | Edit 1 | rim PCM instrument | Level
355 04.4 | Edit 1 | rim PCM instrument | Pan
356 05.4 | Edit 1 | rim PCM instrument | PCM instrument select
357 06.4 | Edit 1 | rim PCM instrument | Velocity curve
358 07.4 | Edit 1 | rim PCM instrument | Pressure curve
359 08.4 | Edit 1 | rim PCM instrument | Pressure tune
360 09.4 | Edit 1 | rim PCM instrument | Pressure decay
361 -----------+--------+---------------------+------------------------------
362 10.1 | Edit 1 | -- | Reverb type
363 10.2 | Edit 1 | -- | Reverb effect level
364 10.3 | Edit 1 | -- | Reverb decay time
365 10.4 | Edit 1 | -- | Reverb frequency damping
366 11.3 | Edit 1 | -- | Delay feedback
367 11.2 | Edit 1 | -- | Delay effect level
368 11.1 | Edit 1 | -- | Delay time
369 11.4 | Edit 1 | -- | Delay frequency damping
370
371
372 # Thanks
373
374 The following tools have proven indispensable in the analysis:
375
376 - [`calc`](http://www.isthe.com/chongo/tech/comp/calc/), a calculator
377 for the command line supporting hexadecimal representations of
378 numbers (both input and output using the `base` and `base2`
379 functions)
380
381 - [`vbindiff`](http://www.cjmweb.net/vbindiff/), a tool to visualise
382 differences between two binary files with a split-screen hexadecimal
383 display
384
385 - [`ghex`](https://wiki.gnome.org/Ghex), a simple hexadecimal editor
386 supporting pattern search and highlighting
387
388
389 # Call for help
390
391 If you own an earlier model of the Wavedrum or the latest Wavedrum
392 Global Edition, I would be *very* happy if you could send me a
393 block-level copy of the SD card (see above for instructions). This
394 would allow me to understand the firmware better and maybe even make
395 it possible to upgrade an older Wavedrum to the latest version (taking
396 into account possible hardware differences, such as differing memory
397 size).
398
399 Please send a link to the micro SD card image to
400 <span class="obfuscated">sflbep,xbwfesvnAfmfqimz/ofu</span>.