Utiliser la Transformation de Fourier (1)

Introduction

Il y a certainement très peu d'ouvrages qui expliqueraient clairement comment utiliser l'Analyse et la Synthèse de Fourier. Par contre, il y en a énormément pour expliquer quels sont les algorithmes de calcul mis en oeuvre (et les variantes selon le procédé). Je ne nie pas qu'il est intéressant de connaître le mécanisme mathématique interne de l'Analyse de Fourier, mais il est patent que ce mécanisme n'a qu'une seule utilisation, l'Analyse de Fourier justement. Les comparaisons par analogie avec d'autres domaines pouvant avoir deux représentations (p.ex. la relation onde/corpuscule en physique quantique) ne permettent aucune conclusion. Quand on a compris ce que fait la Transformation de Fourier, il est inutile de ressasser comment elle s'effectue; par contre il est très utile de savoir l'utiliser.

Comprendre la Transformée de Fourier

Il est regrettable que les ouvrages existants font un grand étalage de technique mathématique ou algorithmique, mais ne font quasiment aucun effort d'imagination quelle est la relation fondamentale entre une représentation en temps et une représentation en fréquences.d'une fonction.

Je renvoie donc à un très ancien ouvrage de J. Max

Obtention de l'onde

Une onde peut s'obtenir soit par calcul, soit par captation (p.ex. microphonique) et enregistrement.

Lors d'un enregistrement, on stocke les valeurs successives de l'amplitude des oscillations autour de la position de repos (ou valeur zéro). Ceci est vrai tant dans le domaine analogique que dans le domaine digital. Le son, en chaque point temporel est caractérisé par cette amplitude - c'est-à-dire que le son est une amplitude en fonction du temps. Les théorèmes de l'Analyse de Fourier disent que, en choisissant convenablement les fragments de son et en leur faisant subir quelques outrages, on peut aussi représenter un son en fonction de la fréquence. Les ouvrages techniques distinguent entre Fouriérages dans le domaine analogique et Fouriérage dans le domaine digital. Je ne parle que du domaine digital, le seul qui me semble accessible en Python.

La théorie dit aussi qu'à partir de la représentation en fréquence, on peut refaire le son par une Transformation inverse. Voilà qui ouvre de vastes perspectives. Mais les sabots sont vastes aussi. On peut suivre les conseils officiels: prendre des fragments dont la longueur est une puissance de 2 et appliquer des fenêtres (Haming, Kaiser, Cauchy, Poisson, etc.); ce sont des moyens sûrs pour obtenir des scories sans interêt. Tant qu'on n'a pas réussi à aller d'un son naturel à son analyse et aussi à revenir à un son resynthétisé à peu près identique à partir de l'analyse, on n' a rien réussi. Pour réussir, le savoir faire musical et l'analyseur situé au fond de l'oreille sont des aides efficaces.

Une expérience

On commence par l'étude d'un son instrumental, dont on connaît la hauteur. Cette hauteur étant connue, on connaît aussi le nombre moyen d'échantillons d'une onde de ce son - par la fonction prony2samples du paquet pythoneon.

La prochaine étape consiste à chercher dans le son des suites de valeurs qui constituent une onde. Compte tenu de ce que le son instrumental naît en général du bruit, il n'est pas indiqué de commencer par découper le son comme un salami; il faut trouver à quel moment le son a atteint son régime de croisière où les fluctuations (p.ex. un vibrato) sont telles que des fragments d'onde ou ondes entières correspondant à la hauteur moyenne sont détectables.

Au lieu d'utiliser un fenêtrage aveugle (ou sourd), on découpera des ondes possibles en détectant les passages par le niveau zéro (soit en montant ou en descendant). On trouve facilement des ondes complètes entre deux passages par zéro et dans la longueur correspond à la hauteur du son qu'on étudie.

