Ecrire un programme en langage C qui permettra à un utilisateur de sélectionner une ou plusieurs notes de musique dans un tableau, de telle façon à réaliser un accord. Le programme lui renverra sur une fenêtre en mode graphique les différentes positions possibles des notes sur un manche de guitare pour réaliser l’accord choisi.
Nous nous sommes donc lancés dans la réalisation de ce projet sous la direction de M. Castro qui nous a guidé et corrigé à juste
mesure pour pouvoir mener à terme les objectifs fixés.

Le programme a été réalisé avec le logiciel Code::Blocks, logiciel de programmation orienté C et C++, à la fois simple d’utilisation mais aussi très complet et supportant plusieurs compilateurs différents.
Code::Blocks est un IDE libre et multiplatforme. Il est écrit en C++ grâce à la bibliothèque wxWidgets. Pour le moment, Code::Blocks est orienté C/C++, mais compile d'autres langages comme le D.
L'avantage d'utiliser ce logiciel est que nous le connaissions parfaitement du fait que nous l'avions utilisé exclusivement en première année pour notre formation à la programmation C.

Le langage C peut être qualifié de bas niveau ou peu typé dans le sens où le langage est conçu pour permettre la manipulation directe des mots machine. Il propose un éventail de types entiers et flottants qui correspondent directement aux types supportés par le processeur. Il fait en outre un usage intensif des adresses mémoires avec la notion de pointeur. Il a une notion de type composé, mais ne propose aucune opération qui traite directement des objets de plus haut niveau (fichier informatique, chaîne de caractères, liste…). Ces types plus évolués doivent être traités en manipulant des pointeurs et des types composés. De même, le langage ne propose pas en standard la gestion de la programmation orientée objet, ni de mécanisme d'exception, ou de traitement multitâche. Il existe des fonctions standards pour gérer les entrées-sorties et les chaînes de caractères, mais contrairement à d'autres langages, aucun opérateur spécifique pour améliorer l'ergonomie. Le C ne permettant pas ni la redéfinition d'opérateurs, ni leur surcharge, ceci rend aisé le remplacement des fonctions standards par des fonctions spécifiquement conçues pour un programme donné. Le langage C a été utilisé pour rendre le système d'exploitation UNIX plus portable. Il a conservé de cela une très grande efficacité pour tout ce qui concerne le développement système. Ainsi la majorité des grands systèmes d'exploitation entre les années 1975 et 1993 ont été développés en C. Ces caractéristiques en font un langage privilégié quand on cherche à maîtriser les ressources utilisées, le code assembleur généré par les compilateurs étant relativement prévisible et parfois même optimal sur les machines d'architecture RISC à grand nombre de registres. Ce langage est donc extrêmement utilisé dans des domaines comme la programmation embarquée sur microcontrôleurs, les calculs intensifs, l'écriture de systèmes d'exploitation et tous les modules où la rapidité de traitement est importante. Il constitue une bonne alternative aux langages d'assemblage dans ces domaines, avec les avantages d'une syntaxe plus lisible et de la portabilité du code. En contrepartie, la mise au point de programmes en C, surtout s'ils utilisent des structures de données complexes, est plus difficile qu'avec des langages de plus haut niveau. En effet, dans un souci de performance le langage C impose à l'utilisateur de programmer certains traitements (libération de la mémoire, vérification de la validité des index sur les tableaux…) qui sont pris en charge automatiquement dans les langages de haut niveau. Le C étant un langage simple, son compilateur l'est également. Cela se ressent au niveau du temps de développement d'un compilateur C pour une nouvelle architecture de processeur : Kernighan et Ritchie estimaient qu'il pouvait être développé en deux mois[1]. C'est pour cela qu'il est souvent choisi comme premier langage sur une nouvelle architecture. Beaucoup de limitations du langage C ont été levées dans d'autres langages de programmation qui ont adopté une syntaxe inspirée de celle de C; outre le langage C++ qui est, à l'origine, du C enrichi de la notion d'objet, on peut citer Java, JavaScript, PHP et C#.
ALLEGRO est une bibliothèque standard utilisée dans la programmation C pour réaliser des applications visuelles, en effet elle comporte toutes les fonctions de base permettant d'afficher en mode graphique de nombreuses possibilités de dessins, allant du simple cercle au jeux vidéo en trois dimensions.
Nous avons utilisé essentiellement ALLEGRO pour notre programme car c'est une bibliothèque simple d'utilisation et qui comporte tout ce dont nous avions besoin pour afficher un résultat satisfaisant.
Se remémorer les bases du langage C par de petits programmes simples, en incluant la bibliothèque Allegro pour l’assimiler et l’exploiter au mieux :
Création d’un premier programme uniquement dédié à gérer l’affichage de la fenêtre principale. Ce programme comprend l’affichage initial du manche de la guitare et des boutons permettant la sélection des notes. Il doit renvoyer sur le manche toutes les positions possibles lorsqu’un des boutons notes aura été activé.
Création d’un programme reprenant le premier programme mais cette fois-ci avec la gestion de couleurs indépendantes pour chacune des notes sélectionnées, distinguant ainsi les notes lors de leur affichage sur le manche. Le programme renvoi encore toutes les positions possibles sur le manche mais de la couleur de la note activée.
Création d’une première fonction Saisie, ayant pour but de sélectionner une seule note, puis d’afficher sa position sur le manche. Une seule note pouvant être sélectionnée et affichée, et une seule position possible pour cette note pouvant être visualisée. Cette fonction Saisie comprend donc une fonction d’initialisation des notes dans les cases décrites par le manche de la guitare.
Intégration de la fonction Saisie dans le programme permettant l’affichage du manche et des boutons, ce nouveau programme est la base du programme final, il gère déjà la saisi d’une note et l’affichage de sa position sur le manche, avec sa couleur appropriée.
Création d’une fonction permettant l'association de chaque note à une couleur différente de façon à pouvoir correctement visualiser les notes selectionnées quand elle apparaîssent sur le manche de la guitare, étant donné que les positions des notes apparaîssent sous formes de disque, une couleur pour une note permet a l'utilisateur de discerner le disque correspondant à la note sélectionnnée.
Mise en place d'un système de boucle permettant la visualisation des plusieurs positions possibles pour une seule note puis integration de cette boucle dans le programme avec un mode de boutons déroulants faisant défiler les positions des notes sélectionnées.
Aurélien se charge principalement de rédiger les fonctions algorithmiques permettant les initialisations des notes et de la saisie de l'utilisateur.
Rémi se concentre sur la partie graphique de l'application, et se tourne essentiellement sur le design et la fonctionalité de l'interface que l'utilisateur pourra visualiser lors de l'execution du programme.
Le programme en lui-même est donc conçu par imbrication de plusieurs fonctions différentes,
la première permet de fixer chaque note dans les cases correspondantes du manche:
void init_note_manche(int tab1[6][12],int tab2[12],int couleur[12],int *rg,int *PsurDiez,int *PsurBemol)
{
int i,j;
*rg=0;
*PsurDiez=0;
*PsurBemol=0;
tab1[0][0]=5;
tab1[1][0]=12;
tab1[2][0]=8;
tab1[3][0]=3;
tab1[4][0]=10;
tab1[5][0]=5;
for(i=0;i<=5;i++)
{
for(j=1;j<=11;j++)
{
if(tab1[i][j-1]<12)
{
tab1[i][j]=tab1[i][j-1]+1;
}
else
{
tab1[i][j]=1;
}
}
}
for(i=0;i<=11;i++)
{
tab2[i]=0;
}
}
la deuxième gère l’affichage du manche puis des boutons
en mode graphique à l’aide de la bibliothèque Allegro, bibliothèque graphique de base pour
la programmation en C:
void init_manche(void)
{
/* write some text to the screen with black letters and transparent background */
textout_centre_ex(screen, font, "Projet: accords de guitare",140, 10, makecol(0, 0, 0), -1);
textout_centre_ex(screen, font, "Appuyez sur les notes que vous voulez faire apparaitre dans l'accord puis validez",350, 285, bleu, -1);
//Tracer de la guitare
//on trace ensuite le manche en bois
rectfill(screen,0,100,900,275,bisque);
line(screen,0,100,900,100,marron);
line(screen,0,101,900,101,marron);
line(screen,0,102,900,102,marron);
line(screen,0,273,900,273,marron);
line(screen,0,274,900,274,marron);
line(screen,0,275,900,275,marron);
//tracer des 6 cordes
int i;
for(i=0; i<=6; i++)
{
line(screen,0,125+25*i,900,125+25*i,noir);
}
int j;
for (j=0; j<=13; j++)
{
line(screen,10+68*j,100,10+68*j,275,marron);
}
textout_centre_ex(screen, font, "caisse de resonnance ==>",800, 90, marron, -1);
textout_centre_ex(screen, font, "<== extremite du manche",100, 90, marron, -1);
//notes correspondantes au cordes du manche si elles sont agitées mais non pincées
textout_centre_ex(screen, font, "MI",10, 117, CMI, -1);
textout_centre_ex(screen, font, "SI",10, 142, CSI, -1);
textout_centre_ex(screen, font, "SOL",10, 167, CSOL, -1);
textout_centre_ex(screen, font, "RE",10, 192, CRE, -1);
textout_centre_ex(screen, font, "LA",10, 217, CLA, -1);
textout_centre_ex(screen, font, "MI",10, 242, CMI, -1);
}
void init_bouton (void)
{
// affichage des boutons
int k;
for (k=0; k<=7; k++)
{
line(screen,10+100*k,300,10+100*k,350,noir);
}
line(screen,10,300,710,300,noir);
line(screen,10,350,710,350,noir);
line(screen,10,370,210,370,noir);
line(screen,10,420,210,420,noir);
line(screen,10,370,10,420,noir);
line(screen,110,370,110,420,noir);
line(screen,210,370,210,420,noir);
textout_centre_ex(screen, font, "DO",60, 325, CDO, -1);
textout_centre_ex(screen, font, "RE",160, 325, CRE, -1);
textout_centre_ex(screen, font, "MI",260, 325, CMI, -1);
textout_centre_ex(screen, font, "FA",360, 325, CFA, -1);
textout_centre_ex(screen, font, "SOL",460, 325, CSOL, -1);
textout_centre_ex(screen, font, "LA",560, 325, CLA, -1);
textout_centre_ex(screen, font, "SI",660, 325, CSI, -1);
textout_centre_ex(screen, font, "#",60, 395, noir, -1);
textout_centre_ex(screen, font, "b",160, 395, noir, -1);
rect(screen,300,370, 450,420,noir);
rect(screen,302,372, 448,418,noir);
textout_centre_ex(screen, font, "valider l'accord",375, 395, noir, -1);
//affichage des boutons --quitter-- et --aide--
rectfill(screen,800,5,870,35,rouge);
rect(screen,799,4,871,36,noir);
rect(screen,801,6,869,34,noir);
textout_centre_ex(screen, font, "quitter",835, 20, blanc, -1);
rectfill(screen,800,40,870,70,turquoise);
rect(screen,799,39,871,71,noir);
rect(screen,801,41,869,69,noir);
textout_centre_ex(screen, font, "aide",835, 55, blanc, -1);
//creation des boutons permettant le defilement des accords possibles
rect(screen,280,500,440,550,noir);
rect(screen,460,500,620,550,noir);
rect(screen,282,502,438,548,noir);
rect(screen,462,502,618,548,noir);
textout_centre_ex(screen, font, "position",360, 515, noir, -1);
textout_centre_ex(screen, font, "position",540, 515, noir, -1);
textout_centre_ex(screen, font, "precedent",360, 535, noir, -1);
textout_centre_ex(screen, font, "suivant",540, 535, noir, -1);
textout_centre_ex(screen, font, "Faites defiler les differentes positions possibles pour l'accord selectionne",450, 568, bleu, -1);
}enfin les fonctions saisi et affichage permettent respectivement de
saisir et stocker les notes sélectionnées par l’utilisateur, puis de les visualiser sur le manche.
Ce programme permet de visualiser jusqu'à 7 notes différentes en même temps bien qu’en général un
accord de guitare comporte au maximum 4 ou 5 notes:
void affichage (int tab1[6][12],int tab2[12],int *rg,int couleur[12],int *PsurDiez,int *PsurBemol)
{
int i,j,k,r,a;
init_manche();
r=*rg;
for (k=0;k<=12;k++)
{
*rg=r;
a=0;
if(tab1[0][0]==tab2[k] && *rg ==0)
{
line(screen,0,125,900,125,bleu);
line(screen,0,126,900,126,bleu);
a=1;
}
else if (tab1[1][0]==tab2[k] && *rg ==0)
{
line(screen,0,150,900,150,bleu);
line(screen,0,151,900,151,bleu);
a=1;
}
else if (tab1[2][0]==tab2[k] && *rg ==0)
{
line(screen,0,175,900,175,bleu);
line(screen,0,176,900,176,bleu);
a=1;
}
else if (tab1[3][0]==tab2[k] && *rg ==0)
{
line(screen,0,200,900,200,bleu);
line(screen,0,201,900,201,bleu);
a=1;
}
else if (tab1[4][0]==tab2[k] && *rg ==0)
{
line(screen,0,225,900,225,bleu);
line(screen,0,226,900,226,bleu);
a=1;
}
else if (tab1[5][0]==tab2[k] && *rg ==0)
{
line(screen,0,250,900,250,bleu);
line(screen,0,251,900,251,bleu);
a=1;
}
for(i=1;i<=12;i++)
{
for(j=0;j<=5;j++)
{
if(tab1[j][i]==tab2[k])
{
if(*rg==0)
{
if(a==0)
{
circlefill(screen,44+68*(i-1),125+25*j,10,couleur[tab2[k]-1]);
a=1;
}
}
else if(a==0)
{
(*rg)--;
}
}
}
}
}
*rg=r;
}L’utilisateur peut aussi accéder à l’explication du fonctionnement du programme s’il clique sur la rubrique « aide » positionnée en dessous du bouton « quitter ».

Voila ce que donne le résultat final :

Nous retiendrons de la réalisation de ce projet tuteuré de nombreux enseignements, le premier étant une correcte répartition des tâches et une bonne gestion du temps pour un travail d'équipe coordonné et efficace ayant permis l'avancement régulier et l'aboutissement du projet
De plus ce projet nous a permis de revoir et consolider nos connaissances sur la programmation en langage C étudiée en première année, mais nous a permis aussi de développer un raisonnement construit et cohérent nécessaire pour développer des applications en programmation
© 2008 Copyright Rémi BARTHELEMY-BLANC & Aurélien DEYRES, Promotion R&T 2007-2008