Hommage à Octave

J'ai récemment ré-essayé Octave, suite a un coup de yenamarre de Matlab : leur politique tarifaire est ridicule , quand on veut mettre à jour un matlab 2017 vers matlab 2023 , ils font payer 1000 euros par année de différence au lieu d'une somme fixe forfaitaire. Matlab passe son temps à buguer après chaque update de macOS donc c'est très difficile de continuer à travailler sur une vieille version quand on est macqueux. Avec Sonoma ça a été un vrai festival. Donc ras-le-bol de matlab, ras-le-bol des commerciaux Mathworks qui refusent de faire la moindre ristourne pour les bons clients, et ras-le-bol de la lourdeur de matlab (y'a besoin d'une jvm et c'est d'ailleurs pour cette raison qu'il passe son temps à merdouiller/cesser de fonctionner sur macOS).

Du coup Octave, ben ça marche pas mal du tout en 2023. La rapidité est tout à fait honorable sur un mac récent, et l'IDE qui reprend grosso modo celui de matlab est en Qt et est tout à fait fonctionnel : éditeur, debuggeur, inspecteur de variables, plots, etc. Donc thumb up pour octave et fuck you pour matlab.

When optimizations cross the border of sanity

I'm a bit annoyed because I have this toy program on my mac:

#include <iostream>
#include <cmath>

int main(int argc, char **) {
  float f = 1, c = 0.1f;
  for (int i=0; i < 45; ++i) {
    std::cerr << "f=" << f << " sqrt(f)=" << sqrt(f) << "\n";
    f *= c;
  }
  return 0;
}

It's pretty simple, and one would expect it to print numbers smaller and smaller until it prints zeroes. That's not what happens when built with clang and the fast-math option on macOS:

clang++ -O1 -ffast-math t.cc && ./a.out
f=1 sqrt(f)=1
f=0.1 sqrt(f)=0.316228
f=0.01 sqrt(f)=0.1
f=0.001 sqrt(f)=0.0316228
f=0.0001 sqrt(f)=0.01
 (skipping some output..)
f=1e-34 sqrt(f)=1e-17
f=1e-35 sqrt(f)=3.16228e-18
f=1e-36 sqrt(f)=1e-18
f=1e-37 sqrt(f)=3.16228e-19
f=1e-38 sqrt(f)=-inf  # WTF ???
f=1e-39 sqrt(f)=-inf
...

So when f is so small that it is represented as a denormal number, the sqrtf function returns PURE GARBAGE instead of returning 0. Or any denormal number. I would accept anything, but not, for fucks sake, a negative number. Not -inf. Please.

I have reported this to Apple (more than one year ago) , I got a reply (one year later), and for them it is not an issue, because the argument of sqrtf being smaller than FLT_MIN allows undefined behaviour (!??). Well, let's agree to disagree. I don't think fast-math should allow the compiler to do whatever it wants. Denormal numbers do happen. Sqrtf is a common function. There is a difference between being fast and slightly incorrect, and being fast and absolutely wrong.

Note: I have not been able to reproduce it with gcc or msvc, or even clang on linux. It is only the mac version of clang/libc++ which is retarded.

Ajouter le support du séquenceur midi ALSA quand il n'est pas fourni d'emblée avec le noyau

Assez souvent avec les noyaux linux qui sont fournis avec les cartes ARM ont un minimum de modules d'activé, et bien souvent le séquenceur ALSA n'en fait pas partie. Comme ça fait plusieurs fois que je fais la manip et que j'oublie à chaque fois les differentes étapes voici ce que j'ai fait pour avoir le séquenceur alsa sur une carte NanoPi Neo 2 sans s'emmerder à recompiler un kernel entier. Recuperer les sources correspondant au kernel courant, dans mon cas sur le github de friendlyarm . Le dossier linux n'a pas de .config, y'en a pas dans /proc/config.gz , pour en recuperer un aller dans fa_tools et faire un ./build.sh -b nanopi-neo2 -p linux -t kernel . Ca échoue rapidement mais on s'en fout maintenant y'a un .config dans le dossier linux.

