skip to main | skip to sidebar
Code 18
Manuel du savoir-faire à l'usage des geeks et des curieux
RSS
  • Accueil
  • Le web au Québec
  • Liens
  • Twitter
  • Facebook
  • À propos

mercredi 13 octobre 2010

Faire du son par programmation C++, partie 2

Publié par Infinite Loop, à 20 h 54 0 commentaire

Je ne sais pas si mon dernier billet sur la façon de produire du son par programmation C++ vous a impressionné, mais quand on commence dans quelque chose, il faut partir par la base pour bien comprendre ce qu'on fait. Alors je poursuis l'exemple en poussant un peu plus loin les notions sans toutefois aller jusqu'à la lecture de fichiers musicaux (ça viendra).

Le programme initial comportait une limitation importante : celle de jouer des sons uniquement au même octave (j'avais choisi le 4ème). Pour ma démonstration, j'ai apporté quelques modifications en calculant la fréquence des notes de la gamme majeure à chaque octave, du 4ème au 7ème (les plus jolis et perceptibles à l'oreille). Si vous souhaitez tester à des octaves plus hauts, remarquez que plus la fréquence est élevée, plus le volume du son baisse. L'oreille humaine est sensible à des sons compris entre 20 et 20000 Hz (expérimentez le avec ce programme).

Pour commencer, j'inclus 2 librairies supplémentaires :

  • math.h pour pouvoir utiliser la fonction pow (calcul de puissance)
  • stdio.h pour utiliser printf et imprimer à l'écran la fréquence de chaque note calculée pour suivre la trace (optionnel)
Ensuite, j'ai redéfini les constantes en indiquant la fréquence de base des notes à l'octave 0 (notation A0 = La à l'octave 0, A4 = La au 4ème octave). Comme le ratio de l'octave est de 2/1, la formule mathématique pour calculer n'importe quelle note à son octave supérieur est : (ratio exposant octave) multiplié par sa fréquence de base. Par exemple, pour un A4: 24 * 27,5 = 440 Hz.

Dans la fonction principale (main), je déclare les différentes variables utilisées au cours du programme. Ceux qui ne sont pas familiers avec la programmation se demanderont peut-être ce que représente notes[]. C'est un tableau qui contient 7 éléments (numérotés dans son fonctionnement interne de 0 à 6). J'y place les notes de base dans l'ordre, ce qui me permettra de parcourir la liste un élément à la fois.

Je lance ensuite 2 boucles imbriquées (for). La première indique que pour chaque octave, je fais aussi une itération sur chaque note du tableau en calculant sa fréquence et en l'envoyant vers le haut-parleur système.
#include <windows.h>
#include <math.h>
#include <stdio.h>

using namespace std;

/* Définition des contantes à l'octave 0 et de chaque fréquence */
#define C0 16.35 // DO
#define D0 18.35 // RE
#define E0 20.60 // MI
#define F0 21.83 // FA
#define G0 24.50 // SOL
#define A0 27.50 // LA
#define B0 30.87 // SI

#define RATIO_OCTAVE 2

int main()
{
float notes[] = {C0, D0, E0, F0, G0, A0, B0};

float current_note;
float frequency;
float freq_octave;
int idx;
int octave;

for(octave=1 ; octave<=7 ; octave++){
freq_octave = pow(RATIO_OCTAVE, octave);

for(idx=0 ; idx<7 ; idx++){
current_note = notes[idx];
frequency = current_note * freq_octave;
printf("%f\n", frequency);
Beep( (int)frequency, 250);
}
}

system("PAUSE");

return EXIT_SUCCESS;
}
Une autre notion qui peut être nouvelle pour vous est l'appel à printf qui permet d'envoyer du texte dans le terminal. Sa syntaxe particulière permet le formatage des données, dans ce cas-ci %f indique que la variable passée comme deuxième paramètre sera de type float (nombre à virgule flottante). Il est suivi d'un \n pour faire un saut de ligne à l'écran. On peut visualiser les notes au même moment qu'elles jouent dans le terminal mais la fenêtre se fermera toute seule si on ne fait pas l'appel à system("PAUSE") à la fin. Ceci permettra d'interrompre le programme et d'afficher la phrase "Press any key to continue...". Comme Homer Simpsons, essayez de figurer quelle touche correspond à "Any"...

Enfin, c'est possible que vous rencontriez l'erreur suivante au moment de la compilation, si vous omettez un léger détail :

Beep(current_note * freq_octave, 250);
[Warning] passing float for converting 1 of BOOL Beep(DWORD, DWORD)

En effet, la fonction Beep() prend comme paramètre un nombre entier (integer en anglais) qui correspond à la fréquence ainsi qu'un deuxième paramètre pour la durée en millisecondes. Or, nous avons calculé la fréquence et l'avons stocké dans une variable de type float, ce qui est incompatible. Pour corriger le tout, il sera nécessaire d'arrondir la valeur de la variable en convertissant son type de float à integer en utilisant un mécanisme qu'on appelle "casting". Devant la variable frequency, on ajoutera entre parenthèse le type dans lequel on veut caster : (int).

En résumé, si vous êtes nouvellement initié à la programmation C++, vous avez déjà vu plusieurs concepts par la pratique :
  • inclusion de librairies pour utiliser des fonctions spécialisées
  • déclaration de constantes, de différents types de variables dont les tableaux (listes)
  • le code placé entre /* et */ n'est pas compilé et exécuté, ce qui permet de mettre des commentaires pour documenter le programme
  • boucles for imbriquées
  • impression à l'écran en mode terminal
  • faire sortir du son système


Tags: Musique, Programmation

0 réponse à "Faire du son par programmation C++, partie 2"


Publier un commentaire

Message plus récent Messages plus anciens Accueil
S'abonner à : Publier des commentaires (Atom)
    Suivre @code18 sur Twitter

    Catégories

    • Apache (21)
    • Citations (167)
    • Club Vidéo (24)
    • Coffre à outils (56)
    • CSS (8)
    • Curiosités (117)
    • Design Pattern (2)
    • Drupal (8)
    • Easter Eggs (22)
    • Extensions Firefox (20)
    • GIMP (7)
    • Histoire (21)
    • HTML (32)
    • Humour (57)
    • Intégration (34)
    • iPod (12)
    • JavaScript (110)
    • Jeu de combat (6)
    • Le coin du geek (128)
    • Liens (12)
    • Linux (56)
    • Livres (78)
    • Lois et principes (46)
    • Marché des saveurs (26)
    • Mathématique (18)
    • Mobile (5)
    • Montréal (32)
    • Musique (112)
    • Pancartes et écriteaux (16)
    • Perl (8)
    • Pérou (1)
    • PHP (130)
    • PostgreSQL (44)
    • Programmation (105)
    • Saviez-vous que (55)
    • Sécurité (22)
    • SEO (5)
    • SQL Server (22)
    • Vieilles publicités (6)
    • Virtualisation (8)
    • Voyages (1)
    • Zend Framework (26)

    Divers

    Archives

    • ►  2015 (6)
      • ►  août 2015 (1)
      • ►  juillet 2015 (1)
      • ►  février 2015 (3)
      • ►  janvier 2015 (1)
    • ►  2014 (8)
      • ►  décembre 2014 (1)
      • ►  novembre 2014 (1)
      • ►  octobre 2014 (1)
      • ►  août 2014 (2)
      • ►  juillet 2014 (2)
      • ►  janvier 2014 (1)
    • ►  2013 (53)
      • ►  décembre 2013 (2)
      • ►  novembre 2013 (1)
      • ►  octobre 2013 (3)
      • ►  septembre 2013 (2)
      • ►  août 2013 (5)
      • ►  juillet 2013 (3)
      • ►  juin 2013 (5)
      • ►  mai 2013 (3)
      • ►  avril 2013 (7)
      • ►  mars 2013 (7)
      • ►  février 2013 (11)
      • ►  janvier 2013 (4)
    • ►  2012 (105)
      • ►  décembre 2012 (8)
      • ►  novembre 2012 (5)
      • ►  octobre 2012 (4)
      • ►  septembre 2012 (1)
      • ►  août 2012 (8)
      • ►  juillet 2012 (7)
      • ►  juin 2012 (7)
      • ►  mai 2012 (10)
      • ►  avril 2012 (13)
      • ►  mars 2012 (15)
      • ►  février 2012 (15)
      • ►  janvier 2012 (12)
    • ►  2011 (146)
      • ►  décembre 2011 (14)
      • ►  novembre 2011 (11)
      • ►  octobre 2011 (12)
      • ►  septembre 2011 (13)
      • ►  août 2011 (15)
      • ►  juillet 2011 (17)
      • ►  juin 2011 (18)
      • ►  mai 2011 (15)
      • ►  avril 2011 (9)
      • ►  mars 2011 (7)
      • ►  février 2011 (3)
      • ►  janvier 2011 (12)
    • ▼  2010 (398)
      • ►  décembre 2010 (29)
      • ►  novembre 2010 (28)
      • ▼  octobre 2010 (32)
        • On est tous des attention whores
        • Citation no. 105 sur le cannibalisme
        • Réseaux sans fil de mes voisins
        • Piège JavaScript no. 7
        • Piège JavaScript no. 6
        • Piège JavaScript no. 5
        • Le plus vieil homme du monde avait 174 ans
        • Détruire le web, un site à la fois
        • Citation no. 104 sur la vie
        • Parce que vous n'avez pas eu le temps de tout voir...
        • Piège JavaScript no. 4
        • Piège JavaScript no. 3
        • Piège JavaScript no. 2
        • Quelques pièges JavaScript
        • Citation no. 103 sur le déjeuner
        • Quand le heavy metal ne se prend pas au sérieux
        • 23 sites pour explorer le HTML5
        • Jouer à Snake sur un vidéo YouTube
        • Faire du son par programmation C++, partie 2
        • Le secret de l'inclinaison de la tour de Pise
        • Barre de progression HTML5
        • 3 façons de charger une librairie JavaScript popul...
        • Citation no. 102 sur les discussions
        • Composer de la musique par programmation avec C++
        • Outlook en mode sans échec qui ne répond pas
        • La tête du banquet de Salomé
        • La disparition de la lettre E
        • Paradis sur mesure
        • Éviter de perdre le contenu rédigé sur le web, rev...
        • Le stockage local HTML5 remplacera-t-il les cookies ?
        • Citation no. 101 sur les mets chinois
        • Où il est question de Bandcamp, Unwoman et d'une p...
      • ►  septembre 2010 (34)
      • ►  août 2010 (22)
      • ►  juillet 2010 (35)
      • ►  juin 2010 (42)
      • ►  mai 2010 (36)
      • ►  avril 2010 (37)
      • ►  mars 2010 (34)
      • ►  février 2010 (32)
      • ►  janvier 2010 (37)
    • ►  2009 (430)
      • ►  décembre 2009 (32)
      • ►  novembre 2009 (34)
      • ►  octobre 2009 (33)
      • ►  septembre 2009 (37)
      • ►  août 2009 (37)
      • ►  juillet 2009 (39)
      • ►  juin 2009 (38)
      • ►  mai 2009 (37)
      • ►  avril 2009 (35)
      • ►  mars 2009 (37)
      • ►  février 2009 (32)
      • ►  janvier 2009 (39)
    • ►  2008 (84)
      • ►  décembre 2008 (34)
      • ►  novembre 2008 (39)
      • ►  octobre 2008 (11)

    Abonnés

Copyright © All Rights Reserved. Code 18 | Converted into Blogger Templates by Theme Craft