Question:
Empêcher la saturation du signal audio
Sriram
2010-11-29 14:10:55 UTC
view on stackexchange narkive permalink

J'essaie d'implémenter un algorithme sur les signaux audio. L'algo fonctionne sur le signal trame par trame. L'une des étapes intermédiaires nécessite l'ajout du signal aux trames précédentes. La trame de sortie est saturée à la fin de cette étape.

Clarification: La trame de sortie de l'opération d'addition est en double, bien que la trame de sortie finale DOIT être en bref. Donc le problème de saturation.

J'ai essayé ce qui suit pour éviter la saturation:
1. Limitation absolue: limitez tout échantillon à une valeur max_val prédéfinie.
2. Normalisation: calculez la valeur max. du cadre, puis mettez à l'échelle chaque échantillon du cadre de manière appropriée.

Aucune de ces approches n'a fonctionné puisque je dois travailler image par image.

Toute aide pour éviter la saturation des signaux est la bienvenue.

Qu'est-ce qui est physiquement / pratiquement saturant? Quel est le maximum / minimum du signal d'entrée? Le signal entier est-il saturé ou s'agit-il uniquement des pics?
les valeurs des trames de signal (opération de post-addition) saturent. le rendement de l'opération ci-dessus est double, mais doit être rendu court. d'où le problème de saturation.
Est-ce pour la musique ou la voix?
@Kellenjb: pour les deux.
Six réponses:
Kellenjb
2010-11-29 22:36:00 UTC
view on stackexchange narkive permalink

Vos tentatives

Par définition, lorsque vous «limitez» les valeurs de votre code, vous causez une saturation. Ce n'est peut-être pas une saturation dans le sens d'un débordement de votre short, mais vous déformez toujours la vague lorsqu'elle dépasse un certain point. Voici un exemple:

Saturation

Je me rends compte que vous ne vous limitez probablement pas au fond, mais je l'avais déjà dessiné avant de m'en rendre compte.

Donc, en d'autres termes, la méthode de limitation stricte ne fonctionnera pas.

Maintenant, pour votre deuxième approche, cette méthode vous amènera à faire ce que certaines personnes audio font intentionnellement. Vous faites en sorte que chaque image soit aussi forte que possible. Cette méthode peut fonctionner correctement si vous obtenez la bonne mise à l'échelle et que votre musique sonne toujours fort, mais ce n'est pas génial pour la plupart des gens.

Une solution

Si vous connaissez le gain effectif maximal possible que votre système peut créer, vous pouvez diviser votre contribution par autant. Pour comprendre ce que cela serait, vous devrez parcourir votre code et déterminer quelle est l'entrée maximale, lui donner un gain de x, déterminer quelle est la sortie maximale en termes de x, puis déterminer dans quoi x devrait être afin de ne jamais saturer. Vous appliqueriez ce gain à votre signal audio entrant avant de faire quoi que ce soit d'autre.

Cette solution est correcte, mais n'est pas idéale pour tout le monde car votre plage dynamique peut être un peu blessée car vous ne le faites généralement pas. fonctionner à l'entrée max tout le temps.

L'autre solution est de faire un gain automatique. Cette méthode est similaire à la méthode précédente, mais votre gain changera avec le temps. Pour ce faire, vous pouvez vérifier la valeur maximale de chaque image de votre entrée. Vous utiliserez pour stocker ce numéro et placer un simple filtre passe-bas sur vos valeurs max et décider du gain à appliquer avec cette valeur.

Voici un exemple de ce que serait votre gain par rapport au volume d'entrée:

auto-gain

Avec ce type de système, la plupart de votre audio aura une plage dynamique élevée, mais lorsque vous vous rapprochez du volume maximum, vous pouvez réduire lentement votre gain.

Données Analyse

Si vous voulez savoir quel type de valeurs votre système reçoit réellement en temps réel, vous aurez besoin d'un type de sortie de débogage. Cette sortie changera en fonction de la plate-forme sur laquelle vous travaillez, mais voici un aperçu général de ce que vous feriez. Si vous êtes dans un environnement intégré, vous aurez besoin d'une sortie série. Ce que vous ferez, c'est à certaines étapes de la sortie de votre code vers un fichier ou un écran ou quelque chose à partir duquel vous pouvez récupérer les données. Prenez ces données et mettez-les dans Excel de Matlab et représentez-les toutes en fonction du temps. Vous serez probablement très facilement en mesure de dire où les choses vont mal.

Méthode très simple