Donc:

cd linux
make menuconfig
et aller dans drivers / soundcard pour rajouter le support du sequenceur alsa sous forme de module.

Il faut aussi recuperer Modules.symvers:

cp /lib/modules/3.10.65/Module.symvers .

Faire

make prepare && make scripts
make CC=gcc-4.9 M=sound/core/seq/
sudo make CC=gcc-4.9 M=sound/core/seq/ modules_install
depmod -a

et voilà normalement on peut maintenant faire un modprobe snd-seq et ça roule.

Executer un binaire arm 32-bit sur une distrib 64-bit (aarch64)

En fait c'est comme pour le i386 / amd64 , sur une distrib debian-like il faut commencer par un dpkg --add-architecture armhf (ou armel selon ce qu'on veut) , un apt-get update, un apt-get install libc6:armhf et ça roule.

Editer un script bash pendant qu'il est en cours d'execution

On est en 2016 et bash n'est toujours pas capable de gérer correctement la situation où on édite un script alors qu'il est en cours d'exécution (gérer correctement, càd ignorer les changements et continuer à executer le script initial, et pas tenter d'executer un bout semi-aléatoire de la nouvelle version du script pour finalement se planter comme une merde)

Ultra short c++ MIDI file reader

There are many full-featured libraries for reading Standard MIDI Files , but they are often doing more than just reading and end up being a bit on the over-engineered side.

Here is what could be the shortest MIDI file parser ever, in a simple self-contained c++ header file. It is short because it does not do much and does not try to be smart.

simple_midi_reader.hh

It should be able to load any MIDI file and turn it into a list of MIDI events that are correctly timestamped (tempo change events are handled). And that's all !

Wow

Wow ça fait longtemps que j'ai pas blogué.

Prompt bash

Ca faisait au moins 10 ans que j'utilisais le même prompt bash, un truc qui affiche grosso modo l'heure et le chemin courant, en couleur, basique mais leger. Un truc qui me manque parfois c'est d'avoir le temps d'execution de la derniere commande, je trouve que c'est une information interessante quand ce temps est de plus de quelques secondes. Et aussi, avoir un affichage du code de retour de la commande précedente. C'est pourquoi j'ai décidé de mettre a jour mon prompt bash ! voici ce qu'il y a maintenant dans le ~/.bashrc , il n'y a rien d'exceptionnel c'est juste des bouts de trucs trouvés sur le net mais je suis content du résultat:

