IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Trouver la fréquence d'un son


Sujet :

JavaScript

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Par défaut Trouver la fréquence d'un son
    Bonjour à tous.
    Pour un site personnel, je cherche à coder un accordeur en ligne, avec la web audio API.

    Mon problème principal consiste à trouver la fréquence d'un son. J'ai pour cela utilisé un objet AudioAnalyser qui doit analyser le son que je récupère du microphone, et la méthode getByteFrequencyData() pour trouver la fréquence du son.

    Petit problème, cette fonction me met les fréquences dans un tableau de bytes, d'une taille de 1024, et je n'arrive pas à bien comprendre ce que sont tous ces numéros.

    Je vous met mon code est le lien pour pouvoir tester ce qu'il existe pour l'instant (ne marche pour l'instant qu'avec firefox, mais ça c'est facilement changeable !).
    http://www.guitar-side.com/testJs/accordeur_test.php

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    <script>
        // Globals
    	var aCtx;
    	var analyser;
    	var microphone;
    	navigator.getUserMedia = ( navigator.getUserMedia ||
                           navigator.webkitGetUserMedia ||
                           navigator.mozGetUserMedia ||
                           navigator.msGetUserMedia);
    	if (navigator.getUserMedia) {
    		navigator.getUserMedia({audio: true}, function(stream) {
    			window.audioContext = window.audioContext || window.webkitAudioContext;
    			aCtx = new AudioContext();
    			analyser = aCtx.createAnalyser();
    			microphone = aCtx.createMediaStreamSource(stream);
    			microphone.connect(analyser);
    			analyser.minDecibels = -90;
    			process();
    		}, function(err) {
    			  console.log("Une erreur est survenue: " +err);
    		});
    	} else {
    		console.log('ça marche pas');
    	}
    	function process(){
                    //boucle pour la récupération des fréquences en temps réel
    		setInterval(function(){
    			FFTData = new Uint8Array(analyser.frequencyBinCount);
    			analyser.getByteFrequencyData(FFTData);
    			var freq = document.getElementById("frequency");
    			freq.innerHTML = '';
    			for(var i=0; i<FFTData.length; i++){
    				freq.innerHTML = freq.innerHTML + ' ' + FFTData[i];
    			}
    		},100);
    	}
      </script>
     
      <div id="frequency">
      </div>
    Voila, je ne sais pas si parmi vous il y a des habitués de cet API, ou des personnes qui aimeraient voir ses fonctionnalités.
    Pour dire vrai, je me demande si utiliser un analyser est une bonne idée, ou si je devrais pas plutôt utiliser un objet BiquandFilterNode ou il y a aussi des possibilité de jouer avec les fréquences.

    Enfin voilà, toutes les suggestions sont les bienvenues !

  2. #2
    Membre éclairé Avatar de SPACHFR
    Profil pro
    Paaaaaa
    Inscrit en
    Février 2004
    Messages
    557
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Paaaaaa

    Informations forums :
    Inscription : Février 2004
    Messages : 557
    Par défaut
    Cette page contient les informations que tu cherches : https://developer.mozilla.org/fr/doc...I/AnalyserNode

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Avril 2011
    Messages : 6
    Par défaut
    J'avais déja la doc, le problème, c'est que je ne comprend pas vraiment comment l’algorithme de fourier (FFT) qui est apparemment utilisé pour cette API, fonctionne.

    En bref, la méthode getFloatFrequencyData() (ou son équivalent en byte getByteFrequencyData() ) me donne un tableau avec la fréquence en indice et l'amplitude en contenu.
    Le problème, c'est que j'ai absolument aucune idée de la correspondance entre les valeurs données par la méthode et de "vraies" fréquences en hertz !

  4. #4
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    Je viens de trouver une lecture intéressante : un mec qui cherche à faire des animations visuelles dans sa page en fonction des fréquences de sa musique en temps réel. En gros, ce que tu cherches à faire. Seul problème, c'est en anglais. Je peux essayer de te faire une petite traduction si tu as besoin.

    Pour la théorie en revanche, j'ai une source en français. Pour faire bref, dans ton tableau tu as des échantillons de fréquence (deuxième dessin sur la page en français). La position dans le tableau te donne la bande de fréquence, et la valeur donne l'amplitude.

    Tu auras du mal à te représenter le contenu de ton tableau si tu envoies sans ménagement les 1024 valeurs s'afficher à l'écran. Un petit dessin vaut mieux qu'un long innerHTML

    J'ai repris ton code pour qu'il dessine les valeurs dans un canevas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    <!DOCTYPE html>
    <html lang=fr>
    <head>
       <meta charset=utf-8>
       <title>Fourier dans ton micro</title>
       <script defer>
     
    "use strict";
     
    document.addEventListener("DOMContentLoaded", function( ){
     
       navigator.getUserMedia = navigator.getUserMedia ||
                                navigator.webkitGetUserMedia ||
                                navigator.mozGetUserMedia ||
                                navigator.msGetUserMedia;
       if (navigator.getUserMedia) {
          navigator.getUserMedia({ audio: true }, function(stream) {
             var audioCtx = new (window.AudioContext ||
                window.webkitAudioContext)();
             var analyser = audioCtx.createAnalyser();
             var microphone = audioCtx.createMediaStreamSource(stream);
             microphone.connect(analyser);
             analyser.minDecibels = -90;
             process(analyser);
          }, function(err) {
             console.log("Erreur du media: " + err);
          });
       } else {
          console.log('API non disponible');
       }
     
       var mustStop = false;
       document.getElementById("stop").onclick = function( ){
          mustStop = true;
       };
     
       function process(analyser) {
          var graph = document.getElementById("graph");
          var drawCtx = graph.getContext("2d");
     
          // calcule les échelles
          var count = analyser.frequencyBinCount;
          var scaleX = graph.width / count;
          var scaleY = graph.height / 256;
     
          // inverse l'axe vertical
          drawCtx.scale(1, -1);
          drawCtx.translate(0, -graph.height);
     
          // fonction de timing
          var raf = requestAnimationFrame ||
                    mozRequestAnimationFrame ||
                    webkitAnimationFrame ||
                    function( callback ){ setTimeout(callback, 20); };
     
          // boucle pour la récupération des fréquences en temps réel
          var FFTData = new Uint8Array(count);
          (function draw() {
             analyser.getByteFrequencyData(FFTData);
     
             // efface le canevas et prépare un nouveau tracé
             drawCtx.clearRect(0, 0, graph.width, graph.height);
             drawCtx.moveTo(0, 0);
             drawCtx.beginPath();
     
             var x, y;
             for (var i = FFTData.length; i--;) {
                x = scaleX * i;
                y = scaleY * FFTData[i];
                drawCtx.lineTo(x, y);
             }
             drawCtx.stroke();
     
             if (!mustStop) { raf(draw); }
          }());
       }
     
    });
     
       </script>
    </head>
    <body>
     
    <canvas id="graph" width="800" height="400"></canvas>
    <button id="stop">Stop</button>
     
    </body>
    </html>
    Ça marche aussi sous Chrome (même mieux en fait : sous Firefox, pour une raison qui m'échappe complètement, la capture du son s'arrête au bout de quelques secondes).




    Edit: Je n'avais pas vu ta réponse. Je joins ici une traduction d'un passage de l'article en anglais dont j'ai parlé, il explique comment calculer les bandes de fréquences dans le tableau.

    […] Nous avons parlé d'échantillonner la courbe de fréquence. Ça se produit à un certain taux (taux d'échantillonage) que vous pouvez trouver via l'attribut sampleRate du contexte audio. il est bon de garder ça en tête quand vous réfléchissez à la résolution des fréquences.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var sampleRate = audioContext.sampleRate;
    Supposons que le taux d'échantillonnage de votre fichier est 48 000, ce qui fait que la fréquence maximum dans le fichier est de 24 000 Hz (grâce à un merveilleux théorème du Dr Harry Nyquist, la fréquence maximum dans un fichier est toujours égale à la moitié du taux d'échantillonnage). Le tableau d'analyse que nous sommes en train de créer contiendra des fréquences jusqu'à ce point. C'est idéal sachant que l'oreille humaine capte dans l'intervalle 0 - 20 000 Hz.

    Donc, si nous créons un tableau à 2 400 éléments, chaque fréquence enregistrée sera éloignée de 10 Hz. Cependant, nous allons créer un tableau de la moitié de la taille du FFT (Fast Fourier Transform), ce qui fait dans ce cas 2 048 qui est la valeur par défaut. Vous pouvez définir ceci via la propriété fftSize.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // on définit la taille de notre FFT
    analyzer.fftSize = 2048;
    // on crée un tableau vide à 1 024 éléments
    var frequencyData = new Uint8Array(1024);
    Ainsi, avec un tableau à 1 024 éléments, et une bande de fréquences de 24 000 Hz, nous savons que chaque élément est éloigné de 24 000 ÷ 1 024 = 23,44 Hz.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

Discussions similaires

  1. Trouver la bonne licence pour son logiciel
    Par achcha dans le forum Licences
    Réponses: 0
    Dernier message: 03/08/2013, 14h21
  2. Reconnaitre les fréquences d'un son via le microphone
    Par Invité dans le forum Débuter
    Réponses: 4
    Dernier message: 02/01/2013, 17h09
  3. [DOM] Trouver un node à partir de son nom
    Par Kevin12 dans le forum Format d'échange (XML, JSON...)
    Réponses: 6
    Dernier message: 08/04/2009, 17h32
  4. Trouver le dernier offset de son exe delphi
    Par Coussati dans le forum Delphi
    Réponses: 5
    Dernier message: 12/06/2006, 11h37
  5. Réponses: 2
    Dernier message: 11/05/2006, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo