Le weblog entièrement nu

Roland, entièrement nu... de temps en temps.

Dernières nouvelles

RSS
Le Debian Handbook est sorti !

Pour ceux qui vivaient dans une grotte récemment, la raison pour laquelle je vivais dans une grotte vient de se terminer : la traduction anglaise du Cahier de l'Admin Debian vient enfin de sortir, sous le titre de “The Debian Administrator's Handbook”. Et pas qu'un peu, puisqu'il est disponible :

  • En version papier chez Lulu ;
  • En consultation en ligne ;
  • En téléchargement aux formats PDF, Epub et Mobipocket ; vu que le site est un poil chargé en ce moment, il est conseillé d'utiliser les torrents (PDF, Epub, Mobipocket, HTML) ;
  • Et il est même disponible directement dans Debian, tant qu'à faire : apt-get install debian-handbook (uniquement dans unstable pour l'instant, mais il va certainement migrer vers les autres distributions).

Le dernier élément est important : le livre est libre (sous licences GPL-2+ et CC-BY-SA-3), et les contributions sont donc possibles et bienvenues.

Pour tous détails supplémentaires, le site web du livre : debian-handbook.info.

Les donations sont toujours possibles (et appréciées !), même après la fin officielle de la campagne de financement.

Raphaël et moi serons vraisemblablement aux RMLL de Genève en juillet, et ça serait bien le diable si nous n'arrivions pas à organiser une séance de dédicaces si le besoin s'en fait sentir…

Tags:
Posted jeu. 10 mai 2012 14:45:02 CEST
La retraite à 10 ans

Petit billet rapide pour annoncer qu'après dix ans de bons et loyaux services, mirexpress vient d'être mis à la retraite. Il est remplacé par polymir, mon nouveau PC tout beau tout brillant et tout moderne. Comme en 2002, je l'ai pris nettement plus puissant que mes besoins actuels ne l'exigent, mais j'ai bien l'intention de le faire durer dix ans lui aussi, ne serait-ce que pour continuer à fournir un contre-exemple pour tous les gens qui pensent que leur ordinateur est forcément obsolète au bout de deux ans.

Tags:
Posted mer. 18 avril 2012 14:45:01 CEST
Et un de plus

Et un anniversaire de plus. Bigre. Toujours pas de divorce, ni de dépression, ni de Rolex. Je n'ai toujours pas décidé d'arrêter de fumer, ni de suivre un régime, ni de grisonner aux tempes. Je me demande si je ne suis pas un peu en retard sur les modèles standard.

D'un autre côté, mes super-pouvoirs de geek ne semblent pas céder à la pression du temps, mes clients sont rigoureusement sélectionnés pour que tout se passe bien avec eux, ma maison ne devrait plus tarder à être complètement étanchéifiée, et ma carrière musicale ne fait que commencer (il est question de me diversifier au kazoo et/ou à l'ocarina).

Accessoirement, il fait beau et y'a des bières au frais. Si vous êtes dans les environs et vous voulez inaugurer la saison des apéros sur la terrasse, vous serez les bienvenus, mais plutôt aujourd'hui parce que demain y r'pleut et qu'après je vais faire la fête ailleurs.

Me voilà donc trentecinquenaire !

Tags:
Posted mer. 11 avril 2012 10:30:02 CEST
FusionForge news, March 2012

The winter has been busy everywhere, and not much happened in FusionForge land. However, this is over, and we've started pushing again, with a focus on making our next 5.2 release ready.

We've started a stabilisation branch and set up Jenkins jobs to run our various testsuites on it. Packages built from that branch have also been uploaded to the "experimental" suite in Debian (they need a manual approval before they actually appear there, but that shouldn't take too long). They should be installable and working even on Debian Squeeze (stable), although they focus mostly on Wheezy (testing). My personal goal is to have a solid 5.2 release and include it in Wheezy so it can be part of an official Debian system.

What this all means is that we welcome tests and reports of breakage; users of 5.1 or earlier versions in particular are encouraged to test upgrades (in virtual machines or development environments, obviously, if the production server is sensitive). We also welcome translators; there are many new plugins, which means many new translatable strings.