Saturez-vous votre double? Cela ne sonne pas comme ça, au lieu de cela, on dirait que vous êtes saturé lorsque vous passez à un court métrage. Une manière très simple et "sale" de faire ceci est de convertir le maximum de votre double (cette valeur est différente selon votre plateforme) et de le mettre à l'échelle pour être la valeur maximum de votre short. Cela garantira qu'en supposant que vous ne débordiez pas votre double, vous ne déborderez pas non plus votre short. Cela entraînera très probablement une sortie beaucoup plus douce que votre entrée. Vous aurez juste besoin de jouer et d'utiliser certaines des analyses de données que j'ai décrites ci-dessus pour que le système fonctionne parfaitement pour vous.

Des méthodes plus avancées qui ne s'appliquent probablement pas à vous fort>

Dans le monde numérique, il y a un compromis entre résolution et plage dynamique. Cela signifie que vous avez un nombre fixe de bits donnés à votre audio. Si vous diminuez la plage dans laquelle votre audio peut se trouver, vous augmentez le nombre de bits par plage dont vous disposez. Si vous pensez à cela dans le sens de volts et que vous avez une entrée 0-5v et un adc 10 bits, vous avez 10 bits à donner à une plage 5v, généralement cela se fait de manière linéaire. Donc 0b0000000000 = 0v, 0b1111111111 = 5v et vous attribuez linéairement les tensions aux bits. En réalité, avec l'audio, ce n'est pas toujours une bonne utilisation de vos bits.

Dans le cas de la voix, vos tensions par rapport à la probabilité de ces tensions ressemblent à ceci:

pdf

Cela signifie que vous avez beaucoup plus de voix dans l'amplitude inférieure et juste un peu dans la quantité élevée. Ainsi, au lieu d'affecter vos bits de manière linéaire, vous pouvez remapper vos bits pour avoir plus de pas dans la plage d'amplitude inférieure et donc moins dans la plage d'amplitude supérieure. Cela vous donne le meilleur des deux mondes, une résolution là où se trouve la majeure partie de votre audio, mais limite votre saturation en augmentant votre plage dynamique.

À présent, ce remappage changera la façon dont vos filtres agissent et devra probablement retravaillez vos filtres, mais c'est pourquoi c'est dans la section "avancé". De plus, puisque vous faites votre travail avec un double et que vous le convertissez en court-métrage, votre court devra probablement être linéaire de toute façon. Votre double vous donne déjà beaucoup plus de précision que ce que votre short vous donnera donc il n'est probablement pas nécessaire d'utiliser cette méthode.

il précise qu'il ne connaît pas le signal avant de le recevoir et qu'il se trouve dans un environnement temps réel. il a également précisé qu'il gardait la même limite stricte pour tout le signal, d'où provient la saturation.
Je ferais probablement +1 à gain automatique / division du signal de base par gain maximum. Pas besoin de connaître le signal d'entrée à l'avance pour cela.
@Mark, @kellenjb, maintenant que je vois qu'il n'a absolument aucun contrôle sur votre entrée, et que vous n'obtenez pas d'entrée, je suggère le gain automatique. Je ne suis pas sûr que ce soit une autre méthode. Je rendrais le niveau de gain déterminé lentement sur une longue période.
Martin
2010-11-29 19:05:50 UTC
view on stackexchange narkive permalink

Si cela ressemble du tout à la façon dont les valeurs débordent en C, au moment où vous avez fait l'ajout, vous auriez dépassé. Vous devrez donc diviser par deux l’image actuelle et la valeur de l’image précédente que vous ajoutez avant d’ajouter, puis ajouter, puis éventuellement normaliser.

Mais dans tous les cas, vous ont du mal à garder un niveau constant (compression audio) si vous n'avez qu'une seule image à la fois, car vous avez besoin d'une moyenne à long terme qui ne saute pas.

Oui. c'est mon problème. Je n'ai pas de statistiques à long terme (pas dans un environnement en temps réel de toute façon). Y a-t-il une technique dans la littérature qui permet de faire cela? en ce moment, je choisis juste un nombre au hasard (très élevé) et le multiplication scalaire avec le signal. cela résout le problème, mais s'en sort misérablement lorsqu'un signal avec des statistiques différentes est utilisé. veuillez également lire le commentaire précédent (ci-dessus) pour plus de détails sur le problème.
Kortuk
2010-11-29 20:24:36 UTC
view on stackexchange narkive permalink

Je suppose que vous devez reporter le résultat parce que vous faites du dsp en temps réel avec de l'audio.

J'ai déjà vu ce problème lorsque les élèves font une erreur dans la façon dont ils reportent le résultat de l'idft. Souvent, ils reportent mal les choses et finissent par provoquer une accumulation continue. D'après votre commentaire à Martin, vous semblez avoir évité cela.

