Interrupted System Call
Hier j'essayais de terminer un petit player mp3 sur nos appareils eInk, mais au démarrage du mp3 ça quittait toujours brusquement. Le code récupéré des taiwanais utilise libmad, et pour faire simple, le principe est le suivi :
- On ouvre un flux sur "/dev/dsp"
- On le configure
- Libmad décompresse le mp3 petit à petit, et à chaque morceau décompressé on le balance dans /dev/dsp
- On referme le flux quand on a fini...
Parfois ça quittait dès le départ, et parfois on avait genre 1/4 de seconde du mp3 avant que ça ne quitte... On a rapidement repéré à quel endroit ça quittait : au moment d'écrire dans /dev/dsp (par blocs de 8192 octets), ça s'arrêtait très rapidement avec un message d'erreur : "Interrupted System Call".
Alors, à quoi correspond ce message ? En fait c'est tout simple : on a fait un appel système (ici, l'écriture dans /dev/dsp) qui a été interrompu par un signal... L'écriture dans /dev/dsp n'est en fait pas une opération atomique, donc on n'a aucune garantie qu'elle puisse se dérouler complètement en une seule fois.
La solution a mettre en place est assez basique : au lieu de quitter à la moindre interruption, on note combien d'octets ont déjà été écrits, on incrémente le pointeur d'autant, on décrémente la taille à écrire, et on relance le fwrite... Et ça marche !
Merci au site suivant pour la petite explication claire et précise : http://book.chinaunix.net/special/ebook/addisonWesley/APUE2/0201433079/ch10lev1sec5.html
Note au passage : c'est marrant de voir comment tout est flux sur Unix... Du coup, pour jouer un son, c'est aussi un simple flux dans lequel on envoie les données du son à jouer. On peut même faire un "cat toto.wav > /dev/dsp" et entendre son wav :p