url du truc (arg je n'arrive pas à coller le code directement dans dotclear, il a l'air d'en interpreter des bouts...)





Voila la tête que ça a:

Je ne vais pas dire que c'est le plus beau prompt du monde, mais je sens qu'il va faire l'affaire pour les 10 ans venir.

Utiliser -mfpmath=sse avec gcc

Un bon moyen (en 32-bit) pour se debarrasser des bizarreries du x87 c'est de compiler avec cette option -mfpmath=sse qui demande à gcc d'utiliser les instructions sse à la place du x87 et ses registres moyenageux de 80-bits. Jusque là tout va sauf que si on regarde les performances des fonctions transcendentales expf, sinf, tan, atan ( par exemple en compilant sse_mathfun_test.c avec les options -ffast-math -O3 -msse2 et -mfpmath=sse ou -mfpmath=387), eh bien on constate qu'elles sont devenues jusqu'à 2.5 fois plus lentes. Genre sur mon core 2, tan() executée avec le fpu x87 prend 119 cycles, alors que la version sse2 prend 298 cycles ! pas cool. Pour expf c'est un peu moins pire, on passe de 143 cycles à 203.

J'ai fait le test avec mingw-w64 sous windows, version 4.6.2 et 4.7.

(Coté visual c++ 2010, le runtime selectionne systematiquement la version sse2 à l'execution, mais elle est beaucoup plus rapide que celle de gcc: 146 cycles pour tan, 103 pour expf)

Google Nexus 7

Hé ouais j'ai un nexus 7 depuis quelques jours. Vous êtes incroyablement nombreux à réclamer un billet de blog à ce sujet, voici donc un petit compte-rendu:

  • j'aime bien le dos. Je comprends pourquoi chaque article sur le nexus 7 en parle, c'est un truc assez reussi pour du plastoc. C'est vraiment agréable au toucher et ça ne fait pas cheap.
  • l'écran est sympa, sans etre une resolution de folie (1280x800) ça fait quand même des pixels bien petits. Par contre faut une vue pas trop mauvaise.
  • la tablette est livrée avec 'A la recherche du temps perdu' et 'Transformers III' , manifestement google n'a pas peur des contrastes forts. On a du mal à imaginer un film plus con que transformers III.
  • jelly bean est fluide
  • ça ne chauffe pas, enfin je crois. Faudrait quand même voir en faisant tourner les 4 cores à 100% , ça doit bien finir pas devenir au moins tiede.
  • y'a pas de dock digne de ce nom, qui permettrait de brancher un périphérique usb tout en rechargeant la tablette: sainul.
  • le micro-usb c'est quand même un bien pénible a brancher/débrancher , je comprends pourquoi apple n'a pas voulu se faire chier avec ce truc.
  • l'installation du sdk + ndk android est quand même bien pourrie , le nombre de machins a installer (java, ant, eclipse, sdk, ndk, plugin eclipse, telecharger les images et les libs pour diverses releases d'android, préparer des devices virtuels pour les tests)
  • c'est quand même un peu long pour deployer une application sur la machine, genre un paquet de 13Mo prend environ 20secondes pour etre installé sur le nexus 7. Ca reste quand même nettement plus rapide que dans l'emulateur.
  • la latence audio est A PLEURER. Quand je joue du fart piano il y a bien un quart de second qui s'écoule entre le relachement de la la touche et le bruit de pet. ça valait vraiment la peine que google se vante de la latence "améliorée" dans jelly bean. Vraiment ça craint. Et en passant par opensl c'est pas mieux (en fait je crois que c'est pire, j'ai l'impression d'avoir plus d'un quart de seconde de latence)
  • y'a zero api pour gerer les periph MIDI branchés sur le port usb, encore un signe que google n'a vraiment rien a foutre de l'audio. La solution c'est de réinventer la roue avec ce genre de truc: android USB-MIDI driver. On dirait aussi que brancher et debrancher des trucs USB a tendance a faire planter la tablette..
  • le tegra 3 n'est quasiment jamais à 1.3GHz , sa fréquence de croisière quand il y a de la charge semble être 1.2GHz , et sinon il descend très vite en fréquence, 100MHz quand la tablette est idle

Google WEBP roxor

Voila un format d'image qui n'a pas reçu beaucoup d'amour quand il a été annoncé, qui n'est pas supporté par firefox, qui n'est pas encore complètement sec (y'a un gros TODO pour les PPC dans le code), et pourtant il est déjà bien. Carrément meilleur que jpg pour les images qui m'intéressent (des bitmaps assez détaillés avec parfois du texte), il permet de remplacer completement le png puisqu'il supporte la transparence. La décompression est très rapide, la lib est raisonnablement petite et portable, bref c'est de la boulette. J'avais commencé à m'intéresser à sa variante webpll pour faire du lossless, mais c'est nettement plus long a compresser/décompresser, ça ne fait que 30% de mieux que le png et webp me permet d'obtenir la qualité d'image souhaitée avec des images beaucoup plus petites.

Donc merci google pour webp, c'est vraiment sympa.

pretty fast FFT

Voici le code d'une FFT raisonnablement rapide, raisonnablement petite (le code tient dans un fichier) et raisonnablement pas chiante au niveau de la license (c'est du bsd). Paradoxalement, ce n'était pas facile d'en trouver une qui réponde à ces contraintes.

Que s'appelorio PFFFT.

Pandaboard

