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 :

Récupérer la fréquence d'un son mediaElement


Sujet :

JavaScript

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 2
    Par défaut Récupérer la fréquence d'un son mediaElement
    Bonsoir à tous, j'ai déjà vu pas mal de sujets sur différents forums à propos de ça, mais honnêtement impossible de m'en sortir.
    J'aimerais récuperer la fréquence d'un musique que je récupere via l'API de deezer pour l'adapter dans des jeux (il s'agit d'un projet de fin d'année).
    Mais je suis coincé au début : Obtenir la fréquence. Je précise que je débute complètement dans cette utilisation de l'API et que je n'ai eu aucun cours dessus, donc il est possible que certaines choses soient aberrantes.

    Code html : 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
    <html>
     
    <script type="text/javascript"></script>
    <script type="text/javascript" src="./JS/jquery.js"></script>
     
    </head>
     
    <body>
     
        <audio controls autoplay id="player" crossorigin="anonymous">
            <source src="<?php  echo ($resultat[" data "][0]["preview "]); ?>" type="audio/mpeg">
        </audio>
        <div>
            <input id="slider" type="range" min="100" max="22000" value="100" />
            <div id="freq-display">100</div>
        </div>
     
    </body>
     
    </html>
    Voici donc l'html associé, le lecteur recoit la requête PHP, aucun soucis dans la diffusion.

    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
    var ctx = new (window.AudioContext || window.webkitAudioContext)();   
    var audioEl = document.getElementById("player");
    var elSource = ctx.createMediaElementSource(audioEl); 
    elSource.connect(ctx.destination);
    var analyser = ctx.createAnalyser();
     
    var array =  new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(array);
     
    window.setTimeout("printHz()",1000);
     
    function printHz(evt){
    	console.log(analyser)
    	console.log(array);
    	window.setTimeout("printHz()",1000);
    }
    Donc là techniquement j'en suis ici (j'ai essayé d'autres choses mais rien n'y fait).
    le console.log(elSource) m'affiche bien les caractéristiques du lecteur, si je console.log(analyser) de même, j'obtiens des informations. Seulement voilà, cela ne me permet pas de déterminer la fréquence
    je vois qu'il faut utiliser quelque chose du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var array =  new Uint8Array(analyser.frequencyBinCount);
            analyser.getByteFrequencyData(array);
    mais j'obtiens un tableau de 1024 cases 0 au lieu d'une alternance 0/1.


    Donc voilà, je ne sais pas si c'est très clair (ça ne l'est pas beaucoup pour moi) mais merci d'avance si quelqu'un qui maîtrise veut bien se pencher dessus !

  2. #2
    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
    L'année dernière, j'avais aidé un bonhomme qui avait le même genre d'objectif que toi. C'étail par là.

    Actuellement ton analyseur n'est pas connecté à ta source donc il ne reçoit pas d'information. D'après le schéma de cette page, il faut connecter l'analyseur à la source, puis la destination à l'analyseur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var analyser = ctx.createAnalyser();
    elSource.connect(analyser);
    analyser.connect(ctx.destination);
    Si tu regardes dans les docs du MDN, notamment ce guide, tu verras qu'ils mentionnent à plusieurs reprises le Voice-O-matic. J'ai été voir, c'est plutôt impressionnant ! Je pense que tu peux t'en inspirer.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2015
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2015
    Messages : 2
    Par défaut
    Bonsoir et merci beaucoup ! Effectivement si je ne connecte pas mon analyser, je pouvais toujours attendre pour les valeurs...

    Du coup merci beaucoup, après ça et en suivant les pages sur lesquelles tu m'as redirigé j'ai réussi à obtenir mon tableau, ensuite j'en fais une moyenne et c'est gagné !

    je mets le code pour ceux qui pourraient passer par ici : (cela permet d'obtenir une frequence moyenne, parfaite pour gérer la vitesse d'un scroll sur un jeu!)
    Par contre je ne comprends toujours vraiment à quoi sert le getByteFrequencyData malgrés la doc, enfin surtout j'ai l'impression de l'utiliser pour rien là ?
    Une autre question que je me pose, pourquoi les valeurs mettent elles du temps à descendre à 0 ? (c'est à dire que même lorsque la musique ne joue plus, les valeurs ne baissent pas brutalement.
    Et en petite précision, y a t'il toujours au moins 1024 valeurs ? les valeurs >20 n'ont pas vraiment de sens, ne serait t'il pas plus exacte d'ajouter un if(array[i]>=20) dans le while de ma fonction getMoyenne ?

    Quoi qu'il en soit, merci beaucoup !

    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
    var ctx = new(window.AudioContext || window.webkitAudioContext)(); // creation contexte
    var audioEl = document.getElementById("player"); // selectionne l'objet du DOM
    var elSource = ctx.createMediaElementSource(audioEl); // on en fait la source
    elSource.connect(ctx.destination); // on connecte la source 
    var analyser = ctx.createAnalyser(); // on crée un analyser
    elSource.connect(analyser); // on connecte la source a l'analyser
    analyser.connect(ctx.destination); // on connecte l'analyser a la destination
    var count; //les variables
    var FTTData;
    var array;
    var moyenne;
    window.setTimeout("printHz()", 500);
     
    function printHz(evt) {
        count = analyser.frequencyBinCount;
        FTTData = new Uint8Array(count);
        analyser.getByteFrequencyData(FTTData);
        moyenne = getMoyenne(FTTData);
        console.log(FTTData);
        window.setTimeout("printHz()", 500);
    }
     
    function getMoyenne(array) {
        var i = 0;
        var longueur = array.length;
        var value = 0;
        while (i < longueur) {
            value += array[i];
            i++
        }
        moyenne = value / longueur;
        console.log(moyenne);
    }
    Encore une fois il n'est pas garanti que le code soit dépourvu de lignes aberrantes !

  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
    Citation Envoyé par msdaath Voir le message
    Par contre je ne comprends toujours vraiment à quoi sert le getByteFrequencyData malgrés la doc, enfin surtout j'ai l'impression de l'utiliser pour rien là ?
    Dans le but d'utiliser le moins de mémoire possible, getByteFrequencyData ne crée pas un tableau à 1024 entrées à chaque fois que tu l'appelles. C'est à toi de lui dire dans quel tableau tu veux qu'il mette les données. Ainsi, quand tu exécutes l'instruction analyser.getByteFrequencyData(FFTData), l'analyseur met ses données dans FFTData.

    Une autre question que je me pose, pourquoi les valeurs mettent elles du temps à descendre à 0 ? (c'est à dire que même lorsque la musique ne joue plus, les valeurs ne baissent pas brutalement.
    Une partie de la réponse se trouve ici. L'analyseur a une propriété smoothingTimeConstant égale à 0.8 par défaut et qui est une sorte de « facteur d'amortissement » qui fait que les valeurs mettent un certain temps à changer.

    Et en petite précision, y a t'il toujours au moins 1024 valeurs ? les valeurs >20 n'ont pas vraiment de sens, ne serait t'il pas plus exacte d'ajouter un if(array[i]>=20) dans le while de ma fonction getMoyenne ?
    Là c'est une histoire de jugement personnel… Et de maths ! En effet, la décomposition d'un signal sonore se fait par une transformée de Fourier (c'est un procédé mathématique qui permet de séparer les fréquences pures dans un signal complexe), et l'API html5 utilise une implémentation connue de ce procédé, qui s'appelle Fast Fourier Transform (d'où les initiales FFT). On demande à cet algorithme une certaine résolution, la « taille » de la transformée, qui détermine le nombre de bandes de fréquences dans le résultat. Cette taille est la propriété fftSize de l'analyseur, qui est 2048 par défaut. Pour une raison qui m'échappe un peu je l'avoue, la taille du tableau doit être égale à la moitié de fftSize.

    Demander une plus grande taille donnera des résultats plus précis mais prendra plus de temps de calcul. À l'inverse, avec une fftSize plus petite, l'algo sera plus rapide mais moins précis.

    Tu peux tout à fait filtrer les valeurs inférieures à 20, mais ce sera peut-être plus utile pour toi de jouer sur les propriétés minDecibels et maxDecibels de l'analyseur. N'hésite pas à faire des tests !

    Encore une fois il n'est pas garanti que le code soit dépourvu de lignes aberrantes !
    Le seul truc un peu gênant c'est les chaînes passées à setTimeout. Passe directement tes fonctions, c'est plus propre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    window.setTimeout(printHz, 500);
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

Discussions similaires

  1. Analyser un fichier MP3 et récupérer la fréquence du son ?
    Par [ZiP] dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 06/04/2009, 21h07
  2. [D6] Récupérer la fréquence de l'écran
    Par Lung dans le forum API, COM et SDKs
    Réponses: 10
    Dernier message: 26/09/2008, 14h57
  3. Récupérer un noeud XML par son nom
    Par mhamdi45 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 10/07/2007, 18h10
  4. Récupérer une variable à partir de son nom ...
    Par CynO dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 13/10/2005, 16h59
  5. Réponses: 3
    Dernier message: 24/09/2004, 21h21

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