On choisit une telle onde pour la soumettre à l'Analyse de Fourier. On peut l'écouter en la faisant répéter un grand nombre de fois. On trouvera que le son est mortellement ennuyeux. C'est normal: il ne s'agit que d'une onde, tandis qu'un son instrumental est un vrai paysage d'ondes - mais toutes à peu près de même longeur.

Le paquet numpy nous fournit les outils: ce sont la fonction numpy.fft.rfft et fonction numpy.fft.irfft qu'on va examiner.

Ce qu'il ne faut pas faire ou Petite excursion sans intérêt

Si notre onde comporte n samples, on peut la copier dans un vecteur zéro z dont la longueur est au moins la plus proche puissance de 2 au-delà de n: si n == 75, on utilise un vecteur z dont la longueur est 128 ou 256 ou .. 4096. Disons que la longueur du vecteur z est nz. Cette technique est recommandée etr s'appelle padding.

La fonction numpy.fft.rfft(z) nous retournera un vecteur complexe de nz valeurs réelles (correspondant à autant de composantes cosinus) et nz valeurs imaginaires (correspondant à autant de composantes sinus). Ces valeurs correspondent à des harmoniques. On peut les lire et même les représenter graphiquement - quel intérêt ? Un son est composé d'harmoniques, n'est-ce pas, mais on le sait. Le contrôle auditif est bien plus pertinent que le contrôle visuel.

On peut essayer de reconstituer un son en partant de ces harmoniques - après avoir fenêtré ou non (dans ce cas on a appliqué une fenêtre rectangulaire). On obtiendra un son qui aura une vague ressemblance avec le son original. On est content ?.

Retour à l'essentiel

Au lieu de prendre des fragments de longueur quelconque, on découpe le son à analyser en ondes. Ces ondes doivent être telles qu'elles débutent avec un sample proche de zéro et finissent avec un sample proche de zéro, début et fin allant dans le même sens. On analyse ainsi des ondes aussi complètes que possible partant de zéro et revenant à zéro. Si le début du fragment ou la fin du fragment (donc dans notre manière de faire, le premier et le dernier sample) sont trop loin de zéro, l'Analyse constate la présence d'une percussion initiale ou un claquement final - artefacts que les procédés officiels tentent d'éliminer par l'artefact d'une fenêtre. Ce qui n'arrange le résultat que dans le domaine visuel, l'oeil étant nettement moins sensible que l'oreille. Mais dans le domaine auditif, cela peut être désastreux.

Si notre fragment w qui comporte n samples est ainsi calibré, on l'analyse par l'appel:

h = numpy.fft.rfft(w)

Le vecteur h que la fonction numpy.fft.rfft(z) nous retourne contient n valeurs complexes qui représentent les harmoniques. Chaque nombre complexe est constitué, selon la terminologie traditionnelle, d'une partie réelle et d'une partie imaginaire. L'usage a imposé ces dénominations extravagantes. On n'y peut rien - il est même inutile d'y réfléchir.

Il s'agit maintenant de contrôler s'il est possible de retrouver le son de départ (celui qu'on a trouvé ennuyeux). Chez numpy tout est possible: la fonction numpy.fft.irfft (attention, il y a un i) est là pour ça. Le vecteur h des harmoniques nous en donne les moyens. Par l'appel:

wi = numpy.fft.irfft(h, n)

on obtient une onde wi qui jouit d'une ressemblance frappante avec notre onde de départ. Si on l'écoute elle est tout aussi ennuyeuse - mais maintenant on connaît la raison. Pour obtenir la même hauteur, il est impératif d'indiquer le nombre de samples n qui correspond à la hauteur de départ.

On veut changer de hauteur ? Il suffit de changer n.

On arrive ainsi au bout de la première étape. Dans la suite on verra comment constituer un son complet

La suite est plus facile ...


Sommaire

Imprimer du code Python
Évolution du projet pythoneon
Utiliser l'Analyse de Fourier
'A Primer on Scientific Programming with Python' de H.P. Langtangen


Copyright 2010 (c) René Bastian - rbastian (arrobe) free.fr