We'll probably do release candidates before the final release; I'll announce them here (in addition to the fusionforge.org website).

Stay tuned!

Tags:
Posted mer. 28 mars 2012 11:30:02 CEST
Looking for the ultimate distributed filesystem, take 2

This follows up on a previous post, and tries to summarize the corrections and suggestions I received.

First, a reminder: yes, I'm really looking for a filesystem, not a storage system. Even if I only consider the “music files” use case, there are just too many things that want to access the files, and there's no way I'm going to port these things to use the storage system's API instead of plain old file access. Examples? The Rhythmbox player. The XMMS2 player. The mt-daapd/forked-daapd DAAP server. My script to backup or restore metadata (tags). Ex-Falso, to do mass edits on these tags. abcde, to add new files when I buy a new CD. Any kind of shell one-liners I currently do without thinking because find, xargs, cp, ln, and so on all operate on files. I understand that providing filesystem semantics on top of a storage system is hard, but that doesn't change my requirements, and saying otherwise is patronising.

So, on to the meat of the matter.

Apparently my understanding of Tahoe-LAFS was mostly correct. It seems that multiple introducers are on their way to become a reality, which would mean the one remaining central point would go away. Most of my other complaints seem to be on their way to be resolved, too, except that it's still targeted as a storage system, and the FUSE/sshfs layer on top still has its drawbacks (quoting from the wiki, “Before uploading a file to a Tahoe filesystem, the whole file has to be available”, “mutable parts of a filesystem should only be accessed via a single sshfs mount [...] data loss may result for concurrently accessed files if this restriction is not followed” and so on). From what I read, the position is that nobody publicly uses Tahoe's filesystem integration, therefore there's no need to fix its shortcomings; my understanding is that nobody uses it precisely because of its shortcomings.

Ceph: apparently does repair/rebalance automatically contrary to what I thought. However, two persons told me that it's really expecting all nodes on the same LAN, and geographically distributed setups aren't really targeted.

XtreemFS: I don't think I got any comments on my evaluation, so I'll assume it still stands.

git-annex: storage system, not a filesystem. Yes, the files can be made available in the filesystem, but if I need to manually retrieve them before accessing them, this doesn't work.

GlusterFS: I'd like to read more docs on how it works, but I haven't been able to find them. Apart from the installation manuals, the only documentation I found was a very short “Concepts” page, which described some of the concepts but didn't give me the big picture on how the who thing works. (I'm turning a blind eye on the Red Had advertisements and the requiremets that everything be installed on RH machines; the hardware requirements are also quite out of line with what I want to do.)

HekaFS (aka CloudFS): I found even fewer docs about this one than about GlusterFS, and apparently HekaFS is on its way to being merged into GlusterFS anyway.

PlasmaFS: I didn't know about this one previously, but the one email I got about it was mainly full of “this won't work” and “this won't work either”. I didn't feel inclined to read further docs after that.

In summary, I guess the replies I got didn't cause me to change my mind too much. Tahoe-LAFS still seems to be, if not the best solution, then at least the “least bad”. Hopefully the drawbacks will be fixed soonish; the main sticking point (at least from my point of view) still seems to be the lack of focus on proper filesystem integration. I'll try setting it all up at some point; I may report further if I end up finding interesting things.

Thanks to all who responded!

Tags:
Posted jeu. 01 mars 2012 12:30:02 CET
Février

Ah oui, le mois est court, j'ai failli me faire avoir. Je serai donc bref pour résumer mes activités de ce mois-ci :

  • Vacances, soleil, neige, monoski. Tiens, y'a du monde aux remontées, serait-ce les vacances scolaires aussi ?
  • Suite à l'explosion en vol de ma précédente tentative, je me suis encore fait refuser par un groupe de rock, pour « manque d'expérience ». C'est marrant, ces groupes amateurs qui cherchent un batteur qui soit tout de suite aussi bien intégré que celui qui s'en va après plusieurs années. Et c'est dommage, parce que de ce que j'en vois, après plusieurs mois la place est souvent encore à prendre ; et plusieurs mois, ç'aurait été suffisant pour s'intégrer.
  • Conséquence : je me retrouve de nouveau à scruter les petites annonces.
  • Conséquence n°2 : j'en suis à deux doigts de monter mon groupe à moi tout seul. Apprendre à me servir des séquenceurs, mixeurs, arrangeurs etc. ça devrait aller. Il reste juste à apprendre le solfège…
  • La météo commence à sentir le printemps, par ici. Pas trop tôt.