Depuis une semaine j'ai une Pandaboard ! Contrairement au toshiba AC100 avec son tegra2 qui pue, celle-ci est basée sur le OMAP4 de texas instruments, qui a une unité SIMD NEON, comme tous les autres cortex A9 et le futur tegra 3. Le cpu dual core fonctionne a 1GHz, la carte mesure 10x12cm , actuellement elle tourne sous ubuntu 11.04 et consomme 4W (mais je ne suis pas sur du tout de la precision du wattmetre). En gros c'est de la boulette.

xmodmap

Steve jobs est un génie, mais le coup de faire des claviers differents ça n'est pas à 100% une super idée. En particulier quand on veut faire tourner linux ou windows sur un mac. Comme j'ai encore passé un temps dingue a essayer d'avoir un clavier apple qui se comporte a peu prêt correctement sous linux (et qui permet en prime d'avoir le middle-click avec le clavier), voici le .Xmodmap auquel j'ai abouti:

! dans le xorg.conf je pars de : XkbModel macintosh , XkbLayout fr
! curieusement les touches @# et <> sont inversees
! en prime , j'assigne le middle click a 'ISO_Level3_Shift-<'
keycode  94 = at numbersign periodcentered Ydiaeresis periodcentered Ydiaeresis
keycode  49 = less greater lessthanequal greaterthanequal Pointer_Button2 Pointer_Button2
! je remplace le dead tilde par un tilde pas dead
keycode  57 = n N asciitilde dead_tilde asciitilde dead_tilde
! fait en sorte que les deux touches 'option' fonctionnent comme sous mac
keycode 64 = ISO_Level3_Shift
! utilise la touche 'command' en tant que alt/meta
keycode  115 = Alt_L Meta_L
! je vire les nobreakspace parce que ca pue
keycode  65 = space space space space space space

! pas trop compris la... 
remove mod1 = ISO_Level3_Shift
add mod1 = Alt_L

Stupid script of the day

Here is a python script that I use to invoke the cl.exe compiler (microsoft visual c++) from the cygwin command line. It automatically rewrites the cygwin paths as native windows paths, and replaces the ugly '/foo' options of cl.exe with nice '-foo' options . It is very minimalistic, it could do much more such as trying to map much more gcc-like options to their msvc equivalent ( "-fno-exceptions" with "/EHsc" , "-g" with "/Zi" etc)

http://gruntthepeon.free.fr/cygmsvc

cpufreq sucks for audio

People doing real-time audio processing on Linux are generally very picky about details (real-time kernel with full preemption, fine-tuning or the IRQ priorities, ...). However I did not cross any document mentioning possible drawbacks of CPU frequency throttling. This feature is now available everywhere. Even my quad-core tower spends most of its time at 1.6GHz instead of 2.66GHz. My good old D800 laptop runs at 600MHz when it is idle, and jumps to 1.6GHz when it needs to. But the question is how fast does it transition from 600MHz to 1.6GHz ? This small program does measure it, using the TSC counter. Please note that this does not work on recent CPU as the TSC rate is no more equivalent to the processor speed (that is its rate is now constant).

And finally the result: on my single-core pentium-m, the max cpu frequency is reached after ~0.05 - 0.1 seconds on a desktop kernel (2.6.27) , and 25 ms on the "linux-rt" kernel . Definitively not a negligible latency. That means that if your audio processing load is not smooth, and you have bursts of cpu usage (for example when new notes are played on your great but cpu-hungry softsynth), then you will not be able to use 100% of your cpu, but only 600/1600*100 = 37.5% of its power ! Not great.

But maybe using threads with real-time (SCHED_RR) priority will help ? Just run the program with "-rt" argument. Now the latency is 1 full fucking second on the "normal" kernel, and +INF seconds on the linux-rt kernel !! Not great at all. Of course, cpufreq being a deamon, it has much less chances to get scheduled where a very high priority thread is consuming all cpu. Ok, that is not fair, so you can add a small usleep(10) in the main loop in order to leave it a chance to do its job (the "pthread_yield" is not enough, apparently). And then the latency is back to ~0.1sec on desktop kernel , but still >10sec on rt kernel.

