<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Artisan Numérique</title>
  <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1233"/>
  <link rel="self" type="application/atom+xml" href="http://artisan.karma-lab.net/node/1233/atom/feed"/>
  <id>http://artisan.karma-lab.net/node/1233/atom/feed</id>
  <updated>2008-02-12T11:36:15+01:00</updated>
  <entry>
    <title>L&#039;art de faire manger des fichiers WAV à TuxDroid </title>
    <link rel="alternate" type="text/html" href="http://artisan.karma-lab.net/node/1233" />
    <id>http://artisan.karma-lab.net/node/1233</id>
    <published>2007-10-05T04:31:51+02:00</published>
    <updated>2008-02-12T11:36:15+01:00</updated>
    <author>
      <name>Ulhume</name>
    </author>
    <category term="TuxDroid" />
    <category term="Aucun" />
    <category term="javafr" />
    <category term="OK" />
    <category term="Tutoriel" />
    <summary type="html"><![CDATA[<p>Grande bataille de gagnée ce soir... (euh... ce matin en fait, j'va être ben frai moi pour bosser  J'ai enfin réussi à enregistrer des sons dans cette maudite mémoire interne du TuxDroid. Oui je sais, j'occupe certaines de mes nuits étrangement... Mais une fois que je tiens un morceau, j'ai du mal à le lacher...</p>
    ]]></summary>
    <content type="html"><![CDATA[<p>Grande bataille de gagnée ce soir... (euh... ce matin en fait, j'va être ben frai moi pour bosser <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/smile.gif" title="Smiling" alt="Smiling" class="smiley-content"/> J'ai enfin réussi à enregistrer des sons dans cette maudite mémoire interne du TuxDroid. Oui je sais, j'occupe certaines de mes nuits étrangement... Mais une fois que je tiens un morceau, j'ai du mal à le lacher...</p>
<p>Car je ne veux pas critiquer les devs du pingouin mécanique, mais y'a du réellement vaudou là dessous... Je suis pas sur d'avoir bien compris... En fait pour stocker N sons dans le tux, il faut (attention, on s'accroche) :</p>
<ol>
<li>Lire le "sample rate" de chaque fichier audio. Information contenue dans le header du fichier wav (qui est constitué de 44 octets), sur 4 octets, en position 24.</li>
<li>Si le sample rate n'est pas très exactement de 8khz, il faut convertir le sample avec la commande sox source.wav -c 1 -r 8000 -b cible.wav.</li>
<li>Il faut ensuite regarder en position 40, la taille de la "charge utile" codé sur 4 octets. Chose étrange, le chiffre est inférieur à la réalité, c'est à dire tailleFichier-44.</li>
<li>Ensuite il faut merger tous les wav's en un seul. Pour cela, on récupère le header du premier wave, sauf la taille (40 octets donc, faut suivre <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>. On réserver 4 octets (pour la futur taille) et on ajoute à la queue leu-leu tes charges utiles (tout sauf les 44 premiers octets) de chacun des samples.</li>
<li>Et là commence le vaudou, le naïf aurait pu croire qu'il faille insérer la taille avec la somme de toutes les tailles... Oui mais non... En fait il faut insérer tailleDansHeader=sommeTailles+0.07*sommeTailles (au petits malin qui veulent factoriser, je rappelle que l'on est en arithmétique entière <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/wink2.gif" title="Wink" alt="Wink" class="smiley-content"/>. Pourquoi .07 ? aucune idée...</li>
<li>Bref, on insère la valeur ainsi trouvée et on se dit c'est fini. Ben non, car tant que la taille physique du fichier est inférieur à tailleDansHeader-44, on ajoute 12 espaces à la suite des données !!!</li>
<li>C'est pas fini, il faut ensuite réinitialiser la mémoire du tux, pour cela, on s'accroche, il faut d'abord envoyer la commande qui indique au Droid le nombre de sample qui vont arriver.</li>
<li>On attends 10 secondes !!!</li>
<li>On envoi à Tux un premier index en 0x400... Pourquoi, je sais pas, c'est comme si on définissant un premier sample "blanc"</li>
<li>Puis on envoi les N indexes suivant, en incrémentant à chaque fois avant de la taille (la vraie, celle du header d'origine) du sample en prenant bien soin de faire une pause de 100ms entre chaque envois...</li>
<li>Enfin, pour ceux qui se demandaient comment envoyer les données elles-même au Tux, ben c'est tout con, on envoi notre super WAV précédemment fusionné... dans la carte son USB avec un aplay -D hw:0,0 merged.wav...</li>
</ol>
<p>J'avoue que je ne m'attendait pas à un truc aussi délirant.. Je subodore que le coup de 0.07 et du padding avec des espaces à la fin permet au firmware de comprendre qu'il doit arrêter de stocker...<br />
Peu importe, aidé du code python de l'API d'origine et de celui de tuxgi, on y arrive. Mais serieux, c'est pas clair du tout à lire le Python... </p>
<p>En tout cas pour ceux qui veulent savoir comment la même chose peut maintenant être réalisée en Java :</p>
<div class='code-container-area'>
<div class='code-container'>
<div class="code">
<ol>
<li class="li1">
<div class="de1">WaveFile<span class="br0">&#91;</span><span class="br0">&#93;</span> files <span class="sy0">=</span> <span class="kw1">new</span> WaveFile<span class="br0">&#91;</span><span class="nu0">4</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">files<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw1">new</span> WaveFile<span class="br0">&#40;</span><span class="st0">&quot;./r2d2wst1.wav&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">files<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw1">new</span> WaveFile<span class="br0">&#40;</span><span class="st0">&quot;./saberon.wav&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">files<span class="br0">&#91;</span><span class="nu0">2</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw1">new</span> WaveFile<span class="br0">&#40;</span><span class="st0">&quot;./hyperdrv.wav&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li2">
<div class="de2">files<span class="br0">&#91;</span><span class="nu0">3</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw1">new</span> WaveFile<span class="br0">&#40;</span><span class="st0">&quot;./beamup.wav&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">tux.<span class="me1">sound</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">store</span><span class="br0">&#40;</span>files<span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p>C'est sur, une fois que le gros est caché dans l'API, c'est plus simple <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/smile.gif" title="Smiling" alt="Smiling" class="smiley-content"/> A noter que l'objet WaveFile converti tout seul les samples au bon format. </p>
<p>Ban ben vala, je suis content, j'ai saoulé tout le monde, je vais me coucher <img src="http://artisan.karma-lab.net/sites/all/modules/contrib/smileys/packs/crystal/smile.gif" title="Smiling" alt="Smiling" class="smiley-content"/></p>
    ]]></content>
  </entry>
</feed>
