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

Signal Discussion :

Détection de silences dans un fichier .wav


Sujet :

Signal

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 36
    Points : 27
    Points
    27
    Par défaut Détection de silences dans un fichier .wav
    Bonjour,

    Je tente de développer un petit programme qui "découpe" une trame audio en fonction du nombre de silences détectés. Pour cela je détermine l'énergie du signal,puis si cette énergie est inférieure à un certain seuil, je fait passer à '1' un signal "silence" (fonction silencerecognition).

    Ensuite, j'ai crée une fonction (streamcutter) qui divise ma trame audio en sous trames, de la manière suivante:

    Dès qu'un silence est détecté, on arrête d'enregistrer la sous trame, on la stocke dans une cellule d'un "cell array", puis on commence l'enregistrement de la trame suivante.

    Mon problème est le suivant:
    Pour calculer l'énergie du signal, je fais intervenir une fonction toute faite appelée enframe, disponible dans une toolbox appelée voicebox, que j'ai trouvée sur internet. Or cette fonction fait apparaître un facteur d'échelle 10 entre l'énergie (et par conséquent la détection de signal) et le signal lui-même. Du coup, lorsque je découpe une trame, je ne parcours que 10% du signal, donc j'effectue un mauvais découpage. Or ce facteur d'échelle 10 peut être annulé (je pense) en faisant passer le paramètre inc (appelé FrameInc dans ma fonction silencerecognition) de la valeur 10 à la valeur 1. Cependant, cette opération fait passer le temps de calcul de quelques secondes à plus de 10 minutes (je n'ai même pas osé attendre)

    Quelqu'un peut-il m'aider, soit en me guidant pour calculer l'énergie d'une autre façon soit en faisant une pirouette avec des index ou je ne sais quoi d'autre (je suis ouvert à toutes les solutions!!!)

    Par ailleurs, afin de mieux exposer mon problème (ou pour filer des sources à ceux qui cherchent des programmes de calcul d'énergie ) mes scripts matlab sont téléchargeables à l'adresse suivante:

    http://www.mediafire.com/?dxb9n5u2pmt

    Un grand grand merci à tous ceux qui auront le temps de se pencher sur le sujet!!

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 36
    Points : 27
    Points
    27
    Par défaut
    En fait, pour faire un peu plus simple, mon problème se résume à ceci:

    - energy est un vecteur de longueur 5.5 e4
    - x est un vecteur de longueur 5.5 e5
    - je souhaiterais générer un signal blanc de la même longueur que x, lorsque energy est supérieur à un seuil
    - malheureusement, pour des problèmes de longueur de calcul, je ne peux pas ramener energy à la même échelle que x.
    Mon code est très simple, c'est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    seuil = max(energy)-0.7*max(energy);
     
    for k=1:length(x)
        if (energy(k) >= seuil)
            silence(k) = 0;
        else
            silence(k) = 1;
        end
    end
    donc, comme on peut s'en douter, problème de longueur d'index. Comme tout débutant, j'ai tenté un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (energy(k/10) >= seuil)
    mais les index sont obligatoirement positif et entiers...

    J'ai l'impression que c'est tout con, mais je ne vois pas la solution!!

    Merci à ceux qui pourront m'aider

  3. #3
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 884
    Points
    52 884
    Par défaut
    Sinon, une autre possibilité (assez empirique je dois bien l'admettre )

    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
    clc
    clear all;
    close all;
     
     
    signal = wavread('2.wav');
    signal = resample(signal, 5000, 32000);
     
    % On travaille en mono
    signal = signal(:,1);
     
    figure
     
    % Affichage du signal
    subplot(311)
    plot(signal, 'b')
    title('Signal');
     
     
    % Calcul de l'énergie (approximation)
    S = abs(signal);
    m = min(S(:));
    S = S - m;
    M = max(S(:));
    S = S/M;
     
    e = S.^2;
     
    % Affichage de e
    subplot(312)
    plot(e, 'r')
    title('~Energie~');
     
    % Seuillage de e
    seuil = .15;
    e = e>seuil;
     
    % Affichage su seuil
    hold on
    plot([0 numel(e)],[seuil seuil],'m-')
     
    % Détection des "silences"
    s=sign(diff([inf;e].'));
    idxmin=strfind(s,[0 1]);
     
    % Conservation des silences suffisamment longs
    % Modifier le paramètre T
    T = 3000;
    d = diff(idxmin);
    temp = find(d>T);
    t = idxmin(temp);
    t(2,:) = idxmin(temp+1);
     
    % Affichage des silences détectés
    subplot(313)
    plot(1:numel(signal),signal, 'b',t,e(t),'m-s')
    title('Signal + silences');
    Reste à définir ce que tu entends par "silence" ?
    Comment sont caractérisés ces silences en durée ?
    Combien y-a-t-il de silences dans ton signal et où sont-ils ?
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  4. #4
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 884
    Points
    52 884
    Par défaut
    Sinon, ton bout de code devrait simplement s'écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    seuil = .3*max(energy);
     
    temp = energy<seuil;
     
    silcence = zeros(1,numel(x));
    silence(1:10:end) = temp;
    Ou quelque chose dans le genre
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    bonjour,

    1. en ce qui concerne tes problèmes de performances sous matlab, sache que les boucles sont déconseillés et les prédicats à l'intérieur des boucles encore plus.

    La méthode de Dut est plus en attente avec le type de programmation attendu sous matlab. En plus tu peux faire des calculs sur des tableaux de très grandes tailles en très peu de temps. Si tu attends plus d'une minute sous matlab, tu peux revoir ton code....

    2. Le calcul de l'énergie doit se faire sur un panel d'échantillons. Il est incohérent de vouloir connaitre l'énergie échantillon par échantillon puisqu'il s'agit d'une intégration dans le temps. Il est donc normal que ton vecteur signal et que ton vecteur énergie ne soit pas de la même taille.
    Par contre tu peux calculer la puissance instantanée de ton signal qui sera le module carré de la valeur de ton échantillon à chaque instant.

    bon courage

  6. #6
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 884
    Points
    52 884
    Par défaut
    Citation Envoyé par Antonin08 Voir le message
    Par contre tu peux calculer la puissance instantanée de ton signal qui sera le module carré de la valeur de ton échantillon à chaque instant.
    Donc c'est la puissance et non pas l'énergie qui est calculée à cette ligne :

    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 36
    Points : 27
    Points
    27
    Par défaut
    Bonjour,

    Suite à la remarque très pertinente de Antonin08:
    1. en ce qui concerne tes problèmes de performances sous matlab, sache que les boucles sont déconseillés et les prédicats à l'intérieur des boucles encore plus.
    Et à un petit brainstorming avec un de mes collègues, j'ai trouvé la solution: dans la fonction streamcutter, il faut remplacer le case 1, par:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    case 1,
            nb=1;                                        
            for k = 1:length(silence)                     
                if (silence(k)==1 && silence(k-1)==0)    
                    A{i}=x(nb:k);                         
                    i=i+1;                                
                    nb=k+1;                               
                end
            end
    Ce qui permet en fait de recopier la totalité du signal lu avant un silence, et de le stocker dans une cellule du cellarray A, sans faire de boucle...

    J'espère que mes explications ne sont pas trop farfelues, et que ces post pourront aider d'autres personnes qui seraient dans mon cas!

    Merci à tous ceux qui m'ont conseillé!

    François

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2008
    Messages : 57
    Points : 52
    Points
    52
    Par défaut
    bonjour,

    Attention, n'oublie pas que sous MATLAB les fonctions sont optimisées pour travailler sur des tableaux.

    Donc pourquoi tester toutes les valeurs k de tes échantillons en sachant que ton test sera négatifs presque "tout le temps"

    Utilise plutôt la fonction diff qui fait la différence échantillon à échantillon et te renverra -1 ou 1 suivant le cas avec les indices de changement d'état en prime grâce à la fonction find.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Ifin = find(diff(silence) == -1 )
    Ideb = find(diff(silence) == 1 )
    Ifin et Ideb contiennent les indices x(nb:k) pour chaque intervalle.
    Il te reste à faire ta boucle sur la longueur de Ideb ou Ifin.
    Attention aux cas limites et également à la prise en charge des cas où Ideb et Ifin ne seraient pas de la même taille...

    voilà

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 19/03/2012, 19h55
  2. Détection des contraintes dans un fichier SQL
    Par mariem_m dans le forum Langage SQL
    Réponses: 9
    Dernier message: 30/11/2010, 10h51
  3. Détection des erreurs dans un fichier texte (txt)
    Par M E H D I dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 25/05/2010, 10h14
  4. Détection de paragraphe dans un fichier texte
    Par superdj dans le forum Pascal
    Réponses: 12
    Dernier message: 19/02/2007, 11h16
  5. Lire DANS un fichier wav avec VBA
    Par SwissEngineer dans le forum Général VBA
    Réponses: 7
    Dernier message: 01/12/2006, 16h56

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