Deuxièmement, c'est pourquoi la radio a un bouton de volume que vous devez utiliser. Lorsque vous changez de stations de radio d'un émetteur à proximité à un autre qui est éloigné, vous devez changer le niveau de votre volume pour l'entendre au même volume. Je vous suggère d'ajouter un bouton de gain contrôlable par l'utilisateur, puis s'il sature, c'est à leur contrôle de le changer. Un utilisateur le fera normalement automatiquement car il devient plus fort car il ne l'aime pas. Ils l'augmenteront également en cas de besoin.

Ce bouton modifierait la mise à l'échelle de vos valeurs. J'espère que cela vous aidera, avec plus d'informations sur votre application, je pourrais vous aider. Vous pouvez créer une moyenne de réponse très lente (filtre passe-bas bas) qui prend de nombreuses images pour changer de manière significative et l'utiliser pour donner un contrôle de gain. Cela signifie qu'un pic soudain provoquera une saturation, mais si votre volume audio change lentement, vous le compenserez facilement. Même si votre audio change rapidement, ce type de filtre empêchera l'utilisateur de le baisser et de le monter si chaque niveau de volume relatif est maintenu pendant une période prolongée.

oui, le dsp en temps réel ou au moins simulé en temps réel avec audio est ce que j'essaie de faire. Malheureusement, je ne suis pas sûr de pouvoir fournir plus de détails: (. Je suis intéressé à en savoir un peu plus sur la moyenne de réponse lente que vous mentionnez. Qu'en est-il du contrôle automatique de gain?
Martin Thompson
2010-11-29 21:13:45 UTC
view on stackexchange narkive permalink

La seule façon de procéder est de vous assurer que vous ne pouvez pas saturer. Votre algorithme a vraisemblablement une sorte de "gain maximum", ce qui signifie que vous savez que le signal peut augmenter au maximum par image. Vous devez vous assurer que la première image a suffisamment de marge pour que le signal ne sature pas à la fin.

Votre exemple a un ajout, qui (sauf si vous en savez plus que ce que vous avez dit jusqu'à présent) augmente votre sortie d'au plus un bit par rapport à l'entrée (avec plus de connaissances sur le système, vous pourrez peut-être dire que la moyenne ne dépassera pas par exemple 2,4 bits sur l'ensemble des trames). Mais dans ce cas simple, si vous avez 8 images, vous devrez laisser 8 bits de marge sur les échantillons originaux. Donc, si vous échantillonnez à 8 bits et calculez en 16 bits, vous devriez être OK.

Mais que faire si ma sortie doit à nouveau être en 8 bits? c'est mon problème. ce n'est pas la saturation du type de données utilisé pour l'addition qui pose problème, ce sont les contraintes imposées par la taille de la sortie qui est.
davidcary
2011-02-16 02:25:27 UTC
view on stackexchange narkive permalink

@Kellenjb, merci pour les images - je pense que cela m'a beaucoup aidé à comprendre les choses.

@Sriram, j'aimerais que vous disiez quelques mots de plus sur ce que vous souhaite que se produise.

Je suppose que ce que vous souhaitez se passerait quelque chose comme "Je veux une sortie toujours aussi forte que possible - juste au bord de l'écrêtage. Mais je ne veux pas que le volume change radicalement d'une image à l'autre. Je veux que le volume change plus comme un humain augmentant lentement le bouton de volume pendant les parties silencieuses, et quelque peu baisser le volume plus rapidement au début de l’écrêtage. Mais je ne veux pas qu’un humain réel tourne le bouton de volume - je veux que le logiciel règle automatiquement le volume à ma place. "

Je ' Je suppose également que votre système a besoin de cracher une trame de données dans une trame ou deux après avoir été dans une trame de données, en temps réel - donc je ne suis pas autorisé à analyser la chanson entière, puis à choisir le parfait volume et maintenez-le constant t h tout au long de la chanson.

Donc je suppose que vous voulez mettre en place un pipeline quelque chose comme ceci:

(1) Une routine d'interruption recueille des données dans un tampon. Souvent, les gens en configurent 2 trames de stockage: cette routine remplit lentement une trame pendant que les étapes suivantes travaillent avec les données de l'autre trame.Ensuite, quand une trame est pleine, vous passez un ping-ping à double tampon pour remplir l'autre trame, tandis que la suivante étapes passent à travailler avec une seule image. Certaines personnes faisant des algorithmes tels que les filtres finis (FIR) tamponnent ici de très nombreuses images.

