1. Retour sur le spectre & l'échantillonnage
- Période, fréquences, amplitude : exercice interactif
- Spectre & forme d'onde : exercice interactif
- Dans le monde continu, il y a une identité entre une onde dans le domaine temporel \( x(t) \), et une onde dans le domaine fréquentiel \( X(f) \). C'est à dire : pour un signal \( x(t) \), il y a un seul spectre \( X(f) \), et inversement. On peut passer de \( x(t) \) à \( X(f) \) par transformée de Fourier, et de \( X(f) \) à \( x(t) \) par transformée de Fourier inverse.
- Le spectre \( X(f) \) est entièrement dans le domaine fréquentiel : toute évolution temporelle du spectre est "moyennée", "intégrée", dans un seul spectre.
- Il existe une alternative, la transformée de Fourier court-terme (STFT pour short-term Fourier transform en anglais), qui fait un compromis entre analyse fréquentielle et analyse temporel. Elle consiste à prélever régulièrement des parties du signal (en le multipliant par une fenêtre), et calculer son spectre. On peut ainsi décrire "localement temporellement" le contenu fréquentiel d'un signal, au prix d'une moins bonne résolution fréquentielle (démo). On a alors un spectre en deux dimensions : \( X[n, f]) \), \( n \) étant la position de la fenêtre, et \( f \) la fréquence. On la représente donc généralement comme une image, la couleur étant la magnitude du spectre correspondant.
- On a alors un compromis à faire : plus cette fenêtre est grande, plus la précision fréquentielle est élevée, mais plus la précision temporelle est faible. Inversement, plus cette fenêtre est petite, plus la précision temporelle est élevée, mais plus la précision fréquentielle est faible.
- Cette transformée de Fourier court-terme, sous certaines contraintes (fenêtres croisées, overlapped, d'une demi-fenêtre), est inversible. La STFT est donc ce qu'on appelle une représentation analyse-synthèse: elle permet d'analyser, mais aussi de re-synthétiser, un signal (comme la transformée de Fourier "normale" d'ailleurs).
- Retour sur la notion de repliement : pourquoi et d'où ?
- Dans le monde continu, une onde est une onde : elle est définie en tout point du temps \( t \), et n'importe quelle onde, représentée par son amplitude en fonction du temps \( x(t) \), et entièrement caractérisable par cette détermination.
- Le fait de discrétiser temporellement cette onde, c'est-à-dire l'échantillonner, à une certaine fréquence d'échantillonnage \( f_e \), rend cette détermination ambigüe. En effet, pour le même relevé d'onde (c'est à dire la séquence de points \( x[n] \) prélevé, mesuré, de l'onde sous-jacente), il peut correspondre plusieurs ondes (demo). Ce phénomène s'appelle repliement, ou aliasing en anglais.
- C'est extrêmement fâcheux, surtout lors de la restitution : lors de la re-conversion de cette suite numérique dans le domaine analogique (électrique, acoustique, etc.), comment choisir l'onde sous-jacente?
- C'est ici qu'intervient le théorème de Nyquist : si une onde est de bande limitée, c'est à dire que son contenu fréquentiel est entre 0Hz et une certaine valeur \( f_N \), alors son échantillonnage est parfaitement déterminé si celui-ci est échantillonné à \( f_e = 2 \cdot f_N \). Alors, les ambiguïtés sont levées.
- Pour cette raison, lors de la restitution, les fréquences restituées sont celles appartenant dans l'intervalle \( [0, F_N] \). Par contre, il faut être sûr que le signal avant échantillonnage est bien de bande limitée \(f_n\) : sinon, toute onde de fréquence supérieure à \( f_N \) sera repliée dans l'intervalle \( [0, f_N] \).
- Ce comportement est parfaitement déterminé : donnée une fréquence d'échantillonnage \( F_e \), donc une fréquence de Nyquist \( f_N = \frac{f_e}{2} \), une onde de fréquence \( f_N + \Delta f \) correspond au même tracé qu'une onde de fréquence \( f_N - \Delta f \).
- Par exemple, si \( f_e = 44,1kHz \), la fréquence de Nyquist est de \( f_N = 22,05 Khz). Donné une onde de fréquence \( f = 30kHz \) , ce décalage fréquentiel vaut \( \Delta f = f - f_N = 30 - 22,05 = 7,95 \) kHz, et cette onde correspond aussi à une onde \( F_N - \Delta f = F_N - (f - F_N) = 22,05 - 7,95 = 14,1 Khz \). Ainsi, une onde de fréquence \( f = 30 kHz \) sera restituée comme une onde \( f = 14,1 kHz \).
- Pour s'assurer de l'identité entre le signal continu et son échantillonnage, il faut donc qu'il soit de bande limitée et qu'il ne comporte pas de contenu fréquentiel supérieur à la moitié de la fréquence d'échantillonnage. Il faut donc appliquer, avant échantillonnage, un filtre anti-repliement. Ce filtre, idéalement, coupe tout contenu fréquentiel au dessus de la fréquence de Nyquist.
- Comme ce filtrage doit être fait avant échantillonnage, le choix logique de ce filtre est un filtre analogique. Néanmoins, la conception d'un filtre aussi sélectif est très complexe, et peut se révéler aussi être couteux.
- À l'inverse, un filtre digital très sélectif est plus facile à réaliser ; néanmoins, pour être appliqué, le signal doit être déjà échantillonné. Cependant, les filtres digitaux contrairement aux filtres analogiques imposent une certaine latence, et ne sont donc pas non plus idéaux.
- Une autre solution, moins efficace mais plus facile à réaliser, consiste ainsi à utiliser un filtre analogique moins efficace, à pente plus faible, et à sur-échantillonner le signal dans un premier temps ; ensuite, un filtre numérique est appliqué pour filtrer efficacement le signal, puis sous-échantillonner ensuite pour redescendre à la fréquence d'échantillonnage cible.
- Un autre inconvénient des filtres digitaux est l'ajout de bruit de quantification, qui se repliera après sous-échantillonnage dans la bande de fréquence souhaités. Il est possible d'obtenir le ratio signal / bruit (qu'on veut le plus haut possible dans ce cas) avec l'équation suivante : \( SNR = 6.02 \cdot N + 1.76 \cdot \log_{10}\frac{f_e}{2 * BW } \), ou \( BW \) est la bande passante du filtre (plus d'info).
- Toutes ces caractéristiques rentrent en compte dans la qualité d'un convertisseur analogique-digital, et sont donc présents sur les fiches techniques des cartes son.
2. Retour sur la quantification
N'oublions pas que la numérisation d'un signal consiste à transcrire un signal continu temporellement (il a une valeur à n'importe quel temps \( t \) mais aussi en amplitude (il existe une infinité de valeurs possibles dans un intervalle donné, typiquement \( [-1 ; 1] \). Il faut donc le discrétiser temporellement (échantillonnage), mais aussi en amplitude, afin d'obtenir une suite de nombres enregistrables sur un disque dur.
- Pour écrire une suite de chiffres, il faut les convertir en format binaire, la mémoire d'un disque dur étant magnétique ou optique.
- N'importe quel nombre, usuellement écrit en base décimale (1, 2 , ..., 10, 11 ..., 99, 100 ...) peut être écrit de manière différente dans une autre base. Typiquement, en informatique on utilise la base binaire : (0, 1, 10, 11, 100, 101, 110, 111, ...)
- Ces bases sont strictement équivalentes, on passe de l'une à l'autre sans soucis : 0 ➝ 0, 1 ➝ 1, 2 ➝ 10, 3 ➝ 11, 4 ➝ 100, 5 ➝ 101, 6 ➝ 110, 7 ➝ 111, 8 ➝ 1000, etc.
- Ce qui change, par contre, c'est le nombre de valeurs qu'on peut encoder avec un nombre de chiffres donné (oui, c'est un peu tord cerveau).
- En système décimal:
- avec un chiffre, on peut exprimer 10 valeurs : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- avec deux chiffres, on peut exprimer 100 valeurs : 0, 1, .., 9, 10, ..., 99
- etc. De manière générale, avec \( n \) chiffres, on peut exprimer \( 10^n \) valeurs.
- Par conséquent, en système binaire :
- avec un chiffre (aussi appelé bit), on peut exprimer 2 valeurs : 0, 1
- avec deux chiffres, on peut exprimer 4 valeurs : 0, 1, 10, 11
- avec trois chiffres, on peut exprimer 8 valeurs : 0, 1, 10, 11, 100, 101, 110, 111
- etc. De manière générale, avec \( n \) chiffres, on peut exprimer \( 2^n \) valeurs.
- Une séquence de 8 bits s'appelle un octet (ou byte en anglais, attention à la confusion).
- Comme, dans le domaine continu, il y une infinité de valeurs entre -1 et 1 (par exemple, si on considère que notre signal a des valeurs -dans cet intervalle), pour pouvoir le numériser il faut aussi choisir un ensemble de valeurs possibles pour l'encodage, et "transcrire" chaque échantillon dans cet ensemble. Ce procédé s'appelle quantification.
- Par exemple, en binaire, si on encode un signal avec 3 chiffres, on peut donc décrire \( 2^3 = 8 \) valeurs possibles. On peut choisir 8 valeurs linéairement (à intervalles réguliers) entre [-1 et 1] : on parle alors de quantification linéaire. Ainsi, notre signal est décrit comme 3 bits pour chaque échantillon.
- Un signal échantillonné et quantifié consiste donc en une séquence de N bits pour chaque échantillon, et donc enregistrable sur un support numérique.
- Cette correspondance entre une valeur et un identifiant en bits s'appelle quantification en bits entiers. Il existe d'autres systèmes d'encodage: par exemple, encoder le signe (+ ou -) avec un bit supplémentaire, ou le système mantissa permettant d'encoder des nombres à virgules flottantes (plus d'info).
- À l'instar du repliement pour l'échantillonnage, la quantification vient aussi avec son inconvéniant : le bruit de quantification.
- Effectivement, le fait de ramener toute "capture" d'un signal d'une infinité de valeurs sur un nombre de choix limité crée des erreurs dans cette captation, un peu comme arrondir un nombre à virgules. On peut penser à son équivalent en image : alors que l'échantillonnage est la résolution "en pixels" de l'image, la quantification est le nombre de couleurs disponibles (8 couleurs, 256 couleurs, millions de couleurs, etc.)
- Heureusement, ce bruit est parfaitement quantifiable mathématiquement.
- Prenons une quantification linéaire, où chaque valeur possible de la grille de quantification est espacée de \( Q \). Par example, si nous avons 8 valeurs entre -1 et 1, chaque valeur est espaceée de \( Q = 1 - (-1) / 8 = 0.25 \)
- Chaque valeur analogique sera donc ramenée à la valeur la plus proche (sauf si on veut vraiment mettre le bazar dans le signal). Cette erreur de quantification sera donc égale, au maximum, de \( \frac{Q}{2} \).
- Si on veut mesurer ce bruit indépendamment du signal quantifié, on peut le considérer donc le comme un rajout de bruit d'amplitude \( [ - \frac{Q}{2} ; \frac{Q}{2} ]\).
- On peut donc calculer le rapport signal sur bruit (Signal-to-Noise Ratio, or SNR) apporté par la quantification en calculant l'amplitude de l'onde (ici 1) et le bruit ramené \frac{Q}{2}. Typiquement, on veut le maximiser : ça veut dire qu'on a plus de signal que de bruit.
- Cette relation, en échelle logarithmique (dB), se calcule : \( SNR = 6.02 \cdot N + 1.76 dB \).
- La quantification apporte un autre problème : si jamais le signal qu'on encode est d'amplitude inférieure à \( Q \), celui-ci disparaît, et celà peut être dommageable, surtout à basse résolution (comme en streaming par exemple). Pour cela, on rajoute un bruit de distribution rectangulaire (moins audible, mais moins efficace), ou triangulaire (plus audible, mais plus efficace), afin de pouvoir "sauver" ces composantes de très basse amplitude, en échange d'un petit bruit de fond. Ce procédé s'appelle dithering (vibrage, dépolissage en français) , et doit-être appliqué avant quantification (typiquement avec du bruit analogique).
- Ce dithering peut être aussi appliqué lors d'un export avec un logiciel de traitement audio-numérique, si on exporte des fichiers audio dans une résolution inférieure (typiquement, passer de 24bits à 16bits), pour les mêmes raisons.
- La quantification linéaire n'est pas forcément une bonne idée pour l'audio : en effet, dans la majorité des enregistrements réalisés, les signaux captés sont de faible amplitude. Avoir la même résolution pour les niveaux forts et les niveaux faibles n'est donc pas idéal.
- Heureusement, dans la quantification, la répartition des valeurs sur laquelle on ramène l'onde analogique est arbitraire. On peut donc avoir une grille beaucoup plus fine dans les basses amplitudes que dans les fortes ; on parle alors de quantification non-linéaire.
- Il existe plusieurs quantifications non-linéaires : la µ-law, historiquement utilisée en Europe, et la A-law, historiquement utilisée en Amérique et au Japon.
- L'utilisation d'une quantification non-lineaire est standard en audio.
- Cet encodage, décrit précédemment, s'appelle PCM, ou Pulse Code Modulation. C'est le standard d'encodage numérique audio utilisé dans 99.9% des cas, même s'il en existe d'autres (comme le DSD par exemple).
3. Formats numériques
Une fois échantillonnées, et quantifiés, ces suites de données binaires doivent être enregistrés dans un certain format sur un ordinateur. Il est important de stocker, avec ces suites, un minimum de méta-données afin de savoir comment les décoder : nombre de canaux, durée, technique de quantification (bit entier, mantissa, etc.), etc.
- L'algorithme étant en charge d'encoder / décoder ces données s'appelle un codec. Il peut être PCM, ou d'un autre format, Les codecs, aussi peuvent prendre en charge plusieurs formats. Certains codecs sont open-source, d'autres propriétaires.
- les codecs non-compressés, ou lossless, où l'information est encodées sans perte de qualité audio (compressée ou pas).
- les codecs compressés, où l'information est encodée avec une compression altérant leur qualité souvent en échange d'un réduction drastique de poids.
- Le format conteneur est une norme indiquant de quelle manière un certain type de données doit être stocké, éventuellement des méta-données (artiste, titre, numéro de piste, heure d'enregistrement, timestamps, etc). On parle aussi de format conteneur. Un format peut accepter plusieurs codecs, notamment dans le cas de formats multi-médias (vidéo typiquement).
Parmi les codecs sans-perte les plus connus, nous avons :
- PCM : sortie du processus de quantification décrites ci-dessus, multi-canal. Formats compatibles: .wav, .aiff, .bwf
- FLAC : compression audio sans perte, multi-canal. Format compatibles : .flac
- ALAC : (Apple Lossless Audio Codec) compression audio sans perte, multi-canal. Formats compatibles: .m4a
- MPEG-4 Audio Lossless Coding. Formats compatibles: .mp4
Pour les codes avec perte, on peut citer :
- MP3 : MPEG-2 Audio Layer III. Formats compatibles : .mp3
- AAC : Advanced Audio Codec. Formats compatibles : .m4a, .mp4
- OPUS : utilisés souvent pour le streaming car très rapide. Amélioration de Vorbis, format .ogg. Formats compatibles: .opus
Tous ces codecs ont une manière différente de compresser les données, à la fois en espace sur le disque dur, ou en vitesse d'encodage / décodage (très utile pour le temps réel, et surtout le streaming).
- Pour calculer la taille d'une séquence du bits sur un ordinateur en PCM en octets, il suffit d'utiliser la formule \( \frac{F_e \cdot n \cdot N \cdot t}{8} \), où \( F_e \) est une fréquence d'échantillonnage, \( n \) le nombre canaux, \( N \) le nombre de bits utilisés pour la quantification, \( t \) la durée en secondes. On mesure souvent en méga-octets (Mo), on divise alors ce nombre par \( 10^6 = 1,000,000 \), ou en giga-octets (Go), mesuré par \( 10^9 = 1,000,000,000 \).
- Pour calculer le flux de données, c'est à dire le nombre de bits envoyés par secondes, on remplace le \( t \) ci-dessus par 1. Cependant, ce débit est généralement mesuré en kbit/s, il faut donc diviser par 1000 et non par 8. On obtient donc la formule : \( \frac{F_e \cdot n \cdot N}{1000} \).
- Cette mesure en flux de données est fondamentale pour la communication, avec câble ou sans-fil : dans les deux cas, chaque mode de transmission a un débit de flux de données limitées, et il faut donc choisir le bon codec pour rester en-dessous de cette limite. Cependant, les algorithmes de compression complexes peuvent aussi introduire de la latence, il y a donc un compromis à faire avec toutes ces contraintes matérielles, et l'application concrète de pourquoi on envoie ces données (stockage, streaming, temps-réel, etc. ).