Nécessité de la correction des erreurs
Dans tout système qui manipule de l'information, il est techniquement impossible, sans technique de codage, d'éviter qu'une information ne soit modifiée par des phénomènes d'origines diverses, mécaniques, électriques, électromagnétiques etc... On imagine sans peine que certaines situations exigent une intégrité absolue des données, et on en arrive parfois à considérer des situations surréalistes. Par exemple, pour les ordinateurs, aussi simples soient-ils, on a très sérieusement étudié les perturbations que pouvaient engendrer les particules cosmiques! C'est une des raisons qui ont motivé l'adjonction d'un bit de parité après chaque octet.
La nature des erreurs dépend du mode de fonctionnement du système et le disque compact n'échappe pas à cette règle. Nous avons vu qu'après la conversion analogique/numérique, l'information était représentée par une séquence d'échantillons binaires codés sur 16 bits. Imaginons qu'un bit d'un échantillon soit altéré. De la même manière qu'un grain de sable peut bloquer tout un rouage, ce bit erroné peut anéantir tous les efforts consacrés à la qualité de reproduction.
L'échantillon de la courbe amplitude/temps est associé à un entier relatif, d'autant plus grand que le point est ``haut'' (ou bas). Supposons que cette valeur soit 13835. Sa représentation binaire sur 16 bits donne 00110110 00001011. Il est évident que si le 16ème bit (à droite) est 0 au lieu de 1, l'erreur est négligeable, le point associé ne sera décalé que d'une bande d'échantillonnage. Par contre, si c'est le premier bit qui est faux, on a une discontinuité énorme par rapport à la courbe originale, et la reconstitution du signal en est fortement affectée.
Ce problème n'est pas propre au disque compact, mais la densité d'information qu'autorise le support rend le problème d'autant plus aigu. On peut très facilement estimer la quantité de bits qui peuvent être altérés par une rayure sur la surface du disque. Un calcul rapide nous montre qu'une simple rayure de l'ordre d'un millimètre suffit à détruire environ 3300 bits d'information sur la piste! Il ne s'agit là que des rayures, et il existe malheureusement bien d'autres sources d'erreurs à considérer, les poussières, le voile du disque, les interférences, ou tout simplement des défauts de métallisation de la surface (que l'on peut facilement apercevoir à l'oeil nu en regardant le disque en contre-jour).
Nous allons voir que le code C.I.R.C. (Cross Interleaved Reed-Solomon Code) utilisé dans le système du disque compact permet de corriger1 totalement 3840 bits effacés, et même jusqu'à 12288 bits par interpolation.
Codes raccourcis, codes démultipliés
On supposera connues les notions fondamentales de la théorie des codes correcteurs et des corps finis. Le lecteur pourra consulter [11], [12] pour les codes et [10], [13] pour les corps finis. Dans tout ce qui va suivre, Fq désigne le corps à q éléments et d la distance de Hamming. Pour un code C, on désigne par n sa longueur, k sa dimension, e sa capacité de correction, et d sa distance minimale (aucune confusion n'est à craindre avec la distance de Hamming).
où ci est la i-ème colonne de la matrice génératrice de C, où < . , . > désigne le produit scalaire usuel sur Fqk et µ est un vecteur de Fqk. Le code C' est donc l'espace orthogonal aux t premiers vecteurs colonnes de la matrice génératrice de C, c'est-à-dire:
Le résultat qui suit est essentiel et va mettre en évidence l'intérêt des codes linéaires raccourcis.
Les codes linéaires que l'on sait bien manipuler ne permettent pas de choisir tous les paramètres essentiels, à savoir distance minimale, dimension et longueur; en général deux des paramètres fixent le troisième. Cette ``règle'' ne change évidemment pas pour les codes raccourcis si ce n'est que l'on peut construire k codes raccourcis distincts du code initial à partir d'un même code linéaire(n,k), on a donc à notre disposition non plus 1 mais k + 1 codes (bien que le code nul ne soit pas d'un grand intérêt). De plus la proposition 2 laisse entendre qu'il est parfois possible d'améliorer la capacité de correction en choisissant correctement le code raccourci. L'exemple qui suit nous en donne la preuve:
Exemple: Considérons le code C de longueur 5 et de dimension 2 sur F2 de matrice génératrice suivante:
1 1 0 1 1 |
1 0 1 0 0 |
La distance minimale de C est d = 2 et si on considère le code raccourci de C obtenu en prenant le vecteur nul et (0,1,1,1,1) et en éliminant la première composante, on trouve bien un code linéaire C'' = {(0,0,0,0),(1,1,1,1)} de distance minimale d'' = 4, de longueur 4 = 5 - 1 et de dimension 1 = 2 - 1.
Remarque: On peut généraliser ce résultat. Supposons que le code est e-correcteur (e = [(d -1) / 2] mais n'est utilisé que pour corriger e' erreurs avec e' < e. Si une erreur sur un mot c du code ne le ``déplace'' pas dans une boule de rayon e' centrée sur un autre mot du code, alors cette erreur est détectée. Le nombre d'erreurs détectables est donc donné par le poids maximum du mot erreur, soit d - (e' + 1). Ce résultat sera utilisé pour le disque compact.
Si on considère un code linéaire C(n,k) sur le corps Fpm avec p premier, chaque symbole de Fpm peut s'écrire comme un mot de Fpm. En effet, on peut décomposer ce symbole dans une base de Fpm considéré comme un Fp-espace vectoriel, dans la base (1, ß, ..., ßm - 1) par exemple, où ß est un élément primitif de Fpm.
Si d est la distance minimale du code C, qu'en est-il de la distance minimale du code démultiplié? Nous allons plutôt nous intéresser à la capacité de correction du démultiplié pour les paquets d'erreurs. Le lecteur pourra consulter [14] pour la distance minimale du démultiplié d'un code.
Effacements, paquets d'erreurs
Comme le laissait entendre l'introduction, les erreurs les plus fréquentes sur le disque compact sont dues à des rayures. Cela entraîne des erreurs consécutives sur le canal binaire. On parlera alors de paquets d'erreurs et nous allons voir qu'on peut augmenter sensiblement la capacité de correction pour ce type d'erreurs.
Dans certaines situations, il est possible que le système ne sache pas interpréter une information, par exemple on ne peut décider s'il s'agit d'un 0 ou d'un 1. Dans ce cas on est en présence de ce que l'on appelle un effacement. Il y a une différence entre une erreur et un effacement, une erreur correspond à un symbole faux, tandis que pour un effacement, on ne sait pas quel symbole interpréter. Cela signifie que la position de l'effacement est connue et cette indication a priori va permettre de ``corriger'' plus d'effacements que d'erreurs. Pour le disque compact, il faudra considérer simultanément les deux situations, erreurs et effacements.
L'exemple suivant est plus parlant: soit c = (c1, ...,c7) un mot d'un code linéaire C de longueur 7, de dimension 3 et de distance minimale 5 (corrigeant donc 2 erreurs).
c1 | c2 | c3 | c4 | c5 | c6 | c7 | ||||||||||||||
c1,1 | c1,2 | c1,3 | c2,1 | c2,2 | c2,3 | c3,1 | c3,2 | c3,3 | c4,1 | c4,2 | c4,3 | c5,1 | c5,2 | c5,3 | c6,1 | c6,2 | c6,3 | c7,1 | c7,2 | c7,3 |
On voit bien que si la longueur d'un paquet d'erreurs excède 4 = 3(2 - 1) + 1 il peut y avoir plus de 2 symboles erronés dans le mot c.
Remarque: Dans certaines situations, le code démultiplié peut corriger m [(d - 1) / 2] erreurs sur un mot du code démultiplié, justement quand ces erreurs n'affectent que [(d - 1) / 2] symboles du mot contracté.
On sait que d(s1,s2) < u + 1 pour tous s1 et s2 dans S d'où
et l'inégalité triangulaire nous donne
Entrelacements
Pour augmenter la capacité de correction des codes pour les paquets d'erreurs, on utilise une technique dite d'entrelacement. Le principe est simple, au lieu de transmettre directement des mots du code, on transmet le premier symbole de chacun des mots, puis le deuxième etc...
Considérons l'exemple suivant pour illustrer la construction: soit C le code linéaire (7,4) de distance minimale d = 3 sur F2 de matrice génératrice G suivante :
1 0 0 0 1 1 1 |
0 1 0 0 1 1 0 |
0 0 1 0 0 1 1 |
0 0 0 1 1 0 1 |
Soient c1=(1,1,0,0,0,0,1), c2 = (0,0,1,1,1,1,0) et c3 = (0,1,1,1,0,0,0) trois mots du code. Le code permet de corriger au plus une erreur sur chacun de ces mots. Supposons que l'on veuille transmettre ces trois mots dans cet ordre. Considérons la matrice dont les lignes sont c1, c2 et c3 :
1 1 0 0 0 0 1 |
0 0 1 1 1 1 0 |
0 1 1 1 0 0 0 |
Si on transmet maintenant les colonnes successives de cette matrice, c'est-à-dire la séquence
100 101 011 011 010 010 100
alors on dit que les trois mots ont été entrelacés. La conséquence de cet entrelacement est qu'un paquet d'erreurs de longueur au plus 3 (symboles en gras) sur cette séquence engendre au plus 1 erreur sur chacun des 3 mots. Si on considère un code linéaire C(n,k) sur un corps K et un entier t, on montre aisément que l'ensemble formé par tous les entrelacements de t mots du code C est un code de longueur nt, de dimension kt sur le corps K permettant de corriger des paquets d'erreurs de longueur lt si le code C corrige des paquets d'erreurs de longueur l.
Nous allons voir maintenant une technique d'entrelacement très performante mais qui nécessite une initialisation du processus. Nous allons exposer la méthode à partir du même exemple que pour la technique d'entrelacement précédente. On reprend les trois mots c1, c2 et c3 et les quatre mots c4, c5 et c6 suivants:
c1 = (1,1,0,0,0,0,1) |
c2 = (0,0,1,1,1,1,0) |
c3 = (0,1,1,1,0,0,0) |
c4 = (1,0,0,0,1,1,1) |
c5 = (0,1,0,0,1,1,0) |
c6 = (0,0,1,0,0,1,1) |
c7 = (0,0,0,1,1,0,1) |
On écrit le tableau dans lequel la ième ligne est formée par la ième colonne des 7 mots décalée à droite de i - 1 composantes. On transmet alors les colonnes du tableau 5 :
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
1 | 0 | 0 | 1 | 0 | 0 | 0 | ... | |||||||
* | 1 | 0 | 1 | 0 | 1 | 0 | 0 | ... | ||||||
* | * | 0 | 1 | 1 | 0 | 0 | 1 | 0 | ... | |||||
* | * | * | 0 | 1 | 1 | 0 | 0 | 0 | 1 | ... | ||||
* | * | * | * | 0 | 1 | 0 | 1 | 1 | 0 | 1 | ... | |||
* | * | * | * | * | 0 | 1 | 0 | 1 | 1 | 1 | 0 | ... | ||
* | * | * | * | * | * | 1 | 0 | 0 | 1 | 0 | 1 | 1 | ... |
Les étoiles désignent les positions qui devront contenir un 0 à l'initialisation du processus. Les points de suspension en fin de ligne indiquent que l'on recommence le procédé avec 7 nouveaux mots du code et ainsi de suite jusqu'à la fin du message. Il faudra aussi achever le processus par des 0. Les symboles du mot c3 sont en jaune dans la matrice. Dans le message transmis, il y aura la 6ème et la 7ème colonne, c'est-à-dire la séquence
Il y a deux symboles du mot c3. Les symboles soulignés représentent un paquet d'erreur de longueur 8. Il est clair que pour tout paquet de longueur 8, il n'y aura jamais plus d'un symbole d'un mot du code qui sera affecté. On aurait pu décaler chaque ligne de r symboles, on dit dans ce cas que le code C a subi un entrelacement à retard r. On montre aisément que :
Remarque: Cette proposition est bien entendu valable pour des effacements.
Application : le code C.I.R.C.
On va s'intéresser à une famille de codes particuliers très utilisés dans la pratique pour leur grande capacité de correction, les codes de Reed-Solomon. Nous allons tout d'abord montrer que la distance minimale, et par conséquent la capacité de correction, d'un code linéaire (n, k) est bornée.
On donne maintenant un théorème essentiel sur la distance minimale des codes cycliques dont on trouvera une démonstration dans [11].
On peut donner la définition des codes de Reed-Solomon et ses propriétés (voir [11] pour les démonstrations).
Considérons le code de Reed-Solomon engendré par le polynôme g(x) = (x - ß).(x - ß2).(x - ß3)(x - ß4) où ß est un élément primitif de F28. Les paramètres du code sont n = 255, k = 251 et d = 5. On construit à partir de ce code deux codes raccourcis (Déf.-Prop. 1). Le premier est noté C1 et a pour paramètres n1 = 28, k1 = 24 et le second C2 a pour paramètres n2 = 32, k2 = 28. La distance minimale d1 (resp. d2) de C1 (resp. C2) est toujours 5 (prop. 17).
Rappelons qu'à la suite de l'échantillonnage, on regroupait 6 échantillons de 32 bits (16 gauches et 16 droits) en trame de 24 octets. Les symboles de la trame sont utilisés comme symboles d'information du code C1, on y ajoute donc 4 symboles de parité. Les mots du code ainsi formés sont entrelacés avec un retard de 4 (voir paragraphe 4) et servent alors de symboles d'information du code C2. On termine donc avec une trame de 32 octets.
Remarque: Nous verrons plus loin qu'avant l'entrelacement, les symboles subissent une permutation qui sera nécessaire pour l'interpolation dans le cas de très grands paquets d'erreurs.
Ce codage est appelé Cross Interleaved Reed-Solomon Code, c'est-à-dire approximativement code croisé de Reed-Solomon avec entrelacement. Le code C2 est utilisé pour corriger une erreur uniquement, et en détecter au plus 3 (voir remarque prop. 3). La probabilité que le code C2 ne détecte pas plus de quatre erreurs est infime. En effet pour que le code C2 fasse une mauvaise correction, il faudrait qu'un mot du code soit ``déplacé'' dans une boule de rayon 1 centrée sur un autre mot du code. Dans tous les autres cas l'erreur est détectée puisque le mot erroné n'appartient à aucune boule de rayon 1 centrée en un mot du code. Calculons cette probabilité: le nombre de vecteurs contenus dans toutes les boules de rayon 1 centrées sur les mots du code est qk2(1 + n2(q - 1)) où q = 28. La probabilité pour qu'une erreur ne soit pas détectée est donc
Il faut remarquer que si l'on avait utilisé la pleine capacité de correction du code C2 à savoir 2 erreurs, la probabilité pour qu'une erreur ne soit pas détectée devenait :
ce qui est nettement plus important. Donc, si C2 détecte une erreur, elle est corrigée. Si plusieurs erreurs sont détectées alors le décodeur envoie les 28 symboles de sortie comme des effacements. Ces 28 symboles effacés sont désentrelacés puis arrivent au décodeur C1. La proposition 7 nous dit que le code C1 peut corriger 4 effacements. Cela correspond d'après la proposition 10 à un maximum de 15 colonnes effacées sur la matrice d'entrelacement (on ne considère pas les colonnes pouvant être partiellement effacées, puisque C2 efface toujours une colonne complète). Autrement dit le code permet de corriger 15 trames successives, ce qui correspond à une longueur de 588 x15 = 8820 bits sur la piste (2.5mm) ou encore à 32 x15 × 8 = 3840 bits de signal.
D'autres types d'entrelacements sont utilisés, par exemple à la sortie du code C2 on regroupe les 16 octets d'indice impair avec les 16 octets d'indice pair de la trame suivante. Cela augmente la probabilité du code C2 de corriger une seule erreur puisque 2 erreurs consécutives affectent alors 2 mots distincts. De même à la sortie du décodeur du code C1 on a théoriquement la séquence suivante :
où Gi (resp. Di ) désigne les deux octets qui composent le ième échantillon gauche (resp. droit), et P1 P2 représentent les 4 symboles de parité sur 16 bits.
Supposons qu'à la sortie du décodeur des effacements n'aient pas été corrigés, on peut alors interpoler ces valeurs dans la mesure ou l'échantillon précédent et l'échantillon suivant sont disponibles. Pour maximiser le nombre de symboles interpolables, on cherche à éloigner au maximum les échantillons successifs dans la trame. Pour cela on fait la permutation suivante avant l'entrée dans le deuxième circuit de codage:
La conséquence de cette permutation et de l'entrelacement avec retard est qu'un paquet d'erreurs sur 48 trames (de 32 symboles) permet toujours à la sortie du décodeur C2 de disposer pour tout échantillon effacé de l'échantillon qui le précède et de l'échantillon qui le suit. On arrive alors à 32 × 48 × 8 = 12288 bits ou encore à 588 x 48 = 28224 bits sur la piste ce qui correspond à une longueur d'environ 8.5mm sur le disque.
Il est absolument exclus d'envoyer un signal faux à la sortie du lecteur, en effet les différents maillons de la chaîne pourraient ne pas supporter un ``click'', particulièrement les enceintes. Si l'interpolation d'un symbole n'est pas réalisable parce que ses deux symboles voisins sont effacés, on baisse progressivement (suivant une sinusoïde) le niveau sonore à partir du début de la trame précédente, on laisse le niveau à zéro sur la trame incriminée et on rétablit progressivement le son pendant les 32 périodes d'échantillonnage de la trame suivante. Ce procédé est audible pour de très grands ``trous'' mais est difficilement décelable pour des micro-coupures.
Remarques: L'interpolation ne restitue pas exactement le signal
original mais l'approximation est très bonne car on est en présence
d'un signal très fortement corrélé puisqu'il s'agit,
en principe, de musique. Il est évident que pour d'autres applications,
ce procédé ne peut pas être envisagé. Précisons
aussi que les pleines possibilités de correction ne sont atteintes
que par des lecteurs de haut de gamme, le prix de certains lecteurs atteint
550000 (nouveaux) francs, et qui apportent parfois de nouvelles solutions
pour minimiser les erreurs à la lecture. La firme Wadia
a conçu un décodeur dont la capacité de calcul est
100 fois celle d'un micro-ordinateur!
Sur les pochettes de disque compact, il est précisé qu'il
ne faut pas essuyer le disque en faisant des cercles, mais du centre vers
les bords. Ceci permet d'éviter qu'une rayure éventuelle
ne se concentre sur des symboles consécutifs de la piste.