Un autre mois ordinaire, donc.

Tags:
Posted mer. 29 févr. 2012 11:30:02 CET
Looking for the ultimate distributed filesystem

(This is not quite a “Dear lazyweb” post. If anything, it's “Dear lazyweb, I've done my homework, now what?”)

I'm looking for the ultimate distributed filesystem. Something that's simple to use, redundant, fault-tolerant, and still smart enough to avoid the more obvious performance chokepoints. Ideally, it should work for all of the following sets of files:

  • Music files. They're currently stored on a plug computer at home and served over DAAP, but DAAP seems to become less and less of a priority for music players (I'll keep the “music players suck” rant for another post), and it has its inconveniences too. Ideally, the files should be integrated in the filesystem of my work computer, the one that serves as a media player in the living-room, the one I use for playing the backing tracks when I'm practising the drums, and the laptop I use when on the road too.
  • Backups. My BackupPC currently runs on the plug computer at home, so backups of my remote servers are in a geographically distinct location; but backups of my home computers are not, and I'd like to change that without having to copy files around by hand. Backups do contain confidential data, so this adds a constraint on the filesystem.
  • Bazaar repositories. I do have a script that pushes and pulls stuff across computers for the many repositories I use, but it's still awkward that I need to do that.
  • Parts of my home directory, such as my browser preferences and bookmarks, or the database of the Hamster time tracking tool, or the working directories of stuff I do for clients, and so on. Again, each of those can be done with specific means (bookmarks synced to a server, CouchDB-like database, DVCS and regular commits, etc.), but wouldn't it be much simpler if there only was one file to begin with?

The requirements on the ultimate distributed filesystem (which I'll call UDFS for short, otherwise you'll get bored and go look at pictures of kittens) are as follows:

  • Availability means redundancy: some of the storage nodes will be on dedicated servers in datacenters, others at home; I can imagine setting up the firewall so that the home computers are reachable from outside, but sometimes network links go down, and the home computers are far from being on 100% of the time.
  • Availability/redundancy also means automated replication and rebalancing: if a node is added to the “grid” (or switched on), it should automatically get its share of the files so as to contribute to availability if another node goes down at a later time.
  • Confidentiality: at the very least, network communications must be encrypted and authenticated; ideally, individual storage nodes wouldn't need to be able to access the stored data. If I store bits of my backups on a friend's server, I don't want to have to trust them not to look at the data; also, my friend may actually want to be unable to look at my data (to provide for deniability in case someone else wants to look at it).
  • Performance: native disk performance may not be realistically reachable, but the system must be smart enough (or configurable enough) to store files on both sides of the ADSL link, for instance, so not all accesses need to go through the bottleneck.
  • Integration with the system: I want a filesystem, not a storage system. All applications know how to navigate a mounted filesystem; very few will interface with an specific application designed to store and fetch chunks of data.
  • Scalability would be nice, although my personal needs are still well below the terabyte range and I can't see myself using more than a dozen nodes or so.

