:: Enseignements :: ESIPE :: E3INFO :: 2008-2009 :: Programmation C ::
[LOGO]

mplayIR3


But du projet

Vous devrez réaliser un programme permettant d'écouter des listes de fichiers MP3 et d'effectuer des affichages en mode texte en fonction du contenu des fichiers.

Lire des MP3

Pour lire des fichiers MP3, vous utiliserez les fonctionnalités fournies par l'API libmpg123, inclue dans le package de distribution du programme mpg123. Le minimum exigible est que votre programme soit capable de lire des MP3, soit dans l'ordre, soit dans un ordre aléatoire, mais sans que l'on diffuse une deuxième fois le même fichier avant que tous les fichiers aient été lus une première fois. Si et seulement si ce contrat de base est rempli, vous pouvez envisager des améliorations comme proposer dynamiquement de modifier le volume, de passer au MP3 suivant/précédent, etc.

Votre programme devra accepter des listes de MP3 sous 3 formes: Le choix de lire en mode séquentiel (MP3 dans l'ordre) ou aléatoire devra être paramétrable par une option. Le mode aléatoire doit fonctionner pour les 3 modes d'entrée indiqués. Ainsi, quand les noms des fichiers seront fournis sur l'entrée standard ou dans un fichier liste, vous devrez stocker intelligemment ces noms pour pouvoir les utiliser dans l'ordre de votre choix, et ce, sans imposer de limite sur le nombre de fichiers MP3 acceptés par le programme.

Le joli histogramme dynamique

Dans tout lecteur audio digne de ce nom, on peut voir un histogramme présentant les puissances instantanées pour plusieurs bandes de fréquence, comme ceci:



Vous devrez proposer une telle animation en mode texte. Pour cela, vous utiliserez la bibliothèque ncurses qui permet de gérer des fenêtres en mode texte dans un terminal, façon vim (plus d'infos sur ncurses ici).

Pour calculer un tel histogramme, la recette est assez simple, une fois que l'on a compris quelques bases en traitement du signal.
  1. décoder une portion de MP3 et obtenir un buffer correspondant au signal échantillonné, avec pour chaque échantillon, une valeur correspondant à une tension (c'est le boulot de libmpg123)
  2. appliquer la Transformée de Fourier Rapide à ce buffer pour calculer les amplitudes du signal par fréquence en V.Hz-1
  3. regrouper ces valeurs d'amplitude par bandes de fréquences (chaque bande correspondra à une barre de l'histogramme)
  4. faire les moyennes des ces groupes de valeurs pour obtenir des valeurs proportionnelles aux hauteurs de vos histogrammes

Transformée de Fourier Rapide

L'algorithme FFT (Fast Fourier Transform) travaille sur un tableau de N valeurs complexes, où N doit être une puissance de 2. Pour chacune des valeurs du tableau d'entrée, la partie réelle correspond à la tension de l'échantillon et la partie imaginaire est nulle. Le principe est de découper le tableau en 2 sous-tableaux contenant respectivement les valeurs d'indices pairs et impairs, et de calculer récursivement les FFT de ces tableaux puis de les combiner. La sortie est un tableau de N valeurs complexes où les parties réelles et imaginaires représentent les coefficients de la série de Fourier correspondant à la portion de signal représentée par le buffer d'entrée.

FFT(a):
N:=taille(a) (N doit être une puissance de 2)
si N=1 alors retourner a
a[0]:=(a0, a2, ..., aN-2) (sous-tableau avec les cases d'indices pairs)
a[1]:=(a1, a3, ..., aN-1) (sous-tableau avec les cases d'indices impairs)
y[0]:=FFT(a[0])
y[1]:=FFT(a[1])
pour k de 0 à N-1 faire
    w:=cos(2k.PI/N)+i.sin(2k.PI/N)
    yk:=yk[0]+w.yk[1]
    yk+N/2:=yk[0]-w.ykk[1]
fait;
retourner y
fin.


Par exemple, si l'on prend en entrée le tableau suivant de taille 16:
3.6   0
2.9   0
5.6   0
4.8   0
3.3   0
5.9   0
5     0
4.3   0
14    0
47    0
22    0
11.2  0
9.7   0
2.3   0
18.2  0
14    0
on obtiendra les valeurs suivantes en sortie:
 173.80     0.00
 -48.27    50.50
  35.71   -32.26
 -12.06    63.16
 -20.20   -23.80
  -4.21    34.10
 -26.51   -23.46
  22.94    -4.15
 -11.00     0.00
  22.94     4.15
 -26.58    23.46
  -4.21   -34.10
 -20.20    23.80
 -12.06   -63.16
  35.71    32.26
 -48.27   -50.50
Comme on peut le voir, la première valeur est spéciale, et les suivantes sont symétriques par rapport à l'indice N/2 (mêmes parties réelles, parties imaginaires opposées). Les valeurs d'amplitude qui nous intéressent correspondant aux modules de ces valeurs complexes (modules insensibles aux variations de signe), on peut donc se contenter de prendre en compte les modules des valeurs comprises entre 1 et N/2.

Les bandes de fréquence

Une fois les N/2 valeurs de fréquence obtenues, il faut découper la fréquence maximale en bandes de taille M. Par exemple, pour un enregistrement de qualité CD à 44100Hz, on aura une fréquence maximum de 22050Hz et donc des bandes de 0 à M-1, de M à 2M-1, etc. Pour obtenir la valeur de la ième bande, il faut faire la moyenne de toutes les valeurs comprises dans cette bande. Ces moyennes sont proportionnelles aux hauteurs des barres de notre bel histogramme.

ATTENTION: si un mp3 est en stéréo, il faudra soit faire la moyenne des signaux gauche et droit, soit afficher les bandes de fréquence de chaque signal.

Music visualization

En plus d'un bel histogramme, un player audio permet souvent l'affichage d'une animation graphique rythmée par la musique. Dans la mesure où vous aurez déjà calculé le spectre des fréquences pour votre histogramme, ça ne vous coûtera pas cher d'utiliser ces valeurs pour afficher une pseudo-animation en mode texte. Vous devrez donc proposer une telle animation rythmée par le son, mais vous avez carte blanche quant à sa nature. De plus, il y aura un bonus artistique pour l'animation qui sera jugée la plus jolie par les enseignants.

Conditions de développement

Le but de ce projet est moins de pondre du code que de développer le plus proprement possible. C'est pourquoi, vous développerez ce projet sur le serveur CVS de l'université. Comme nous attendons de vous que vous le fassiez sérieusement, votre rendu devra contenir un dump du fichier de logs de votre projet CVS, afin que nous puissions nous assurer que vous avez bien développé par petites touches successives et propres (commits bien commentés), et non pas avec un seul commit du résultat la veille du rendu.

Conditions de rendu

Vous travaillerez en binômes et vous lirez avec attention la charte des projets. Vous rendrez votre projet au moyen d'un package Debian. Le rendu consistera donc en un mail dans lequel vous donnerez l'URL de votre repository, qui devra se trouver sur votre compte web de l'université. Le test de votre projet se fera alors avec la commande:

sudo apt-get install mplayIR3

La commande mplayIR3 doit alors être installée et doit pouvoir permettre l'écoute de fichiers MP3, passés au programme comme indiqué plus haut. Naturellement, toutes les options que vous proposerez (ne serait-ce que --help) devront être gérées avec getopt_long. Votre package devra correctement gérer les dépendances, de façon à récupérer les bibliothèques libmpg123 et ncurses si elles ne se trouvent pas déjà sur le système (libmpg123 n'étant pas déjà packagée, vous devrez le faire et placer le package correspondant sur votre repository).

Afin de pouvoir accéder aux sources de votre travail, vous préparerez également un package source contenant les choses suivantes: Il serait également bon de fournir quelques liens vers des MP3 (légaux) de test.

Comme pour l'exécutable, l'accès à votre package source se fera au moyen de apt-get:

apt-get source mplayIR3

Le projet est à rendre par mail à tous les enseignants (i.e. Sylvain Cherrier, Matthieu Constant et Sébastien Paumier), au plus tard le jeudi 14 mai 2009 à 23h.