As a conclusion, I would say that doing a 'cpufreq-set -g performance' when your audio software is running is certainly not a stupid idea. Especially on a single-core cpu where the cpufreq deamon is likely to be starved when things start to get hot.

Stripping dead code

Bloat is bad. Here is how to remove unused functions from your binaries:

  • On MacOS: really easy, just use the -dead_strip linker option, that Steve Jobs in his infinite wisdom, has invented for us. The -dead_strip_dylibs will also remove references to unused dynamic libraries.
  • On Linux: a bit more tricky. You have to compile the sources with the -ffunction-sections -fdata-sections , and then link with the --gc-sections flag.
  • On Windows, with msvc: you have to compile the sources with /Gy option ("enable function-level linking"), and then link with /OPT:ref /RELEASE

sin_ps en sse2

C'est l'heure de rendre hommage à msvc 2008 pour sa puxoritude. Le saviez-vous:

  • en mode 64 bits, visual c++ n'autorise plus l'assembleur inline. C'est peut être une bonne chose étant donné que bon nombres de dev windows ont tendance à pisser des kilometres d'assembleur tout pourri et non portable quand des intrinsics font le boulot mieux et plus portablement.
  • en mode 64 bits, visual c++ ne permet pas d'utiliser les fonctions MMX, eh oui ! Pourtant rien ne l'interdit en principe, c'est juste un choix débile de ms.

Ce qui m'amene à la raison d'etre de ce billet, la première mise à jour majeure de sse_mathfun.h ! Avec des bon gros bouts de code SSE2 bien filandreux inseré subtilement dans des #ifdef USE_SSE2, ce qui permet de compiler le susdit fichier avec le cl.exe 64 bits.

truc qui sux en c++

Bon j'en ai marre. Le truc qui me fait particulièrement chier avec le c++ ces derniers temps c'est ce genre de truc:

class Foo {
  virtual void quack(bool like_a_duck) const { cout << "miaou"; }
};

class Bar : public Foo {
  void quack(bool) { cout << "coin"; }
  /* RRRRAAAATAAAAAAIIIII J'AI OUBLIE LE CONST COMME UN
      GROS NUL ET LE COMPILO NE VA RIEN ME DIRE */
};

Ce que je voudrais, c'est pouvoir dire au compilateur cette fonction "quack(bool)" que je definis ici dans ma classe dérivée, c'est une fonction qui surcharge une fonction virtuelle "quack(bool)" définie dans une classe parente. Si tu ne trouves pas de fonction "quack(bool)" dans les classes parentes qui soit virtuelle, ça veut dire que j'ai fait une connerie (j'ai oublié un const, ou un & etc...) et je veux que toi, compilateur, tu fasses une erreur. Les fonctions virtuelles pures c'est bien gentil mais y'a des fois où elles ne sont pas pures et qu'on a quand même besoin de les overrider.

Un moyen d'annoter les fonctions qu'on override ça aurait l'avantage:

  • de documenter le code pour que je vois d'un coup d'oeil quelles sont celles qui sont des fonctions virtuelles overridées.
  • de vérifier que je ne me suis pas planté dans son prototype.
  • de m'économiser quelques heures de chasse au bug.

Sur codeproject y'a une tentative d'annotation des fonctions virtuelles mais c'est pas super élégant ... Y'a aussi un warning specifique dans g++ qui essaye de detecter ce genre de bugs mais c'est un truc heuristique et donc y'a des faux-positifs -> c'est de la merde.

Les regexp

Ken Thompson et Dennis RitchieComme j'avais besoin d'un petit code portable et pas trop lourd en dépendances pour matcher des regexp j'ai perdu un peu (beaucoup trop en fait) de temps à regarder comment ça marche et si je pouvais en écrire un qui soit minimal et rapide.

