Moyen le plus simple de détecter le début et la fin des enveloppes audio

43

Ci-dessous un signal qui représente un enregistrement de quelqu'un qui parle. Je voudrais créer une série de signaux audio plus petits basés sur cela. L'idée est de détecter le début et la fin d'un son "important" et d'utiliser ceux-ci comme marqueurs pour créer un nouvel extrait de son. En d'autres termes, j'aimerais utiliser le silence comme indicateur du début ou de la fin d'un «morceau» audio et créer de nouveaux tampons audio en conséquence.

Ainsi, par exemple, si une personne s’enregistre en disant

Hi [some silence] My name is Bob [some silence] How are you?

alors je voudrais faire trois clips audio à partir de cela. Un qui dit Hi, un qui dit My name is Bobet un qui dit How are you?.

Mon idée de départ est de parcourir le tampon audio en vérifiant en permanence les zones de faible amplitude. Peut-être que je pourrais le faire en prenant les dix premiers échantillons, en faisant la moyenne des valeurs et si le résultat est faible, étiquetez-le comme étant silencieux. Je procéderais dans le tampon en vérifiant les dix échantillons suivants. En procédant ainsi, je pouvais détecter le début et la fin des enveloppes.

Si quelqu'un a des conseils sur un bon moyen, mais simple , de le faire, ce serait formidable. Pour mes besoins, la solution peut être assez rudimentaire.

Je ne suis pas un professionnel chez DSP, mais je comprends certains concepts de base. De plus, je le ferais par programme, alors il serait préférable de parler d’algorithmes et d’échantillons numériques.

Merci pour votre aide!

entrez la description de l'image ici


EDIT 1

Super réponses jusqu'à présent! Je voulais juste préciser que ce n’est pas de l’audio en direct et que j’écrirai moi-même les algorithmes en C ou en Objective-C, de sorte que les solutions utilisant des bibliothèques ne sont pas vraiment une option.

Eric Brotto
la source
1
On dirait que vous essayez de le dissocier en utilisant des périodes de silence comme points de rupture. Pourquoi ne pas simplement utiliser le seuil de puissance pour déterminer le "silence" et prévoir un laps de temps pour déterminer s'il est suffisamment long pour constituer une pause?
Jim Clay
@ JimClay Oui, c'est exactement ce que j'essaie de faire. Je n'ai jamais entendu parler du seuil de puissance, mais cela ressemble à quelque chose que je pourrais utiliser. Est-ce compliqué? Pourriez-vous développer un peu cela?
Eric Brotto
@EricBrotto Peut-être devriez-vous nous en dire un peu plus sur les fonctionnalités de vos bibliothèques. Cela nous permettra de mieux utiliser la méthodologie actuelle.
Spacey
Quel est le meilleur moyen de détecter le silence? Quel devrait être le niveau de retenue retenu autre que 0,05 x = wavread ('s1.wav'); i = 1; tandis que abs (x (i)) <0,05% Détection de silence i = i + 1; extrémité x (1: i) = []; x (6000: 10000) = 0;
Zeee

Réponses:

26

C'est le problème classique de la détection de la parole . La première chose à faire serait de Google le concept. Il est largement utilisé dans la communication numérique. De nombreuses recherches ont été menées sur ce sujet et il existe de bons articles.

En règle générale, plus vous avez de bruit de fond, plus votre méthode de détection de la parole doit être élaborée. Si vous utilisez des enregistrements pris dans une pièce silencieuse, vous pouvez le faire très facilement (plus tard). Si vous avez toutes sortes de bruits pendant que quelqu'un parle (camions qui passent, aboiements de chiens, assiettes cassantes, attaques d'extraterrestres attaquant), vous devrez utiliser quelque chose de beaucoup plus intelligent.

En regardant la forme d'onde que vous avez attachée, votre bruit est minimal, donc je suggère ce qui suit:

  1. Extraire l'enveloppe du signal
  2. Choisissez un bon seuil
  3. Détecter les endroits où la magnitude de l'enveloppe dépasse le seuil

Qu'est-ce-que tout cela veut dire? Une enveloppe de signal est une courbe qui décrit sa magnitude dans le temps, indépendamment de la façon dont son contenu fréquentiel le fait osciller (voir image ci-dessous).

entrez la description de l'image ici

{1,45,-6,2,-43,2}{1,45,6,2,43,2} peuvent être trouvés à titre expérimental et peuvent dépendre de plusieurs facteurs tels que votre taux d'échantillonnage.

