wavedrum: update section on loops
[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 44.1k -b 16 -e signed-integer -c 1 XXX
236
237 Obviously, this isn't quite correct. I'm interpreting every 16 bits
238 as a sample in signed integer format, but the sound is distorted and
239 far from the realistic instrument sound when playing back the loops
240 through the Wavedrum.
241
242 All loops start with this 44 byte long header:
243
244 04 dc 10 d3 __ __ __ 95 01 d4 00 d0 30 f8 22 b5
245 46 95 56 95 57 95 57 95 d6 2e 56 95 56 e2 57 95
246 54 95 46 95 32 f4 22 f4 __ __ __ 95
247
248 Clearly, more work is required to figure out the complete format of
249 these loop files. Once this is understood we could use custom loops
250 with the Wavedrum.
251
252 The raw audio data in `WD2_DATA.BOR` suffers from the same problems.
253 Although the data can be interpreted as raw audio, the sound is
254 distorted and playback is unnaturally fast.
255
256
257 ## System files
258
259 I don't know what `SYSTEM/WDORS110.BIN` is used for. The only useful
260 string contained in the file is "BOOTABLE". Your guess is as good as
261 mine as to what it does.
262
263 `SYSTEM/VERSION.INF` is only 16 bytes short and pretty boring as it
264 contains just what the name implies: version numbers.
265
266 02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00
267
268 This string of numbers is interpreted as follows: firmware version
269 2.02, sub-version 1.10, data version 2.02 (followed by two empty
270 bytes); 57 44 4f 52 (hex for "WDOR") stands for "Wavedrum Oriental"
271 (followed by four empty bytes). You can have the Wavedrum display all
272 its version numbers by pressing the button labelled "Global" when
273 powering on the device. Note that the file name `WDORS110.BIN`
274 references the version number 1.10, while `WDORM202.BIN` references
275 the firmware version number 2.02.
276
277 `SYSTEM/WDORM202.BIN` contains the firmware of the Wavedrum Oriental.
278 There are many interesting strings and binary patterns in the file,
279 but I'm still a long way from *understanding* how it works. To view
280 the strings with the `strings` command, you have to specify the
281 encoding as 32-bit little endian:
282
283 strings --encoding L SYSTEM/WDORM202.BIN
284
285 Some of the strings embedded in the firmware are file names, some of
286 which are not available on the micro SD card. This includes the
287 following files: SYS00000.BIN, SYS00100.BIN, SYSTEM/WDORS100.BIN,
288 SYSTEM/WDX_M100.BIN, SYSTEM/WDX_S100.BIN, and SUBXXXXX.BIN (a
289 pattern?).
290
291
292 # The programme format
293
294 Looking at the hexdump of the file `PROG.BOR` which holds all custom
295 presets, I couldn't find any obvious patterns in the file, so I
296 resorted to editing a single programme, setting particular consecutive
297 parameters to easily recognisable sequences of values (such as 100,
298 99, 98, and 97 for hd1, hd2, hd3, and hd4) and locating the changes in
299 the hexdump.
300
301 <img class="full stretch" src="/images/posts/2013/wavedrum-diff.png" alt="Analysing the programme format by changing values and looking at the differences" />
302
303 This procedure has allowed me to figure out in what order the
304 parameters are stored in the file. Each programme is exactly 54
305 16-bit words long; each parameter takes up exactly 16 bits. Negative
306 values are stored in [two's
307 complement](https://en.wikipedia.org/wiki/Two%27s_complement) format
308 (e.g. negative six is stored as 0xFFFA). The file is exactly 16200
309 bytes long which is just enough to hold 150 custom programmes, each
310 taking up 108 bytes.
311
312 The parameters are stored in this order:
313
314 identifier | mode | target | name
315 -----------+--------+---------------------+------------------------------
316 07.1 | Edit 1 | head algorithm | Pressure curve
317 type | Edit 2 | -- | Pre EQ
318 -----------+--------+---------------------+------------------------------
319 01.1 | Edit 1 | head algorithm | Tune
320 02.1 | Edit 1 | head algorithm | Decay
321 03.1 | Edit 1 | head algorithm | Level
322 04.1 | Edit 1 | head algorithm | Pan
323 05.1 | Edit 1 | head algorithm | Algorithm select
324 hd.1 | Edit 2 | head algorithm | Algorithm parameter 1
325 hd.2 | Edit 2 | head algorithm | Algorithm parameter 2
326 hd.3 | Edit 2 | head algorithm | Algorithm parameter 3
327 hd.4 | Edit 2 | head algorithm | Algorithm parameter 4
328 hd.5 | Edit 2 | head algorithm | Algorithm parameter 5
329 hd.6 | Edit 2 | head algorithm | Algorithm parameter 6
330 hd.7 | Edit 2 | head algorithm | Algorithm parameter 7
331 hd.8 | Edit 2 | head algorithm | Algorithm parameter 8
332 -----------+--------+---------------------+------------------------------
333 01.3 | Edit 1 | rim algorithm | Tune
334 02.3 | Edit 1 | rim algorithm | Decay
335 03.3 | Edit 1 | rim algorithm | Level
336 04.3 | Edit 1 | rim algorithm | Pan
337 05.3 | Edit 1 | rim algorithm | Algorithm select
338 rm.1 | Edit 2 | rim algorithm | Algorithm parameter 1
339 rm.2 | Edit 2 | rim algorithm | Algorithm parameter 2
340 rm.3 | Edit 2 | rim algorithm | Algorithm parameter 3
341 rm.4 | Edit 2 | rim algorithm | Algorithm parameter 4
342 rm.5 | Edit 2 | rim algorithm | Algorithm parameter 5
343 rm.6 | Edit 2 | rim algorithm | Algorithm parameter 6
344 rm.7 | Edit 2 | rim algorithm | Algorithm parameter 7
345 rm.8 | Edit 2 | rim algorithm | Algorithm parameter 8
346 -----------+--------+---------------------+------------------------------
347 01.2 | Edit 1 | head PCM instrument | Tune
348 02.2 | Edit 1 | head PCM instrument | Decay
349 03.2 | Edit 1 | head PCM instrument | Level
350 04.2 | Edit 1 | head PCM instrument | Pan
351 05.2 | Edit 1 | head PCM instrument | PCM instrument select
352 06.2 | Edit 1 | head PCM instrument | Velocity curve
353 07.2 | Edit 1 | head PCM instrument | Pressure curve
354 08.2 | Edit 1 | head PCM instrument | Pressure tune
355 09.2 | Edit 1 | head PCM instrument | Pressure decay
356 -----------+--------+---------------------+------------------------------
357 01.4 | Edit 1 | rim PCM instrument | Tune
358 02.4 | Edit 1 | rim PCM instrument | Decay
359 03.4 | Edit 1 | rim PCM instrument | Level
360 04.4 | Edit 1 | rim PCM instrument | Pan
361 05.4 | Edit 1 | rim PCM instrument | PCM instrument select
362 06.4 | Edit 1 | rim PCM instrument | Velocity curve
363 07.4 | Edit 1 | rim PCM instrument | Pressure curve
364 08.4 | Edit 1 | rim PCM instrument | Pressure tune
365 09.4 | Edit 1 | rim PCM instrument | Pressure decay
366 -----------+--------+---------------------+------------------------------
367 10.1 | Edit 1 | -- | Reverb type
368 10.2 | Edit 1 | -- | Reverb effect level
369 10.3 | Edit 1 | -- | Reverb decay time
370 10.4 | Edit 1 | -- | Reverb frequency damping
371 11.3 | Edit 1 | -- | Delay feedback
372 11.2 | Edit 1 | -- | Delay effect level
373 11.1 | Edit 1 | -- | Delay time
374 11.4 | Edit 1 | -- | Delay frequency damping
375
376
377 # Thanks
378
379 The following tools have proven indispensable in the analysis:
380
381 - [`calc`](http://www.isthe.com/chongo/tech/comp/calc/), a calculator
382 for the command line supporting hexadecimal representations of
383 numbers (both input and output using the `base` and `base2`
384 functions)
385
386 - [`vbindiff`](http://www.cjmweb.net/vbindiff/), a tool to visualise
387 differences between two binary files with a split-screen hexadecimal
388 display
389
390 - [`ghex`](https://wiki.gnome.org/Ghex), a simple hexadecimal editor
391 supporting pattern search and highlighting
392
393
394 # Call for help
395
396 If you own an earlier model of the Wavedrum or the latest Wavedrum
397 Global Edition, I would be *very* happy if you could send me a
398 block-level copy of the SD card (see above for instructions). This
399 would allow me to understand the firmware better and maybe even make
400 it possible to upgrade an older Wavedrum to the latest version (taking
401 into account possible hardware differences, such as differing memory
402 size).
403
404 Please send a link to the micro SD card image to
405 <span class="obfuscated">sflbep,xbwfesvnAfmfqimz/ofu</span>.