diff options
author | rekado <rekado@elephly.net> | 2015-08-16 05:15:04 +0200 |
---|---|---|
committer | rekado <rekado@elephly.net> | 2015-08-17 22:56:02 +0200 |
commit | 0d58b658a63f4ec3e938deffee22763131a816b8 (patch) | |
tree | 95f5475f5bb021209f9d239af29d6c58d11c72a0 /posts | |
parent | 69b4e3db8cac30029fb94640f30354ac7c338b5b (diff) |
Convert articles to skribe format.
Diffstat (limited to 'posts')
58 files changed, 2285 insertions, 2037 deletions
diff --git a/posts/2009-07-01-chapman_stick.markdown b/posts/2009-07-01-chapman_stick.markdown deleted file mode 100644 index d576b92..0000000 --- a/posts/2009-07-01-chapman_stick.markdown +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: The Chapman Stick® -date: 2009/07/01 -tags: music, chapman stick ---- - -The [Chapman Stick](http://stick.com) is a stringed instrument invented quite -some time ago by [Emmett Chapman](http://www.emmettchapman.net). It is a blank -slate equipped with a grid-like touchboard, two groups of stings and a powerful -pickup allowing the player to tap notes rather than requiring fretting and -strumming. - -![Grand Stick after arrival in Shanghai](/images/posts/stick.jpg) - -I usually describe the Stick as being a guitar and a bass unified on one -fretboard, though I think that it is much more than that. It rather combines -the advantages of a piano over a traditionally stringed instument---such as -tonal range---with the advantages of the fretted instruments, i.e. direct fine -control over the sound through plain fingers on strings. More than that, it -even expands on these concepts and brings a number of [improvements and innovations](http://stick.com/instruments/tunings/12/classic_66). - -Check out the [official website](http://stick.com) to read more about what sets -apart the Stick from other tapping instruments. - -There's a documentary about Emmett and the Stick story in the make. You can -[see the trailer here](http://www.chapdoc.com/trailer.html). - -I've received my first Stick---a 12-stringed Grand---in July 2009 and have just -placed my order for an Alto Stick made from Indonesian Rosewood. diff --git a/posts/2009-07-01-chapman_stick.skr b/posts/2009-07-01-chapman_stick.skr new file mode 100644 index 0000000..119b941 --- /dev/null +++ b/posts/2009-07-01-chapman_stick.skr @@ -0,0 +1,36 @@ +(define meta + `((title . "The Chapman Stick®") + (date . ,(string->date* "2009-07-01 00:00")) + (tags "music" "chapman stick"))) + +(list + (p [The ,(ref "http://stick.com" [Chapman Stick]) is a stringed + instrument invented quite some time ago by ,(ref + "http://www.emmettchapman.net" [Emmett Chapman]). It is a + blank slate equipped with a grid-like touchboard, two groups of + stings and a powerful pickup allowing the player to tap notes + rather than requiring fretting and strumming.]) + + (figure "stick.jpg" "Grand Stick after arrival in Shanghai") + + (p [I usually describe the Stick as being a guitar and a bass + unified on one fretboard, though I think that it is much more + than that. It rather combines the advantages of a piano over a + traditionally stringed instument—such as tonal range—with the + advantages of the fretted instruments, i.e. direct fine control + over the sound through plain fingers on strings. More than + that, it even expands on these concepts and brings a number of + ,(ref "http://stick.com/instruments/tunings/12/classic_66" + [improvements and innovations]).]) + + (p [Check out the ,(ref "http://stick.com" [official website]) to + read more about what sets apart the Stick from other tapping + instruments.]) + + (p [There’s a documentary about Emmett and the Stick story in the + make. You can ,(ref "http://www.chapdoc.com/trailer.html" [see + the trailer here]).]) + + (p [I’ve received my first Stick—a 12-stringed Grand—in July 2009 + and have just placed my order for an Alto Stick made from + Indonesian Rosewood.])) diff --git a/posts/2010-03-23-fur-man.markdown b/posts/2010-03-23-fur-man.markdown deleted file mode 100644 index cf245ed..0000000 --- a/posts/2010-03-23-fur-man.markdown +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Fur Man -date: 2010/03/23 -tags: drawing, weird -license: by-sa ---- - -The Fur Man is an obese mammal, who lives most of his miserable lifetime in -utter solitude. The reasons for that are rather obvious. - -So far there has only been one sighting of the sickening Fur Man (on March 23, -2010). Some have suggested there might be only a single specimen existing on -earth, though this claim is disputed. - -<a href='/downies/fur-man.png' title='click to see super-large version'> - <img class='full' src='/images/posts/fur-man.png' alt='artist rendering of the sickening Fur Man'/> -</a> - -**Update:** -The Fur Man was sighted hiding behind a plant in an office building in Shanghai. - -<img class='full' src='/images/posts/fur-man-white-board.jpg' alt='Fur Man sighting'/> diff --git a/posts/2010-03-23-fur-man.skr b/posts/2010-03-23-fur-man.skr new file mode 100644 index 0000000..15273f4 --- /dev/null +++ b/posts/2010-03-23-fur-man.skr @@ -0,0 +1,27 @@ +(define meta + `((title . "Fur Man") + (date . ,(string->date* "2010-03-23 00:00")) + (license . "by-sa") + (tags "drawing" "weird"))) + +(list + (p [The Fur Man is an obese mammal, who lives most of his miserable + lifetime in utter solitude. The reasons for that are rather + obvious.]) + + (p [So far there has only been one sighting of the sickening Fur Man + (on March 23, 2010). Some have suggested there might be only a + single specimen existing on earth, though this claim is + disputed.]) + + '(a (@ (href "/downies/fur-man.png") + (title "click to see super-large version")) + (img (@ (class "full") + (src "/images/posts/fur-man.png") + (alt "artist rendering of the sickening Fur Man")))) + + (p [,(strong [Update:]) The Fur Man was sighted hiding behind a plant + in an office building in Shanghai.]) + + (wide-img "fur-man-white-board.jpg" + "Fur Man sighting")) diff --git a/posts/2010-03-26-billie-jean.markdown b/posts/2010-03-26-billie-jean.markdown deleted file mode 100644 index 9d3901f..0000000 --- a/posts/2010-03-26-billie-jean.markdown +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Billie Jean -date: 2010/03/26 -tags: video, music ---- - -![Playing Billie Jean on the Stick](/images/posts/billiejean.png) - -[This video](http://v.youku.com/v_show/id_XMTMyOTc3Nzcy.html) was recorded some -time in December 2009. I had just learned how to [tap with both hands on the -Chapman Stick](/posts/2009-07-01-chapman_stick.html) when I was contacted by -representatives of the Chinese video portal [Youku.com](http://youku.com). They -asked me to provide them with a quick video of myself showing off the peculiar -instrument I told them I had just learned to play. - -Later the video was to be tacked on to [footage that was recorded some days -earlier with the Youku team](http://v.youku.com/v_show/id_XMTMzMDA1MDU2.html). -All together this was supposed to be my entry for the voting to join the show -全家都来赛 (the official English name is the silly *"Super Family"*). - -As the show's purpose is to present talented families, I asked Jackie to play -the drums while I would cover bass, chords and vocals of Michael Jackson's -*Billie Jean*. The result [can be seen -here](http://v.youku.com/v_show/id_XMTMyOTc3Nzcy.html). diff --git a/posts/2010-03-26-billie-jean.skr b/posts/2010-03-26-billie-jean.skr new file mode 100644 index 0000000..3c20155 --- /dev/null +++ b/posts/2010-03-26-billie-jean.skr @@ -0,0 +1,30 @@ +(define meta + `((title . "Billie Jean") + (date . ,(string->date* "2010-03-26 00:00")) + (tags "video" "music"))) + +(list + (figure "billiejean.png" "Playing Billie Jean on the Stick") + + (p [,(ref "http://v.youku.com/v_show/id_XMTMyOTc3Nzcy.html" "This + video") was recorded some time in December 2009. I had just + learned how to ,(ref "/posts/2009-07-01-chapman_stick.html" "tap + with both hands on the Chapman Stick") when I was contacted by + representatives of the Chinese video portal ,(ref + "http://youku.com" "Youku.com"). They asked me to provide them + with a quick video of myself showing off the peculiar instrument I + told them I had just learned to play.]) + + (p [Later the video was to be tacked on to ,(ref + "http://v.youku.com/v_show/id_XMTMzMDA1MDU2.html" "footage that + was recorded some days earlier with the Youku team"). All + together this was supposed to be my entry for the voting to join + the show 全家都来赛 (the official English name is the silly ,(em + [“Super Family”])).]) + + (p [As the show’s purpose is to present ‘talented families’, I asked + Jackie to play the drums while I would cover bass, chords and + vocals of Michael Jackson’s ,(em [Billie Jean]). The result + ,(ref "http://v.youku.com/v_show/id_XMTMyOTc3Nzcy.html" "can be + seen here").])) + diff --git a/posts/2010-03-26-rehearsals.markdown b/posts/2010-03-26-rehearsals.markdown deleted file mode 100644 index d6b3c51..0000000 --- a/posts/2010-03-26-rehearsals.markdown +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Rehearsals -date: 2010/03/26 -tags: music, chapman stick, video, tv, quan jia dou lai sai -type: short -photo: rehearsals.jpg ---- - -[This video](http://v.youku.com/v_show/id_XMTUxMDczMDE2.html) was shot by the -friendly youku team during the rehearsals for the live broadcast of Quan Jia -Dou Lai Sai. - -Thanks to youku for their support! diff --git a/posts/2010-03-26-rehearsals.skr b/posts/2010-03-26-rehearsals.skr new file mode 100644 index 0000000..82e55c4 --- /dev/null +++ b/posts/2010-03-26-rehearsals.skr @@ -0,0 +1,13 @@ +(define meta + `((title . "Rehearsals") + (date . ,(string->date* "2010-03-26 00:00")) + (tags "music" "chapman stick" "video" "tv" "quan jia dou lai sai") + (type . "short") + (photo . "rehearsals.jpg"))) + +(list + (p [,(ref "http://v.youku.com/v_show/id_XMTUxMDczMDE2.html" "This + video") was shot by the friendly youku team during the rehearsals + for the live broadcast of Quan Jia Dou Lai Sai.]) + + (p [Thanks to Youku for their support!])) diff --git a/posts/2010-03-26-youku-niuren.markdown b/posts/2010-03-26-youku-niuren.markdown deleted file mode 100644 index 18887e5..0000000 --- a/posts/2010-03-26-youku-niuren.markdown +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: 2009 Youku Niuren -date: 2010/03/26 -tags: tv, youku, video, quan jia dou lai sai -photo: niuren.jpg -type: short ---- - -On January 23, 2010 Jackie and I attended the annual Niuren show hosted by -youku. We were handed a cheap plastic board, symbolizing entry into Quan Jia -Dou Lai Sai. Here's a [video of the -ceremony](http://v.youku.com/v_show/id_XMTQ3NjI2MzYw.html). diff --git a/posts/2010-03-26-youku-niuren.skr b/posts/2010-03-26-youku-niuren.skr new file mode 100644 index 0000000..b64dc63 --- /dev/null +++ b/posts/2010-03-26-youku-niuren.skr @@ -0,0 +1,13 @@ +(define meta + `((title . "2009 Youku Niuren") + (date . ,(string->date* "2010-03-26 00:00")) + (photo . "niuren.jpg") + (type . "short") + (tags "tv" "youku" "video" "quan jia dou lai sai"))) + +(list + (p [On January 23, 2010 Jackie and I attended the annual Niuren show + hosted by Youku. We were handed a cheap plastic board, + symbolizing entry into ,(em [Quan Jia Dou Lai Sai]). Here’s a + ,(ref "http://v.youku.com/v_show/id_XMTQ3NjI2MzYw.html" "video of + the ceremony").])) diff --git a/posts/2010-03-26-youku-vs-tudou-final.markdown b/posts/2010-03-26-youku-vs-tudou-final.markdown deleted file mode 100644 index 6798698..0000000 --- a/posts/2010-03-26-youku-vs-tudou-final.markdown +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Youku vs. Tudou—Final -date: 2010/03/26 -tags: tv, youku, quan jia dou lai sai -type: short -photo: 2010-02-10-qiutianbuhuilai.jpg ---- - -Here is a [full recording of the live -broadcast](http://v.youku.com/v_show/id_XMTUxNTM5NjUy.html) on Wednesday, -thanks to Youku! Some timestamps for all the impatient: 24:24, 53:50, 111:00. diff --git a/posts/2010-03-26-youku-vs-tudou-final.skr b/posts/2010-03-26-youku-vs-tudou-final.skr new file mode 100644 index 0000000..4b70029 --- /dev/null +++ b/posts/2010-03-26-youku-vs-tudou-final.skr @@ -0,0 +1,12 @@ +(define meta + `((title . "Youku vs. Tudou—Final") + (date . ,(string->date* "2010-03-26 00:00")) + (type . "short") + (photo . "2010-02-10-qiutianbuhuilai.jpg") + (tags "tv" "youku" "quan jia dou lai sai"))) + +(list + (p [Here is a ,(ref "http://v.youku.com/v_show/id_XMTUxNTM5NjUy.html" + "full recording of the live broadcast") on Wednesday, thanks to + Youku! Some timestamps for all the impatient: 24:24, 53:50, + 111:00.])) diff --git a/posts/2010-03-28-elephly.markdown b/posts/2010-03-28-elephly.markdown deleted file mode 100644 index 99b45a0..0000000 --- a/posts/2010-03-28-elephly.markdown +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: The Elephly -date: 2010/03/28 -flattr: 390348/The-Elephly -license: by-sa ---- - -This is Chlodwig, the marvelous elephly. The Elephly is a creature half -elephant, half fly, a quarter duck and three quarters weirdness---amounting to -200% of pure awesomeness! - -[![The elephly](/images/posts/elephly.png)](/downies/elephly.svg) - -Chlodwig came into existence when Rekado felt bored during a class of -Electrical Engineering. When Rekado realized the wonder that his creation was, -he decided to manually trace the outline of the faint sketch in Inkscape and -colorize it. This process took quite some time, because it often required -Rekado to remove strokes and blur out details in order to reduce the drawing to -the most essential. - -Get your very own scalable drawing of the elephly by touching the elephly's belly! diff --git a/posts/2010-03-28-elephly.skr b/posts/2010-03-28-elephly.skr new file mode 100644 index 0000000..9696367 --- /dev/null +++ b/posts/2010-03-28-elephly.skr @@ -0,0 +1,26 @@ +(define meta + `((title . "The Elephly") + (date . ,(string->date* "2010-03-28 00:00")) + (flattr . "390348/The-Elephly") + (license . "by-sa") + (tags "weird"))) + +(list + + (p [This is Chlodwig, the marvelous elephly. The elephly is a + creature half elephant, half fly, a quarter duck and three + quarters weirdness—amounting to 200% of pure awesomeness!]) + + (p (ref "/downies/elephly.svg" '(img (@ (src "/images/posts/elephly.png") + (alt "The elephly"))))) + + (p [Chlodwig came into existence when Rekado felt bored during a + class of Electrical Engineering. When Rekado realised the wonder + that his creation was, he decided to manually trace the outline + of the faint sketch in Inkscape and colorise it. This process + took quite some time, because it often required Rekado to remove + strokes and blur out details in order to reduce the drawing to + the most essential.]) + + (p [Get your very own scalable drawing of the elephly by touching the + elephly’s belly!])) diff --git a/posts/2010-04-05-deng-hou.markdown b/posts/2010-04-05-deng-hou.markdown deleted file mode 100644 index 982da7b..0000000 --- a/posts/2010-04-05-deng-hou.markdown +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Deng Hou -date: 2010/04/05 -tags: music, chinese -flattr: "325437" ---- - -When we were told that during our appearance on “Jia Ting Yan Bo -Shi” we were to peform a song, Jackie and I thought it would be a good -idea to write our own song. I still had a chunk of nice simple music without -lyrics. After Jackie had spent a day to think about the first verse, we would -both sit down to discuss, reject and rewrite both words and music. - -The unnamed song was first performed on the set of “Jia Ting Yan Bo -Shi”. I hope we can get our greedy hands on a recording if the program -directors decide to remove it from the final cut. - -You can [download a demo recording here](/downies/music/deng_hou.ogg) or listen -to it right here. - -<object height="81" width="100%"> <param name="movie" value="https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6334329"></param> <param name="allowscriptaccess" value="always"></param> <embed allowscriptaccess="always" height="81" src="https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6334329" type="application/x-shockwave-flash" width="100%"></embed> </object> <span><a href="http://soundcloud.com/rekado/deng-hou">等候</a> by <a href="http://soundcloud.com/rekado">rekado</a></span> - -## Lyrics - -### Verse 1 - -<pre class="lyrics"> -da da da da -ping dan de ri zi you ni cai hui jing cai -平淡的日子有你才会精彩 - -da da da da -wei feng ta chui guo ni liu xia de hua -微风它吹过你留下的花 - -gu du de xin -孤独的心 -xiang yao fei dao you ni de tian kong xia -想要飞到你的天空下 - -wei xiao -de gan jue na me jian dan de hui lai -微笑 的感觉那么简单的回来 -</pre> - -### Part B - -<pre class="lyrics"> -cen jing de tian mi hui yi wang bu liao -曾经的甜蜜回忆忘不了 -shi luo de xin kan bu dao -失落的心看不到 -yang guang de fang xiang -黎明的方向 -</pre> - -### Verse 2 - -<pre class="lyrics"> -da da da da -ping dan de ri zi you ni cai hui jing cai -平淡的日子有你才会精彩 - -da da da da -xue hua ta piao guo ni wo zou de lu -雪花它飘过你我走的路 - -jian ding de xin -坚定的心 - -kan jian bu yuan chu lv se de chun tian -相信明年春天与你重逢 - -wei lai -未来 -de sheng huo cheng xian zai wo de nao hai -的生活呈现在我的脑海 -</pre> - - -### Part B' - -<pre class="lyrics"> -ming tian de xiang yi xiang wei meng jian liao -明天的相依相隈梦见了 - -yong gan de xin zai hu huan -勇敢的心在呼唤 - -li ming de shu guang -黎明的曙光 -</pre> diff --git a/posts/2010-04-05-deng-hou.skr b/posts/2010-04-05-deng-hou.skr new file mode 100644 index 0000000..7f8c7c4 --- /dev/null +++ b/posts/2010-04-05-deng-hou.skr @@ -0,0 +1,108 @@ +(define meta + `((title . "Deng Hou") + (date . ,(string->date* "2010-04-05 00:00")) + (flattr . "325437") + (tags "music" "chinese"))) + +(list + + (p [When we were told that during our appearance on “Jia Ting Yan Bo + Shi” we were to peform a song, Jackie and I thought it would be a + good idea to write our own song. I still had a chunk of nice + simple music without lyrics. After Jackie had spent a day to + think about the first verse, we would both sit down to discuss, + reject and rewrite both words and music.]) + + (p [The unnamed song was first performed on the set of “Jia Ting Yan + Bo Shi”. I hope we can get our greedy hands on a recording if + the program directors decide to remove it from the final cut.]) + + (p [You can ,(ref "/downies/music/deng_hou.ogg" "download a demo + recording here") or listen to it right here.]) + + '(object (@ (height "81") + (width "100%")) + (param (@ (name "movie") + (value "https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6334329"))) + (param (@ (name "allowscriptaccess") + (value "always"))) + (embed (@ (allowscriptaccess "always") + (height "81") + (src "https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6334329") + (type "application/x-shockwave-flash") + (width "100%")))) + + '(span (a (@ (href "http://soundcloud.com/rekado/deng-hou")) "等候") + " by " + (a (@ (href "http://soundcloud.com/rekado")) "rekado")) + + (h2 [Lyrics]) + + (h3 [Verse 1]) + + (lyrics [ +da da da da +ping dan de ri zi you ni cai hui jing cai +平淡的日子有你才会精彩 + +da da da da +wei feng ta chui guo ni liu xia de hua +微风它吹过你留下的花 + +gu du de xin +孤独的心 +xiang yao fei dao you ni de tian kong xia +想要飞到你的天空下 + +wei xiao +de gan jue na me jian dan de hui lai +微笑 的感觉那么简单的回来 +]) + + (h3 [Part B]) + + (lyrics [ +cen jing de tian mi hui yi wang bu liao +曾经的甜蜜回忆忘不了 +shi luo de xin kan bu dao +失落的心看不到 +yang guang de fang xiang +黎明的方向 +]) + + (h3 [Verse 2]) + + (lyrics [ +da da da da +ping dan de ri zi you ni cai hui jing cai +平淡的日子有你才会精彩 + +da da da da +xue hua ta piao guo ni wo zou de lu +雪花它飘过你我走的路 + +jian ding de xin +坚定的心 + +kan jian bu yuan chu lv se de chun tian +相信明年春天与你重逢 + +wei lai +未来 +de sheng huo cheng xian zai wo de nao hai +的生活呈现在我的脑海 +]) + + + (h3 [Part B']) + + (lyrics [ +ming tian de xiang yi xiang wei meng jian liao +明天的相依相隈梦见了 + +yong gan de xin zai hu huan +勇敢的心在呼唤 + +li ming de shu guang +黎明的曙光 +])) diff --git a/posts/2010-04-12-jiatingyanboshi.markdown b/posts/2010-04-12-jiatingyanboshi.markdown deleted file mode 100644 index edb0242..0000000 --- a/posts/2010-04-12-jiatingyanboshi.markdown +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Jia Ting Yan Bo Shi -date: 2010/04/12 -tags: tv, chinese ---- - -The final cut of what has been recorded for the interview show *Jia Ting Yan Bo -Shi* is going to be aired on Friday, April 16 on *Shanghai Dianshi Tai*. - -You will hear Jackie and myself talk about many private issues and our opinions -on living in Shanghai. Our first live performance of [“Deng -Hou”](/posts/2010-04-05-deng-hou.html) is also going to be aired during the -program. - -**Update (April 18, 2010):** A 20 minute section of [the show is already -online](http://www.letv.com/ptv/vplay/660375.html). - -**Update (April 21, 2010):** [Part B](http://ent.joy.cn/video/1168864.htm) and -[part C](http://ent.joy.cn/video/1168865.htm) are also up now. At the end of -part C you can hear our terrible rendition of Deng Hou. The vocal harmony is -pretty off there. diff --git a/posts/2010-04-12-jiatingyanboshi.skr b/posts/2010-04-12-jiatingyanboshi.skr new file mode 100644 index 0000000..f31c3bc --- /dev/null +++ b/posts/2010-04-12-jiatingyanboshi.skr @@ -0,0 +1,24 @@ +(define meta + `((title . "Jia Ting Yan Bo Shi") + (date . ,(string->date* "2010-04-12 00:00")) + (tags "tv" "chinese"))) + +(list + (p [The final cut of what has been recorded for the interview show + ,(em [Jia Ting Yan Bo Shi]) is going to be aired on Friday, + April 16 on ,(em [Shanghai Dianshi Tai]).]) + + (p [You will hear Jackie and myself talk about many private issues + and our opinions on living in Shanghai. Our first live + performance of ,(ref "/posts/2010-04-05-deng-hou.html" "“Deng + Hou”") is also going to be aired during the program.]) + + (p [,(strong [Update (April 18, 2010):]) A 20 minute section of ,(ref + "http://www.letv.com/ptv/vplay/660375.html" "the show is already + online").]) + + (p [,(strong [Update (April 21, 2010):]) ,(ref + "http://ent.joy.cn/video/1168864.htm" "Part B") and ,(ref + "http://ent.joy.cn/video/1168865.htm" "part C") are also up + now. At the end of part C you can hear our terrible rendition of + Deng Hou. The vocal harmony is pretty off there.])) diff --git a/posts/2010-06-01-chapman-stick-on-national-tv.markdown b/posts/2010-06-01-chapman-stick-on-national-tv.markdown deleted file mode 100644 index a39d0d7..0000000 --- a/posts/2010-06-01-chapman-stick-on-national-tv.markdown +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: The Stick—Live on Chinese TV -date: 2010/06/01 -tags: show, tv, chapman stick, video, music ---- - -Once upon a time, there was a mediocre musician with a dream. The story has not -yet ended, so I cannot say much more than that. If this story would, however, -be written down by my sentimental alter ego one day (long after the last polar -bear will have surrendered before the army of blind manatees, oh, the huge -manatee!), it would probably make mention of the following event. - -![The Chapman Stick on Chinese national TV](/images/posts/stick-on-tv.jpg) - -Tossed around on the waves of his whimsical nature, the mediocre musican fell -into the path of an opportunity. In a way as to apologize for the accidental -collision, the clumsy musician offered to make up for the damage by playing -tunes and singing songs for pure entertainment. Not without a hidden agenda was -it that on that day the musician decided to bring an instrument, playing which -he was not even capable of. - -Lo and behold: ’twas the Chapman Stick the musician had strapped on, -knowing well that the juxtaposition of the minimalistic yet noble instrument -with the silly cowboy dress... What can I say? There is no way I could justify -that preposterous appearance. - -Anyway, I participated in a popular Shanghainese show and played the Stick. The -show was broadcast live on February 8, 2010 and despite the promise to be given -a reel of the performance, it took four months and lots of effort on my part to -find [this low-fi snippet](http://v.youku.com/v_show/id_XMTc3OTAyMTY0.html) of -the very first appearance of the Stick on Chinese TV. - -What you can see here is part of my introduction, a teaser of sorts, to keep -the audience hooked till the actual performance later in the show. The song I -was playing is a somewhat funkier adaption of Wang Li Hong's -"龙的传人". - -You can [download this historical video clip -here](/downies/videos/qjdls_chapman_stick_1.mp4). diff --git a/posts/2010-06-01-chapman-stick-on-national-tv.skr b/posts/2010-06-01-chapman-stick-on-national-tv.skr new file mode 100644 index 0000000..7f5f878 --- /dev/null +++ b/posts/2010-06-01-chapman-stick-on-national-tv.skr @@ -0,0 +1,44 @@ +(define meta + `((title . "The Stick—Live on Chinese TV") + (date . ,(string->date* "2010-06-01 00:00")) + (tags "show" "tv" "chapman stick" "video" "music"))) + +(list + (p [Once upon a time, there was a mediocre musician with a dream. The + story has not yet ended, so I cannot say much more than that. If + this story would, however, be written down by my sentimental alter + ego one day (long after the last polar bear will have surrendered + before the army of blind manatees, oh, the huge manatee!), it + would probably make mention of the following event.]) + + (figure "stick-on-tv.jpg" + "The Chapman Stick on Chinese national TV") + + (p [Tossed around on the waves of his whimsical nature, the mediocre + musican fell into the path of an opportunity. In a way as to + apologize for the accidental collision, the clumsy musician + offered to make up for the damage by playing tunes and singing + songs for pure entertainment. Not without a hidden agenda was it + that on that day the musician decided to bring an instrument, + playing which he was not even capable of.]) + + (p [Lo and behold: ’twas the Chapman Stick the musician had strapped + on, knowing well that the juxtaposition of the minimalistic yet + noble instrument with the silly cowboy dress... What can I say? + There is no way I could justify that preposterous appearance.]) + + (p [Anyway, I participated in a popular Shanghainese show and played + the Stick. The show was broadcast live on February 8, 2010 and + despite the promise to be given a reel of the performance, it took + four months and lots of effort on my part to find ,(ref + "http://v.youku.com/v_show/id_XMTc3OTAyMTY0.html" "this low-fi + snippet") of the very first appearance of the Stick on Chinese + TV.]) + + (p [What you can see here is part of my introduction, a teaser of + sorts, to keep the audience hooked till the actual performance + later in the show. The song I was playing is a somewhat funkier + adaption of Wang Li Hong’s “龙的传人”.]) + + (p [You can ,(ref "/downies/videos/qjdls_chapman_stick_1.mp4" + "download this historical video clip here").])) diff --git a/posts/2010-06-24-2010-niuren.markdown b/posts/2010-06-24-2010-niuren.markdown deleted file mode 100644 index a58b1dd..0000000 --- a/posts/2010-06-24-2010-niuren.markdown +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: 2010 Youku Niuren Competition -date: 2010/06/24 -tags: music, show, youku ---- - -<img class="full stretch" src="/images/posts/niuren2010.jpg" alt="At the Shanghai venue of Niuren 2010"/> - -In an SMS two days before the Shanghai event of this year's Niuren competition, -my friend at Youku asked me if I would want to perform a song on the stage. -After some initial hesitation I eventually agreed to playing the guitar while -singing. Originally, I wanted to perform 坏人 but at the venue I realized that -this particular song is not quite as popular as 秋天不回来. - -Not very well prepared I got on the stage as the third performer that -afternoon. I unexplicably managed to spoil the guitar intro, but still nobody -seemed to really mind. It felt good not to feel the pressuring perfectionism -flaring up inside of me again. - -With this precautionary tale in mind, go ahead and [watch the clip on -youku](http://v.youku.com/v_show/id_XMTgzNDE0OTU2.html)! If you prefer to watch -a version that I'm okay with, then [check out the older -video](/posts/2009-11-02-qtbhl.html). - -**Update (June 29, 2010)**: There is a [short clip on -youku](http://v.youku.com/v_show/id_XMTg1MjkyODAw.html) that aired on TV to -advertise the competition. The clip was featured on the start page of youku and -thus reached quite a large number of people. diff --git a/posts/2010-06-24-2010-niuren.skr b/posts/2010-06-24-2010-niuren.skr new file mode 100644 index 0000000..1e2dff6 --- /dev/null +++ b/posts/2010-06-24-2010-niuren.skr @@ -0,0 +1,33 @@ +(define meta + `((title . "2010 Youku Niuren Competition") + (date . ,(string->date* "2010-06-24 00:00")) + (tags "music" "show" "youku"))) + +(list + (wide-img "niuren2010.jpg" + "At the Shanghai venue of Niuren 2010") + + (p [In an SMS two days before the Shanghai event of this year’s + Niuren competition, my friend at Youku asked me if I would want + to perform a song on the stage. After some initial hesitation I + eventually agreed to playing the guitar while singing. + Originally, I wanted to perform 坏人 but at the venue I realized + that this particular song is not quite as popular as 秋天不回来.]) + + (p [Not very well prepared I got on the stage as the third performer + that afternoon. I unexplicably managed to spoil the guitar + intro, but still nobody seemed to really mind. It felt good not + to feel the pressuring perfectionism flaring up inside of me + again.]) + + (p [With this precautionary tale in mind, go ahead and ,(ref + "http://v.youku.com/v_show/id_XMTgzNDE0OTU2.html" "watch the clip + on youku")! If you prefer to watch a version that I’m okay with, + then ,(ref "/posts/2009-11-02-qtbhl.html" "check out the older + video").]) + + (p [,(strong [Update (June 29, 2010)]): There is a ,(ref + "http://v.youku.com/v_show/id_XMTg1MjkyODAw.html" "short clip on + youku") that aired on TV to advertise the competition. The clip + was featured on the start page of youku and thus reached quite a + large number of people.])) diff --git a/posts/2010-07-02-newspaper.markdown b/posts/2010-07-02-newspaper.markdown deleted file mode 100644 index 0dc3b0d..0000000 --- a/posts/2010-07-02-newspaper.markdown +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Newspaper Report -date: 2010/07/02 -tags: niuren, youku, chapman stick, media ---- - -[![small view of the article](/images/posts/newspaper.jpg)](/images/posts/newspaper-large.jpg) - -A few weeks ago I accepted the offer to perform a song at this year's Niuren -Competition. As I was notified just two days before the event, I couldn't make -arrangements for taking the Stick, so [I just played a well-known song on the -guitar](/posts/2010-06-24-2010-niuren.html). After the performance, I chatted with -a woman on site who had an awful lot of questions for me. Turns out she is a -reporter for the local newspaper ["Overseas Chinese -News"](http://www.yesqiaobao.com). Later the journalist asked me to send her -some photos of myself playing an instrument to illustrate an article they were -preparing. - -The article is now available online, both as a [newspaper-styled -image](http://www.yesqiaobao.com/qilinzhoukan/epaper/linfen/html/2010/06/30/C1/images/back.jpg) -and a [text -version](http://www.yesqiaobao.com/qilinzhoukan/epaper/linfen/html/2010/06/30/C1/C1_40.htm). -I am very happy that they chose the photo of me playing the Chapman Stick at -home. Thanks to Sandra Yan for the article! (Careful: the newspaper's website -seems to be optimized for the Internet Explorer.) diff --git a/posts/2010-07-02-newspaper.skr b/posts/2010-07-02-newspaper.skr new file mode 100644 index 0000000..0c07319 --- /dev/null +++ b/posts/2010-07-02-newspaper.skr @@ -0,0 +1,31 @@ +(define meta + `((title . "Newspaper Report") + (date . ,(string->date* "2010-07-02 00:00")) + (tags "niuren" "youku" "chapman stick" "media"))) + +(list + + (ref "/images/posts/newspaper-large.jpg" + (figure "newspaper.jpg" + "small view of the article")) + + (p [A few weeks ago I accepted the offer to perform a song at this + year’s Niuren Competition. As I was notified just two days + before the event, I couldn’t make arrangements for taking the + Stick, so ,(ref "/posts/2010-06-24-2010-niuren.html" "I just + played a well-known song on the guitar"). After the performance, + I chatted with a woman on site who had an awful lot of questions + for me. Turns out she is a reporter for the local newspaper + ,(ref "http://www.yesqiaobao.com" "“Overseas Chinese News”"). + Later the journalist asked me to send her some photos of myself + playing an instrument to illustrate an article they were + preparing.]) + + (p [The article is now available online, both as a ,(ref + "http://www.yesqiaobao.com/qilinzhoukan/epaper/linfen/html/2010/06/30/C1/images/back.jpg" + "newspaper-styled image") and a ,(ref + "http://www.yesqiaobao.com/qilinzhoukan/epaper/linfen/html/2010/06/30/C1/C1_40.htm" + "text version"). I am very happy that they chose the photo of me + playing the Chapman Stick at home. Thanks to Sandra Yan for the + article! (Careful: the newspaper’s website seems to be optimized + for the Internet Explorer.)])) diff --git a/posts/2010-07-08-wishful-thinking.markdown b/posts/2010-07-08-wishful-thinking.markdown deleted file mode 100644 index e5a7339..0000000 --- a/posts/2010-07-08-wishful-thinking.markdown +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Wishful Thinking -date: 2010/07/08 -tags: musings, ecology, energy ---- - -I used to be a magical thinker many years ago. Whenever I wished for something -I would keep looking at the road side while sitting on the backseat of my -parents’ car or when I was walking home from school, hoping to spot the -object of my dreams. - -For many years I badly wished for a tortoise or a turtle to come into my life, -just waiting for me at the side of the road. As I used to find coins just about -twice a month, I reckoned I could stumble upon animals just as easily. Animals -longing to let go of their wild nature, willing to become my companion and just -waiting for me to come by. - -It never happened. (It should also be noted that my dream to stumble upon a -tame specimen of Gallimimus at the side of the road never came true.) I never -found a turtle at the side of the road. - -Until today. A dream came true, but it had unnoticedly turned into a nightmare. -When I walked out the door this morning I caught sight of about four -centimeters of what seemed to resemble a six-legged crab. As I got closer I -could make out that one of the legs was actually a tail and another was a head -on a long neck. Closer yet I recognized it as a tiny turtle standing squarely -on the right side of my path. - -![dead turtle](/images/posts/turtle.jpg) - -Noticing an ant crawling on its eye I realized that it was dead. Its limbs had -not completely stiffened yet when I picked it up to move its body off the -street and onto the sidewalk where I went on to take a picture of a shattered -dream. - -In an attempt to stretch this story into a metaphor for something more dramatic -than the mere death of critter—albeit a cute one—I chose -“Wishful Thinking” as the title for this entry. Although this story -is not representative of anything in particular, it did remind me of what I -recently read on Magical Thinking in Derrick Jensen᾿s “What We -Leave Behind”. - -(There's much I disagree with when it comes to Jensen's worldview, but this -section is quite powerful.) - -<blockquote> - - <p>Are you a magical thinker? I know that too often I am. With apologies to Jeff - Foxworthy, let᾿s play a little game.</p> - - <p>If you put a bumper sticker on you hybrid Prius that reads <em>Visualize World - Peace</em> in the hope this will bring about world peace, you might just be a - magical thinker.</p> - - <p>If you buy a hybrid Prius in the hope this will slow global warming, you - might just be a magical thinker.</p> - - <p>[...]</p> - - <p>If you think buying compact fluorescent light bulbs will slow global warming, - you might just be a magical thinker.</p> - - <p>[...]</p> - - <p>If you think this culture will stop killing the planet without being - force-fully stopped, you might just be delusional, and if you don᾿t act - to stop this culture, then you will be failing in your responsibility as a - living being (p.224/5).</p> - -</blockquote> - - -“Ugh, did he just really turn a story about a rotting turtle into an -environmental protection guilt-fest?”---so it seems. What I was aiming -for was that: remembering my innocent dreaming and my firm believe that -watching just closely enough will make the unlikely more likely, in the face of -the distasteful partial manifestation of that dream demonstrated just how -unsatisfying Wishful Thinking can be. Observing the road side would have only -increased my chance of discovering unpleasant road-kills. My convenient idea of -looking out for what is easiest to spot just addressed the wrong problem -(turtles aren't the type to lurk at the side of roads) and at the same time -left me unsatisfied. I think I'm eventually driving the point home: attempting -to solve the wrong problem is unrewarding in every way. - -If you think our culture will survive if only we could manage to find an -alternative to cheap oil, you might just be a magical thinker---or you might be -part of the actual problem. - diff --git a/posts/2010-07-08-wishful-thinking.skr b/posts/2010-07-08-wishful-thinking.skr new file mode 100644 index 0000000..7abf251 --- /dev/null +++ b/posts/2010-07-08-wishful-thinking.skr @@ -0,0 +1,92 @@ +(define meta + `((title . "Wishful Thinking") + (date . ,(string->date* "2010-07-08 00:00")) + (tags "musings" "ecology" "energy"))) + +(list + + (p [I used to be a magical thinker many years ago. Whenever I wished + for something I would keep looking at the road side while sitting + on the backseat of my parents’ car or when I was walking home + from school, hoping to spot the object of my dreams.]) + + (p [For many years I badly wished for a tortoise or a turtle to come + into my life, just waiting for me at the side of the road. As I + used to find coins just about twice a month, I reckoned I could + stumble upon animals just as easily. Animals longing to let go + of their wild nature, willing to become my companion and just + waiting for me to come by.]) + + (p [It never happened. (It should also be noted that my dream to + stumble upon a tame specimen of Gallimimus at the side of the + road never came true.) I never found a turtle at the side of the + road.]) + + (p [Until today. A dream came true, but it had unnoticedly turned + into a nightmare. When I walked out the door this morning I + caught sight of about four centimeters of what seemed to resemble + a six-legged crab. As I got closer I could make out that one of + the legs was actually a tail and another was a head on a long + neck. Closer yet I recognized it as a tiny turtle standing + squarely on the right side of my path.]) + + (wide-img "turtle.jpg" + "dead turtle") + + (p [Noticing an ant crawling on its eye I realized that it was dead. + Its limbs had not completely stiffened yet when I picked it up to + move its body off the street and onto the sidewalk where I went + on to take a picture of a shattered dream.]) + + (p [In an attempt to stretch this story into a metaphor for something + more dramatic than the mere death of critter—albeit a cute one—I + chose “Wishful Thinking” as the title for this entry. Although + this story is not representative of anything in particular, it + did remind me of what I recently read on Magical Thinking in + Derrick Jensen’s “What We Leave Behind”.]) + + (p [(There’s much I disagree with when it comes to Jensen’s + worldview, but this section is quite powerful.)]) + + (blockquote + (p [Are you a magical thinker? I know that too often I am. With + apologies to Jeff Foxworthy, let’s play a little game.]) + + (p [If you put a bumper sticker on you hybrid Prius that reads + ,(em [Visualize World Peace]) in the hope this will bring + about world peace, you might just be a magical thinker.]) + + (p [If you buy a hybrid Prius in the hope this will slow global + warming, you might just be a magical thinker.]) + + '(p "[...]") + + (p [If you think buying compact fluorescent light bulbs will slow + global warming, you might just be a magical thinker.]) + + '(p "[...]") + + (p [If you think this culture will stop killing the planet without + being force-fully stopped, you might just be delusional, and if + you don’t act to stop this culture, then you will be failing in + your responsibility as a living being (p.224/5).])) + + + (p [“Ugh, did he just really turn a story about a rotting turtle into + an environmental protection guilt-fest?”—so it seems. What I was + aiming for was that: remembering my innocent dreaming and my firm + believe that watching just closely enough will make the unlikely + more likely, in the face of the distasteful partial manifestation + of that dream demonstrated just how unsatisfying Wishful Thinking + can be. Observing the road side would have only increased my + chance of discovering unpleasant road-kills. My convenient idea + of looking out for what is easiest to spot just addressed the + wrong problem (turtles aren’t the type to lurk at the side of + roads) and at the same time left me unsatisfied. I think I’m + eventually driving the point home: attempting to solve the wrong + problem is unrewarding in every way.]) + + (p [If you think our culture will survive if only we could manage to + find an alternative to cheap oil, you might just be a magical + thinker—or you might be part of the actual problem.])) + diff --git a/posts/2010-07-14-one-night-in-beijing.markdown b/posts/2010-07-14-one-night-in-beijing.markdown deleted file mode 100644 index 64535c5..0000000 --- a/posts/2010-07-14-one-night-in-beijing.markdown +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: One Night In Beijing -date: 2010/07/14 -tags: music, youku, video, show ---- - -When I noticed that the online voting system for the big Niuren 2010 event was -not to be trusted, I was pretty convinced not be one of those chosen to perform -on stage in Bejing. In order to be sure, I wrote a message to my friend at -Youku. Some hours later I was informed that disregarding the number of the -votes (which did turn out to be comparatively high in the end) I was supposed -to be invited to give a performance on the Stick. After all formal issues were -agreed upon, I prepared to leave for Beijing on Sunday morning with the Chapman -Stick in tow. - -When I arrived at the venue I was surprised to find the stage to be a lot -larger than I anticipated. - -<img class="full" src="/images/posts/niuren2010_beijing_stage.jpg" alt="The stage in Beijing"/> - -When it was time for my soundcheck the clouds had formed a dark opaque blanket -across the unattractive skies of Beijing and at times rain drops mixed with the -soil on the vast meadow to form squishy mud. The crew seemed to marvel at the -impression of hearing two instruments' sounds, each articulated by one -individual hand on its own set of strings but on one instrument. - -At about ten o᾿clock in the evening, the show began. It only lasted for -about 15 minutes as the occasional rain proceeded to grow into drowning -vertical streams of water. The stage was lacking any sort of rain protection -and it didn᾿t take long until the stage lights went off as the cables -were drenched. - -The show was eventually cancelled which only made sense considering that most -of the mud-dwellers in front of the stage had given up their hopes for better -weather and had left the premises in shoals. - -Disappointed we returned to the hotel. When finally everybody had returned we -discussed with the organizers how to proceed, how to salvage the investment. At -first the idea was going around to stage the event on Monday evening, without -an audience, just recording and pretending it all happened the day before. This -idea was soon discarded, though, when the organizers learned that most of had -would be flying back home on Monday morning. A compromises was found when the -decision was made to record individual performances—or rather very pale -and primitive versions of what was originally planned—in the lobby of the -hotel. - -![Recording video clips in the hotel lobby at 2am](/images/posts/niuren2010_beijing_lobby.jpg) - -These clips—all of which were recorded between two and three -a.m.—are supposed to serve as teasers for the actual show which has now -been postponed to some time in August or September. I will add the links to -those video clips in the next few days, provided I can find them. A new entry -will be posted once the date for the postponed show in Beijing has been -confirmed. - -**Update (July 29):*** The short video clip has been uploaded. You can [watch -it on youku](http://v.youku.com/v_show/id_XMTkzMzc1NDI4.html). - -**Update:*** Gao Ming interviewed the participants during the preparations of -the show. There is a 25+ minutes [video clip on -youku](http://v.youku.com/v_show/id_XMTg5NzMwNDI4.html). At about 2:40 he comes -across the table where I am relaxing with other participants. diff --git a/posts/2010-07-14-one-night-in-beijing.skr b/posts/2010-07-14-one-night-in-beijing.skr new file mode 100644 index 0000000..9027747 --- /dev/null +++ b/posts/2010-07-14-one-night-in-beijing.skr @@ -0,0 +1,73 @@ +(define meta + `((title . "One Night In Beijing") + (date . ,(string->date* "2010-07-14 00:00")) + (tags "music" "youku" "video" "show"))) + +(list + (p [When I noticed that the online voting system for the big Niuren + 2010 event was not to be trusted, I was pretty convinced not be + one of those chosen to perform on stage in Bejing. In order to + be sure, I wrote a message to my friend at Youku. Some hours + later I was informed that disregarding the number of the votes + (which did turn out to be comparatively high in the end) I was + supposed to be invited to give a performance on the Stick. After + all formal issues were agreed upon, I prepared to leave for + Beijing on Sunday morning with the Chapman Stick in tow.]) + + (p [When I arrived at the venue I was surprised to find the stage to + be a lot larger than I anticipated.]) + + (wide-img "niuren2010_beijing_stage.jpg" + "The stage in Beijing") + + (p [When it was time for my soundcheck the clouds had formed a dark + opaque blanket across the unattractive skies of Beijing and at + times rain drops mixed with the soil on the vast meadow to form + squishy mud. The crew seemed to marvel at the impression of + hearing two instruments’ sounds, each articulated by one + individual hand on its own set of strings but on one + instrument.]) + + (p [At about ten o’clock in the evening, the show began. It only + lasted for about 15 minutes as the occasional rain proceeded to + grow into drowning vertical streams of water. The stage was + lacking any sort of rain protection and it didn’t take long until + the stage lights went off as the cables were drenched.]) + + (p [The show was eventually cancelled which only made sense + considering that most of the mud-dwellers in front of the stage + had given up their hopes for better weather and had left the + premises in shoals.]) + + (p [Disappointed we returned to the hotel. When finally everybody + had returned we discussed with the organizers how to proceed, how + to salvage the investment. At first the idea was going around to + stage the event on Monday evening, without an audience, just + recording and pretending it all happened the day before. This + idea was soon discarded, though, when the organizers learned that + most of had would be flying back home on Monday morning. A + compromise was found when the decision was made to record + individual performances—or rather very pale and primitive + versions of what was originally planned—in the lobby of the + hotel.]) + + (figure "niuren2010_beijing_lobby.jpg" + "Recording video clips in the hotel lobby at 2am") + + (p [These clips—all of which were recorded between two and three + a.m.—are supposed to serve as teasers for the actual show which + has now been postponed to some time in August or September. I + will add the links to those video clips in the next few days, + provided I can find them. A new entry will be posted once the + date for the postponed show in Beijing has been confirmed.]) + + (p [,(strong [Update (July 29):]) The short video clip has been + uploaded. You can ,(ref + "http://v.youku.com/v_show/id_XMTkzMzc1NDI4.html" "watch it on + youku").]) + + (p [,(strong [Update:]) Gao Ming interviewed the participants during + the preparations of the show. There is a 25+ minutes ,(ref + "http://v.youku.com/v_show/id_XMTg5NzMwNDI4.html" "video clip on + youku"). At about 2:40 he comes across the table where I am + relaxing with other participants.])) diff --git a/posts/2010-08-04-alto-stick.markdown b/posts/2010-08-04-alto-stick.markdown deleted file mode 100644 index d5687ba..0000000 --- a/posts/2010-08-04-alto-stick.markdown +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: “Flow” on Alto Stick -date: 2010/08/04 -tags: music, alto stick, chapman stick ---- - -<img src='/images/posts/alto-stick.jpg' alt="Alto Stick 6061" class="full stretch"/> - -Just yesterday I received my new Alto Stick (#6061). It is a Chapman Stick with -ten strings and a shorter scale, very similar to a guitar, really. Yesterday -night I just could not put it down, so I experimented with layered chords and -arpeggios. The video I recorded that night just would not sync to the audio -track, so I recorded the idea once again just some minutes ago in the early -morning. - -There are many bumps in this recording, still I like it. Maybe you do, too. - -<object height="81" width="100%"> <param name="movie" value="https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F34493000&show_comments=true&auto_play=false&color=ff7700"></param> <param name="allowscriptaccess" value="always"></param> <embed allowscriptaccess="always" height="81" src="https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F34493000&show_comments=true&auto_play=false&color=ff7700" type="application/x-shockwave-flash" width="100%"></embed> </object> <span><a href="http://soundcloud.com/rekado/flow">Flow</a> by <a href="http://soundcloud.com/rekado">rekado</a></span> diff --git a/posts/2010-08-04-alto-stick.skr b/posts/2010-08-04-alto-stick.skr new file mode 100644 index 0000000..0c90d06 --- /dev/null +++ b/posts/2010-08-04-alto-stick.skr @@ -0,0 +1,36 @@ +(define meta + `((title . "“Flow” on Alto Stick") + (date . ,(string->date* "2010-08-04 00:00")) + (tags "music" "alto stick" "chapman stick"))) + +(list + (wide-img "alto-stick.jpg" + "Alto Stick 6061") + + (p [Just yesterday I received my new Alto Stick (#6061). It is a + Chapman Stick with ten strings and a shorter scale, very similar + to a guitar, really. Yesterday night I just could not put it + down, so I experimented with layered chords and arpeggios. The + video I recorded that night just would not sync to the audio + track, so I recorded the idea once again just some minutes ago in + the early morning.]) + + (p [There are many bumps in this recording, still I like it. Maybe + you do, too.]) + + '(object (@ (height "81") + (width "100%")) + (param (@ (name "movie") + (value "https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F34493000&show_comments=true&auto_play=false&color=ff7700"))) + (param (@ (name "allowscriptaccess") + (value "always"))) + (embed (@ (allowscriptaccess "always") + (height "81") + (src "https://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F34493000&show_comments=true&auto_play=false&color=ff7700") + (type "application/x-shockwave-flash") + (width "100%")))) + + `(span + ,(ref "http://soundcloud.com/rekado/flow" "Flow") + " by " + ,(ref "http://soundcloud.com/rekado" "rekado"))) diff --git a/posts/2010-08-15-yueyintang.markdown b/posts/2010-08-15-yueyintang.markdown deleted file mode 100644 index d070c68..0000000 --- a/posts/2010-08-15-yueyintang.markdown +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Yueyin Tang -date: 2010/08/15 -tags: music ---- - -Just so you know why there has not been any update for a while: Jackie and I -were asked to play a 20 to 40 minutes set on a Wednesday night in September -with some friends in a bar. We think we could be playing these songs without -too much hassle: - - - - 神话 - - Eye of the Tiger - - 天使 - - Kayleigh - - 秋天不回来 - - Caveman (original song) - - -I was told that there would be a full drum set and amplifiers for bass and -guitar. As we are but two people, I will play the Grand Stick to fill the spots -of both guitarist and bass player while singing. Jackie has to get back into -drumming within in the next few days, so I will be busy with tutoring her a -little. - -"Caveman" is not a full song yet. Once intended to be the second part of my -*opus magnum*, writing stalled when I stopped actively working on the whole -thing. About three years ago I made a short [demo -recording](/downies/music/caveman_demo.ogg) of it in Berlin. The lyrics have -changed since, but are still incomplete. I will have to take some time to flesh -it out and turn it into a real song. - -Last Wednesday I failed at recording 天使 for various reasons. For one the fear -to disturb the sleeping neighbours---they go to bed at eight in the -evening---was very inhibiting to my singing; on top of that sleep deprivation -attributed to rather sloppy playing. I also stared into the camera to often, -which made for disturbing footage. I am going to venture another attempt -tonight. diff --git a/posts/2010-08-15-yueyintang.skr b/posts/2010-08-15-yueyintang.skr new file mode 100644 index 0000000..bd350ee --- /dev/null +++ b/posts/2010-08-15-yueyintang.skr @@ -0,0 +1,40 @@ +(define meta + `((title . "Yueyin Tang") + (date . ,(string->date* "2010-08-15 00:00")) + (tags "music"))) + +(list + (p [Just so you know why there has not been any update for a while: + Jackie and I were asked to play a 20 to 40 minutes set on a + Wednesday night in September with some friends in a bar. We + think we could be playing these songs without too much hassle:]) + + (ul + (li [神话]) + (li [Eye of the Tiger]) + (li [天使]) + (li [Kayleigh]) + (li [秋天不回来]) + (li [Caveman (original song)])) + + (p [I was told that there would be a full drum set and amplifiers for + bass and guitar. As we are but two people, I will play the Grand + Stick to fill the spots of both guitarist and bass player while + singing. Jackie has to get back into drumming within in the next + few days, so I will be busy with tutoring her a little.]) + + (p [“Caveman” is not a full song yet. Once intended to be the second + part of my ,(em [opus magnum]), writing stalled when I stopped + actively working on the whole thing. About three years ago I + made a short ,(ref "/downies/music/caveman_demo.ogg" "demo + recording") of it in Berlin. The lyrics have changed since, but + are still incomplete. I will have to take some time to flesh it + out and turn it into a real song.]) + + (p [Last Wednesday I failed at recording 天使 for various reasons. + For one the fear to disturb the sleeping neighbours—they go to + bed at eight in the evening—was very inhibiting to my singing; on + top of that sleep deprivation attributed to rather sloppy + playing. I also stared into the camera to often, which made for + disturbing footage. I am going to venture another attempt + tonight.])) diff --git a/posts/2010-08-17-tianshi.markdown b/posts/2010-08-17-tianshi.markdown deleted file mode 100644 index 4da1752..0000000 --- a/posts/2010-08-17-tianshi.markdown +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: “Tianshi” on Alto Stick -date: 2010/08/17 -tags: music, video, chinese, alto stick, chapman stick -flattr: 472329/Tianshi-on-Alto-Stick ---- - -When my colleague was in the middle of preparations for getting married, he -asked me to play a nice song at his wedding. “Nice” songs are a -neglected minority in Chinese pop music; most of the popular songs deal with -love affairs gone wrong, broken hearts, the loss of the original feeling, or -they describe the emptiness after the loved one has passed away. Nothing that -would really fit to the (admittedly cheesy) celebration of Eternal Love™. -Hence, my vast catalogue of popular songs was all but useless. I had to learn -how to play a new song: Mayday᾿s “Angel”. - -This is my practise session in its blunt ugliness. I spliced in a solo section -recorded at a different angle to divert you from the boredom. As you will -probably notice, the introduction was lifted from my improvisation -[“Flow” which I recorded -earlier](/posts/2010-08-05-flow-on-the-alto-stick-video.html). - -(Yes, this is the same shirt as in my last video...) - -My next recording will likely be an original song, unless I will be asked by my -friends at youku.com for more sino pop before it is ready. - -<video width="100%" autobuffer controls poster="tianshi.jpg"> - <source src='/downies/videos/tianshi_low.mp4'/> - <source src='/downies/videos/tianshi_low.ogv'/> -</video> - -I offer this video for download in several formats. Choose one from the list -below. When you do not want to care about codecs, [download the free VLC -player](http://videolan.org). If you are on Linux `mplayer` will work fine, -too. - - -## Medium Quality (HD 720) - -<div class="download"> - <table> - <tr><th>codecs</th><td>h.264 + mp3</td></tr> - <tr><th>bitrate A</th><td>192 kbps</td></tr> - <tr><th>bitrate V</th><td>3 Mbps</td></tr> - <tr><th>container</th><td>mp4</td></tr> - <tr><th>size</th><td>109 MB<td></tr> - </table> - <a href='/downies/videos/tianshi_medium.mp4'>download</a> -</div> - -<div class="download"> - <table> - <tr><th>codecs</th><td>ogg theora</td></tr> - <tr><th>bitrate A</th><td>192 kbps</td></tr> - <tr><th>bitrate V</th><td>3 Mbps</td></tr> - <tr><th>container</th><td>ogv</td></tr> - <tr><th>size</th><td>135 MB</td></tr> - </table> - <a href='/downies/videos/tianshi_medium.ogv'>download</a> -</div> - - -## Low Quality (HD 480) - -<div class="download"> - <table> - <tr><th>codecs</th><td>h.264 + mp3</td></tr> - <tr><th>bitrate A</th><td>128 kbps</td></tr> - <tr><th>bitrate V</th><td>1.5 Mbps</td></tr> - <tr><th>container</th><td>mp4</td></tr> - <tr><th>size</th><td>56 MB<td></tr> - </table> - <a href='/downies/videos/tianshi_low.mp4'>download</a> -</div> - -<div class="download"> - <table> - <tr><th>codecs</th><td>ogg theora</td></tr> - <tr><th>bitrate A</th><td>128 kbps</td></tr> - <tr><th>bitrate V</th><td>1.5 Mbps</td></tr> - <tr><th>container</th><td>ogv</td></tr> - <tr><th>size</th><td>55 MB</td></tr> - </table> - <a href='/downies/videos/tianshi_low.ogv'>download</a> -</div> - -## Streaming - -The video is available on both -[Youku](http://v.youku.com/v_show/id_XMTk5MDQ4MDE2.html) and -[YouTube](http://www.youtube.com/watch?v=rSclwOFYIYc). diff --git a/posts/2010-08-17-tianshi.skr b/posts/2010-08-17-tianshi.skr new file mode 100644 index 0000000..69dc223 --- /dev/null +++ b/posts/2010-08-17-tianshi.skr @@ -0,0 +1,88 @@ +(define meta + `((title . "“Tianshi” on Alto Stick") + (date . ,(string->date* "2010-08-17 00:00")) + (flattr . "472329/Tianshi-on-Alto-Stick") + (tags "music" "video" "chinese" "alto stick" "chapman stick"))) + +(list + (p [When my colleague was in the middle of preparations for getting + married, he asked me to play a nice song at his wedding. “Nice” + songs are a neglected minority in Chinese pop music; most of the + popular songs deal with love affairs gone wrong, broken hearts, + the loss of the original feeling, or they describe the emptiness + after the loved one has passed away. Nothing that would really + fit to the (admittedly cheesy) celebration of Eternal Love™. + Hence, my vast catalogue of popular songs was all but useless. I + had to learn how to play a new song: Mayday’s “Angel”.]) + + (p [This is my practise session in its blunt ugliness. I spliced in a + solo section recorded at a different angle to divert you from the + boredom. As you will probably notice, the introduction was lifted + from my improvisation ,(ref + "/posts/2010-08-05-flow-on-the-alto-stick-video.html" "“Flow” + which I recorded earlier").]) + + (p [(Yes, this is the same shirt as in my last video...)]) + + (p [My next recording will likely be an original song, unless I will + be asked by my friends at youku.com for more sino pop before it is + ready.]) + + '(video (@ (width "100%") + (autobuffer "true") + (controls "true") + (poster "tianshi.jpg")) + (source (@ (src "/downies/videos/tianshi_low.mp4"))) + (source (@ (src "/downies/videos/tianshi_low.ogv")))) + + (p [I offer this video for download in several formats. Choose one + from the list below. When you do not want to care about codecs, + ,(ref "http://videolan.org" "download the free VLC player"). If + you are on GNU/Linux ,(code [mplayer]) will work fine, too.]) + + + (h2 [Medium Quality (HD 720)]) + + `(div (@ (class "download")) + (table + (tr (th "codecs") (td "h.264 + mp3")) + (tr (th "bitrate A") (td "192 kbps")) + (tr (th "bitrate V") (td "3 Mbps")) + (tr (th "container") (td "mp4")) + (tr (th "size") (td "109 MB"))) + ,(ref "/downies/videos/tianshi_medium.mp4" "download")) + + `(div (@ (class "download")) + (table + (tr (th "codecs") (td "ogg theora")) + (tr (th "bitrate A") (td "192 kbps")) + (tr (th "bitrate V") (td "3 Mbps")) + (tr (th "container") (td "ogv")) + (tr (th "size") (td "135 MB"))) + ,(ref "/downies/videos/tianshi_medium.ogv" "download")) + + + (h2 [Low Quality (HD 480)]) + `(div (@ (class "download")) + (table + (tr (th "codecs") (td "h.264 + mp3")) + (tr (th "bitrate A") (td "128 kbps")) + (tr (th "bitrate V") (td "1.5 Mbps")) + (tr (th "container") (td "mp4")) + (tr (th "size") (td "56 MB"))) + ,(ref "/downies/videos/tianshi_low.mp4" "download")) + + `(div (@ (class "download")) + (table + (tr (th "codecs") (td "ogg theora")) + (tr (th "bitrate A") (td "128 kbps")) + (tr (th "bitrate V") (td "1.5 Mbps")) + (tr (th "container") (td "ogv")) + (tr (th "size") (td "55 MB"))) + ,(ref "/downies/videos/tianshi_low.ogv" "download")) + + (h2 [Streaming]) + + (p [The video is available on ,(ref + "http://v.youku.com/v_show/id_XMTk5MDQ4MDE2.html" "Youku").])) + diff --git a/posts/2010-10-14-chinese-tune-mda-epiano.markdown b/posts/2010-10-14-chinese-tune-mda-epiano.markdown deleted file mode 100644 index 9b8b984..0000000 --- a/posts/2010-10-14-chinese-tune-mda-epiano.markdown +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Chinese Tune / The mdaEPiano -date: 2010/10/14 -tags: code, music -photo: mda-epiano-coding.jpg -flattr: 72898/LV2-port-of-the-mda-E-Piano-VSTi ---- - -In the past two days (actually, mornings and evenings) I have been working on -porting the famous [mda EPiano VSTi plugin](http://mda-vst.com) to the LV2 -plugin framework. The sound of the electric piano is very inspiring. Hear for -yourself: - -<object height="81" width="100%"> <param name="movie" value="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6120886&show_comments=true&auto_play=false&color=ffaa00"></param> <param name="allowscriptaccess" value="always"></param> <embed allowscriptaccess="always" height="81" src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6120886&show_comments=true&auto_play=false&color=ffaa00" type="application/x-shockwave-flash" width="100%"></embed> </object> - -You can [download the recording from soundcloud](http://soundcloud.com/rekado/chinese-tune). -The recording was done with `arecordmidi` while routing all incoming midi -events through the LV2 plugin. An instance of `jack_capture` was used to -record the generated sound simultaneously. If you want to compare my port of -the plugin to your favorite synthesizer, you can [download the midi file -here](/downies/music/chinese-tune.mid). - -The LV2 port can be -[downloaded from my git repository](http://git.elephly.net/software/lv2-mdametapiano.git). diff --git a/posts/2010-10-14-chinese-tune-mda-epiano.skr b/posts/2010-10-14-chinese-tune-mda-epiano.skr new file mode 100644 index 0000000..b009a89 --- /dev/null +++ b/posts/2010-10-14-chinese-tune-mda-epiano.skr @@ -0,0 +1,35 @@ +(define meta + `((title . "Chinese Tune / The mdaEPiano") + (date . ,(string->date* "2010-10-14 00:00")) + (photo . "mda-epiano-coding.jpg") + (flattr . "72898/LV2-port-of-the-mda-E-Piano-VSTi") + (tags "code" "music"))) + +(list + (p [In the past two days (actually, mornings and evenings) I have + been working on porting the famous ,(ref "http://mda-vst.com" + "mda EPiano VSTi plugin") to the LV2 plugin framework. The sound + of the electric piano is very inspiring. Hear for yourself:]) + + '(object (@ (height "81") (width "100%")) + (param (@ (name "movie") (value "http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6120886&show_comments=true&auto_play=false&color=ffaa00"))) + (param (@ (name "allowscriptaccess") (value "always"))) + (embed (@ (allowscriptaccess "always") + (height "81") + (src "http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F6120886&show_comments=true&auto_play=false&color=ffaa00") + (type "application/x-shockwave-flash") + (width "100%")))) + + (p [You can ,(ref "http://soundcloud.com/rekado/chinese-tune" + "download the recording from soundcloud"). The recording was + done with ,(code [arecordmidi]) while routing all incoming midi + events through the LV2 plugin. An instance of ,(code + [jack_capture]) was used to record the generated sound + simultaneously. If you want to compare my port of the plugin to + your favorite synthesizer, you can ,(ref + "/downies/music/chinese-tune.mid" "download the midi file + here").]) + + (p [The LV2 port can be ,(ref + "http://git.elephly.net/software/lv2-mdametapiano.git" + "downloaded from my git repository").])) diff --git a/posts/2012-01-25-new-blog.markdown b/posts/2012-01-25-new-blog.markdown deleted file mode 100644 index e661ee3..0000000 --- a/posts/2012-01-25-new-blog.markdown +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: New Blog -date: 2012/01/25 -tags: meta ---- - -Hey there, I'm back! - -I'm currently migrating the old blog posts to my new site. Once this is done -you can expect me to use this blog thingie a little more often. diff --git a/posts/2012-01-25-new-blog.skr b/posts/2012-01-25-new-blog.skr new file mode 100644 index 0000000..4d2e0f8 --- /dev/null +++ b/posts/2012-01-25-new-blog.skr @@ -0,0 +1,11 @@ +(define meta + `((title . "New Blog") + (date . ,(string->date* "2012-01-25 00:00")) + (tags "meta"))) + +(list + (p [Hey there, I’m back!]) + + (p [I’m currently migrating the old blog posts to my new site. Once + this is done you can expect me to use this blog thingie a little + more often.])) diff --git a/posts/2013-01-27-preamp-board-arrived.markdown b/posts/2013-01-27-preamp-board-arrived.markdown deleted file mode 100644 index aee96d9..0000000 --- a/posts/2013-01-27-preamp-board-arrived.markdown +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Stick preamp PCB arrived -tags: audio,pcb,DIY,preamp,chapman stick,free software ---- - -![One of the boards](/images/posts/pcb-1.jpg) - -Today I received a package from Shenzhen containing ten printed circuit boards. -I ordered a single board through [a taobao store](http://taobao.com) for only -100 RMB (about USD 16), but I suppose there is not much of a -difference between the production costs of ten boards and that of one. - -The board is the heart of my two-channel Chapman Stick preamp / signal router. -It includes a cross-over circuit for the bass side, so that I can partition the -bass signal into two frequency ranges that can be routed and processed -independently. It has three very simple effect inserts (high bass, low bass, -and melody), two buffered outputs (both signals mixed down to mono or dual -mono), and a tuner output (which could be used for an on-stage monitor). - -The circuit and the board were designed using the -[free](http://www.fsf.org/about/what-is-free-software) programs -`gschem` and `pcb` of the excellent -[gEDA suite](http://www.geda-project.org). (For some odd reason `pcb` -is not available through the official Archlinux repositories; I -installed it through the Arch User Repository.) You can get my circuit -diagrams, the PCB layout, and custom footprints through the -[git repository](http://git.elephly.net/hardware/stick-preamp.git) I -set up for this project. - -![Oops.](/images/posts/pcb-2.jpg) - -The manufacturer only received the exported Gerber files that I checked with -`gerbv`. Sadly, I didn't realise that the silk screen layer would be printed on -the bottom side of the single-layer board, so the text on all ten boards is -mirrored. (I suppose I could get used to saying "TЯƎƧИI", but "YᗡO⅃ƎM" just -sounds weird.) Now I will have to carefully check the orientation of the -transistors before soldering them onto the board because I'm not sure whether -they have been mirrored when I designed the board. - -I'm still missing two or three parts (different component packages and power -line filtering), but I'll start soldering the first components to one of the -boards tonight. diff --git a/posts/2013-01-27-preamp-board-arrived.skr b/posts/2013-01-27-preamp-board-arrived.skr new file mode 100644 index 0000000..5888ef8 --- /dev/null +++ b/posts/2013-01-27-preamp-board-arrived.skr @@ -0,0 +1,50 @@ +(define meta + `((title . "Stick preamp PCB arrived") + (date . ,(string->date* "2013-01-27 00:00")) + (tags "audio" "pcb" "DIY" "preamp" "chapman stick" "free software"))) + +(list + (figure "pcb-1.jpg" "One of the boards") + + (p [Today I received a package from Shenzhen containing ten printed + circuit boards. I ordered a single board through ,(ref + "http://taobao.com" "a taobao store") for only 100,(~)RMB (about + USD,(~)16), but I suppose there is not much of a difference + between the production costs of ten boards and that of one.]) + + (p [The board is the heart of my two-channel Chapman Stick preamp / + signal router. It includes a cross-over circuit for the bass + side, so that I can partition the bass signal into two frequency + ranges that can be routed and processed independently. It has + three very simple effect inserts (high bass, low bass, and + melody), two buffered outputs (both signals mixed down to mono or + dual mono), and a tuner output (which could be used for an + on-stage monitor).]) + + (p [The circuit and the board were designed using the ,(ref + "http://www.fsf.org/about/what-is-free-software" "free") programs + ,(code [gschem]) and ,(code [pcb]) of the excellent ,(ref + "http://www.geda-project.org" "gEDA suite"). (For some odd reason + ,(code [pcb]) is not available through the official Archlinux + repositories; I installed it through the Arch User Repository.) + You can get my circuit diagrams, the PCB layout, and custom + footprints through the ,(ref + "http://git.elephly.net/hardware/stick-preamp.git" "git + repository") I set up for this project.]) + + (figure "pcb-2.jpg" "Oops.") + + (p [The manufacturer only received the exported Gerber files that I + checked with ,(code [gerbv]). Sadly, I didn’t realise that the + silk screen layer would be printed on the bottom side of the + single-layer board, so the text on all ten boards is mirrored. (I + suppose I could get used to saying “TЯƎƧИI”, but “YᗡO⅃ƎM” just + sounds weird.) Now I will have to carefully check the orientation + of the transistors before soldering them onto the board because + I’m not sure whether they have been mirrored when I designed the + board.]) + + (p [I’m still missing two or three parts (different component packages + and power line filtering), but I’ll start soldering the first + components to one of the boards tonight.])) + diff --git a/posts/2013-05-24-improvisation.markdown b/posts/2013-05-24-improvisation.markdown deleted file mode 100644 index 05846f1..0000000 --- a/posts/2013-05-24-improvisation.markdown +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Introduction to jazz improvisation -tags: audio,music,guitar,coursera,learning,jazz ---- - -Since a few weeks I'm learning how to play more interesting jazz solos -from Gary Burton through his [Coursera](http://coursera.org) MOOC -[Introduction to -Improvisation](https://class.coursera.org/improvisation-001/). - -What's great about the course is that it forces me to record solos and -upload them for peer review. I don't normally publish practice -recordings as I'm never quite satisfied with them, but this also means -that many half-decent ideas are never published at all. - -You can find my growing collection of improvisation recordings in -fulfilment of the assignments [on -SoundCloud](https://soundcloud.com/rekado/sets/gary-burtons-improvisation), -embedded below: - -<iframe width="100%" height="450" scrolling="no" frameborder="no" -src="http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F5556211&show_artwork=true"></iframe>
\ No newline at end of file diff --git a/posts/2013-05-24-improvisation.skr b/posts/2013-05-24-improvisation.skr new file mode 100644 index 0000000..051708b --- /dev/null +++ b/posts/2013-05-24-improvisation.skr @@ -0,0 +1,28 @@ +(define meta + `((title . "Introduction to jazz improvisation") + (date . ,(string->date* "2013-05-24 00:00")) + (tags "audio" "music" "guitar" "coursera" "learning" "jazz"))) + +(list + (p [Since a few weeks I’m learning how to play more interesting jazz + solos from Gary Burton through his ,(ref "http://coursera.org" + "Coursera") MOOC ,(ref + "https://class.coursera.org/improvisation-001/" "Introduction to + Improvisation").]) + + (p [What’s great about the course is that it forces me to record solos + and upload them for peer review. I don’t normally publish + practice recordings as I’m never quite satisfied with them, but + this also means that many half-decent ideas are never published at + all.]) + + (p [You can find my growing collection of improvisation recordings in + fulfilment of the assignments ,(ref + "https://soundcloud.com/rekado/sets/gary-burtons-improvisation" + "on SoundCloud"), embedded below:]) + + '(iframe (@ (width "100%") + (height "450") + (scrolling "no") + (frameborder "no") + (src "http://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Fplaylists%2F5556211&show_artwork=true")))) diff --git a/posts/2013-08-11-hacking-the-wavedrum.markdown b/posts/2013-08-11-hacking-the-wavedrum.markdown deleted file mode 100644 index 0046386..0000000 --- a/posts/2013-08-11-hacking-the-wavedrum.markdown +++ /dev/null @@ -1,420 +0,0 @@ ---- -title: Hacking the Wavedrum -tags: DIY,electronics,music,hacking,wavedrum ---- - -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. -The Wavedrum's card reader is perfectly capable of reading 8GB micro -SD HC cards, so if you want to play with the data on the card I -recommend mirroring the original card image onto whatever micro SD -card you have at your disposal and play with that instead of the -original 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>├── [ 16] <b class="EXEC">CALIB.BOR</b></li> -<li>├── [ 16K] <b class="DIR">Factory</b></li> -<li>│ ├── [192K] <b class="EXEC">F_INFO.BOR</b></li> -<li>│ ├── [ 57K] <b class="EXEC">F_INST_H.BOR</b></li> -<li>│ ├── [ 57K] <b class="EXEC">F_INST_R.BOR</b></li> -<li>│ ├── [ 16K] <b class="EXEC">F_PROG.BOR</b></li> -<li>│ └── [ 88] <b class="EXEC">F_USER.BOR</b></li> -<li>├── [ 57K] <b class="EXEC">INST_H.BOR</b></li> -<li>├── [ 57K] <b class="EXEC">INST_R.BOR</b></li> -<li>├── [ 16K] <b class="DIR">LOOP</b></li> -<li>│ ├── [744K] <b class="EXEC">LOOP0001.BIN</b></li> -<li>│ ├── [402K] <b class="EXEC">LOOP0002.BIN</b></li> -<li>│ ├── [750K] <b class="EXEC">LOOP0003.BIN</b></li> -<li>⋮</li> -<li>│ ├── [173K] <b class="EXEC">LOOP0138.BIN</b></li> -<li>│ ├── [173K] <b class="EXEC">LOOP0139.BIN</b></li> -<li>│ └── [234K] <b class="EXEC">LOOP0140.BIN</b></li> -<li>├── [ 16K] <b class="EXEC">PRE_PROG.BOR</b></li> -<li>├── [ 16K] <b class="DIR">SYSTEM</b></li> -<li>│ ├── [ 16] <b class="EXEC">VERSION.INF</b></li> -<li>│ ├── [1.0M] <b class="EXEC">WDORM202.BIN</b></li> -<li>│ └── [8.0K] <b class="EXEC">WDORS110.BIN</b></li> -<li>├── [ 88] <b class="EXEC">USER.BOR</b></li> -<li>├── [157M] <b class="EXEC">WD2_DATA.BOR</b></li> -<li>├── [192K] <b class="EXEC">WD2_INFO.BOR</b></li> -<li>└── [ 16K] <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 `WD2_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 16 -e signed-integer -c 1 XXX - -Obviously, this isn't quite correct. I'm interpreting every 16 bits -as a sample in signed integer format, but the sound is distorted and -far from the realistic instrument sound when playing back the loops -through the Wavedrum. - -All loops start with this 44 byte long header: - - 04 dc 10 d3 uU vV 5W 95 01 d4 00 d0 30 f8 22 b5 - 46 95 56 95 57 95 57 95 d6 2e 56 95 56 e2 57 95 - 54 95 46 95 32 f4 22 f4 xX yY 5W 95 - -With a few exceptions (namely 0009, 0025, 0027, 0030, 0033, 0036, -0049, 0054, 0064, 0082, 0091, 0103, 0104, 0107, 0108, 0127, 0128, -0129, 0130, 0131, 0132, 0135), vV equals yY in most loops. It seems -that loops with the same number of bytes have the exact same numbers -for uU, vV, W, xX, and yY. This is especially apparent in the -loops 0127 to 0132 (inclusive), which are all 192,010 bytes long and -all have the values 54:7b:54 for uU:vV:5W and 88:78:54 for xX:yY:5W. - -Clearly, more work is required to figure out the complete format of -these loop files. 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 `WD2_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. - -I'm currently writing a Haskell library to parse / build progammes and -parameters. The code is available for -[free](https://www.fsf.org/about/what-is-free-software) -[here](http://git.elephly.net/wavedrum/wavedrum-lib.git) under the -[GNU GPLv3](https://gnu.org/licenses/gpl.html). - -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>. - -Read [more posts about the Wavedrum here](http://elephly.net/tags/wavedrum.html). diff --git a/posts/2013-08-11-hacking-the-wavedrum.skr b/posts/2013-08-11-hacking-the-wavedrum.skr new file mode 100644 index 0000000..39115a3 --- /dev/null +++ b/posts/2013-08-11-hacking-the-wavedrum.skr @@ -0,0 +1,454 @@ +(define meta + `((title . "Hacking the Wavedrum") + (date . ,(string->date* "2013-08-11 00:00")) + (tags "DIY" "electronics" "music" "hacking" "wavedrum"))) + +(define (row id mode target name) + `(tr (td (@ (align "right")) ,id) + (td (@ (align "left")) ,mode) + (td (@ (align "left")) ,target) + (td (@ (align "left")) ,name))) + +(list + + (p [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.]) + + (p [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.]) + + (p [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.]) + + + (h2 [A look inside the Wavedrum]) + + (p [Not really knowing what to look for I opened up the Wavedrum in + the hopes of finding ,(em [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.]) + + (p [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.]) + + (wide-img "2013/wavedrum-opened.jpg" + "After removing the rim and the drum head") + + (p [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.)]) + + (list 'warning [,(strong [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.]) + + (p [With this warning out of the way, let’s move on.]) + + (p [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 ,(em [in situ]).]) + + (wide-img "2013/wavedrum-mainboard.jpg" + "The mainboard of the Wavedrum Oriental") + + + (h2 [The treasure trove]) + + (p [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.]) + + (figure "2013/wavedrum-card-tape.jpg" "The taped-over SD card") + + (p [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 ,(code [dmesg]).) Eventually, + the card was recognised as ,(code [/dev/sdb1]). (,(code + [/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 ,(em + [copy]) of the card. The Wavedrum’s card reader is perfectly + capable of reading 8GB micro SD HC cards, so if you want to play + with the data on the card I recommend mirroring the original card + image onto whatever micro SD card you have at your disposal and + play with that instead of the original card. To create a block + level copy of the card I ,(em [did not]) mount the filesystem and + simply executed the following command:]) + + (pre (code [dd if=/dev/sdb1 of=wavedrum.img])) + + (p [This instructs ,(code [dd]) to copy all blocks from the input + device file (,(code [if]), i.e. ,(code [/dev/sdb1])) to the + output file (,(code [of])) of the name ,(code [wavedrum.img]). + Dependent on the number of disks on your system, the input device + file may have a different name. Check the output of ,(code + [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 ,(em [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).]) + + (p [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:]) + + (pre (code [mkdir wavedrum +mount -o loop,ro wavedrum.img wavedrum/])) + + (p [Let’s take a look at the files on the card:]) + + '(ul (@ (class "tree")) + (li (span (@ (class "NORM")) "/" )) + (li "├── ( 16) " (span (@ (class "EXEC")) "CALIB.BOR")) + (li "├── ( 16K) " (span (@ (class "DIR")) "Factory")) + (li "│ ├── (192K) " (span (@ (class "EXEC")) "F_INFO.BOR")) + (li "│ ├── ( 57K) " (span (@ (class "EXEC")) "F_INST_H.BOR")) + (li "│ ├── ( 57K) " (span (@ (class "EXEC")) "F_INST_R.BOR")) + (li "│ ├── ( 16K) " (span (@ (class "EXEC")) "F_PROG.BOR")) + (li "│ └── ( 88) " (span (@ (class "EXEC")) "F_USER.BOR")) + (li "├── ( 57K) " (span (@ (class "EXEC")) "INST_H.BOR")) + (li "├── ( 57K) " (span (@ (class "EXEC")) "INST_R.BOR")) + (li "├── ( 16K) " (span (@ (class "DIR")) "LOOP")) + (li "│ ├── (744K) " (span (@ (class "EXEC")) "LOOP0001.BIN")) + (li "│ ├── (402K) " (span (@ (class "EXEC")) "LOOP0002.BIN")) + (li "│ ├── (750K) " (span (@ (class "EXEC")) "LOOP0003.BIN")) + (li "...") + (li "│ ├── (173K) " (span (@ (class "EXEC")) "LOOP0138.BIN")) + (li "│ ├── (173K) " (span (@ (class "EXEC")) "LOOP0139.BIN")) + (li "│ └── (234K) " (span (@ (class "EXEC")) "LOOP0140.BIN")) + (li "├── ( 16K) " (span (@ (class "EXEC")) "PRE_PROG.BOR")) + (li "├── ( 16K) " (span (@ (class "DIR")) "SYSTEM")) + (li "│ ├── ( 16) " (span (@ (class "EXEC")) "VERSION.INF")) + (li "│ ├── (1.0M) " (span (@ (class "EXEC")) "WDORM202.BIN")) + (li "│ └── (8.0K) " (span (@ (class "EXEC")) "WDORS110.BIN")) + (li "├── ( 88) " (span (@ (class "EXEC")) "USER.BOR")) + (li "├── (157M) " (span (@ (class "EXEC")) "WD2_DATA.BOR")) + (li "├── (192K) " (span (@ (class "EXEC")) "WD2_INFO.BOR")) + (li "└── ( 16K) " (span (@ (class "EXEC")) "WD2_PROG.BOR"))) + + (p [The files in the ,(code [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 ,(code [Factory]) + directory. All initial programmes that come with the Wavedrum + are stored in ,(code [Factory/F_PROG.BOR]); once programmes have + been edited ,(code [WD2_PROG.BOR]) in the root directory will + differ from ,(code [Factory/F_PROG.BOR]). (More about the nature + of these differences later.) ,(code [PRE_PROG.BOR]) is the same + as ,(code [Factory/F_PROG.BOR]) and is probably used to make the + original factory presets available in addition to custom + programmes, starting at position ,(code [P.00]), the programme + slot after ,(code [149]).]) + + (p [The initial mapping of presets to any of the 12 slots (3 banks + with 4 slots each) is stored in ,(code [Factory/F_USER.BOR]). + Initially, ,(code [USER.BOR]) in the root directory will be + identical to this file. The format of this file is rather + simple:]) + + (pre (code [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])) + + (p [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:]) + + (ul + (li [delay pan]) + (li [aux input level]) + (li [loop phrase select]) + (li [loop play mode (off=38)]) + (li [head sensor threshold]) + (li [head sensor sensitivity]) + (li [rim sensor threshold]) + (li [rim sensor sensitivity]) + (li [pressure sensor threshold]) + (li [pressure maximum])) + + (p [I don’t know yet what purpose ,(code [F_INST_H.BOR]) and ,(code + [F_INST_R.BOR]) serve, 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, + ,(code [INST_H.BOR]) and ,(code [INST_R.BOR]) in the root + directory were still identical to their counterparts in the + ,(code [Factory]) directory.]) + + (p [The ,(code [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.]) + + + (h2 [Audio data]) + + (p [All files in the ,(code [LOOP]) directory as well as ,(code + [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 ,(code [play]) (part of + the ,(ref "http://sox.sourceforge.net" "SoX") applications):]) + + (pre (code [find LOOP -name "*.BIN" -print |\\ + xargs -I XXX \\ + play -t raw -r 48k -b 16 -e signed-integer -c 1 XXX])) + + (p [Obviously, this isn’t quite correct. I’m interpreting every 16 + bits as a sample in signed integer format, but the sound is + distorted and far from the realistic instrument sound when + playing back the loops through the Wavedrum.]) + + (p [All loops start with this 44 byte long header:]) + + (pre (code [04 dc 10 d3 uU vV 5W 95 01 d4 00 d0 30 f8 22 b5 +46 95 56 95 57 95 57 95 d6 2e 56 95 56 e2 57 95 +54 95 46 95 32 f4 22 f4 xX yY 5W 95])) + + (p [With a few exceptions (namely 0009, 0025, 0027, 0030, 0033, 0036, + 0049, 0054, 0064, 0082, 0091, 0103, 0104, 0107, 0108, 0127, 0128, + 0129, 0130, 0131, 0132, 0135), vV equals yY in most loops. It + seems that loops with the same number of bytes have the exact + same numbers for uU, vV, W, xX, and yY. This is especially + apparent in the loops 0127 to 0132 (inclusive), which are all + 192,010 bytes long and all have the values 54:7b:54 for uU:vV:5W + and 88:78:54 for xX:yY:5W.]) + + (p [Clearly, more work is required to figure out the complete format + of these loop files. Once this is understood we could use custom + loops with the Wavedrum.]) + + (p [The raw audio data in ,(code [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.]) + + + (h2 [System files]) + + (p [I don’t know what ,(code [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.]) + + (p [,(code [SYSTEM/VERSION.INF]) is only 16 bytes short and pretty + boring as it contains just what the name implies: version + numbers.]) + + (pre (code [02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00])) + + (p [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 ,(code [WDORS110.BIN]) references the version + number 1.10, while ,(code [WDORM202.BIN]) references the firmware + version number 2.02.]) + + (p [,(code [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 ,(em + [understanding]) how it works. To view the strings with the + ,(code [strings]) command, you have to specify the encoding as + 32-bit little endian:]) + + (pre (code [strings --encoding L SYSTEM/WDORM202.BIN])) + + (p [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?).]) + + + (h2 [The programme format]) + + (p [Looking at the hexdump of the file ,(code [WD2_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.]) + + (wide-img "2013/wavedrum-diff.png" + "Analysing the programme format by changing values and looking at the differences") + + (p [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 ,(ref + "https://en.wikipedia.org/wiki/Two%27s_complement" "two’s + 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.]) + + (p [I’m currently writing a Haskell library to parse / build + progammes and parameters. The code is available for ,(ref + "https://www.fsf.org/about/what-is-free-software" "free") ,(ref + "http://git.elephly.net/wavedrum/wavedrum-lib.git" "here") under + the ,(ref "https://gnu.org/licenses/gpl.html" "GNU GPLv3").]) + + (p [The parameters are stored in this order:]) + + (table :align '("right") + :headers '("identifier" "mode" "target" "name") + :rows + '(("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"))) + + + (h2 [Thanks]) + + (p [The following tools have proven indispensable in the analysis:]) + + (ul + (li [,(ref "http://www.isthe.com/chongo/tech/comp/calc/" "calc"), a + calculator for the command line supporting hexadecimal + representations of numbers (both input and output using the + ,(code [base]) and ,(code [base2]) functions)]) + + (li [,(ref "http://www.cjmweb.net/vbindiff/" "vbindiff"), a tool to + visualise differences between two binary files with a + split-screen hexadecimal display]) + + (li [,(ref "https://wiki.gnome.org/Ghex" "ghex"), a simple + hexadecimal editor supporting pattern search and highlighting])) + + + (h2 [Call for help]) + + (p [If you own an earlier model of the Wavedrum or the latest + Wavedrum Global Edition, I would be ,(em [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).]) + + (p [Please send a link to the micro SD card image to ,(email + "rekado@elephly.net").]) + + (p [Read ,(ref "/tags/wavedrum.html" "more posts about the Wavedrum + here").])) diff --git a/posts/2013-10-01-dm-crypt.markdown b/posts/2013-10-01-dm-crypt.markdown deleted file mode 100644 index 401de87..0000000 --- a/posts/2013-10-01-dm-crypt.markdown +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: How to create an encrypted file container with dm-crypt -tags: gnu, linux, crypto, tutorial ---- - -Here are some instructions on how to create an encrypted filesystem on a file. - -Create an empty file with the size of your container. Here I'll use a 100MB -container. The file is created with `dd` which reads chunks from an input -device and writes the contents to a file or another device. - - dd if=/dev/zero bs=1M count=100 of=~/my-container.img - -This command means the following: read 100 chunks of one megabyte from the zero -device `/dev/zero` and write them to the file `~/my-container.img`. This will -create a file named `my-container.img` in your home directory that will be -about 100MB of zeros[^1]. - -[^1]: You could use `/dev/random` as the input device if you wanted to, but -that would be considerably slower and wouldn't help you much. Later commands -will initialise the file/partition, so you don't need to initialise it manually -with random numbers.) - -Next, we'll initialise the LUKS partition on the file and set the initial -passphrase. - - sudo cryptsetup luksFormat ~/mycontainer - -Note that you need to type "YES" (i.e. "yes" in *uppercase*) to confirm the -operation; there is no error message when you fail this step which may be -confusing. Make sure that the file you want to format is your container file -or an empty partition's device file. Input your passphrase when prompted. You -will have to input this passphrase whenever you mount the container unless you -decide to store the passphrase with the container (which obviously is not very -safe). Note that you have to run this as root, because cryptsetup must access -the loopback device. (On the Hurd this would not be necessary, I think.) - -Now, we'll open the container. Opening the container creates a kernel device -file which can then be mounted. - - sudo cryptsetup luksOpen ~/mycontainer secret-device - -This command will prompt for the container's passphrase and then create a -device file with the name `/dev/mapper/secret-device`. You may choose another -name than "secret-device". - -The container is now decrypted. Since the device has no filesystem yet we -still cannot put any data on it. Use `mkfs.ext4` to create an ext4 filesystem -on the decrypted container: - - sudo mkfs.ext4 /dev/mapper/secret-device - -Now the filesystem can be mounted like a filesystem on a regular block device. - - mkdir ~/my-mount-point - sudo mount /dev/mapper/secret-device ~/my-mount-point - -The first command creates a new mount point (an empty directory) named -"my-mount-point" in your home directory. The second command mounts the -decrypted device at this location. - -You can now write to the directory as usual. Once you are done follow these -steps to unmount the device and close (= re-encrypt) the container: - - sudo umount ~/my-mount-point - sudo cryptsetup luksClose secret-device - -To access the container again only these two commands are required: - - sudo cryptsetup luksOpen ~/mycontainer secret-device - sudo mount /dev/mapper/secret-device ~/my-mount-point diff --git a/posts/2013-10-01-dm-crypt.skr b/posts/2013-10-01-dm-crypt.skr new file mode 100644 index 0000000..cae43e6 --- /dev/null +++ b/posts/2013-10-01-dm-crypt.skr @@ -0,0 +1,87 @@ +(define meta + `((title . "How to create an encrypted file container with dm-crypt") + (date . ,(string->date* "2013-10-01 00:00")) + (tags "gnu" "linux" "crypto" "tutorial"))) + +(list + + (p [Here are some instructions on how to create an encrypted + filesystem on a file.]) + + (p [Create an empty file with the size of your container. Here I’ll + use a 100MB container. The file is created with ,(code [dd]) + which reads chunks from an input device and writes the contents + to a file or another device.]) + + (pre (code [dd if=/dev/zero bs=1M count=100 of=~/my-container.img])) + + (p [This command means the following: read 100 chunks of one megabyte + from the ,(ref "#fn1" "zero device") ,(code [/dev/zero]) and + write them to the file ,(code [~/my-container.img]). This will + create a file named ,(code [my-container.img]) in your home + directory that will be about 100MB of zeros.]) + + (p [Next, we’ll initialise the LUKS partition on the file and set the + initial passphrase.]) + + (pre (code [sudo cryptsetup luksFormat ~/mycontainer])) + + (p [Note that you need to type “YES” (i.e. ‘yes’ in ,(em [uppercase]) + to confirm the operation; there is no error message when you fail + this step which may be confusing. Make sure that the file you + want to format is your container file or an empty partition’s + device file. Input your passphrase when prompted. You will have + to input this passphrase whenever you mount the container unless + you decide to store the passphrase with the container (which + obviously is not very safe). Note that you have to run this as + root, because cryptsetup must access the loopback device. (On + the Hurd this would not be necessary, I think.)]) + + (p [Now, we’ll open the container. Opening the container creates a + kernel device file which can then be mounted.]) + + (pre (code [sudo cryptsetup luksOpen ~/mycontainer secret-device])) + + (p [This command will prompt for the container’s passphrase and then + create a device file with the name ,(code + [/dev/mapper/secret-device]). You may choose another name than + “secret-device”.]) + + (p [The container is now decrypted. Since the device has no + filesystem yet we still cannot put any data on it. Use ,(code + [mkfs.ext4]) to create an ext4 filesystem on the decrypted + container:]) + + (pre (code [sudo mkfs.ext4 /dev/mapper/secret-device])) + + (p [Now the filesystem can be mounted like a filesystem on a regular + block device.]) + + (pre (code [mkdir ~/my-mount-point +sudo mount /dev/mapper/secret-device ~/my-mount-point])) + + (p [The first command creates a new mount point (an empty directory) + named “my-mount-point” in your home directory. The second + command mounts the decrypted device at this location.]) + + (p [You can now write to the directory as usual. Once you are done + follow these steps to unmount the device and close (= re-encrypt) + the container:]) + + (pre (code [sudo umount ~/my-mount-point +sudo cryptsetup luksClose secret-device])) + + (p [To access the container again only these two commands are + required:]) + + (pre (code [sudo cryptsetup luksOpen ~/mycontainer secret-device +sudo mount /dev/mapper/secret-device ~/my-mount-point])) + + `(div (@ (class "footnotes")) + (ol + (li (@ (id "fn1")) + ,(p [You could use ,(code [/dev/random]) as the input device if + you wanted to, but that would be considerably slower and + wouldn’t help you much. Later commands will initialise + the file/partition, so you don’t need to initialise it + manually with random numbers.]))))) diff --git a/posts/2013-10-31-wavedrum-data-comparison.markdown b/posts/2013-10-31-wavedrum-data-comparison.markdown deleted file mode 100644 index 6c6320c..0000000 --- a/posts/2013-10-31-wavedrum-data-comparison.markdown +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Firmware comparison between Wavedrums Original, Black and Oriental -tags: DIY,electronics,music,hacking,wavedrum ---- - -Since -[my first post on hacking the Wavedrum](/posts/2013-08-11-hacking-the-wavedrum.html) -two fellow musicians have sent me copies of the contents of their -Wavedrum instruments, so I now have the data for the original silver -issue, the black re-issue and the Oriental. - -The differences between the data from the silver and the data from the -black Wavedrum are very few. Of the files sent to me only five -differ: `USER.BIN`, `CALIB.BIN`, `WD2_PROG.BIN`, `SYSTEM/VERSION.INF`, -and `SYSTEM/WDX_M100.BIN`. `USER.BIN` contains only the mapping of -programmes to slots and banks, which have been altered by the -respective owners of the two instruments, so it can safely be ignored. -Likewise, `WD2_PROG.BIN` contains custom user programmes and hence is -of no interest. - -`CALIB.BIN` contains as of yet unknown calibration information, just -like the similarly named `CALIB.BOR` on my Wavedrum Oriental. The -contents of `CALIB.BIN` from the original Wavedrum are identical to -those of the matching file on the Oriental. The only difference -that the Black has over the other two is a single digit. This is from -the Oriental: - - 01 00 00 75 00 00 00 00 02 00 00 00 00 00 00 00 - -And this is from the Black: - - 01 00 00 75 00 00 00 00 01 00 00 00 00 00 00 00 - -Not very exciting. - -`SYSTEM/VERSION.INF` contains the hardware/software versions. Here -are the contents of the Original, followed by the Black and the -Oriental: - - 01 20 01 10 01 20 00 00 00 00 00 00 00 00 00 00 - 01 32 01 10 01 32 00 00 57 44 58 5F 00 00 00 00 - 02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00 - -Again, these are in decimal notation and are in this format: firmware -version (two bytes), sub-version (two bytes), data version -(two-bytes), two empty bytes, four bytes for an optional identifier -followed by four empty bytes. - -|Type | Firmware version | Sub-version | Data version | Identifier | -|--------:|------------------|--------------|----------------|--------------| -|Original | 1.20 | 1.10 | 1.20 | none | -|Black | 1.32 | 1.10 | 1.32 | WDX_ | -|Oriental | 2.02 | 1.10 | 2.02 | WDOR | - -Looking at the version numbers above it becomes apparent that the -sounds themselves are not covered by these numbers as the sounds on -the Black are no different from those on the Original, yet the data -version differs. - -The file `SYSTEM/WDX_M100.BIN` must be the firmware on both the -Original and the Black Wavedrum, serving the same purpose as -`SYSTEM/WDORM202.BIN` on the Oriental. There are quite a few changes -even between version 1.20 and 1.32, but I haven't yet taken the time -to analyse them. It is interesting to note, though, that every -firmware file is /exactly/ one megabyte long, independent of the -Wavedrum type. This is due to padding which in the Original firmware -begins at offset 0xC967C, in the Black firmware at offset 0xC9C68, and -in the Oriental firmware at offset 0xDCB64 - -More to follow. - -Read [more posts about the Wavedrum here](http://elephly.net/tags/wavedrum.html). diff --git a/posts/2013-10-31-wavedrum-data-comparison.skr b/posts/2013-10-31-wavedrum-data-comparison.skr new file mode 100644 index 0000000..911777b --- /dev/null +++ b/posts/2013-10-31-wavedrum-data-comparison.skr @@ -0,0 +1,82 @@ +(define meta + `((title . "Firmware comparison between Wavedrums Original, Black and Oriental") + (date . ,(string->date* "2013-10-31 00:00")) + (tags "DIY" "electronics" "music" "hacking" "wavedrum"))) + +(define (row first . rest) + `(tr (td (@ (align "right")) ,first) + ,@(map (lambda (field) `(td (@ (align "left")) ,field)) rest))) + +(list + + (p [Since ,(ref "/posts/2013-08-11-hacking-the-wavedrum.html" "my + first post on hacking the Wavedrum") two fellow musicians have + sent me copies of the contents of their Wavedrum instruments, so + I now have the data for the original silver issue, the black + re-issue and the Oriental.]) + + (p [The differences between the data from the silver and the data + from the black Wavedrum are very few. Of the files sent to me + only five differ: ,(code [USER.BIN]), ,(code [CALIB.BIN]), ,(code + [WD2_PROG.BIN]), ,(code [SYSTEM/VERSION.INF]), and ,(code + [SYSTEM/WDX_M100.BIN]). ,(code [USER.BIN]) contains only the + mapping of programmes to slots and banks, which have been altered + by the respective owners of the two instruments, so it can safely + be ignored. Likewise, ,(code [WD2_PROG.BIN]) contains custom + user programmes and hence is of no interest.]) + + (p [,(code [CALIB.BIN]) contains as of yet unknown calibration + information, just like the similarly named ,(code [CALIB.BOR]) on + my Wavedrum Oriental. The contents of ,(code [CALIB.BIN]) from + the original Wavedrum are identical to those of the matching file + on the Oriental. The only difference that the Black has over the + other two is a single digit. This is from the Oriental:]) + + (pre (code [01 00 00 75 00 00 00 00 02 00 00 00 00 00 00 00])) + + (p [And this is from the Black:]) + + (pre (code [01 00 00 75 00 00 00 00 01 00 00 00 00 00 00 00])) + + (p [Not very exciting.]) + + (p [,(code [SYSTEM/VERSION.INF]) contains the hardware/software + versions. Here are the contents of the Original, followed by the + Black and the Oriental:]) + + (pre (code [01 20 01 10 01 20 00 00 00 00 00 00 00 00 00 00 +01 32 01 10 01 32 00 00 57 44 58 5F 00 00 00 00 +02 02 01 10 02 02 00 00 57 44 4f 52 00 00 00 00])) + + (p [Again, these are in decimal notation and are in this format: + firmware version (two bytes), sub-version (two bytes), data + version (two-bytes), two empty bytes, four bytes for an optional + identifier followed by four empty bytes.]) + + (table :align '("right") + :headers '("Type" "Firmware" "Sub-version" "Data version" "Identifier") + :rows + '(("Original" "1.20" "1.10" "1.20" "none") + ("Black" "1.32" "1.10" "1.32" "WDX_") + ("Oriental" "2.02" "1.10" "2.02" "WDOR"))) + + (p [Looking at the version numbers above it becomes apparent that the + sounds themselves are not covered by these numbers as the sounds + on the Black are no different from those on the Original, yet the + data version differs.]) + + (p [The file ,(code [SYSTEM/WDX_M100.BIN]) must be the firmware on + both the Original and the Black Wavedrum, serving the same + purpose as ,(code [SYSTEM/WDORM202.BIN]) on the Oriental. There + are quite a few changes even between version 1.20 and 1.32, but I + haven’t yet taken the time to analyse them. It is interesting to + note, though, that every firmware file is ,(em [exactly]) one + megabyte long, independent of the Wavedrum type. This is due to + padding which in the Original firmware begins at offset 0xC967C, + in the Black firmware at offset 0xC9C68, and in the Oriental + firmware at offset 0xDCB64.]) + + (p [More to follow.]) + + (p [Read ,(ref "/tags/wavedrum.html" "more posts about the Wavedrum + here").])) diff --git a/posts/2013-12-09-wavedrum-connectors.markdown b/posts/2013-12-09-wavedrum-connectors.markdown deleted file mode 100644 index ab03368..0000000 --- a/posts/2013-12-09-wavedrum-connectors.markdown +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: Connectors on the Wavedrum's circuit board -tags: DIY,electronics,music,hacking,wavedrum ---- - -On the circuit board of the Wavedrum there are solder holes to -accomodate three large connectors. Since they are so easily -accessible and thus very inviting to anyone interested in modifying -the instrument, I decided to trace each of the pins to its -destination. - -The three connectors are named CN10, CN11, and CN12, respectively. -CN10 is found on the bottom right, CN11 on the bottom left, and CN12 -close to the left edge below the micro SD card reader. - -<img class="full stretch" src="/images/posts/2013/wavedrum-connectors.jpg" alt="connectors on the mainboard" /> - -# CN10: digital audio interface - -Most of the ten pins of CN10 are outputs. The first three pins carry -clock signals used by the analogue to digital and digital to analogue -converters on the top-side of the board. Pin four gives access to the -PDN (power down) signal which is used to disable the converters. The -next three pins are connected over the resistors R85, R84, and R83 to -the DSP's pins 145, 144, and 143 (respectively); according to the -[DSP's datasheet](http://www.analog.com/static/imported-files/data_sheets/ADSP-21371_21375.pdf) -these pins are `DAI_P8` (`SFSI`), `DAI_P10` (`SD2B`), and `DAI_P11` -(`SD3A`), and are thus part of the Digital Audio Interface (DAI). The -remaining three pins on CN10 expose the supply voltage, ground, and an -alternative positive voltage (the same as on the plus pole of the -silver capacitors near the right edge of the board). These are the -signals left to right: - - . | direction | description ----|-----------|----------------- - 1 | output | Master clock - 2 | output | Audio serial clock - 3 | output | Left/right clock - 4 | output | `PDN` (power down) - 5 | input? | `DAI_P8` / `SFSI` - 6 | input? | `DAI_P10` / `SD2B` - 7 | input? | `DAI_P11` / `SD3A` - 8 | output | V_A, or V_DD - 9 | output | GND -10 | output | alternative positive voltage - -What is this all good for? Well, since all these clocks and voltages -are exported it becomes relatively easy to connect an external digital -to analogue converter (when `DAI_P8`, `DAI_P10`, and `DAI_P11` are -used as outputs), or an external analogue to digital converter (if the -DSP pins are used as inputs instead). As there are protective -resistors between the DSP pins and the connector pins 5--7 I assume -that they are supposed to be used as inputs. - - -# CN11: JTAG interface - -Moving on to the left bottom edge of the board we see a 14-pin -connector with the name CN11. This connector gives access to the JTAG -interface on the DSP, which allows system debugging. Unfortunately, I -don't own a JTAG dongle and the free JTAG debugger -[OpenOCD](http://openocd.sourceforge.net) does not support the SHARC -core, so I haven't been able to experiment with the debugging -interface. I'm not sure whether it is possible to use debugging -feature without hardware/software provided by Analog Devices. Using -JTAG it should be possible to overwrite the flash memory and replace -the firmware. This is the most promising method to upgrade (or -downgrade) a Wavedrum. - -The pins on the bottom row are all connected to ground, so the -following table only lists the signal names of the upper row of the -connector in order from left to right: - - -. | Signal | Full name ---+---------+------------------------ -1 | `~EMU` | Emulation status -2 | `GND` | Ground -3 | `TMS` | Test mode select -4 | `TCK` | Test clock -5 | `~TRST` | Test reset -6 | `TDI` | Test data input -7 | `TDO` | Test data output - - - -# CN12: two-wire serial interface - -CN12 exposes the DSP's two-wire interface, a serial interface -compatible with the proprietary I^2C interface. This allows us to -connect a number of external serial devices to the serial bus. As -firmware support is required to communicate with the devices on the -serial bus I don't see how this could be used without a custom -firmware. - -The following table lists the signals from top to bottom: - -. | Signal | Full name ---+------------+------------------------ -1 | `V_D` | Positive voltage -2 | `TWI_DATA` | Two-wire interface data -3 | `TWI_CLK` | Two-wire interface clock -4 | `GND` | Ground - - -# Bonus: boot mode - -What led me to tracing the routes of the connectors was my curiosity -about the boot mode. According to the DSP's datasheet, there are four -possible boot modes to select from by playing with the states of the -pins `BOOT_CFG1-0` (one of these boot modes is "no boot"). Tracing -these two pins from the DSP it becomes clear that the third boot mode -"EPROM/FLASH boot" is hardwired (`BOOT_CFG1-0 = 10`). The other two -usable boot modes are SPI master and slave boots. - -BOOT_CFG1-0 | Booting Mode --------------+-------------------- -00 | SPI Slave Boot -01 | SPI Master Boot -10 | EPROM/Flash Boot -11 | No boot - -<img class="full stretch" src="/images/posts/2013/wavedrum-bootcfg.jpg" alt="boot configuration traces" /> - -As can be seen on the photo, the Wavedrum engineers were kind enough -to leave solder pads connected to boot configuration pins on the -board, allowing us to rewire them as we see fit. To set `BOOT_CFG0` -the pads for `R72` have to be bridged; likewise, to clear `BOOT_CFG1` -only the two pads of `R59` have to be bridged. - - -# References - -- [ADSP-21371/ADSP-21375 datasheet](http://www.analog.com/static/imported-files/data_sheets/ADSP-21371_21375.pdf) -- [ADSP hardware reference](http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf) diff --git a/posts/2013-12-09-wavedrum-connectors.skr b/posts/2013-12-09-wavedrum-connectors.skr new file mode 100644 index 0000000..a6382ed --- /dev/null +++ b/posts/2013-12-09-wavedrum-connectors.skr @@ -0,0 +1,149 @@ +(define meta + `((title . "Connectors on the Wavedrum’s circuit board") + (date . ,(string->date* "2013-12-09 00:00")) + (tags "DIY" "electronics" "music" "hacking" "wavedrum"))) + +(list + + (p [On the circuit board of the Wavedrum there are solder holes to + accomodate three large connectors. Since they are so easily + accessible and thus very inviting to anyone interested in + modifying the instrument, I decided to trace each of the pins to + its destination.]) + + (p [The three connectors are named CN10, CN11, and CN12, + respectively. CN10 is found on the bottom right, CN11 on the + bottom left, and CN12 close to the left edge below the micro SD + card reader.]) + + (wide-img "2013/wavedrum-connectors.jpg" + "connectors on the mainboard") + + (h2 [CN10: digital audio interface]) + + (p [Most of the ten pins of CN10 are outputs. The first three pins + carry clock signals used by the analogue to digital and digital + to analogue converters on the top-side of the board. Pin four + gives access to the PDN (power down) signal which is used to + disable the converters. The next three pins are connected over + the resistors R85, R84, and R83 to the DSP's pins 145, 144, and + 143 (respectively); according to the ,(ref + "http://www.analog.com/static/imported-files/data_sheets/ADSP-21371_21375.pdf" + "DSP's datasheet") these pins are ,(code [DAI_P8]) (,(code [SFSI])), ,(code [DAI_P10]) + (,(code [SD2B])), and ,(code [DAI_P11]) (,(code [SD3A])), and are thus part of the + Digital Audio Interface (DAI). The remaining three pins on CN10 + expose the supply voltage, ground, and an alternative positive + voltage (the same as on the plus pole of the silver capacitors + near the right edge of the board). These are the signals left to + right:]) + + (table :align '("right") + :headers '("" "direction" "description") + :rows + '(("1" "output" "Master clock") + ("2" "output" "Audio serial clock") + ("3" "output" "Left/right clock") + ("4" "output" ((code "PDN") " (power down)")) + ("5" "input?" ((code "DAI_P8") " / " (code "SFSI"))) + ("6" "input?" ((code "DAI_P10") " / " (code "SD2B"))) + ("7" "input?" ((code "DAI_P11") " / " (code "SD3A"))) + ("8" "output" ((code "V_A") ", or " (code "V_DD"))) + ("9" "output" "GND") + ("10" "output" "alternative positive voltage"))) + + (p [What is this all good for? Well, since all these clocks and + voltages are exported it becomes relatively easy to connect an + external digital to analogue converter (when ,(code [DAI_P8]), + ,(code [DAI_P10]), and ,(code [DAI_P11]) are used as outputs), or + an external analogue to digital converter (if the DSP pins are + used as inputs instead). nAs there are protective resistors + between the DSP pins and the connector pins 5–7 I assume that + they are supposed to be used as inputs.]) + + + (h2 [CN11: JTAG interface]) + + (p [Moving on to the left bottom edge of the board we see a 14-pin + connector with the name CN11. This connector gives access to the + JTAG interface on the DSP, which allows system debugging. + Unfortunately, I don't own a JTAG dongle and the free JTAG + debugger ,(ref "http://openocd.sourceforge.net" "OpenOCD") does + not support the SHARC core, so I haven't been able to experiment + with the debugging interface. I'm not sure whether it is + possible to use debugging feature without hardware/software + provided by Analog Devices. Using JTAG it should be possible to + overwrite the flash memory and replace the firmware. This is the + most promising method to upgrade (or downgrade) a Wavedrum.]) + + (p [The pins on the bottom row are all connected to ground, so the + following table only lists the signal names of the upper row of + the connector in order from left to right:]) + + (table :align '("right") + :headers '("" "Signal" "Full name") + :rows + '(("1" (code [~EMU]) "Emulation status") + ("2" (code [GND]) "Ground") + ("3" (code [TMS]) "Test mode select") + ("4" (code [TCK]) "Test clock") + ("5" (code [~TRST]) "Test reset") + ("6" (code [TDI]) "Test data input") + ("7" (code [TDO]) "Test data output"))) + + (h2 [CN12: two-wire serial interface]) + + (p [CN12 exposes the DSP's two-wire interface, a serial interface + compatible with the proprietary I^2C interface. This allows us + to connect a number of external serial devices to the serial bus. + As firmware support is required to communicate with the devices + on the serial bus I don't see how this could be used without a + custom firmware.]) + + (p [The following table lists the signals from top to bottom:]) + + (table :align '("right") + :headers '("" "Signal" "Full name") + :rows + '(("1" (code [V_D]) "Positive voltage") + ("2" (code [TWI_DATA]) "Two-wire interface data") + ("3" (code [TWI_CLK]) "Two-wire interface clock") + ("4" (code [GND]) "Ground"))) + + + (h2 [Bonus: boot mode]) + + (p [What led me to tracing the routes of the connectors was my + curiosity about the boot mode. According to the DSP's datasheet, + there are four possible boot modes to select from by playing with + the states of the pins ,(code [BOOT_CFG1-0]) (one of these boot + modes is “no boot”). Tracing these two pins from the DSP it + becomes clear that the third boot mode “EPROM/FLASH boot” is + hardwired (,(code [BOOT_CFG1-0 = 10])). The other two usable + boot modes are SPI master and slave boots.]) + + (table :align '("right") + :headers '("BOOT_CFG1-0" "Booting mode") + :rows + '(("00" "SPI Slave Boot") + ("01" "SPI Master Boot") + ("10" "EPROM/Flash Boot") + ("11" "No boot"))) + + (wide-img "2013/wavedrum-bootcfg.jpg" + "boot configuration traces") + + (p [As can be seen on the photo, the Wavedrum engineers were kind + enough to leave solder pads connected to boot configuration pins + on the board, allowing us to rewire them as we see fit. To set + ,(code [BOOT_CFG0]) the pads for ,(code [R72]) have to be + bridged; likewise, to clear ,(code [BOOT_CFG1]) only the two pads + of ,(code [R59]) have to be bridged.]) + + + (h2 [References]) + + (ul + (li [,(ref "http://www.analog.com/static/imported-files/data_sheets/ADSP-21371_21375.pdf" + "ADSP-21371/ADSP-21375 datasheet")]) + (li [,(ref "http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf" + "ADSP hardware reference")]))) diff --git a/posts/2014-09-18-wavedrum-firmware-disassembler.markdown b/posts/2014-09-18-wavedrum-firmware-disassembler.markdown deleted file mode 100644 index af8d043..0000000 --- a/posts/2014-09-18-wavedrum-firmware-disassembler.markdown +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Disassembling the Wavedrum firmware -tags: DIY,electronics,music,hacking,wavedrum,SHARC ---- - -The Wavedrum's processing unit is an ADSP-21375 by Analog Devices, a -member of the SHARC processor family. The firmware of the Wavedrum, -which is stored on a micro SD-card and, more importantly, on the flash -memory chip is loaded into the processor during the boot process. - -[Last time](2013-12-09-wavedrum-connectors.html) I confirmed by tracing the -connections of the two boot pins that the processor is wired to boot -from EPROM/Flash (`BOOT_CFG1-0 = 10`). I'm too lazy to try to verify -that the firmware on the micro SD-card is identical to the contents of -the flash memory, so I'll just assume that this is the case. - -When the processor is initially powered on, the internal memory is in -an undefined state. According to the -[ADSP hardware reference](http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf) -(section 17-7 *Processor Booting*), the processor core is put into -`IDLE` mode while loading the boot kernel from an external source (in -our case this is the flash memory) into the internal memory at address -0x90000 (`IVT_START_ADDR`), and finally executes the boot kernel code -when a peripheral interrupt signals that the kernel has been loaded. -Then the application code is loaded from the memory and finally the -application's Interrupt Vector Table (IVT) is loaded. The boot kernel -is 256 48-bit words long, as is the IVT. The application code is of -arbitrary length. - - -# Word packing - -The boot kernel is exactly 256 48-bit words long (shorter kernels are -padded with NOPs), but the words are not transferred as 48-bit words. -The boot kernel is transferred from the external memory as a stream of -384 "packed" 32-bit words (see table 17-6 in the hardware reference). -To understand packing we have to know that conceptionally the internal -memory consists of many rows of four columns, each of which is 16 bit -wide. Accessing 48-bit words is often referred to as 3-column access -in the reference, whereas accessing 32-bit words is called 2-column -access. All of the SHARC instructions are 48 bit wide. This means -that any 32-bit wide package never contains the full instruction. -Dependent on the order of the packages, the 48-bit words can be -reconstructed from a stream of 32-bit words. - -Here's the original explanation in the hardware reference on page -17-27: - -> During the boot process, word packing (for example 8 to 32-bit) is -> performed over the SPI. In other words, the kernel is not loaded -> directly with 256 x 48-bit words, instead it is loaded with 384 x -> 32-bit ‘packed words’ (2-column access). The same physical memory -> for instruction boot is loaded via DMA in normal word (NW) 2 -> column. However, after booting the same physical memory region is -> fetched by the sequencer in NW 3-column. For example the loader -> kernel itself has a NW 2 columns count of 256 x 3/2 = 384 words but -> the kernel is executed with 256 instruction fetches. - -When booting from external memory the bus width is set to 8 bits. -According to the -[ADSP hardware reference](http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf) -(section "External Port Booting"), the processor reads a stream of -8-bit words from the data port and packs four of them into 32-bit -words (LSB first) before storing them into the internal memory. - -Figure 17-5 in the hardware reference visualises this process rather -nicely. It shows how streams of different word sizes end up being -stored in the internal memory. - -<img class="full stretch" src="/images/posts/2014/wavedrum-word-packing.png" alt="word packing" /> - -Once I understood that words are transferred from the memory in 8-bit -chuncks with the LSB first, writing a disassembler that would -translate the binary boot kernel into assembly code was no longer very -challenging. - - -# A free disassembler for ADSP-213xx - -I implemented a simple tool in Haskell that takes a binary firmware -and spits out assembly code for the ADSP. At the moment it only -supports a limited set of instructions, just enough so that I could -translate the boot kernel. The remainder of the instructions -will be implemented later as I happen to encounter them in the -application code. - -It currently only parses the first 256 words of the firmware, -i.e. only the boot kernel. Before I can parse the remainder I need to -figure out the memory layout. - -The code is freely available under the -[GPL](http://www.gnu.org/licenses/#GPL) and can be -[downloaded here](http://git.elephly.net/wavedrum/sharc-disassembler.git). -See the included instructions for assistance in compiling and using -the disassembler. - - -# Next steps - -My work isn't over yet. Next I'll focus on the following tasks: - -- figure out how the boot kernel loads the application code into the - processor -- disassemble (parts of) the application code -- look out for snippets that involve loading code from the micro-SD - card to the flash memory, because that's our ticket to upgrade the - firmware easily - -If you want to help me, I'd be happy if you could send me a copy of -the Global Edition's firmware. To do this you only need to take out -the micro SD-card and create a disk image of it. (On GNU/Linux this -can easily be done with `dd` on the command line; see -[my first post on hacking the Wavedrum](http://elephly.net/posts/2013-08-11-hacking-the-wavedrum.html) -for more detailed instructions.) - -I would also be very grateful for code reviews and patches. -Translating the various specifications into executable code wasn't -always easy and I'm sure there are bugs in the code here and there. - -Read [more posts about the Wavedrum here](http://elephly.net/tags/wavedrum.html). diff --git a/posts/2014-09-18-wavedrum-firmware-disassembler.skr b/posts/2014-09-18-wavedrum-firmware-disassembler.skr new file mode 100644 index 0000000..244aecd --- /dev/null +++ b/posts/2014-09-18-wavedrum-firmware-disassembler.skr @@ -0,0 +1,136 @@ +(define meta +`((title . "Disassembling the Wavedrum firmware") + (date . ,(string->date* "2014-09-18 00:00")) + (tags "DIY" "electronics" "music" "hacking" "wavedrum" "SHARC"))) + +(list + + (p [The Wavedrum’s processing unit is an ADSP-21375 by Analog Devices, + a member of the SHARC processor family. The firmware of the + Wavedrum, which is stored on a micro SD-card and, more + importantly, on the flash memory chip is loaded into the processor + during the boot process.]) + + (p [,(ref "2013-12-09-wavedrum-connectors.html" "Last time") I + confirmed by tracing the connections of the two boot pins that the + processor is wired to boot from EPROM/Flash (,(code [BOOT_CFG1-0 = + 10])). I’m too lazy to try to verify that the firmware on the + micro SD-card is identical to the contents of the flash memory, so + I’ll just assume that this is the case.]) + + ;; TODO: link to hardware reference is dead + (p [When the processor is initially powered on, the internal memory is + in an undefined state. According to the ,(ref + "http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf" + "ADSP hardware reference") (section 17-7 ,(em [Processor + Booting])), the processor core is put into ,(code [IDLE]) mode + while loading the boot kernel from an external source (in our case + this is the flash memory) into the internal memory at address + 0x90000 (,(code [IVT_START_ADDR])), and finally executes the boot + kernel code when a peripheral interrupt signals that the kernel + has been loaded. Then the application code is loaded from the + memory and finally the application’s Interrupt Vector Table (IVT) + is loaded. The boot kernel is 256 48-bit words long, as is the + IVT. The application code is of arbitrary length.]) + + + (h2 [Word packing]) + + (p [The boot kernel is exactly 256 48-bit words long (shorter kernels + are padded with NOPs), but the words are not transferred as 48-bit + words. The boot kernel is transferred from the external memory as + a stream of 384 “packed” 32-bit words (see table 17-6 in the + hardware reference). To understand packing we have to know that + conceptionally the internal memory consists of many rows of four + columns, each of which is 16 bit wide. Accessing 48-bit words is + often referred to as 3-column access in the reference, whereas + accessing 32-bit words is called 2-column access. All of the + SHARC instructions are 48 bit wide. This means that any 32-bit + wide package never contains the full instruction. Dependent on + the order of the packages, the 48-bit words can be reconstructed + from a stream of 32-bit words.]) + + (p [Here’s the original explanation in the hardware reference on page + 17-27:]) + + (blockquote (p [During the boot process, word packing (for example 8 + to 32-bit) is performed over the SPI. In other words, + the kernel is not loaded directly with 256 x 48-bit + words, instead it is loaded with 384 x 32-bit ‘packed + words’ (2-column access). The same physical memory for + instruction boot is loaded via DMA in normal word (NW) + 2 column. However, after booting the same physical + memory region is fetched by the sequencer in NW + 3-column. For example the loader kernel itself has a + NW 2 columns count of 256 x 3/2 = 384 words but the + kernel is executed with 256 instruction fetches.])) + + (p [When booting from external memory the bus width is set to 8 bits. + According to the ,(ref + "http://www.analog.com/static/imported-files/processor_manuals/ADSP-21367_hwr_rev2-1.pdf" + "ADSP hardware reference") (section “External Port Booting”), the + processor reads a stream of 8-bit words from the data port and + packs four of them into 32-bit words (LSB first) before storing + them into the internal memory.]) + + (p [Figure 17-5 in the hardware reference visualises this process + rather nicely. It shows how streams of different word sizes end + up being stored in the internal memory.]) + + (wide-img "2014/wavedrum-word-packing.png" "word packing") + + (p [Once I understood that words are transferred from the memory in + 8-bit chuncks with the LSB first, writing a disassembler that + would translate the binary boot kernel into assembly code was no + longer very challenging.]) + + + (h2 [A free disassembler for ADSP-213xx]) + + (p [I implemented a simple tool in Haskell that takes a binary + firmware and spits out assembly code for the ADSP. At the moment + it only supports a limited set of instructions, just enough so + that I could translate the boot kernel. The remainder of the + instructions will be implemented later as I happen to encounter + them in the application code.]) + + (p [It currently only parses the first 256 words of the firmware, + i.e. only the boot kernel. Before I can parse the remainder I + need to figure out the memory layout.]) + + (p [The code is freely available under the ,(ref + "http://www.gnu.org/licenses/#GPL" "GPL") and can be ,(ref + "http://git.elephly.net/wavedrum/sharc-disassembler.git" + "downloaded here"). See the included instructions for assistance + in compiling and using the disassembler.]) + + + (h2 [Next steps]) + + (p [My work isn’t over yet. Next I’ll focus on the following tasks:]) + + (ul + (li [figure out how the boot kernel loads the application code into + the processor]) + (li [disassemble (parts of) the application code]) + (li [look out for snippets that involve loading code from the + micro-SD card to the flash memory, because that’s our ticket to + upgrade the firmware easily])) + + (p [If you want to help me, I’d be happy if you could send me a copy + of the Global Edition’s firmware. To do this you only need to + take out the micro SD-card and create a disk image of it. (On + GNU/Linux this can easily be done with ,(code [dd]) on the command + line; see ,(ref + "/posts/2013-08-11-hacking-the-wavedrum.html" + "my first post on hacking the Wavedrum") for more detailed + instructions.)]) + + (p [I would also be very grateful for code reviews and patches. + Translating the various specifications into executable code wasn’t + always easy and I’m sure there are bugs in the code here and + there.]) + + (p [Read ,(ref "/tags/wavedrum.html" "more posts + about the Wavedrum here").])) + diff --git a/posts/2014-11-23-upgrading-trulyergonomic-firmware.markdown b/posts/2014-11-23-upgrading-trulyergonomic-firmware.markdown deleted file mode 100644 index 25f470c..0000000 --- a/posts/2014-11-23-upgrading-trulyergonomic-firmware.markdown +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Upgrading the TEK's firmware on GNU/Linux -date: 2014/11/23 -tags: keyboard, virtualbox ---- - -I'm using the Truly Ergonomic Keyboard (model 209) for most of my -typing, because it's a pretty comfortable keyboard (when it works). -One of the greatest features of this keyboard is that the layout can -be customised and flashed to the hardware with a firmware upgrade. -Unfortunately, the application used to flash the firmware is only -available for Microsoft Windows. - -As a GNU/Linux user I find this to be very inconvenient. I simply -don't have access to a machine running Microsoft Windows (not even at -the office). Luckily, Microsoft provides -[free virtual machine images](http://modern.ie) of various versions of -their operating system for browser evaluation purposes. I -occasionally use them to verify that a web page works all right in the -proprietary and often quirky Microsoft browsers. Although these -images could be used in KVM, converting and tweaking them takes a -little too long and is a bit annoying. For the quickest results these -images should be imported with Virtual Box instead. - -Truly Ergonomic recommends not to use virtualisation software to -update the firmware of the keyboard, but as I was out of other options -I decided to give it a try anyway. You probably should not be doing -this if you don't feel you would be able to perform a -[manual reset](https://www.trulyergonomic.com/store/troubleshooting--truly-ergonomic-mechanical-keyboard#Reset) -of the controller in case something goes wrong. - -## Preparation - -- a recent version of Virtual Box -- a virtual machine image of Microsoft Windows -- a user account that is a member of the group *vboxusers*; required - to access any host USB devices from within a Virtual Box machine. - If you have just added your account to this group, remember that you - need to log off and on again before the changes come into effect. -- enable USB 2.0 support, provided by the *Oracle VM VirtualBox - Extension Pack*. The extension pack has to be installed through the - preferences menu in the VirtualBox client. Note that you may have - to run the client as root to have sufficient permissions to install - the extension pack. -- a USB device filter configured to pass host USB devices through to - the virtual machine - -If everything is set up properly you should be able to forward USB -devices from the host system to the virtual machine. Try setting up a -USB device filter in the USB settings menu of the virtual machine. -You should be able to create a filter for the Truly Ergonomic Keyboard -right there. If you cannot see a list of USB devices at all at this -point check that your user account is a member of the group -*vboxusers*. - - -## Performing the upgrade - -Inside the Windows machine start the official firmware upgrade tool, -load the firmware you want to flash to the keyboard, and click on -*Upgrade*. This will result in an error message, but that's okay: -don't panic! The reason why this error occurs is that the USB -identifier of the keyboard will have changed from something like this: - - ID 0e6a:030c Megawin Technology Co., Ltd Truly Ergonomic Computer Keyboard - -to something like this: - - ID 0e6a:030b Megawin Technology Co., Ltd Truly Ergonomic Computer Keyboard (Device Firmware Update mode) - -Since the USB identifier has changed, VirtualBox may no longer forward -this device from the host to the virtual machine guest system. All -you have to do is add a filter for this new USB device in the guest -settings and resume the upgrade by clicking on *Upgrade* again. This -will again lead to another error, but I found that by that time the -upgrade has already been performed successfully. - -Note that while the USB device is being forwarded to the guest system -you cannot use it in the host. To test if the new firmware works as -expected in your system, disable the USB filters in the guest -settings. - - -## Next steps - -It should also be possible to flash the firmware directly from a -GNU/Linux system. I suppose one could sniff the USB communication and -build a little tool that performs the upgrade natively on GNU/Linux. diff --git a/posts/2014-11-23-upgrading-trulyergonomic-firmware.skr b/posts/2014-11-23-upgrading-trulyergonomic-firmware.skr new file mode 100644 index 0000000..b0b8ce3 --- /dev/null +++ b/posts/2014-11-23-upgrading-trulyergonomic-firmware.skr @@ -0,0 +1,99 @@ +(define meta +`((title . "Upgrading the TEK’s firmware on GNU/Linux") + (date . ,(string->date* "2014-11-23 00:00")) + (tags "keyboard" "virtualbox"))) + +(list + + (p [I’m using the Truly Ergonomic Keyboard (model 209) for most of my + typing, because it’s a pretty comfortable keyboard (when it + works). One of the greatest features of this keyboard is that the + layout can be customised and flashed to the hardware with a + firmware upgrade. Unfortunately, the application used to flash + the firmware is only available for Microsoft Windows.]) + + (p [As a GNU/Linux user I find this to be very inconvenient. I + simply don’t have access to a machine running Microsoft Windows + (not even at the office). Luckily, Microsoft provides ,(ref + "http://modern.ie" "free virtual machine images") of various + versions of their operating system for browser evaluation + purposes. I occasionally use them to verify that a web page + works all right in the proprietary and often quirky Microsoft + browsers. Although these images could be used in KVM, converting + and tweaking them takes a little too long and is a bit annoying. + For the quickest results these images should be imported with + Virtual Box instead.]) + + (p [Truly Ergonomic recommends not to use virtualisation software to + update the firmware of the keyboard, but as I was out of other + options I decided to give it a try anyway. You probably should + not be doing this if you don’t feel you would be able to perform a + ,(ref + "https://www.trulyergonomic.com/store/troubleshooting--truly-ergonomic-mechanical-keyboard#Reset" + "manual reset") of the controller in case something goes wrong.]) + + (h2 [Preparation]) + + (ul + (li [a recent version of Virtual Box]) + (li [a virtual machine image of Microsoft Windows]) + + (li [a user account that is a member of the group ,(code + [vboxusers]); required to access any host USB devices from + within a Virtual Box machine. If you have just added your + account to this group, remember that you need to log off and on + again before the changes come into effect.]) + + (li [enable USB 2.0 support, provided by the ,(em [Oracle VM + VirtualBox Extension Pack]). The extension pack has to be + installed through the preferences menu in the VirtualBox client. + Note that you may have to run the client as root to have + sufficient permissions to install the extension pack.]) + + (li [a USB device filter configured to pass host USB devices through + to the virtual machine])) + + (p [If everything is set up properly you should be able to forward USB + devices from the host system to the virtual machine. Try setting + up a USB device filter in the USB settings menu of the virtual + machine. You should be able to create a filter for the Truly + Ergonomic Keyboard right there. If you cannot see a list of USB + devices at all at this point check that your user account is a + member of the group ,(code [vboxusers]).]) + + + (h2 [Performing the upgrade]) + + (p [Inside the Windows machine start the official firmware upgrade + tool, load the firmware you want to flash to the keyboard, and + click on ,(em [Upgrade]). This will result in an error message, + but that’s okay: don’t panic! The reason why this error occurs is + that the USB identifier of the keyboard will have changed from + something like this:]) + + (pre (code [ID 0e6a:030c Megawin Technology Co., Ltd Truly Ergonomic Computer Keyboard])) + + (p [to something like this:]) + + (pre (code [ID 0e6a:030b Megawin Technology Co., Ltd Truly Ergonomic Computer Keyboard (Device Firmware Update mode)])) + + (p [Since the USB identifier has changed, VirtualBox may no longer + forward this device from the host to the virtual machine guest + system. All you have to do is add a filter for this new USB + device in the guest settings and resume the upgrade by clicking on + ,(em [Upgrade]) again. This will again lead to another error, but + I found that by that time the upgrade has already been performed + successfully.]) + + (p [Note that while the USB device is being forwarded to the guest + system you cannot use it in the host. To test if the new firmware + works as expected in your system, disable the USB filters in the + guest settings.]) + + + (h2 [Next steps]) + + (p [It should also be possible to flash the firmware directly from a + GNU/Linux system. I suppose one could sniff the USB communication + and build a little tool that performs the upgrade natively on + GNU/Linux.])) diff --git a/posts/2015-04-17-gnu-guix.markdown b/posts/2015-04-17-gnu-guix.markdown deleted file mode 100644 index d17d514..0000000 --- a/posts/2015-04-17-gnu-guix.markdown +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: GNU Guix in an HPC environment -date: 2015/04/17 -tags: free software, bioinformatics, system administration, packaging, cluster ---- - -I spend my daytime hours as a system administrator at a research -institute in a heterogeneous computing environment. We have two big -compute clusters (one on CentOS the other on Ubuntu) with about 100 -nodes each and dozens of custom GNU/Linux workstations. A common task -for me is to ensure the users can run their bioinformatics software, -both on their workstation and on the clusters. Only few -bioinformatics tools and libraries are popular enough to have been -packaged for CentOS or Ubuntu, so usually some work has to be done to -build the applications and all of their dependencies for the target -platforms. - -## How to waste time building and deploying software - -In theory compiling software is not a very difficult thing to do. -Once all development headers have been installed on the build host, -compilation is usually a matter of configuring the build with a -configure script and running GNU make with various flags (this is an -assumption which is violated by bioinformatics software on a regular -basis, but let's not get into this now). However, there are practical -problems that become painfully obvious in a shared environment with a -large number of users. - -### Naive compilation - -Compiling software directly on the target machine is an option only in -the most trivial cases. With more complicated build systems or -complicated build-time dependencies there is a strong incentive for -system administrators to do the hard work of setting up a suitable -build environment for a particular piece of software only once. Most -people would agree that package management is a great step up from -naive compilation, as the build steps are formalised in some sort of -recipe that can be executed by build tools in a reproducible manner. -Updates to software only require tweaks to these recipes. Package -management is a good thing. - -### System-dependence - -Non-trivial software that was built and dynamically linked on one -machine with a particular set of libraries and header files at -particular versions can only really work on a system with the very -same libraries at compatible versions in place. Established package -managers allow packagers to specify hard dependencies and version -ranges, but the binaries that are produced on the build host will only -work under the constraints imposed on them at build time. To support -an environment in which software must run on, say, both CentOS 6.5 and -CentOS 7.1, the packages must be built in both environments and -binaries for both targets have to be provided. - -There are ways to emulate a different build environment (e.g. Fedora's -`mockbuild`), but we cannot get around the fact that dynamically -linked software built for one kind of system will only ever work on -that very kind of system. At runtime we can change what libraries -will be dynamically loaded, but this is a hack that pushes the problem -from package maintainers to users. Running software with -`LD_LIBRARY_PATH` set is not a solution, nor is static linking, the -equivalent to copying chunks of libraries at build time. - -### Version conflicts - -Libraries and applications that come pre-installed or pre-packaged -with the system may not be the versions a user claims to need. Say, a -user wants the latest version of GCC to compile code using new -language features specified in C++11 (e.g. anonymous functions). Full -support for C++11 arrived in GCC 4.8.1, yet on CentOS 6.5 only version -4.4.7 is available through the repositories. The system administrator -may not necessarily be able to upgrade GCC system-wide. Or maybe -other users on a shared system do need version 4.4.7 to be available -(e.g. for bug-compatibility). There is no easy way to satisfy all -users, so a system administrator might give up and let users build -their own software in their home directories instead of solving the -problem. - -However, compiling GCC is a daunting task for a user and they really -shouldn't have to do this at all. We already established that package -management is a good thing; why should we deny users the benefits of -package management? Traditional package management techniques are -ill-suited to the task of installing multiple versions of applications -or libraries into independent prefixes. RPM, for example, allows -users to maintain a local, independent package database, but `yum` -won't work with multiple package databases. Additionally, only *one* -package database can be used at once, so a user would have to -re-install system libraries into the local package database to satisfy -dependencies. As a result, users lose the important feature of -automatic dependency resolution. - -### Interoperability - -A system administrator who decides to package software as relocatable -RPMs, to install the applications to custom prefixes and to maintain a -separate repository has nothing to show for when a user asks to have -the packaged software installed on an Ubuntu workstation. There are -ways to convert RPMs to DEB packages (with varying degrees of -success), but it seems silly to have to convert or rebuild stuff -repeatedly when the software, its dependencies and its mode of -deployment really didn't change at all. - -What happens when a Slackware user comes along next? Or someone using -Arch Linux? Sure, as a system administrator you could refuse to -support any system other than CentOS 7.1, users be damned. -Traditionally, it seems that system administrators default to this -style for convenience and/or practical reasons, but I consider this -unhelpful and even somewhat oppressive. - - -## Functional package management with GNU Guix - -Luckily I'm not the only person to consider traditional packaging -methods inadequate for a number of valid purposes. There are -different projects aiming to improve and simplify software deployment -and management, one of which I will focus on in this article. As a -functional programmer, Scheme aficionado and free software enthusiast -I was intrigued to learn about -[GNU Guix](https://www.gnu.org/software/guix/), a functional package -manager written in -[Guile Scheme](https://www.gnu.org/software/guile/), the designated -extension language for the [GNU system](https://www.gnu.org/). - -In purely functional programming languages a function will produce the -very same output when called repeatedly with the same input values. -This allows for interesting optimisation, but most importantly it -makes it *possible* and in some cases even *easy* to reason about the -behaviour of a function. It is independent from global state, has no -side effects, and its outputs can be cached as they are certain not to -change as long as the inputs stay the same. - -Functional package management lifts this concept to the realm of -software building and deployment. Global state in a system equates to -system-wide installations of software, libraries and development -headers. Side effects are changes to the global environment or global -system paths such as `/usr/bin/`. To reject global state means to -reject the common file system hierarchy for software deployment and to -use a minimal `chroot` for building software. The introduction of the -Guix manual describes the approach as follows: - -> The term "functional" refers to a specific package management -> discipline. In Guix, the package build and installation process is -> seen as a function, in the mathematical sense. That function takes -> inputs, such as build scripts, a compiler, and libraries, and -> returns an installed package. As a pure function, its result -> depends solely on its inputs—for instance, it cannot refer to -> software or scripts that were not explicitly passed as inputs. A -> build function always produces the same result when passed a given -> set of inputs. It cannot alter the system’s environment in any way; -> for instance, it cannot create, modify, or delete files outside of -> its build and installation directories. This is achieved by running -> build processes in isolated environments (or "containers"), where -> only their explicit inputs are visible. - -> The result of package build functions is "cached" in the file -> system, in a special directory called "the store". Each package is -> installed in a directory of its own, in the store—by default under -> ‘/gnu/store’. The directory name contains a hash of all the inputs -> used to build that package; thus, changing an input yields a -> different directory name. - -The following diagram (taken from the -[slides for a talk by Ludovic Courtès](https://www.gnu.org/software/guix/guix-fosdem-20150131.pdf)) -illustrates how the build daemon handles the package build processes -requested by a client via remote procedure calls: - -<img class="full stretch" src="/images/posts/2015/guix-build.png" alt="Software is built by the Guix daemon in isolttion" /> - -### Isolated, yet shared - -Note that the package outputs are still dynamically linked. Libraries -are referenced in the binaries with their full store paths using the -runpath feature. These package outputs are no self-contained, -monolithic application directories as you might know them from MacOS. - -Any built software is cached in the store which is shared by all users -system-wide. However, by default the software in the store has no -effect whatsoever on the users' environments. Building software and -have the results stored in `/gnu/store` does not alter any global -state; no files pollute `/usr/bin/` or `/usr/lib/`. Any effects are -restricted to the package's single output directory inside the -`/gnu/store`. - -Guix provides per-user profiles to map software from the store into a -user environment. The store provides deduplication as it serves as a -cache for packages that have already been built. A profile is little -more than a "forest" of symbolic links to items in the store. The -union of links to the outputs of all software packages the user -requested makes up the user's profile. By adding another layer of -symbolic link indirection, Guix allows users to seamlessly switch -among different generations of the same profile, going back in time. - -Each user profile is completely isolated from one another, making it -possible for different users to have different versions of GCC -installed. Even one and the same user could have multiple profiles -with different versions of GCC and switch between them as needed. - -Guix takes the functional packaging method seriously, so except for -the running kernel and the exposed machine hardware there are -virtually no dependencies on global state (i.e. system libraries or -headers). This also means that the Guix store is populated with the -complete dependency tree, down to the kernel headers and the C -library. As a result, software in the Guix store can run on very -different GNU/Linux distributions; a shared Guix store allows me to -use the very same software on my Fedora workstation, as well as on the -Ubuntu cluster, and on the CentOS 6.5 cluster. - -This means that software only has to be packaged up once. Since -package recipes are written in a very declarative domain-specific -language on top of Scheme, packaging is surprisingly simple (and to -this Schemer is rather enjoyable). - -### User freedom - -Guix liberates users from the software deployment decisions of their -system administrators by giving them the power to build software into -an isolated directory in the store using simple package recipes. -Administrators only need to configure and run the Guix daemon, the -core piece running as root. The daemon listens to requests issued by -the Guix command line tool, which can be run by users without root -permissions. The command line tool allows users to manage their -profiles, switch generations, build and install software through the -Guix daemon. The daemon takes care of the store, of evaluating the -build expressions and "caching" build results, and it updates the -forest of symbolic links to update profile state. - -Users are finally free to conveniently manage their own software, -something they could previously only do in a crude manner by compiling -manually. - - -## Using a shared Guix store - -Guix is not designed to be run in a centralised manner. A Guix daemon -is supposed to run on each system as root and it listens to RPCs from -local users only. In an environment with multiple clusters and -multiple workstations this approach requires considerable effort to -make it work correctly and securely. - -<img class="full stretch" src="/images/posts/2015/guix-shared.svg" alt="Sharing Guix store and profiles" /> - -Instead we opted to run the Guix daemon on a single dedicated server, -writing profile data and store items onto an NFS share. The cluster -nodes and workstations mount this share read-only. Although this -means that users lose the ability to manage their profiles directly on -their workstations and on the cluster nodes (because they have no -local installation of the Guix client or the Guix daemon, and because -they lack write access to the shared store), their software profiles -are now available wherever they are. To manage their profiles, users -would log on to the Guix server where they can install software into -their profiles, roll back to previous versions or send other queries -to the Guix daemon. (At some point I think it would make sense to -enhance Guix such that RPCs can be made over SSH, so that explicit -logging on to a management machine is no longer necessary.) - - -## Guix as a platform for scientific software - -Since winter 2014 I have been packaging software for GNU Guix, which -meanwhile has accumulated quite a few common and obscure -[bioinformatics tools and libraries](http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/bioinformatics.scm). -A list of software (updated daily) available through Guix is -[available here](https://www.gnu.org/software/guix/package-list.html). -We also have common Python modules for scientific computing, as well -as programming languages such as R and Julia. - -I think GNU Guix is a great platform for scientific software in -heterogeneous computing environments. The Guix project follows the -[Free System Distribution Guidelines](https://gnu.org/distros/free-system-distribution-guidelines.html), -which mean that free software is welcome upstream. For software that -imposes additional usage or distribution restrictions (such as when -the original Artistic license is used instead of the Clarified -Artistic license, or when commercial use is prohibited by the license) -Guix allows the use of out-of-tree package modules through the -`GUIX_PACKAGE_PATH` variable. As Guix packages are just Scheme -variables in Scheme modules, it is trivial to extend the official GNU -Guix distribution with package modules by simply setting the -`GUIX_PACKAGE_PATH`. - -If you want to learn more about GNU Guix I recommend taking a look at -the excellent -[GNU Guix project page](https://www.gnu.org/software/guix/). Feel -free to contact me if you want to learn more about packaging -scientific software for Guix. It is not difficult and we all can -benefit from joining efforts in adopting this usable, dependable, -hackable, and liberating platform for scientific computing with free -software. - -The Guix community is very friendly, supportive, responsive and -welcoming. I encourage you to visit the project's -[IRC channel #guix on Freenode](https://webchat.freenode.net?channels=#guix), -where I go by the handle "rekado". diff --git a/posts/2015-04-17-gnu-guix.skr b/posts/2015-04-17-gnu-guix.skr new file mode 100644 index 0000000..f7e2400 --- /dev/null +++ b/posts/2015-04-17-gnu-guix.skr @@ -0,0 +1,315 @@ +(define meta + `((title . "GNU Guix in an HPC environment") + (date . ,(string->date* "2015-04-17 00:00")) + (tags "gnu" "free software" "guix" "bioinformatics" "system administration" "packaging" "cluster"))) + +(list + (p [I spend my daytime hours as a system administrator at a research + institute in a heterogeneous computing environment. We have two + big compute clusters (one on CentOS the other on Ubuntu) with + about 100 nodes each and dozens of custom GNU/Linux workstations. + A common task for me is to ensure the users can run their + bioinformatics software, both on their workstation and on the + clusters. Only few bioinformatics tools and libraries are + popular enough to have been packaged for CentOS or Ubuntu, so + usually some work has to be done to build the applications and + all of their dependencies for the target platforms.]) + + (h2 [How to waste time building and deploying software]) + + (p [In theory, compiling software is not a very difficult thing to + do. Once all development headers have been installed on the + build host, compilation is usually a matter of configuring the + build with a configure script and running GNU make with various + flags (this is an assumption which is violated by bioinformatics + software on a regular basis, but let’s not get into this now). + However, there are practical problems that become painfully + obvious in a shared environment with a large number of users.]) + + (h3 [Naive compilation]) + + (p [Compiling software directly on the target machine is an option + only in the most trivial cases. With more complicated build + systems or complicated build-time dependencies there is a strong + incentive for system administrators to do the hard work of + setting up a suitable build environment for a particular piece of + software only once. Most people would agree that package + management is a great step up from naive compilation, as the + build steps are formalised in some sort of recipe that can be + executed by build tools in a reproducible manner. Updates to + software only require tweaks to these recipes. Package + management is a good thing.]) + + (h3 [System-dependence]) + + (p [Non-trivial software that was built and dynamically linked on one + machine with a particular set of libraries and header files at + particular versions can only really work on a system with the + very same libraries at compatible versions in place. Established + package managers allow packagers to specify hard dependencies and + version ranges, but the binaries that are produced on the build + host will only work under the constraints imposed on them at + build time. To support an environment in which software must run + on, say, both CentOS 6.5 and CentOS 7.1, the packages must be + built in both environments and binaries for both targets have to + be provided.]) + + (p [There are ways to emulate a different build environment + (e.g. Fedora’s ,(code [mockbuild])), but we cannot get around the + fact that dynamically linked software built for one kind of + system will only ever work on that very kind of system. At + runtime we can change what libraries will be dynamically loaded, + but this is a hack that pushes the problem from package + maintainers to users. Running software with ,(code + [LD_LIBRARY_PATH]) set is not a solution, nor is static linking, + the equivalent to copying chunks of libraries at build time.]) + + (h3 [Version conflicts]) + + (p [Libraries and applications that come pre-installed or + pre-packaged with the system may not be the versions a user + claims to need. Say, a user wants the latest version of GCC to + compile code using new language features specified in C++11 + (e.g. anonymous functions). Full support for C++11 arrived in + GCC 4.8.1, yet on CentOS 6.5 only version 4.4.7 is available + through the repositories. The system administrator may not + necessarily be able to upgrade GCC system-wide. Or maybe other + users on a shared system do need version 4.4.7 to be available + (e.g. for bug-compatibility). There is no easy way to satisfy + all users, so a system administrator might give up and let users + build their own software in their home directories instead of + solving the problem.]) + + (p [However, compiling GCC is a daunting task for a user and they + really shouldn’t have to do this at all. We already established + that package management is a good thing; why should we deny users + the benefits of package management? Traditional package + management techniques are ill-suited to the task of installing + multiple versions of applications or libraries into independent + prefixes. RPM, for example, allows users to maintain a local, + independent package database, but ,(code [yum]) won’t work with + multiple package databases. Additionally, only ,(em [one]) + package database can be used at once, so a user would have to + re-install system libraries into the local package database to + satisfy dependencies. As a result, users lose the important + feature of automatic dependency resolution.]) + + (h3 [Interoperability]) + + (p [A system administrator who decides to package software as + relocatable RPMs, to install the applications to custom prefixes + and to maintain a separate repository has nothing to show for + when a user asks to have the packaged software installed on an + Ubuntu workstation. There are ways to convert RPMs to DEB + packages (with varying degrees of success), but it seems silly to + have to convert or rebuild stuff repeatedly when the software, + its dependencies and its mode of deployment really didn’t change + at all.]) + + (p [What happens when a Slackware user comes along next? Or someone + using Arch Linux? Sure, as a system administrator you could + refuse to support any system other than CentOS 7.1, users be + damned. Traditionally, it seems that system administrators + default to this style for convenience and/or practical reasons, + but I consider this unhelpful and even somewhat oppressive.]) + + + (h2 [Functional package management with GNU Guix]) + + (p [Luckily, I’m not the only person to consider traditional + packaging methods inadequate for a number of valid purposes. + There are different projects aiming to improve and simplify + software deployment and management, one of which I will focus on + in this article. As a functional programmer, Scheme aficionado + and free software enthusiast I was intrigued to learn about ,(ref + "https://www.gnu.org/software/guix/" "GNU Guix"), a functional + package manager written in ,(ref + "https://www.gnu.org/software/guile/" "Guile Scheme"), the + designated extension language for the ,(ref + "https://www.gnu.org/" "GNU system").]) + + (p [In purely functional programming languages a function will + produce the very same output when called repeatedly with the same + input values. This allows for interesting optimisation, but most + importantly it makes it ,(em [possible]) and in some cases even + ,(em [easy]) to reason about the behaviour of a function. It is + independent from global state, has no side effects, and its + outputs can be cached as they are certain not to change as long + as the inputs stay the same.]) + + (p [Functional package management lifts this concept to the realm of + software building and deployment. Global state in a system + equates to system-wide installations of software, libraries and + development headers. Side effects are changes to the global + environment or global system paths such as ,(code [/usr/bin/]). + To reject global state means to reject the common file system + hierarchy for software deployment and to use a minimal ,(code + [chroot]) for building software. The introduction of the Guix + manual describes the approach as follows:]) + + (blockquote + (p [The term “functional” refers to a specific package management + discipline. In Guix, the package build and installation process + is seen as a function, in the mathematical sense. That function + takes inputs, such as build scripts, a compiler, and libraries, + and returns an installed package. As a pure function, its + result depends solely on its inputs—for instance, it cannot + refer to software or scripts that were not explicitly passed as + inputs. A build function always produces the same result when + passed a given set of inputs. It cannot alter the system’s + environment in any way; for instance, it cannot create, modify, + or delete files outside of its build and installation + directories. This is achieved by running build processes in + isolated environments (or “containers”), where only their + explicit inputs are visible.]) + + (p [The result of package build functions is “cached” in the file + system, in a special directory called “the store”. Each package + is installed in a directory of its own, in the store—by default + under ‘/gnu/store’. The directory name contains a hash of all + the inputs used to build that package; thus, changing an input + yields a different directory name.])) + + (p [The following diagram (taken from the ,(ref + "https://www.gnu.org/software/guix/guix-fosdem-20150131.pdf" + "slides for a talk by Ludovic Courtès")) illustrates how the + build daemon handles the package build processes requested by a + client via remote procedure calls:]) + + (wide-img "2015/guix-build.png" + "Software is built by the Guix daemon in isolation") + + (h3 [Isolated, yet shared]) + + (p [Note that the package outputs are still dynamically linked. + Libraries are referenced in the binaries with their full store + paths using the runpath feature. These package outputs are no + self-contained, monolithic application directories as you might + know them from MacOS.]) + + (p [Any built software is cached in the store which is shared by all + users system-wide. However, by default the software in the store + has no effect whatsoever on the users’ environments. Building + software and have the results stored in ,(code [/gnu/store]) does + not alter any global state; no files pollute ,(code [/usr/bin/]) + or ,(code [/usr/lib/]). Any effects are restricted to the + package’s single output directory inside the ,(code + [/gnu/store]).]) + + (p [Guix provides per-user profiles to map software from the store + into a user environment. The store provides deduplication as it + serves as a cache for packages that have already been built. A + profile is little more than a “forest” of symbolic links to items + in the store. The union of links to the outputs of all software + packages the user requested makes up the user’s profile. By + adding another layer of symbolic link indirection, Guix allows + users to seamlessly switch among different generations of the + same profile, going back in time.]) + + (p [Each user profile is completely isolated from one another, making + it possible for different users to have different versions of GCC + installed. Even one and the same user could have multiple + profiles with different versions of GCC and switch between them + as needed.]) + + (p [Guix takes the functional packaging method seriously, so except + for the running kernel and the exposed machine hardware there are + virtually no dependencies on global state (i.e. system libraries + or headers). This also means that the Guix store is populated + with the complete dependency tree, down to the kernel headers and + the C library. As a result, software in the Guix store can run + on very different GNU/Linux distributions; a shared Guix store + allows me to use the very same software on my Fedora workstation, + as well as on the Ubuntu cluster, and on the CentOS 6.5 cluster.]) + + (p [This means that software only has to be packaged up once. Since + package recipes are written in a very declarative domain-specific + language on top of Scheme, packaging is surprisingly simple (and + to this Schemer is rather enjoyable).]) + + (h3 [User freedom]) + + (p [Guix liberates users from the software deployment decisions of + their system administrators by giving them the power to build + software into an isolated directory in the store using simple + package recipes. Administrators only need to configure and run + the Guix daemon, the core piece running as root. The daemon + listens to requests issued by the Guix command line tool, which + can be run by users without root permissions. The command line + tool allows users to manage their profiles, switch generations, + build and install software through the Guix daemon. The daemon + takes care of the store, of evaluating the build expressions and + “caching” build results, and it updates the forest of symbolic + links to update profile state.]) + + (p [Users are finally free to conveniently manage their own software, + something they could previously only do in a crude manner by + compiling manually.]) + + + (h2 [Using a shared Guix store]) + + (p [Guix is not designed to be run in a centralised manner. A Guix + daemon is supposed to run on each system as root and it listens + to RPCs from local users only. In an environment with multiple + clusters and multiple workstations this approach requires + considerable effort to make it work correctly and securely.]) + + (wide-img "2015/guix-shared.svg" + "Sharing Guix store and profiles") + + (p [Instead we opted to run the Guix daemon on a single dedicated + server, writing profile data and store items onto an NFS share. + The cluster nodes and workstations mount this share read-only. + Although this means that users lose the ability to manage their + profiles directly on their workstations and on the cluster nodes + (because they have no local installation of the Guix client or + the Guix daemon, and because they lack write access to the shared + store), their software profiles are now available wherever they + are. To manage their profiles, users would log on to the Guix + server where they can install software into their profiles, roll + back to previous versions or send other queries to the Guix + daemon. (At some point I think it would make sense to enhance + Guix such that RPCs can be made over SSH, so that explicit + logging on to a management machine is no longer necessary.)]) + + + (h2 [Guix as a platform for scientific software]) + + (p [Since winter 2014 I have been packaging software for GNU Guix, + which meanwhile has accumulated quite a few common and obscure + ,(ref + "http://git.savannah.gnu.org/cgit/guix.git/tree/gnu/packages/bioinformatics.scm" + "bioinformatics tools and libraries"). A list of software + (updated daily) available through Guix is ,(ref + "https://www.gnu.org/software/guix/package-list.html" "available + here"). We also have common Python modules for scientific + computing, as well as programming languages such as R and Julia.]) + + (p [I think GNU Guix is a great platform for scientific software in + heterogeneous computing environments. The Guix project follows + the ,(ref + "https://gnu.org/distros/free-system-distribution-guidelines.html" + "Free System Distribution Guidelines"), which mean that free + software is welcome upstream. For software that imposes + additional usage or distribution restrictions (such as when the + original Artistic license is used instead of the Clarified + Artistic license, or when commercial use is prohibited by the + license) Guix allows the use of out-of-tree package modules + through the ,(code [GUIX_PACKAGE_PATH]) variable. As Guix + packages are just Scheme variables in Scheme modules, it is + trivial to extend the official GNU Guix distribution with package + modules by simply setting the ,(code [GUIX_PACKAGE_PATH]).]) + + (p [If you want to learn more about GNU Guix I recommend taking a + look at the excellent ,(ref "https://www.gnu.org/software/guix/" + "GNU Guix project page"). Feel free to contact me if you want to + learn more about packaging scientific software for Guix. It is + not difficult and we all can benefit from joining efforts in + adopting this usable, dependable, hackable, and liberating + platform for scientific computing with free software.]) + + (p [The Guix community is very friendly, supportive, responsive and + welcoming. I encourage you to visit the project’s ,(ref + "https://webchat.freenode.net?channels=#guix" "IRC channel #guix + on Freenode"), where I go by the handle “rekado”.])) diff --git a/posts/2015-06-21-getting-started-with-guix.markdown b/posts/2015-06-21-getting-started-with-guix.markdown deleted file mode 100644 index 25dfb00..0000000 --- a/posts/2015-06-21-getting-started-with-guix.markdown +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Getting started with GNU Guix -date: 2015/06/21 -tags: free software, system administration, packaging, guix ---- - -[Previously I wrote](/posts/2015-04-17-gnu-guix.html) about how using -GNU Guix in an HPC environment enables easy software deployment for -multiple users with different needs when it comes to application and -library versions. Although Guix comes with an excellent manual which -is also -[available online](https://www.gnu.org/software/guix/manual/guix.html), -some people may want to have just some simple installation -instructions in one place and some pointers to get started. I'm -attempting to provide just that with this article. - -While Guix can be built from source it is much more convenient to use -the self-contained tarball which provides pre-built binaries for Guix -and all its dependencies. You need to have GNU tar and xz installed -to unpack the tarball. Note that the tarball will only work on -GNU/Linux systems; it will not work on MacOS. - - -## Six simple steps - -*First*, if you are using a 64 bit machine, download the compressed -[x86_64 archive from the FTP server](ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.x86_64-linux.tar.xz). -There also is a -[tarball for 32 bit machines](ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.i686-linux.tar.xz) -and -[one for the less common MIPS](ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.mips64el-linux.tar.xz). - -*Second*, unpack the archive as root in the root directory: - - # cd / - # tar xf guix-binary-0.8.2.SYSTEM.tar.xz - -This creates a pre-populated store at `/gnu/store` (containing the -"guix" package and the complete dependency graph), the *local state -directory* `/var/guix`, and a Guix profile for the root user at -`/root/.guix-profile`, which contains the guix command line tools and -the daemon. - -*Third*, create a build user pool, as root: - - # groupadd --system guix-builder - # for i in `seq 1 10`; - do - useradd -g guix-builder -G guix-builder \ - -d /var/empty -s `which nologin` \ - -c "Guix build user $i" --system \ - guix-builder$i; - done - -These are the restricted user accounts which are used by the daemon to -build software in a controlled environment. You may not need ten, but -it's a good default. - -*Fourth*, run the daemon and tell it about the `guix-builder` group: - - # /root/.guix-profile/bin/guix-daemon --build-users-group=guix-builder - -*Fifth*, make the `guix` command available to other users on the - machine by linking it to a location everyone can access, such as - `/usr/local/bin`. - - # mkdir -p /usr/local/bin - # cd /usr/local/bin - # ln -s /root/.guix-profile/bin/guix - -Now any user---not just the almighty root---can install software by -invoking `guix package -i whatever`. Yay! - -*Finally*, if you do not want to build all software locally (which can - take a very long time) and you think you can trust the GNU Guix build - farm hydra.gnu.org, authorise it as a source for so-called binary - substitutes using the included public key: - - # guix archive --authorize < /root/.guix-profile/share/guix/hydra.gnu.org.pub - -Note that hydra.gnu.org isn't at all special. Packages are built -there continuously from source. Guix is flexible and can pull binary -substitutes from other locations as long as you authorise them. - -# Where to go from here - -Congratulations! You now have a fully functional installation of the -Guix package manager. - -To get the latest package recipes for Guix just run `guix pull`, which -will download and compile the most recent development version. - -I recommend reading the excellent Guix reference manual, which is -[available on the web](https://www.gnu.org/software/guix/manual/guix.html) -and, of course, included as an Info document in your Guix -installation. If you don't have Emacs---the best Info reader, which -also happens to be an excellent text editor---I encourage you to -install it from Guix; it is just a `guix package -i emacs` away! - -If you have questions that are not covered by the manual feel free to -chat with members of the Guix community -[on IRC in the #guix channel on Freenode](https://webchat.freenode.net/?channels=#guix). -For matters relating to using Guix in a bioinformatics environment you -are welcome to subscribe and write to the -[mailing list bio-packaging@mailman.open-bio.org](http://lists.open-bio.org/mailman/listinfo/bio-packaging). diff --git a/posts/2015-06-21-getting-started-with-guix.skr b/posts/2015-06-21-getting-started-with-guix.skr new file mode 100644 index 0000000..503978f --- /dev/null +++ b/posts/2015-06-21-getting-started-with-guix.skr @@ -0,0 +1,113 @@ +(define meta + `((title . "Getting started with GNU Guix") + (date . ,(string->date* "2015-06-21 00:00")) + (tags "gnu" "free software" "system administration" "packaging" "guix"))) + +(list + (p [,(ref "/posts/2015-04-17-gnu-guix.html" "Previously I wrote") + about how using GNU Guix in an HPC environment enables easy + software deployment for multiple users with different needs when + it comes to application and library versions. Although Guix comes + with an excellent manual which is also ,(ref + "https://www.gnu.org/software/guix/manual/guix.html" "available + online"), some people may want to have just some simple + installation instructions in one place and some pointers to get + started. I’m attempting to provide just that with this article.]) + + (p [While Guix can be built from source it is much more convenient to + use the self-contained tarball which provides pre-built binaries + for Guix and all its dependencies. You need to have GNU tar and + xz installed to unpack the tarball. Note that the tarball will + only work on GNU/Linux systems; it will not work on MacOS.]) + + + (h2 [Six simple steps]) + + (p [,(em [First]), if you are using a 64 bit machine, download the + compressed ,(ref + "ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.x86_64-linux.tar.xz" + "x86_64 archive from the FTP server"). There also is a ,(ref + "ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.i686-linux.tar.xz" + "tarball for 32 bit machines") and ,(ref + "ftp://alpha.gnu.org/gnu/guix/guix-binary-0.8.2.mips64el-linux.tar.xz" + "one for the less common MIPS").]) + + (p [,(em [Second]), unpack the archive as root in the root directory:]) + + (pre (code [# cd / +# tar xf guix-binary-0.8.2.SYSTEM.tar.xz])) + + (p [This creates a pre-populated store at ,(code [/gnu/store]) + (containing the “guix” package and the complete dependency graph), + the ,(em [local state directory]) ,(code [/var/guix]), and a Guix + profile for the root user at ,(code [/root/.guix-profile]), which + contains the guix command line tools and the daemon.]) + + (p [,(em [Third]), create a build user pool, as root:]) + + (pre (code [# groupadd --system guix-builder +# for i in `seq 1 10`; + do + useradd -g guix-builder -G guix-builder \ + -d /var/empty -s `which nologin` \ + -c "Guix build user $i" --system \ + guix-builder$i; + done])) + + (p [These are the restricted user accounts which are used by the + daemon to build software in a controlled environment. You may not + need ten, but it’s a good default.]) + + (p [,(em [Fourth]), run the daemon and tell it about the ,(code + [guix-builder]) group:]) + + (pre (code [# /root/.guix-profile/bin/guix-daemon --build-users-group=guix-builder])) + + (p [,(em [Fifth]), make the ,(code [guix]) command available to other users + on the machine by linking it to a location everyone can access, + such as ,(code [/usr/local/bin]).]) + + (pre (code [# mkdir -p /usr/local/bin +# cd /usr/local/bin +# ln -s /root/.guix-profile/bin/guix])) + + (p [Now any user—not just the almighty root—can install software by + invoking ,(code [guix package -i whatever]). Yay!]) + + (p [,(em [Finally]), if you do not want to build all software locally + (which can take a very long time) and you think you can trust the + GNU Guix build farm hydra.gnu.org, authorise it as a source for + so-called binary substitutes using the included public key:]) + + (pre (code [# guix archive --authorize < /root/.guix-profile/share/guix/hydra.gnu.org.pub])) + + (p [Note that hydra.gnu.org isn’t at all special. Packages are built + there continuously from source. Guix is flexible and can pull + binary substitutes from other locations as long as you authorise + them.]) + + (h2 [Where to go from here]) + + (p [Congratulations! You now have a fully functional installation of + the Guix package manager.]) + + (p [To get the latest package recipes for Guix just run ,(code [guix + pull]), which will download and compile the most recent + development version.]) + + (p [I recommend reading the excellent Guix reference manual, which is + ,(ref "https://www.gnu.org/software/guix/manual/guix.html" + "available on the web") and, of course, included as an Info + document in your Guix installation. If you don’t have Emacs—the + best Info reader, which also happens to be an excellent text + editor—I encourage you to install it from Guix; it is just a + ,(code [guix package -i emacs]) away!]) + + (p [If you have questions that are not covered by the manual feel free + to chat with members of the Guix community ,(ref + "https://webchat.freenode.net/?channels=#guix" "on IRC in the + #guix channel on Freenode"). For matters relating to using Guix + in a bioinformatics environment you are welcome to subscribe and + write to the ,(ref + "http://lists.open-bio.org/mailman/listinfo/bio-packaging" + "mailing list bio-packaging@mailman.open-bio.org").])) |