Vous pouvez voir sur l'image que le niveau de bruit est faible, que l'enveloppe de signal sera toujours au-dessus d'un certain seuil (niveau de volume) et que vous pouvez considérer ces régions comme des régions détectées par la parole .

Phonon
la source
3
En fait, je l'avais implémenté comme l'un des plug-ins de Good'ol Winamp. Ce que vous décrivez est bon mais pas suffisant. Il y a généralement des sons vocaux (voyelles) et des sons non exprimés (consonnes). S'il n'y avait que du son exprimé, ce que vous décrivez fonctionnera - mais les sons non exprimés sont de très basse énergie et ne se distinguent pas vraiment du bruit général. Et les conditions sans bruit sont également très rares, même dans les studios.
Dipan Mehta
comment y parvenir en python?
kRazzy R
26

Ce que vous voulez vraiment faire s'appelle essentiellement Détection d'activité vocale ou détection de la parole.

Fondamentalement, tout signal vocal pur (qui ne contient pas de musique) comporte trois parties.

  1. Le son exprimé - qui est essentiellement causé par les voyelles
  2. Le son non vocalisé - qui contient des consonnes.

La caractéristique du son humain est telle que, même si beaucoup d’énergie est utilisée dans le son exprimé, l’information réelle est contenue dans les consonnes. En outre, le son exprimé est généralement une fréquence plus basse lorsque les sons non exprimés sont des fréquences plus élevées. [Pour être précis, tous les sons exprimés résonnent plus ou moins comme une fréquence constante pour une personne donnée qui correspond à sa hauteur].

Maintenant, comme tout système, il y a du bruit. Le son exprimé est généralement assez puissant pour pouvoir être distingué de manière visible. Lorsque vous appliquez un filtrage de fréquence inférieure, il est possible de collecter une bonne amplitude des sons sonores. Toutefois, le son non exprimé (avec toutes les informations riches) sera perdu.

Venir à la question comment le résoudre:

L'astuce réside dans le fait que les sons non vocalisés proviennent toujours d'une source qui résonne. et intrinsèquement restreint sur une certaine fréquence. Où comme, le bruit est plutôt uniforme. Donc, une mesure simple qui distingue les trois est "alimentation locale" ou bien l'équivalent consiste à prendre l'auto-corrélation fenêtre.

Si vous prenez à la fois 100 échantillons - et se corrèlent automatiquement, s'il ne contient que du bruit, les résultats seront quasiment nuls (c'est la propriété du bruit blanc) - comme pour le signal vocal, cette amplitude sera observable car le signal a toujours une meilleure structure. Cela avait fonctionné pour moi, par le passé.

VAD a été un domaine de recherche actif, car presque toutes les communications de téléphonie mobile veulent détecter les parties non parlées et les supprimer de l’encodage. Mais s'ils supprimaient les paroles non exprimées, cela rendrait la téléphonie inutile.

La norme G.729 calcule la VAD en fonction de caractéristiques telles que: fréquences spectrales de ligne, énergie en bande pleine, énergie en bande basse (<1 kHz) et taux de passage à zéro.

La norme GSM fonctionne comme suit: L’option 1 calcule le RSB dans neuf bandes et applique un seuil à ces valeurs. L'option 2 calcule différents paramètres: puissance du canal, métriques de voix et puissance du bruit. Il seuille ensuite les métriques de voix en utilisant un seuil qui varie en fonction du RSB estimé. (de wikipedia)

Pour des techniques plus avancées, je liste quelques références sur ce sujet.

  1. Référence la plus citée : Jongseo Sohn; Nam Soo Kim; Wonyong Sung; "Une détection d'activité vocale basée sur un modèle statistique" Lettres de traitement du signal, IEEE, janvier 1999, volume: 6 numéro: 1 pp: 1-3

  2. Les solutions les plus pertinentes pour vous: Mark Marzinzik et Birger Kollmeier "Détection de pause de parole pour l'estimation du spectre de bruit en suivant la dynamique d'enveloppe de puissance" IEEE TRANSACTIONS SUR LE TRAITEMENT VOCAL ET AUDIO, VOL. 10, NO. 2, FÉVRIER 2002 pp.109

  3. Ramírez, J .; JM Górriz, JC Segura (2007). "Détection d'activité vocale. Principes de base et robustesse du système de reconnaissance vocale". Dans M. Grimm et K. Kroschel. Reconnaissance et compréhension de la parole robustes. pp. 1–22. ISBN 978-3-902613-08-0.

  4. Introduction: Jonathan Kola, Carol Espy-Wilson et Tarun Pruthi "Détection d'activité vocale"