(2) Dans la boucle principale "d'arrière-plan", le logiciel exécute un algorithme DSP sur le dernier tampon d'entrée "complet" et génère des résultats de sortie dans le tampon de sortie. Souvent, les gens configurent 2 images de stockage de tampon de sortie, de sorte que cette routine remplit rapidement une image de sortie, tandis que les étapes suivantes se drainent lentement données de l'autre trame, avec un schéma de double tampon ping-pong. Certaines personnes faisant des algorithmes tels que les filtres infinis (IIR) tamponnent de très nombreuses images de stockage avec ces valeurs de sortie La plupart du temps, l'algorithme DSP prend en entrée les sorties précédentes de cette étape, pas Cette étape est celle où la plupart des gens rencontrent des problèmes d'écrêtage et de saturation, donc la plupart des réponses que je vois ici se concentrent sur cette étape.Mais d'après vos réponses, il semble que vous ayez déjà compris que vous ont besoin d'un type de données large avec de nombreux bits de précision "supplémentaires" pour calculer ces valeurs intermédiaires.

(3) Dans la boucle principale, le logiciel multiplie chaque valeur de la trame intermédiaire par un facteur d'échelle V pour générer une "valeur mise à l'échelle". (Il ne stocke pas cette valeur dans aucun tampon).

