Partage
  • Partager sur Facebook
  • Partager sur Twitter

Calculer le db d’un micro, singal audio

Sujet résolu
    26 août 2015 à 10:39:12

    Bonjour à tout le monde,

    Voici mon problème, j’utilise JavaSound pour récupère mon son(en octets) grâce à la class "TargetDataLine" en utilisant la méthode « read » (targetDaraLine.read(audioDataFull,0,audiDataFull.length)). Je voudrai pouvoir déterminer grâce à mes octets l’amplitude du son ou le niveau dB.
    J’ai déjà effectué des recherches et j’ai trouvé un sujet assez bien fait : ici

    Il en ressort deux opérations :
    dB = 20 * log10(amplitude)


    amplitude = 14731 / 32768 = 0.44 dB = 20 * log10(0.44) = -7.13

    (32768 si le fichier audio est codé en 16 bits)
    (14731 valeur des octets à l’ instant t)

    Mais je ne comprends pas totalement les calcule n’y les valeurs de référence quelqu’un pourrait m’aider ?
    Merci d’avance .
    • Partager sur Facebook
    • Partager sur Twitter
      26 août 2015 à 11:22:53

      Salut !

      C'est purement physique tout cela ^^

      Pour obtenir la valeur en dB, l’opération est bien 20*log10(amplitude) (avec log10 le log en base 10 tout simplement).

      L'amplitude est bien déterminée par un rapport de deux nombre : (valeur obtenue) / (valeur de référence max), où en 16 bits 32768 est le maximum (2^15). Après il faut juste effectuer le calcul avec le log et tu as ta valeur en dB !

      Source utile : https://fr.wikipedia.org/wiki/D%C3%A9cibel

      -
      Edité par BabC 26 août 2015 à 11:23:23

      • Partager sur Facebook
      • Partager sur Twitter
        26 août 2015 à 11:46:57

        Merci pour la réponse,

        Donc si je veux faire un graphe dynamique (a l'instant t(s) ou au plus proche) avec les dB en ordonnée et le temps en abscisse je dois récupérer tout les octets les mettre par deux (si en 16 bits) calculer leur valeur (en float j'imagine) et après faire les divers opérations. Puis le résultat obtenue je le compare avec la valeur max théorique qui est ici 32768 (si 16 bits encore une fois). C'est bien ça ou je suis a coter de la plaque ? :D

        • Partager sur Facebook
        • Partager sur Twitter
          26 août 2015 à 12:23:03

          Pourquoi par deux ?

          Imaginons que toutes les 100ms tu récupère une valeur "value" par ton read(). Tu passe alors par une methode du genre :

          private static float calculdB (float value){
          return (20*Math.LOG(value/32768));
          }

          (Je fais ça de tête, il faut vérifier si la fonction Log est bien dans Math, et si c'est bien un log10)



          • Partager sur Facebook
          • Partager sur Twitter
            26 août 2015 à 13:40:49

            Ben quand on récupère notre tableau d'octet grâce a la méthode read de TargetDataLine on l'a octet par octet et 16bits = 2 octets non ?

            Et pour le paramètre value que tu donne a la méthode calculdB c'est la valeur des deux octet non ?

            • Partager sur Facebook
            • Partager sur Twitter
              26 août 2015 à 13:53:28

              Es-tu sur déjà que ton son est codé sur 16bits ?

              La valeur passée en paramètre de ma méthode est la valeur de ton son, a adapter après...  Mais je ne pourrais pas te dire si oui ou non il faudra coupler les valeurs (même si ça m’étonne de faire ainsi...)

              • Partager sur Facebook
              • Partager sur Twitter
                27 août 2015 à 9:42:32

                Oui via mon format audio.

                Je suis en train de me renseigner un peut plus sur le faite de calculer les dB je tiendrai au courant le sujet mais je suis toujours preneur de nouvelles explications ^^.

                • Partager sur Facebook
                • Partager sur Twitter
                  1 septembre 2015 à 10:03:04

                  Rebonjour,
                  Suite a de nombreuses recherches je n'arrive toujours pas a comprendre comment traiter mes octets audio pour avoir l'amplitude et le db.
                  J'ai trouver plusieurs sites telle que : ici et

                  Si quelqu'un peut me donner un coup de main ça sera avec plaisir ^^ car j'ai du mal avec les math, physique .

                  Merci
                  • Partager sur Facebook
                  • Partager sur Twitter
                    1 septembre 2015 à 10:50:29

                    Resalut !

                    Selon les liens que tu as donné, il faut traiter tes octets deux a deux, bit a bit, et les stocker dans une nouvelle variable.

                    2e lien :

                        for(int b; (b = line.read(buf, 0, buf.length)) > -1;) {
                    
                                    // convert bytes to samples here
                                    for(int i = 0, s = 0; i < b;) {
                                        int sample = 0;
                    
                                        sample |= buf[i++] & 0xFF; // (reverse these two lines
                                        sample |= buf[i++] << 8;   //  if the format is big endian)
                    
                                        // normalize to range of +/-1.0f
                                        samples[s++] = sample / 32768f;
                                    }
                    
                                    float rms = 0f;
                                    float peak = 0f;
                                    for(float sample : samples) {
                    
                                        float abs = Math.abs(sample);
                                        if(abs > peak) {
                                            peak = abs;
                                        }
                    
                                        rms += sample * sample;
                                    }
                    
                                    rms = (float)Math.sqrt(rms / samples.length);
                    
                                    if(lastPeak > peak) {
                                        peak = lastPeak * 0.875f;
                                    }
                    
                                    lastPeak = peak;
                    
                                    setMeterOnEDT(rms, peak);
                                }

                    As-tu les connaissances sur Bigendian/Littleendian, car ils en parle et ça peut être un problème a un moment pour toi ;)

                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 septembre 2015 à 11:13:14

                      Oui j'ai vu ce code je l'ai essayer c'est la class meter.

                      Pour l'histoire du Bigendian/Littleendian c'est poids fort / poids faible non ? On le configure grâce a notre format audio au moment ou on ouvre une TargetDataLine c'est ça si je ne dit pas de bêtise ?

                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 septembre 2015 à 11:21:15

                        Oui en gros c'est ça, c'est la manière dont le format est fait (bit de poids fort en premier ou bit de poids faible).

                        Pour la config, selon la javadoc c'est bien cela ;) (un petit bool de AudioFormat a mettre a true pour du Bigendian)

                        Et donc l’implémentation de cette classe ça donne quoi ? Procède étape par étape si ce n'est déjà fait, vois si tu peux déjà lire tes octets bit a bit, puis les "concaténer" deux a deux, ou l'inverse.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 septembre 2015 à 11:37:21

                          Quand j’implémente cette classe sa fonctionne bien j'ai une vue du lvl sonore de mon son. Le probleme c'est que je n'ai pas de valeur négative alors que quand tu regarde par exemple dans Audacity avec le graphe "forme d'onde", ta des valeurs négatives (la forme du signal est proche d'une sinusoïdal avec comme valeur moyenne 0 ) . C'est ce résultat que je désirs enfin surtout les valeurs du graphe. J'ai regarder et si j'ai bien comprit c'est l'amplitude du son par rapport au temps. Pour le faite de lire les octets oui je réussi tres bien j'ai déjà fait des traitements dessus (séparation des canaux ...) donc j'ai mes octets sans probleme c'est la suite qui coince ... Transformer ces octets en valeur positive et négative en comprenant le fonctionnement ^^.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 septembre 2015 à 11:42:18

                            Ah bah super !

                            Le problème doit être dans ton calcul avec ton log alors ... Tu peux nous faire voir ton code pour le traitement amplitude -> db ?

                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 septembre 2015 à 11:53:12

                              Pour l'instant je n'est pas de calcule :-° ^^. C'est ce que je recherche "la bonne parole", je ne comprend pas quelle calcule je dois faire , quel traitement effectuer sur mes octets pour avoir en premier l'amplitude de mon son et ensuite grace au resultat trouver avoir le dB enfin si c'est cette logique qu'il faut suivre ^^.

                              (Quand je dit : "Quand j’implémente cette classe sa fonctionne bien j'ai une vue du lvl sonore de mon son." c'est pas ma class ici c'est la class Meter ^^)

                              • Partager sur Facebook
                              • Partager sur Twitter
                                1 septembre 2015 à 12:06:52

                                Soit je suis très fatigué, soit tu m'as perdu ^^

                                Tu arrive a lire tes octets, a les coupler et a avoir un vue de ton son ? Pour moi ce résultat est ton amplitude ! (ou alors je suis a cote de la plaque ... =P)

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  1 septembre 2015 à 13:39:03

                                  Je m’explique peut être mal aussi :D. Je reformule :

                                  - J'arrive a lire mes octets.

                                  - Pour les coupler je suis pas sur (lier au poids fort / poids faible non ?) si c'est le qu'a pas encore fait ^^.

                                  - Après je sais pas si le résultat de mes octets donne mon amplitude ... Il faut pas faire un calcule pour la récupérer ? Sa me parait trop simple non ? ^^

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    1 septembre 2015 à 15:22:04

                                    Trop simple trop simple... faut pas pousser non plus =P

                                    Tu arrive (presque) a lire ce que ton micro perçoit, soit l'amplitude d'un signal ! Je pense qu'il ne faut pas aller plus loin ^^

                                    Pour le couplage ça se passe comme ça du coup :

                                                // convert bytes to samples here
                                                for(int i = 0, s = 0; i < b;) {
                                                    int sample = 0;
                                     
                                                    sample |= buf[i++] & 0xFF; // (reverse these two lines
                                                    sample |= buf[i++] << 8;   //  if the format is big endian)
                                     
                                                    // normalize to range of +/-1.0f
                                                    samples[s++] = sample / 32768f;
                                                }

                                    Inverse bien les lignes si ton AudioFormat est en BigEndian ;)
                                    Attention ici il fait la normalisation avec 2^15 !

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      1 septembre 2015 à 16:31:35

                                      Ok merci de m'aider car pas simple tout ça au final :euh:  ^^.

                                      Donc la on est en 16 bits c'est ça ? On additionne les deux octet de l’échantillon en faisant les décalages nécessaire (pour le poids fort de 8 bits à gauche et inverse pour le poids faible) et ensuite on divise le tout par 32768 (en 16 bits) pour afficher le graphe sur un plage +1/-1.

                                      J'ai trouver aussi :

                                      private int getAmplitude(int poidsFort, int poidsFaible) {
                                      		return (poidsFort<< 8) + (poidsFaible & 0x00ff);
                                      	}



                                      Cette valeur finale sera donc mon amplitude ... je n'ai rien oublier ? ^^

                                      -
                                      Edité par BadShade 1 septembre 2015 à 16:33:19

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        1 septembre 2015 à 16:38:01

                                        Bingo ;)

                                        Bon après tout cela n'est que mon propre raisonnement et mes connaissances en traitement du signal... Mais on verra bien tes résultats, et si tout marche alors c'est qu'on avait raison x)

                                        Le fait que l'on soit en 16bit vient de toi et ton micro, mais tu as dit que oui précédemment ;)

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          1 septembre 2015 à 16:56:30

                                          Je vais coder ça ^^ pour le 16 bits ça dépend du forma ou je veux enregistrer mon son je peux le configurer en 16 ou 8 bits.

                                          D’ailleurs pour le 8 bits comme je n'ai pas de poids faible poids fort je convertie uniquement mon octet en int et j'ai mon amplitude ??

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            2 septembre 2015 à 9:53:32

                                            Ok merci pour tout , tu m'as bien aider à voir plus clair dans tout ça :D.

                                            J'ai plus qu'a trouver un moyen d'afficher tout ça, en créant un graphe dynamique un peut comme Audacity. Je pense que ça ne va pas être très simple car rien que le rafraichissement pour afficher les valeurs vont prendre énormément de puissance et je ne veux surcharger mon CPU ...

                                            Il va falloir que je trouve un bon compromis, si quelqu'un a des pistes je suis preneur ;).

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              2 septembre 2015 à 10:15:19

                                              Tu dois avoir des librairies toutes faites pour tracer des graphs. Tu stocks tes valeurs dans une liste ou quelque chose comme ça ;)
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                2 septembre 2015 à 10:45:54

                                                Oui comme "Jfreechart" avec les graphes dynamique j'ai déjà travailler avec mais le probleme c'est que le graphe n'a pas de scrollbar donc on perde de vue les ancienne valeurs. J'ai peur de devoir crée moi même un class pour le générer ... Un peut comme le montre ce site ou celui-ci .
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  2 septembre 2015 à 12:16:08

                                                  Essaie deja de générer un graph simple, et si les valeurs ne sont pas du tout bonnes c'est qu'on s'est planté quelque part ^^
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    2 septembre 2015 à 16:19:06

                                                    Moi je dit on est pas trop mal :p. Voici ce que ça donne :

                                                     Signial audio

                                                    On vois bien la différence d'amplitude quand j’arrête l’appareille et le relance donc je pense que les calcule sont bon.

                                                    Plus qu'à trouver un graphe ou autre qui permet de l’afficher avec une scrollbar pour voire l'intégralité du graphe, donc je suis preneur d'idées ^^

                                                    -
                                                    Edité par BadShade 2 septembre 2015 à 18:29:12

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      3 septembre 2015 à 9:11:45

                                                      Au top !

                                                      C'est le bruit ambiant du coup ? Ou tu parlais aussi/ musique ?

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        3 septembre 2015 à 9:52:28

                                                        Non non , c'est de la musique. Je branche mon ipode avec une prise jack à ma carte son et mon programme fait le reste. Donc là où l’amplitude est en bas c'est le moment où je m'ai pause sur mon ipode, après j'ai varier un peut la puissance du son est sa fonctionne relativement bien. Le seul probleme reste le graphe, il pompe beaucoup trop de puissance (30% du CPU o_O et j'ai pas un bas de gamme ...). Il faudrait que je trouve aussi un moyen d'avoir une scroll pour pouvoir naviguer dedans ... C'est la où les chose ce complique ^^. C'est pour avec ces sites : ce site ou celui-ci , j'ai trouver quelque piste sur le faite de crée soit même le graphe mais pas simple du tout . Pour ça je suis preneur de toute idée :ange:.
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          3 septembre 2015 à 10:20:17

                                                          Après ça fait un bon exercice de tout faire soit même ;) C'est même là où tu apprends le mieux !

                                                          Je pense qu'avec le lien vers stackoverflow (extends JComponent implements Scrollable) tu devrai t'en sortir =)

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter

                                                          Calculer le db d’un micro, singal audio

                                                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                          • Editeur
                                                          • Markdown