<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Forum du club des développeurs et IT Pro - Blogs - r0d</title>
		<link>https://www.developpez.net/forums/blogs/43806-r0d/</link>
		<description>Developpez.com, le Club des Développeurs et IT Pro</description>
		<language>fr</language>
		<lastBuildDate>Mon, 07 Sep 2026 12:54:13 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>https://forum.developpez.be/images/misc/rss.jpg</url>
			<title>Forum du club des développeurs et IT Pro - Blogs - r0d</title>
			<link>https://www.developpez.net/forums/blogs/43806-r0d/</link>
		</image>
		<item>
			<title><![CDATA[Journal d'un développeur ivre : L'enfer de l'audio dans Unity #1]]></title>
			<link>https://www.developpez.net/forums/blogs/43806-r0d/b9911/journal-d-developpeur-ivre-l-enfer-l-audio-unity-sharp1/</link>
			<pubDate>Tue, 24 Nov 2020 20:00:55 GMT</pubDate>
			<description>Unity est un très bon outil....</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">Unity est un très bon outil.<br />
<br />
Par exemple, imaginons que vous souhaitez manipuler des textures, ou des images, ce qui revient au même, mais comme disait le grand-frère, &quot;La guerre c'est la paix&quot;. Enfin bref. Si vous souhaitez importer, exporter, serialiser, manipuler des images dans Unity, vous avez à disposition pléthore de classes, fonctions, outils, tout ce dont vous avez besoin, parfois même tellement qu'on peut s'y perdre.<br />
En revanche, si vous souhaitez manipuler des fichiers audio, j'aime autant vous prévenir de suite : c'est la chienlit !<br />
Il n'y a même pas une fonction pour charger un fichier audio !<br />
Non mais mais allô ?! Les mecs ils font un éditeur de jeu vidéo et ils prennent pas leur shampooing ?!<br />
<br />
Nous, on aimerait bien pouvoir écrire du code genre :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code csharp :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:36px;">AudioSource source = AudioSource.LoadFromFile<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;C:/mon/son/qui/tue.wav&quot;</span><span class="br0">&#41;</span>;</pre>
</div>Car c'est l'équivalent de ce que je fais pour mes textures.<br />
<br />
Et bien non, on peut pas faire ça.<br />
Tenez-vous bien, pour charger un fichier audio qui est sur votre disque dur, il faut utiliser... tenez-vous bien... un client http qui va faire une requête ! <br />
Voici un exemple de code fournit par les gars de la team Unity et qui est censé fonctionner :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code csharp :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:96px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="26"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">string</span> url = <span style="color: #FF0000;">&quot;file://C:/mon/son/qui/tue.wav&quot;</span>;
WWW audioLoader = <span style="color: #0000ff;">new</span> WWW<span class="br0">&#40;</span>url<span class="br0">&#41;</span>;
<span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>!audioLoader.isDone<span class="br0">&#41;</span>
   System.Threading.Thread.Sleep<span class="br0">&#40;</span><span style="color: #cc66cc;">100</span><span class="br0">&#41;</span>;
audioSource.clip = audioLoader.GetAudioClip<span class="br0">&#40;</span><span style="color: #0000ff;">false</span>, <span style="color: #0000ff;">false</span>, AudioType.WAV<span class="br0">&#41;</span>;</pre></td></tr></table></pre>
</div>Bon c'est un peu relou, mais soit, allons-y.<br />
<br />
Bon évidemment, ça ne fonctionne pas.<br />
Premier problème, la classe WWW est deprecated.<br />
Bon c'est pas grave, ils nous disent qu'on peut la remplacer par la classe UnityWebRequest. <br />
Ok.<br />
Sauf que UnityWebRequest c'est un peu relou parce qu'il faut l'utiliser dans une coroutine. C'est un peu chiant mais allons-y. Du coup le code devient un truc comme ça :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code csharp :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #0000ff;">public</span> LoadAudioFile<span class="br0">&#40;</span>AudioSource sound<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
    Action&lt;AudioClip&gt; callback = <span style="color: #0000ff;">delegate</span> <span class="br0">&#40;</span>AudioClip clip<span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>clip != <span style="color: #0000ff;">null</span><span class="br0">&#41;</span>
           sound.clip = clip;
    <span class="br0">&#125;</span>;
&nbsp;
    LoadClip<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;file://C:/mon/son/qui/tue.wav&quot;</span>, AudioType.WAV, callback<span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
<span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> LoadClip<span class="br0">&#40;</span><span style="color: #0000ff;">string</span> path, AudioType audio_type, Action&lt;AudioClip&gt; callback<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
    StartCoroutine<span class="br0">&#40;</span>LoadAudioClipFromUrl<span class="br0">&#40;</span>path, audio_type, <span class="br0">&#40;</span>audioClip<span class="br0">&#41;</span> =&gt;
    <span class="br0">&#123;</span>
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>audioClip != <span style="color: #0000ff;">null</span><span class="br0">&#41;</span>
        <span class="br0">&#123;</span>
            callback.Invoke<span class="br0">&#40;</span>audioClip<span class="br0">&#41;</span>;
        <span class="br0">&#125;</span>
    <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;
<span class="br0">&#125;</span>
&nbsp;
IEnumerator <span style="color: #0000ff;">private</span> LoadAudioClipFromUrl<span class="br0">&#40;</span><span style="color: #0000ff;">string</span> audio_url, AudioType audio_type, Action&lt;AudioClip&gt; callback<span class="br0">&#41;</span>
<span class="br0">&#123;</span>
    <span style="color: #0000ff;">using</span> <span class="br0">&#40;</span>UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestMultimedia.GetAudioClip<span class="br0">&#40;</span>audio_url, audio_type<span class="br0">&#41;</span><span class="br0">&#41;</span>
    <span class="br0">&#123;</span>
        <span style="color: #0000ff;">while</span> <span class="br0">&#40;</span>!www.isDone<span class="br0">&#41;</span>
            System.Threading.Thread.Sleep<span class="br0">&#40;</span><span style="color: #cc66cc;">100</span><span class="br0">&#41;</span>;
&nbsp;
        <span style="color: #0000ff;">yield</span> <span style="color: #0000ff;">return</span> www.SendWebRequest<span class="br0">&#40;</span><span class="br0">&#41;</span>;
&nbsp;
        <span style="color: #0000ff;">if</span> <span class="br0">&#40;</span>www.isNetworkError<span class="br0">&#41;</span>
            Debug.Log<span class="br0">&#40;</span><span style="color: #0000ff;">string</span>.Format<span class="br0">&#40;</span><span style="color: #FF0000;">&quot;Error downloading audio clip at <span style="color: black;"><span class="br0">&#123;</span><span style="color: #cc66cc;">0</span><span class="br0">&#125;</span></span> : <span style="color: black;"><span class="br0">&#123;</span><span style="color: #cc66cc;">1</span><span class="br0">&#125;</span></span>&quot;</span>, audio_url, www.error<span class="br0">&#41;</span><span class="br0">&#41;</span>;
&nbsp;
        callback.Invoke<span class="br0">&#40;</span>UnityEngine.Networking.DownloadHandlerAudioClip.GetContent<span class="br0">&#40;</span>www<span class="br0">&#41;</span><span class="br0">&#41;</span>;
    <span class="br0">&#125;</span>
 <span class="br0">&#125;</span></pre></td></tr></table></pre>
</div><br />
Bon ok, c'est vachement de code pour pas grand chose mais soit.<br />
Sauf que ...<br />
Si le fichier qu'on veut charger n'existe pas, ben on est bloqué dans une boucle infinie et c'est pas beau à voir. Même alt+F4 ne nous sauve pas toujours.<br />
Bon ok, alors on ajoute des timeout et nbTry... et on gère tous les cas bizarres où le Network est &quot;buzy&quot;... oui parce que je vous rappelle que ce qu'on fait là, c'est une requête GET de type HTTP ... enfin bref...<br />
<br />
Après avoir bien blindé le code, ça semble fonctionner. Dans l'éditeur en tout cas. C'est quand même relou : tout ça pour charger un pauvre fichier audio... enfin bref ...<br />
<br />
Maintenant voyons voir ce que ça donne en stand alone.<br />
<br />
Hé bien là, figurez-vous, c'est le drame ! Les requêtes http partent dans le vide interstellaire et sont incapables de trouver un foutu fichier local ! <br />
Même avec le path codé en dur, rien à faire : vous vous mangez des 404 dans le museau; l'enfer de Dante est une sinécure à côté.<br />
Et votre beau fichier de log, que vous avez maintenu parfaitement propre avec la plus grande fierté depuis le début du projet, à tel point que lorsque le boss commence à péter une durite, seuls ces magnifiques fichiers de logs peuvent le calmer. Et bien vos beaux fichiers de logs, ben là ils sont complètement fuckés, parce que des requêtes http qui n'aboutissent pas, ben ça en fout partout !<br />
<br />
Du coup, ben là c'est moi qui commence à pèter une durite. Et encore, ce n'est que le début ...</blockquote>

]]></content:encoded>
			<dc:creator>r0d</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/43806-r0d/b9911/journal-d-developpeur-ivre-l-enfer-l-audio-unity-sharp1/</guid>
		</item>
		<item>
			<title><![CDATA[Problème de synchronisation: une allégorie numérique de l'anarchisme.]]></title>
			<link>https://www.developpez.net/forums/blogs/43806-r0d/b1155/probleme-synchronisation-allegorie-numerique-l-anarchisme/</link>
			<pubDate>Mon, 22 Feb 2016 14:47:46 GMT</pubDate>
			<description>Bonjour. 
 
Je vais vous...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">Bonjour.<br />
<br />
Je vais vous raconter une allégorie qui s'est développée graduellement dans mon esprit depuis quelques jours. Depuis qu'un ami développeur m'a conté comment il a résolu un problème de façon simple, élégante et efficace, en sortant des standards établis. À partir de ce matériau brut, un bel exploit technique, mon esprit a travaillé, modelé, extrapolé, pour finalement élaborer cette petite essence symbolique. J'ai finalement décidé de mettre cette pensée par écrit parce que je la trouve particulièrement intéressante. Elle permet d'ouvrir de nombreuses portes que nous préférons usuellement garder fermées, par oubli ou désintérêt, mais qui peuvent déboucher sur des jardins fertiles.<br />
<br />
Avant de me lancer dans le récit, je me dois de prendre une précaution préliminaire. Elle paraîtra certainement futile ou absconse pour certains, mais pour les dialecticiens, elle est fondamentale et inévitable: ce texte n'est pas une comparaison, mais une allégorie. Il ne faut pas le lire comme un élément de démonstration dans un essai de philosophie axiomatique, mais comme une illustration dans un argumentaire d'éthique politique.<br />
<br />
Voyons maintenant ce problème de synchronisation.<br />
<br />
Mon ami voulait implémenter un petit système de synchronisation entre plusieurs appareils. Pour des raisons techniques qu'il est inutile d'aborder ici, il ne souhaitait pas utiliser un outil existant, mais il préférait l'implémenter lui-même. Les appareils en question étaient des <a href="https://fr.wikipedia.org/wiki/Raspberry_Pi" target="_blank">Raspberries</a>, et le problème était le suivant:<br />
En entrée, nous avons une vidéo. Cette vidéo doit être divisée en plusieurs, disons en 6 pour l'exemple (3x2), puis chaque partie de la vidéo doit être affichée sur un écran différent. Chaque écran étant contrôlé par un Raspberry (chaque écran a son propre Raspberry).<br />
<br />
<img src="https://www.developpez.net/forums/attachments/p201534d1456152004/c-cpp/outils-c-cpp/cppbuilder/nombre-fichiers-ouverts-simultanement/lenna.png/" border="0" alt="Nom : lenna.png
Affichages : 285
Taille : 92,7 Ko"  style="float: CONFIG" /><br />
<br />
Le découpage de la vidéo en 6 vidéos est une question triviale que résout la première API de traitement d'image venue. En revanche, et ce fut inattendu, le problème que rencontra mon ami fut au niveau de la synchronisation. Puisque chaque appareil est exactement identique, et que chacun d'entre eux ne fait rien d'autre que de lire sa propre vidéo, il paraissait évident que chacun lirait sa vidéo à la même vitesse que les autres. Et pourtant, il n'en fut rien. Pour des raisons que les électroniciens doivent connaître, certains lisent plus vite que d'autres, et au cours de la lecture des vidéos, ils se désynchronisent entre eux.<br />
<br />
Pour résoudre ce problème, l'approche standard consiste à utiliser une architecture maître/esclaves, dans laquelle le maître se charge de synchroniser les esclaves. Cette architecture posait de nombreux problèmes, alors l'ingénieux tenta une autre approche: pas de maître, pas d'esclave. De temps en temps, et à intervalle régulier, chaque appareil envoie à tous les autres son avancement dans la lecture (identifiant de la frame en cours), et ceux qui sont en avance attendent ce dernier.<br />
<br />
C'est tout.<br />
C'est aussi simple que cela, et ça marche parfaitement.<br />
<br />
Quelles réflexions peut-on développer à partir de ce petit exploit technique? Elles sont nombreuses, mais dans ce texte je voulais en aborder deux.<br />
<br />
La première, c'est une variation sur un très vieil argument de la pensée anarchiste. L'idée c'est qu'un Léviathan, un maître qui coordonne le tout, est nettement moins efficace qu'une méthode simple et intelligente, une éthique, appliquée à chaque individu. On retrouve cet argument par exemple chez Victor Hugo, qu'il a immortalisé dans le célèbre bon mot: &quot;l'ordre sans le pouvoir&quot;. L'idée c'est qu'il est plus efficace de mettre en place des règles simples que chacun respecte, plutôt que d'ériger une machinerie complexe dans laquelle chaque modification aura des effets de bord imprévisibles et souvent ingérables.<br />
<br />
La seconde est une considération sur l'égalité. Malgré le fait que ce mot soit gravé au fronton de tous les monuments français, ce concept n'est pas dans l'air du temps. Et je crois que c'est une erreur, peut-être la plus grande erreur politique de nos sociétés modernes. Oxfam nous informe que 1% de la population possède plus de la moitié des richesses mondiale, mais cela n'émeut aucuns responsables politiques. Un ministre d'un gouvernement socialiste souhaite des milliardaires, cela ne choque personne. Or il s'agit là implicitement d'un éloge de l'inégalité, puisque l'échec séculaire de la théorie du ruissellement a démontré que pour qu'il y ait des riches, il faut des pauvres.<br />
<br />
Mais qu'est-ce que l'égalité? Pour répondre à cette question, nous pourrions nous engager dans des constructions sémantiques, faire appel à l’étymologie. Nous pourrions nous noyer dans des études pragmatiques des étants, ou dans une historiographie de l'ayant été. Moi je vous propose une définition éthique, basée sur mon petit problème de synchronisation: l'égalité, c'est que ceux qui sont devant attendent ceux qui sont à la traine.<br />
<br />
Car à quoi sert d'arriver vite quelque part si on y arrive seul? L'Homme n'est rien sans l'Homme. Même le plus individualiste d'entre nous ne peux réfuter le fait qu'il a besoin d'agriculteurs, d'artisans, de services divers et variés. Sans tous ces gens qui travaillent pour nous, de façon plus ou moins directe, nous ne serions même pas capables de survivre. Et si c'est évident pour la survie, c'est aussi le cas pour l'épanouissement intellectuel. Nous avons besoin des autres, à tous les niveaux.<br />
<br />
J'aime bien pousser encore un peu plus loin cette idée et proposer le bon mot suivant: l'important ce n'est pas où on va, mais qu'on y aille ensemble.<br />
<br />
<br />
<br />
<i>Edité le 23/06/2016: une petite erreur s'était glissée dans ma description de l'ingénieuse solution trouvée par mon ami.</i></blockquote>

]]></content:encoded>
			<dc:creator>r0d</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/43806-r0d/b1155/probleme-synchronisation-allegorie-numerique-l-anarchisme/</guid>
		</item>
	</channel>
</rss>