En gros il y a deux approches:

  • l'approche historique, qui est celle employée par Ken Thompson il y a plus de 40 ans, qui consiste à construire un automate a partir de l'expression regulière, et ensuite de lui balancer les chaines qu'on cherche à matcher et regarder ce qui en sort.
  • l'approche populaire, qui consiste a explorer de façon recursive l'arboresence de toutes les possibilités.

L'approche recursive est celle employée maintenant dans quasiment tous les moteurs de regexp. Et pourtant si on lit ce texte de Russ Cox , c'est un très mauvais choix: contrairement au NFA de Thompson, le temps de test d'une regexp un peu pathologique va exploser exponentiellement avec l'approche récursive, alors qu'avec le NFA la complexité maximale est garantie (linéaire par rapport au nombre de caractères dans l'expression regulière et dans la chaine à matcher).

The regular expression implementations used by today's popular tools are significantly slower than the ones used in many of those thirty-year-old Unix tools.



L'argumentaire de Russ Cox est très convainquant, du coup j'ai fait un petit code de regexp utilisant le NFA, en me disant que les quelques sacrifices à faire pour loger tout ça dans un automate valaient bien ces performances annoncées. Les sacrifices sont:

  • pas de backreferences du genre "(coin|pan)\1" pour matcher "coincoin" ou "panpan"
  • coût supplémentaire matcher les sous-expressions entre parenthèses (il faut ajouter des "tags" à chaque etat actif dans l'automate pour chaque groupe de parentheses)
  • coût supplementaire pour gerer les répétitions comptées "(coin){2,5}" (il faut remplacer ça par (coin)(coin)(coin)?(coin)?(coin)? dans l'automate)

Pour finir j'ai quand même voulu vérifier que mon code allait vraiment aussi vite qu'annoncé en le comparant à une version de réference: PCRE (perl-compatible regular expressions). Et là grosse deception.. D'accord PCRE explose sur des expressions débiles du genre matcher "a?a?a?a?a?a?a?a?a" avec "a", mais sur des regexp bien basiques il est généralement 3x à 10x plus rapide que mon implémentation :'(

OWNED

Rosetta

Rosetta c'est le translateur de code ppc vers x86 qui permet d'executer de façon totalement transparente des binaires initialement compilés pour powerpc sur les mac intels. Jusqu'à present je ne l'avais utilisé que via la gui mais hier je suis tombé sur ce blog qui explique comme l'utiliser en ligne de commande, et ça déchire !

Pour lancer un executable en ppc: /usr/libexec/oah/translate /path/to/ppc_program

Et encore plus fort, on peut debugger du code ppc: OAH_GDB=YES /path/to/ppc_program et à côté: gdb --oah suivi de la commande attach pid_of_ppc_program et hop

C'est génial.

STL containers fight

sumofight I like std::vector a lot. I use it almost everytime I need a container. I like it because it is very simple to use, it is very efficient (the data is stored contiguously in memory). It is even good for insertion of new elements: if one knows in advance the number of elements, the insertion cost (at the end) is O(1), just like std::list, and it is O(log(n)) when one uses push_back (it does not reallocate each time a new element is appended). When the number of elements is small (let's say less than 30), searching for a value is generally faster with an (unsorted) std::vector than with something more powerful such as std::set.

std::vector is a good general purpose solution.

So I use it a lot. On a lot of classes. And I came to wonder what is the impact of using all these std::vector<...> on the code size. Is it more "dense" than other containers, such as std::list ?

As an experiment, I took a small program instanciating 100 container classes std::vector<FooPlop1>, std::vector<FooPlop2>, ....std::vector<FooPlop100> . The program creates the containers, fill them once, and iterates on them (with a simple side-effect so that the compiler is not tempted to optimize everything away). Here are the results for various gcc versions / optimizations flags, the first column give the size in byte of each std::vector<FooPlopXX> (that is the total stripped binary size divided by 100), the second one gives the compilation time (in seconds). The compiler used is g++-4.3 on debian, but the relative results do not seem to depend too much on the compiler version (I checked with gcc 3.4, 4.1, 4.2, and version 4.3 was the best). Building 64bit binaries has no more effect than a general 20-30% increase in size.

# std::vector
 3058 16.98 # g++-4.3 -m32
  697 17.61 # g++-4.3 -m32 -O2
 1319 27.20 # g++-4.3 -m32 -O3
  599 15.79 # g++-4.3 -m32 -Os
# std::list
 1708 11.66 # g++-4.3 -m32
  293  9.76 # g++-4.3 -m32 -O2
  575 26.17 # g++-4.3 -m32 -O3
  288  9.16 # g++-4.3 -m32 -Os
# __gnu_cxx::slist
 1845 12.01 # g++-4.3 -m32
  467 10.86 # g++-4.3 -m32 -O2
  848 17.28 # g++-4.3 -m32 -O3
  413  9.97 # g++-4.3 -m32 -Os
# std::deque
 8219 39.19 # g++-4.3 -m32
 3407 55.98 # g++-4.3 -m32 -O2
 3442 59.47 # g++-4.3 -m32 -O3
 2751 44.31 # g++-4.3 -m32 -Os
# std::set
 4703 26.32 # g++-4.3 -m32
  864 18.36 # g++-4.3 -m32 -O2
 1306 22.22 # g++-4.3 -m32 -O3
  774 17.68 # g++-4.3 -m32 -Os

So what are the conclusions ? std::list wins easily against all others containers on the "bloat" side (we can ignore slist which is deprecated). And it compiles much quicker.

However, std::set is much, much less bloated than what I imagined, good to know.

std::deque proves once again that he is the shame of the STL containers. Slow to compile (50 seconds for a program that just instantiates 100 different std::deque is a lot!) , slow to iterate, AND bloated.

A last remark: using containers of pointers (std::vector<FooPlop1*>) does not change the numbers given above.

Not dead

Est-ce que ça marche ?

Bon on dirait que oui. Un grand merci à Free pour avoir supprimé sans préavis la table dc_comment suite à l'irruption d'un bot spammeur un peu virulent. Comme je n'avais pas de sauvegarde, les commentaires si avisés de mes nombreux visiteurs ont disparu. Pour toujours.

En plus j'ai du désactiver totalement les commentaires, 5 minutes après avoir recréé la table dc_comment il y avait déjà deux posts vantant des "videos de singes qui urinent dans la bouche" (en anglais)

Diffmerge

Le mois de décembre démarre en trompette, alors aujourd'hui je vais parler un d'outil que j'ai découvert y'a pas longtemps et arrache définitivement les poils: diffmerge. Autant le dire tout de suite: il n'est pas libre. Par contre, c'est le pied pour faire des 3-way merge, et j'ai l'impression qu'il est assez fort pour faire des diffs de qualité. Je l'ai ajouté comme outil de merge pour Mercurial, et franchement il est bien meilleur que le diff graphique d'Apple, et très simple à utiliser.

Et puisque on me demande d'être plus en phase avec l'actualité, je me permets d'addresser mes chaleureuses et sincères félicitations à Miss Chine qui a brillament remporté le concours Miss Monde 2007.

Les simpsons sur wii

Comme j'aime bien les simpsons et que j'ai une wii, j'ai un peu craqué sur le jeu intitulé "Les Simpsons: le jeu" qui vient de sortir. Alors je ne vais pas vous faire languir plus longtemps, voici mon verdict: c'est une merde.

Carbon is dying

Bon c'était annoncé depuis longtemps, mais maintenant que Leopard est sorti, c'est écrit noir sur blanc dans la doc:

http://developer.apple.com/documentation/Carbon/Conceptual/Carbon64BitGuide/PortingTo64Bit

Donc voilà, si on veut faire de la gui en 64 bits, il faudra se taper de l'objective C. Les API en C c'est fini...

Marche arrière

C'est bon j'ai vu Leopard, ça a l'air sympa et bien véloce, mais je crois que je vais laisser aux autres fanboys le soin d'essuyer les plâtres concernant les quelques bugs qui me gênent. Et je vais faire pareil pour la transition vers XCode 3.0 (si tant est qu'on puisse l'installer sur tiger) je crois..

Donc retour a Tiger, pour quelques temps.

ça m'a permis de découvrir que SuperDuper, l'utilitaire de clonage de partoches si utile, ne permet pas de restaurer une partoche Tiger quand on l'execute depuis Leopard. Je le soupçonne d'installer le noyau de leopard quand il dit qu'il "rend la partition bootable", et du coup ça fait un machin qui hurle a la mort quand on essaye de l'amorcer. J'ai quand même foiré deux restaurations avant de comprendre.. et mine de rien c'est à chaque fois un peu longuet de restaurer 70go de données .

Getting correct middle click and right click emulation on X11.app/Leopard

I'm writing this one in english because it may be helpful to some people. I am quite pissed off with the number of stupid bugs that are plaguing Apple's latest X11.app . Especially the fact that the so-called "emulate three button mouse" option is completely broken. In Tiger, it used to map 'option+click' to middle click, and 'command+click' to right click. In Leopard it is: 'option+click' = right click, and 'command+click' = 'Meta Middle-click' ... WTF ?!

issuing these commands in a terminal:

defaults write org.x.X11 fake_button2 option
defaults write org.x.X11 fake_button3 control

restores the old behaviour for middle-click, and uses control for right click (so you get a real right click, and a meta-right-click). If anyone knows how to get right-click with 'command+click' I would be interested.

Ajax

Aujourd'hui j'ai fait un peu d'ajax, c'était bien.

Ping

J'ai ouï dire que quelques esprits chagrins laissaient entendre que ce blog était déjà l'abandon. Je tiens à signaler qu'il n'en est rien.

Vibro-macbouc 2

J'ai renvoyé le Seagate à 7200 rpm et je l'ai sagement echangé contre un Western Digital de 250Go à 5400rpm. Je monte le bouzin, les yeux pleins d'étoiles, persuadé de la perfection du résultat et... MERDE IL VIBRE ENCORE. Moins, mais ça fleurte avec la limite du tolerable, du coup je ne sais pas si je vais le garder :'(

Je me demande ce que le disque original a de si spécial..

UPDATE Mon sens de l'observation toujours en éveil ma permis de noter qu'en appuyant très fort sur le mac les vibrations étaient notablement atténuées. Je viens de glisser un bout de carton sous le disque dur et miracle, ça ne vibre plus \o/

RE-UPDATE En remettant la batterie j'avais encore des vibrations. En fait j'ai dû mettre aussi un bout de carton sous le macbouc, au niveau du disque dur. Ce coup-ci, il n'y a vraiment plus aucune vibration ! Si le bout de carton à l'interieur du macbook ne prend pas feu c'est vraiment super !

Lancer de fleurs

fleursPuisque personne ne m'a fait de compliments sur la magnifique charte graphique de ce blog, je vais le faire moi-même:

Je trouve ce blog très beau.

xterm tuning

pouet pouet Bien souvent, on me demande quel est mon secret pour avoir des xterms si beaux. Et c'est en fanfare que je le dévoile ci-dessous. ça se met dans le .Xdefaults, et ça remplace les 16 couleurs à chier par 16 belles couleurs aux tons voisins mais moins criards. C'est plutôt adapté à un term sur fond fond noir, mais ça passe aussi très bien sur un fond blanc.

XTerm*background:  black
XTerm*foreground:  gray
XTerm*cursorColor: yellow
XTerm*color0:      black
XTerm*color1:      #9e1828
XTerm*color2:      #aece92
XTerm*color3:      #968a38
XTerm*color4:      #8181f1
XTerm*color5:      #963c59
XTerm*color6:      #418179
XTerm*color7:      gray
XTerm*color8:      gray40
XTerm*color9:      #d14b12
XTerm*color10:     #78ce23
XTerm*color11:     #f4af0c
XTerm*color12:     #2b77f2
XTerm*color13:     #cc2a98
XTerm*color14:     #15a5c1
XTerm*color15:     white

\o/

Ayé moi aussi j'ai un blogue