(4) Dans la boucle principale, le logiciel réduit chaque "valeur mise à l'échelle" au type de sortie final (8 bits ?) requis par votre périphérique de sortie, et stocker le résultat dans un autre tampon. (La sortie de cette étape devrait presque certainement ne pas être renvoyée dans l'algorithme DSP de l'étape 2. BTC Sound Encoder " de Roman Black est l'un des très rares algorithmes que je connaisse où un tel retour est utile).

(5) Une routine d'interruption prend un échantillon à la fois de la sortie tampon de (4), et le recrache sur le périphérique de sortie. (Cela peut également utiliser un arrangement de ping-pong à double tampon.) Souvent, la fréquence d'échantillonnage d'entrée et la fréquence d'échantillonnage de sortie sont les mêmes (44100 échantillons / s), et la même routine d'interruption fait (5) et (1).

D'après votre réponse à Martin, j'ai l'impression qu'un réglage de volume fixe particulier V1 pour V peut être adéquat pour une chanson, et un autre réglage de volume fixe V2 peut être adéquat pour une autre chanson. pourrait écouter toute la chanson et calculer un volume parfait pour cette chanson - comment feriez-vous cela? Est-ce correct si quelques échantillons de la chanson sont coupés?

Peut-être que quelque chose comme ce contrôle de gain automatique relativement simple (AGC ou VOGAD) résoudrait votre problème:

  • Chaque fois que l'étape 2 finit de produire une image, calculez une nouvelle valeur V qui sera utilisé pour mettre à l'échelle les échantillons de cette image au cours de l'étape 3. Une des méthodes les plus simples: trouver la valeur la plus positive (maximale) et la valeur la plus négative de cette image, et multiplier les deux valeurs par le V actuel utilisé pour la précédente Cadre. Vérifiez si l'un ou l'autre des échantillons sera écrêté (c'est-à-dire que le résultat est supérieur à +127 ou inférieur à -127) ou est proche de l'écrêtage (c'est-à-dire supérieur à +63 ou inférieur à -63), et réglez le multiplicateur de volume VM de manière appropriée:

    • Si le volume est trop faible (aucun des échantillons ne se clipse, aucun des échantillons n'est proche de l'écrêtage), réglez le multiplicateur de volume sur un nombre légèrement supérieur à 1: VM = VM_UP, où VM_UP est quelque chose comme 1.01 ou 1 + 2 ^ (- 12).

    • Si le volume est trop élevé (certains des échantillons sont coupés, ou trop d'échantillons sont trop proches clipping, ou les deux), définissez le multiplicateur de volume VM sur un nombre légèrement inférieur à 1: VM = VM_DOWN, où VM_DOWN est quelque chose comme 0,98 ou 1 - 2 ^ (- 8).

    • Si le volume semble correct (ni trop élevé, ni trop faible), maintenez VM = 1.

  • Périodiquement (idéalement une fois par échantillon , mais si cela mange trop de temps une fois par image ou une fois par milliseconde ou une fois tous les dixièmes de seconde peut être suffisant), réajustez le volume avec un mult saturant iply:

    • V: = (V * VM).
    • Si V est maintenant trop petit (inférieur à V_min), définissez V: = V_min.
    • Si V est maintenant trop grand (plus que V_max), définissez V: = V_max.

Vous voudrez modifier le temps de compilation constantes VM_UP et VM_DOWN jusqu'à ce qu'il «sonne juste» subjectivement. Peut-être régler VM_DOWN de sorte que, avec des entrées très bruyantes, il faut une seconde ou deux pour faire tourner le bouton de volume du volume maximum au volume minimum. Peut-être réglez VM_UP de sorte que, avec un silence absolu, cela prenne une dizaine de secondes pour faire tourner très lentement le bouton de volume du volume minimum au volume maximum.

Vous pouvez garantir que vous ne saturerez jamais instantanément réduire le volume V chaque fois qu'une image semble saturée, de sorte que (avec le volume réduit V) elle atteint à peine les sommets de +127 ou -127, mais je soupçonne qu'il sera préférable de réduire lentement le volume, et permettent à quelques échantillons de saturer pendant quelques images.

Il existe une grande variété de méthodes plus compliquées pour (a) détection d'enveloppe / de crête / de «volume perceptif»: calculez un nombre qui indique si une image les données sont trop fortes ou trop faibles, et de combien Il existe également une grande variété de façons plus compliquées pour un AGC de (b) utiliser ce nombre à partir de l'image actuelle (et peut-être pour les dernières images) et du volume utilisé pendant la dernière image afin de calculer le volume à utiliser pour l'image suivante.

Lectures complémentaires:

Chris H
2010-11-29 23:24:27 UTC
view on stackexchange narkive permalink

Vous pouvez utiliser le codage prédictif linéaire pour compresser le signal en un "résiduel" et un filtre pour recréer cette image audio plus tard. C'est assez compliqué, mais voici un bon article. Si vous conservez exactement le résidu, il s'agit d'un algorithme sans perte. Vous pouvez également utiliser moins de bits pour encoder le résidu et conserver une bonne qualité.

J. Makhoul. Prédiction linéaire: révision du didacticiel. Actes de l'IEEE, 63 (4): 561–580, avril 1975.

Et un chapitre de DAFX contient des algorithmes MATLAB écrits pour vous.

U. Zolzer, éditeur. DAFX - Effets audio numériques. John Wiley & Sons, Ltd, Baffins Lane, Chichester, West Sussex, PO 19 1UD, Angleterre, 2002.

Fondamentalement, étant donné une trame de signal d'entrée, vous pouvez calculer une enveloppe spectrale et un résidu. Voir les images ci-dessous et notez l'amplitude du résidu. alt textalt text

Utilisez le filtre de la deuxième figure et donnez-lui le résidu lorsque vous voulez recréer le son. Remarquez que le résidu a une amplitude assez stable, et notez les unités. Vous devez au moins pouvoir encoder cela. Le filtre est un filtre "LTI" et possède de belles propriétés que vous pourriez probablement utiliser pour combiner des cadres.

Y a-t-il un lien public vers cela?
J'ai lu ceci et je suis désolé de dire que j'en ai compris la majeure partie. Je ne comprends pas comment ça corrige quoi que ce soit. Il semble que vous dites que si vous donnez un délai plus important, vous pouvez mieux compenser le volume.
Pas de lien public, désolé, mais je sais que le livre DAFX est disponible en ligne quelque part. (google pour un ebook) Je n'ajoute pas de retards, à l'exception des retards pour implémenter le filtre dans la deuxième figure, qui est utilisé pour recréer le son ultérieurement. Cela ne concerne que l'encodage. Il transforme un signal d'entrée en un filtre et un résidu. Le résidu a une petite amplitude et peut être codé avec un petit nombre de bits. Les filtres peuvent être ajoutés en les utilisant en série. Les résidus peuvent être ajoutés sans débordement car ils ont de petites valeurs, et stockés comme tels comme une étape intermédiaire avant la sortie finale
Je ne sais pas comment LPC résoudrait le problème. même si l'ajout des résidus ne déborde pas, la convolution avec le filtre pour obtenir l'image d'origine, puis la conversion en un type de données avec une plage plus courte entraînerait une saturation. cet algo doit se produire en temps réel (ou au moins simulé en temps réel), donc ma limite de temps pour le traitement est également très faible.
Évidemment, si vous ajoutez des nombres énormes, vous ne pourrez pas y jouer. Vous devrez normaliser. Ce que je dis, c'est que vous pouvez utiliser ces résidus comme stockage temporaire pour éviter le débordement et maintenir la plage dynamique jusqu'à ce que vous atteigniez enfin votre signal de sortie. Cela fonctionne en temps réel dans les systèmes embarqués. C'est même moins cher qu'une FFT.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 2.0 sous laquelle il est distribué.
Loading...