Dipan Mehta
la source
comment y parvenir en python?
kRazzy R
9

Je soutiens totalement Jim Clay sur son approche, mais modifie légèrement la saveur en utilisant une enveloppe:

Nous savons que la parole se produit principalement autour de 1-2kHz. Votre échantillonnage de données est susceptible d'être de 44 kHz (cela dépend de votre appareil d'enregistrement). Donc, ce que je ferais en premier lieu est une moyenne mobile du signal carré en temps réel sur 10 points, pour avoir une enveloppe de la puissance du signal. Cela induira un retard dans la détection, vous voulez donc garder ce niveau bas.

J'ajouterais ensuite une phase d'étalonnage sur votre système: demandez à l'utilisateur de rester silencieux, appuyez sur un bouton et enregistrez le bruit de fond pendant environ 10 secondes. Prenez l’amplitude moyenne ou médiane de l’enveloppe, multipliez-la par 2 pour avoir une sécurité, et cela vous donnerait automatiquement le seuil dont Jim a parlé.

S'il ne s'agit pas d'un enregistrement en temps réel, vous pouvez trouver utile d'utiliser une moyenne mobile à 0 phase pour réduire les inconvénients causés par le retard. Dites-nous si cela fonctionne pour vous tel qu'il est.

Jean-Yves
la source
9

Eric,

Si vous recherchez vraiment quelque chose de rapide et de sale, la première chose que vous devez obtenir est l’enveloppe, et je le ferais simplement (en MATLAB) en:

 envelope = abs(hilbert(yourSignal));

À ce stade, je voudrais simplement définir un seuil et «la voix existe» si vous dépassez un certain seuil.

C'est une solution très simple, mais cela pourrait fonctionner pour vous.

Spacey
la source
1
+1 Peut-être pourriez-vous élaborer sur la méthode derrière cette ligne de code? Je suis sûr que l'OP n'est pas familiarisé avec l'extraction d'enveloppe via Hilbert Transform.
Phonon
@Mohammad Merci! Mais s'il vous plaît voir mon EDIT 1. Je voudrais vraiment rapide et sale, mais j'ai également besoin de faire les algorithmes moi-même :)
Eric Brotto
@EricBrotto Ah ok, eh bien, je peux vous dire comment implémenter un transformateur d'Hilbert, mais je suppose que vous avez la possibilité de faire une FFT dans vos bibliothèques C / Obj-C? Si ce n'est pas ça va être un problème ... :-)
Spacey
comment y parvenir en python?
kRazzy R
Monsieur / Madame, pourriez-vous m'indiquer des ressources sur la manière dont cet Hilbert est implémenté en Python?
kRazzy R
6

Je suppose que vous avez affaire à des signaux réels et non complexes. Si ce n'est pas le cas, faites-le moi savoir et je pourrai modifier la réponse.

La puissance est définie comme le carré du signal (c.-à-d. Les échantillons de signal multipliés par eux-mêmes). Vous pouvez comparer la puissance à un certain seuil pour déterminer si de la parole est présente ou non. Vous devrez probablement effectuer certaines mesures sur vos enregistrements pour trouver de manière empirique un bon seuil.

Si vos enregistrements sont "propres" (c'est-à-dire pas beaucoup de bruit), j'irais probablement aussi simple que possible en comparant la puissance instantanée (c'est-à-dire un seul échantillon) au seuil. Cela signifie que vous n'avez même pas besoin de régler le problème si vous ne le souhaitez pas, vous avez simplement besoin de la valeur absolue et de le comparer à la racine carrée du seuil de puissance, qui peut être précalculé. Lorsque vous détectez un discours, saisissez-le et un certain nombre d’enregistrements avant, pour vous assurer de bien entendre tout le discours (peut-être 1/10 de seconde?). Continuez jusqu'à ce que vous trouviez une période prolongée sans échantillons qui dépassent le seuil. Là encore, la durée de la période devrait être déterminée de manière empirique.

Rincer et répéter.

Jim Clay
la source
4

J'ai écrit une classe de détecteurs d'activité en Java. Cela fait partie de ma collection open source DSP Java . Vous pouvez utiliser le programme de test WavSplitter.java pour le récupérer avec un fichier WAV en entrée.

Christian d'Heureuse
la source
Gardez à l'esprit que l'OP dit qu'il doit écrire lui-même les algorithmes en C.
Sam Maloney
Il est très facile de convertir de tels algorithmes de Java en C.
Christian d'Heureuse Le
Monsieur, comment y parvenir en python?
kRazzy R