Quite a few constraints, eh? I have a feeling they are not mutually incompatible though, so I had a look at several candidates. I started with Wikipedia, and I followed the links to Tahoe-LAFS, XtreemFS and Ceph. The following is my evaluation of these candidates based on much reading of docs and websites and wikis, some questioning on IRC, and very little testing.

  • Availability/redundancy 1: all three candidates work on the net, and they all provide for data replication. XtreemFS seems to operate on a “fall-back” mode while the other two are more distributed (meaning there's no canonical node hosting any particular file). Tahoe uses erasure codes (files can be split across N shares, k of which are enough to reconstruct the whole file; the N/k ratio controls the amount of redundancy); it seems to require the “introducer” node to be always up, which introduces a single point of failure, but this node can be replaced with no loss of data if it fails (this just requires reconfiguring the storage nodes, which can probably be automated). Ceph can work with any number of meta-data servers, so redundancy is assured there (data itself can be replicated in a configurable way too).
  • Availability/redundancy 2: either I'm a fool and I didn't find out about that, or none of the three candidates provides for automated rebalancing. Apparently Tahoe provides a way to “repair” files without enough redundancy, but that needs to be run manually on each file, rather than being systematic, and it's a kind of add-on to the system rather than being properly integrated. Ceph only does rebalancing of meta-data. XtreemFS seems to work a bit like RAID1 with spare disks, but details are scarce.
  • Confidentiality: Tahoe wins, hands down. Neither network sniffers nor storage nodes can see the contents of the stored files. They can't even find out about their name or the directory structure. XtreemFS encrypts the data on the network (but it is still stored in cleartext on the nodes). Ceph doesn't even try.
  • Performance: Ceph wins (or loses less, at any rate): it seems possible to configure a topology for the storage nodes, and to drive the storage location policy according to this topology; so I could define sets of nodes (“my servers in datacenters”, “my plug computer at home”, “my desktop and laptop computers”, “my friends' computers”) and decide that each file should be stored at least once on each set of nodes. Tahoe stores shares of files on a number of storage nodes chosed in kind of a round-robin way; read access uses the same round-robin system, which means that you will probably end up fetching a file at least partially over your slow link even when you could fetch it entirely from the local network. The XtreemFS website doesn't seem to acknowledge the possibility of the network being slow.
  • Integration: Ceph and XtreemFS win: they're native filesystems. Tahoe is in the “storage and retrieval system” category; the FUSE layer is marked as experimental and not recommended, and the SFTP layer (which can be mounted as a filesystem with sshfs) has many documented drawbacks. Maybe a WebDAV frontend, combined with fusedav, would provide a working alternative, but it's not implemented yet.
  • Scalability: all three candidates boast about scalability (in data size and in number of nodes). Ceph seems to require some configuration every time a new storage node is added. Tahoe seems much more dynamic: new nodes (storage or clients) just need to be told where the introducer node is, and then they merge into the grid seamlessly by being told about other nodes (a bit like Bittorrent, where clients learn about each other by asking the tracker).

The overall picture seems full of good things scattered across different solutions, but unfortunately none of the existing ones seems to address the whole problem; at least, not my whole problem. It would be good if each focused on one layer and did that layer well, but that seems not to be the case either, so they can't be combined to get the best of all worlds. It may be that I'm missing something, or that I failed to read some docs properly, or that I misunderstood the docs, or that the docs themselves are simply lacking; but my ideal UDFS currently doesn't seem to exist as a turn-key solution.

However, the main pieces are available, and implementing the remaining parts may be doable. My humble idea of a way forward would be based on Tahoe-LAFS, with the following three changes:

  • A configurable dispatch policy, so that administrators could define their own behaviour. The current Tahoe parts already turn files into a number of blobs that only need to be stored on various nodes, and the function that chooses which nodes seems to be reasonably self-contained, so it could maybe even be made pluggable, and an administrator could implement a storage policy that matches the constraints and the network topology. Ditto for the function that picks which nodes the data is read from (which, as far as I can tell, is the same; splitting could bring some benefits here).
  • A working FUSE implementation, either on top of SFTP if the drawbacks can be fixed, on top of WebDAV if that gets implemented, or native to Tahoe if that can be done.
  • Automatic rebalancing of data when new nodes are added or turned on, or when an intermittent network link comes up. The current script seems to be an afterthought; if it can be made more automated and more reliable, I'll be happy with that.

Also nice to have would be a way to work with multiple introducer nodes, but that seems to be in the works already. This would be pretty damn close to my UDFS; read/write performance would certainly be far from what can be obtained on native filesystems stored on local disks, but my use cases involve reasonably small files for which instant access is not compulsory, and the filesystem cache would probably absorb most of the access times.

In case anyone is looking for ideas of things to do in their spare time, here are rough sketches of other possible UDFS implementations I thought of. These are wild ideas, and I'm not even sure they could be doable in practice:

  • eCryptfs on top of Ceph. The file contents are still only accessible to those in possession of the adequate key, and replication/distribution is handled by Ceph. That could probably work; the main drawbacks I can see come from Ceph's administrative overhead and manual configuration.
  • LUKS and a standard filesystem, on top of the part of Ceph that manages block devices (RADOS). I'm not sure this could be mounted simultaneously by several nodes, though.
  • LUKS on top of Ceph's RADOS, and Lustre or GlusterFS on top of that? Am I even making sense?
  • A kind of union filesystem with local caching, on top of Tahoe-LAFS. Say we take unionfs-fuse, and add local caching: if the requested file is already in cache, performance is near native; if not, we still get the advantages of Tahoe. I'm not sure how caching works with WebDAV, but once Tahoe gets a WebDAV frontend it might be a simple matter of adding a Squid cache between that and davfs.
  • I even thought of building a filesystem on top of the Bittorrent protocol; redundancy would be obtained by ensuring that there are at least N “distributed copies” of a file among the peers. I gave up even before reaching the details phase, though, but maybe a variant of the idea could be workable.

Such is the state of my research so far. I would welcome feedback, pointers to things I neglected to read, corrections for things I misread or misunderstood, comments on the ideas and so on. I'll probably post an update if my search goes significantly forward.

Update: I've already received two pieces of feedback, including a lengthy one with corrections about Tahoe-LAFS. For the sake of fairness, I'll solicit (and wait for) the same from the other candidates I looked at. I was also pointed at HekaFS, GlusterFS and git-annex, which I'll have to look at in more details. Other suggestions are still welcome, but the more I get, the more the full update will be delayed. Thanks already!

Update 2: See take 2 for the full update.

Tags:
Posted dim. 15 janv. 2012 21:45:02 CET
Fin d'année

Je ne voudrais pas vous laisser, chers et chères lecteurtrices, sans nouvelles de tout le mois. Ça tombe bien, il me reste un peu de temps avant d'en fêter la fin officielle. Et comme traditionnellement c'est une période où on boucle une année, c'est l'occasion de revenir sur les événements marquants de mon petit monde. Comme ça, en vrac, parce que comme dit la chanson, un an de plus qu'il n'avait l'année dernière, un an de moins qu'il n'aura l'an prochain.

  • Ma mezzanine et son petit vasistas de toit se sont transformés en un vrai bureau et une terrasse (de toit aussi). Mine de rien, ça change la vie, l'apéro sur la terrasse (plutôt que dans la cuisine-bunker). Reste à fignoler quelques détails d'étanchéité, et ça sera tout bon.
  • Après plusieurs tentatives, il semble que je sois officiellement intégré comme batteur dans un groupe musical. Le répertoire actuel comprend essentiellement des reprises dans un style défini comme « blues/rock à l'ancienne », et ça va d'AC/DC à ZZ Top. Je ne manquerai pas de vous faire part des éventuelles apparitions publiques.
  • En plus d'acquérir une certaine aisance (relative) sur ma batterie, je continue d'accumuler des super-pouvoirs de geek et des points d'XP en travaillant pour des clients ; c'est un cercle vicieux, parce que ça me permet de traiter des clients plus nombreux, qui à leur tour me font travailler sur… etc. Je crois qu'à un moment il va falloir se limiter, sinon ça ne va plus rentrer dans 24 heures.
  • L'inconvénient quand on grandit c'est que ça devient mal vu de continuer à jouer avec des « jeux de gamins ». Mais au bout d'un certain temps, l'effet se retourne : il suffit de coller le mot magique « vintage », et hop ça redevient socialement acceptable de ressortir ses Lego et de faire du pixel-art. Et pour peu qu'on fasse une utilisation non-conventionnelle des jouets (cf. mon bricolage avec les wiimotes, dont je vous reparlerai certainement bientôt), ça passe même pour de l'avant-garde.

Si je devais résumer cette année, je dirais que j'ai parfaitement tenu mes bonnes résolutions (et qui peut en dire autant ?), et que je vais donc les reconduire, publiquement cette fois : prendre la vie comme elle vient, en profiter quand c'est possible, et garder fermement un sens des priorités pour ne pas se laisser embêter par les tracasseries et les fâcheux.

Et sur ces bonnes paroles, j'ai un réveillon déguisé musical à préparer, donc je vous souhaite un bon bout d'an. Paix aux gens de bonne volonté. Et aux autres aussi, on est pas vaches.

Tags:
Posted ven. 30 déc. 2011 10:45:01 CET
Cahier de l'admin Debian : dernières nouvelles

Il se passe des choses dans le petit monde du livre Debian.

Premièrement, la nouvelle édition du Cahier de l'Admin Debian est sortie, après deux ans de mises à jour amoureuses par Raphaël Hertzog et votre serviteur. Nous voulons croire qu'elle aura aussi bonne presse que les précédentes, puisqu'elle met à jour tout le contenu pour coller à Debian Squeeze. Noël approche, pensez à votre administrateur système !

Deuxièmement, la campagne de financement pour la traduction en anglais a atteint son premier objectif, et Raphaël et moi allons donc commencer la traduction. Nous vous tiendrons bien entendu informés de son avancement. Notez qu'il reste actuellement 12 jours pour les préventes, mais je suis certain qu'on trouvera un moyen de faire des ventes même après la fin de la campagne de souscriptions.

Troisièmement, et c'est peut-être plus important : cette même campagne de souscriptions sert également à financer la libération du livre (au sens de « publication sous une licence libre »). Cette libération sera déclenchée à l'atteinte d'un deuxième objectif, qui est en bonne voie mais pas encore complet. C'est donc le bon moment pour contribuer. Vous pouvez bien entendu choisir la répartition de votre contribution, pour privilégier le fonds de libération ou les contreparties personnelles.

Et si jamais on organise des séances de dédicace dans les plus prestigieuses librairies, je vous en parlerai, promis.

Tags:
Posted mer. 16 nov. 2011 10:30:02 CET
Guitar Hero Controller (Wii) to MIDI

This is a follow-up on a previous post: I used a bit of a rainy Sunday to read some docs and write some Python, and I now have a script that converts events from a Guitar Hero World Tour drums controller to MIDI.

A brief explanation of how it works: in its standard configuration, the drums controller has five pads and a pedal, and it uses a Wiimote to communicate the events (what pad was hit with what force, or what button was pressed/released, or the position of the mini-stick) to the Wii itself. This communication happens over Bluetooth and not over a dedicated cable or protocol, so it is possible to remove the Wii and use a standard computer with Bluetooth (built-in or via a dongle) instead, and the computer will receive messages. There's some decoding to do, but fortunately people have reverse-engineered the frames, and come up with the libcwiid library and its Python binding, which hides the complexity of the decoding and just delivers structured data to the programs that use it. Then we analyze this data and extract the relevant info from it (with some juggling of bits): "the X pad was hit with force Y". From there, it's a simple matter of mapping the pads to a MIDI note and the force to a MIDI velocity, and of sending the appropriate MIDI message to the target, for instance with the libportmidi library.

What you do with the MIDI output is your call: I use it to add more pads to my electronic drum kit, but it could equally be used to drive a software synthetizer, or an external sound module. Or a light-show machine. Or fireworks. Or a model railway. Or whatever.

Here's the current version of the wiigh2midi.py script (for updated versions, see the Bazaar repository).

#! /usr/bin/python

import cwiid, time, asyncore, pypm

class Wiimidi:
    wiimote = None
    midiout = None
    lastaction = time.time()

    wii2color = { 27: 'kick',
                  25: 'red',
                  17: 'yellow',
                  15: 'blue',
                  14: 'orange',
                  18: 'green' }

    color2midi = { 'kick': 36, # Bass drum
                   'red': 38, # Snare drum
                   'blue': 48, # High tom
                   'green': 43, # Low tom
                   'yellow': 42, # Closed hi-hat
                   'orange': 52, # Crash cymbal
                   }

    def connect_wiimote(self):
        print "Press 1+2 on the Wiimote..."
        try:
            self.wiimote = cwiid.Wiimote()
        except:
            self.wiimote = None
            return None
        print "Connected."
        self.lastaction = time.time()
        self.wiimote.rumble=1
        time.sleep(.2)
        self.wiimote.rumble=0
        return self.wiimote

    def disconnect_wiimote(self):
        if self.wiimote is not None:
            print "Closing connection to the Wiimote."
            self.wiimote.close()
            self.wiimote = None
        return

    def connect_midi(self):
        for i in range(pypm.CountDevices()):
            interf,name,inp,outp,opened = pypm.GetDeviceInfo(i)
            if outp == 1:
                if name == 'UM-1G MIDI 1':
                    self.midiout = pypm.Output(i, 0)
                    return
        for i in range(pypm.CountDevices()):
            interf,name,inp,outp,opened = pypm.GetDeviceInfo(i)
            if outp == 1:
                print i, name," ",
                print
        dev = int(raw_input("Type output number: "))
        self.midiout = pypm.Output(dev, 0)

    def wiimote_callback(self, messages, timestamp):
        self.lastaction = time.time()
        m = messages[0][1]
        # rx = m['r_stick'][0]
        ry = m['r_stick'][1]
        l = m['l']
        # r = m['r']
        which = ( (l << 1) & 16) + (ry >> 1)
        softness = l & 7
        if softness == 7 or which == 0:
            return
        # print "rx=%d\t ry=%d\t l=%d\t r=%d\t rest=%d" % (rx,ry,l,r,rest)
        # print "which = %d, softness = %d" % (which, softness)
        strength = 7-softness
        color = self.wii2color[which]

        midi_vel = 16*strength
        midi_note = self.color2midi[color]
        self.midiout.WriteShort(0x9a,midi_note,midi_vel)
        self.midiout.WriteShort(0x9a,midi_note,0)
        # print "%s %d -> %d %d" % (color, strength, midi_note, midi_vel)

    def main(self):
        self.connect_midi()
        while True:
            if self.wiimote is None:
                self.connect_wiimote()
                if self.wiimote:
                    # Tell Wiimote to display rock sign
                    self.wiimote.led = cwiid.LED1_ON | cwiid.LED4_ON
                    # We only care for the extension data
                    self.wiimote.rpt_mode = cwiid.RPT_EXT
                    self.wiimote.enable(cwiid.FLAG_MESG_IFC | cwiid.FLAG_REPEAT_BTN)
                    self.wiimote.mesg_callback = self.wiimote_callback
                    self.lastaction = time.time()
                else:
                    print "Retrying... "
                    print
            asyncore.loop(timeout=0, count=1)
            if self.lastaction < time.time() - 3600:
                print "An hour passed since last action..."
                self.disconnect_wiimote()
            time.sleep(0.05)
        print "Exited safely."

# Instantiate and run
inst = Wiimidi()
inst.main()

There are a few obvious improvements to be made: first, handling guitar controllers in addition to drums. Second, handling the buttons could provide extra "pads", to trigger sound effects for instance (thunder, lasers, voices…), or to initiate program changes, or to change the mappings of the pads. Maybe storing the mutable parts (default MIDI adapter, pad-to-note mapping) in a configuration file. Maybe add a user interface to ease the configuration. Patches welcome, otherwise maybe I'll do that myself on another rainy Sunday.

Notes and references (in other words, the giants on whose shoulders this program stands):

  • As mentioned, this script uses the pyPortMidi binding, available in Debian Wheezy as python-pypm (and easily backported to Squeeze).
  • It also uses the Python bindings to CWiid, available in Debian as python-cwiid.
  • I based the pad-to-MIDI mapping on the relevant part of the General MIDI specification.
  • The bit-mangling operations used to map cwiid messages to plain data were worked out by comparing the tables from the Wiibrew wiki on the classic controller and the drums controller.
  • The skeleton of the script was initially based on MythPyWii, although not much of it still remains.

More cowbell!

Tags:
Posted lun. 07 nov. 2011 11:30:02 CET
Creative Commons License Sauf indication contraire, le contenu de ce site est mis à disposition sous un contrat Creative Commons.