67 votes

Algorithme de mixage du son

J'ai deux flux sonores bruts que j'ai besoin d'ajouter ensemble. Pour les besoins de cette question, nous pouvons supposer qu'ils ont le même débit binaire et la même profondeur de bit (disons un échantillon de 16 bits et un taux d'échantillonnage de 44,1 kHz).

Il est évident que si je les additionne, mon espace de 16 bits sera débordé ou non. Si je les additionne et que je les divise par deux, le volume de chacun est divisé par deux, ce qui n'est pas correct d'un point de vue sonore. Si deux personnes parlent dans une pièce, leurs voix ne deviennent pas plus faibles de moitié et un microphone peut les capter toutes les deux sans toucher le limiteur.

  • Quelle est donc la méthode correcte pour ajouter ces sons ensemble dans mon mixeur logiciel ?
  • Ai-je tort et la bonne méthode consiste-t-elle à réduire de moitié le volume de chacun d'eux ?
  • Dois-je ajouter un compresseur/limiteur ou un autre étage de traitement pour obtenir le volume et l'effet de mixage que je recherche ?

-Adam

7 votes

Même question, mais meilleures réponses : dsp.stackexchange.com/questions/3581/

0 votes

J'ai été vraiment déçue. Dans la vie réelle, j'entends toujours les deux signaux quelle que soit la phase dans laquelle ils se trouvent . Mais en additionnant simplement les échantillons de deux ondes inversées en phase, on obtient le silence total . Pas une seule mention de cela...

4 votes

@jmendeth L'annulation de phase est réelle. Mettez deux haut-parleurs juste à côté l'un de l'autre, et inversez la phase de l'un d'eux (échangez les fils). Vos basses seront détruites. La raison pour laquelle vous n'obtenez pas une annulation complète est que vos enceintes ne sont pas des sources ponctuelles et que vous avez deux oreilles.

32voto

Roddy Points 32503

Vous devez les additionner, mais écrêter le résultat dans la fourchette autorisée pour éviter tout débordement.

En cas d'écrêtage, il faut sera introduire de la distorsion dans l'audio, mais c'est inévitable. Vous pouvez utiliser votre code d'écrêtage pour "détecter" cette condition et la signaler à l'utilisateur/opérateur (équivalent du voyant rouge "clip" sur une table de mixage...).

Vous pourriez mettre en place un compresseur/limiteur plus "correct", mais sans connaître votre application exacte, il est difficile de dire si cela en vaut la peine.

Si vous effectuez de nombreux traitements audio, il est préférable de représenter vos niveaux audio sous forme de valeurs à virgule flottante et de ne revenir à l'espace 16 bits qu'à la fin du processus. Les systèmes audio numériques haut de gamme fonctionnent souvent de cette manière.

1 votes

Cette réponse est correcte, mais je l'agrémente de quelques notes sur la façon d'implémenter des contrôles de niveau automatiques ci-dessous (écrites avant que j'aie des privilèges de commentaires).

8 votes

@Kyberias Cela n'a pas de sens ; la première phrase explique littéralement exactement ce qu'il faut faire.

0 votes

OP déjà ce que cette réponse suggère et quel est le défaut pour le faire, de la question "Évidemment si je les additionne juste ensemble je vais déborder et sous-déborder mon espace de 16 bits." @user1881400

30voto

podperson Points 768

Je préférerais commenter l'une des deux réponses les mieux classées mais, en raison de ma maigre réputation (je suppose), je ne peux pas le faire.

La réponse "cochée" : additionner et découper est correcte, mais pas si vous voulez éviter le découpage.

La réponse avec le lien commence par un algorithme vaudou utilisable pour deux signaux positifs dans [0,1] mais applique ensuite une algèbre très défectueuse pour dériver un algorithme complètement incorrect pour les valeurs signées et les valeurs 8 bits. L'algorithme n'est pas non plus adapté à trois entrées ou plus (le produit des signaux diminue alors que la somme augmente).

Donc - convertir les signaux d'entrée en flottants, les mettre à l'échelle de [0,1] (par exemple, une valeur signée de 16 bits deviendrait
float v = ( s + 32767.0 ) / 65536.0 (close enough...))
et les additionner.

Pour mettre à l'échelle les signaux d'entrée, vous devriez probablement faire un travail réel plutôt que de multiplier par ou soustraire une valeur vaudou. Je suggérerais de conserver un volume moyen courant et ensuite, s'il commence à dériver vers le haut (au-dessus de 0,25 par exemple) ou vers le bas (en dessous de 0,01 par exemple), de commencer à appliquer une valeur d'échelle basée sur le volume. Cela devient essentiellement une implémentation de niveau automatique, et cela s'adapte à n'importe quel nombre d'entrées. Mieux encore, dans la plupart des cas, cela ne perturbera pas du tout votre signal.

0 votes

Merci pour les notes ! Je pense que cela mérite une réponse, mais vous avez maintenant 50 représentants, donc vous devriez pouvoir commenter sur le site maintenant.

26voto

Ben Dyer Points 544

Il existe un article sur le mélange ici . J'aimerais savoir ce que d'autres pensent de tout cela.

1 votes

C'est intéressant. En gros, il fait l'addition, puis applique une "compression" très simple du signal pour éviter l'écrêtage. Le problème est que cela modifie considérablement les valeurs d'échantillonnage même s'il n'y a pas besoin d'écrêter. Pour certaines applications (téléphonie, jeux), ce type d'approche fonctionnerait probablement très bien. Mais pour le traitement audio haut de gamme, on pourrait considérer qu'elle dégrade le signal...

9 votes

Cet article est trompeur (voir ma réponse ci-dessous). Si vous introduisez des valeurs d'exemple dans ses formules finales, vous obtenez de mauvais résultats (son algèbre est mauvaise). Par exemple, une entrée de silence vous donne une sortie de -1. Quoi qu'il en soit, il ne s'adapte pas à plus de deux entrées et c'est un algorithme vaudou qui n'a aucun fondement dans la réalité.

0 votes

Il n'est pas judicieux de changer la colonne pour chaque échantillon. Et l'algorithme n'est pas correct car si vous avez deux canaux avec le même signal, le mixage de ces deux canaux devrait être le même que celui de chaque canal. Mais cet algorithme donne une perte de signal.

19voto

Mark Heath Points 22240

La plupart des applications de mixage audio effectuent leur mixage avec des nombres à virgule flottante (32 bits est largement suffisant pour mixer un petit nombre de flux). Traduisez les échantillons 16 bits en nombres à virgule flottante, la plage -1,0 à 1,0 représentant la pleine échelle dans le monde 16 bits. Puis additionnez les échantillons - vous avez maintenant beaucoup de marge de manœuvre. Enfin, si vous vous retrouvez avec des échantillons dont la valeur dépasse la pleine échelle, vous pouvez soit atténuer l'ensemble du signal, soit utiliser la limitation dure (écrêtage des valeurs à 1,0).

Vous obtiendrez ainsi des résultats bien meilleurs qu'en additionnant des échantillons 16 bits et en les laissant déborder. Voici un exemple de code très simple montrant comment vous pouvez additionner deux échantillons de 16 bits :

short sample1 = ...;
short sample2 = ...;
float samplef1 = sample1 / 32768.0f;
float samplef2 = sample2 / 32768.0f;
float mixed = samplef1 + sample2f;
// reduce the volume a bit:
mixed *= 0.8;
// hard clipping
if (mixed > 1.0f) mixed = 1.0f;
if (mixed < -1.0f) mixed = -1.0f;
short outputSample = (short)(mixed * 32768.0f)

1 votes

Bien sûr, mais cela augmentera les risques d'écrêtage, donc ajustez votre volume en conséquence.

0 votes

Cela a-t-il introduit un bruit blanc pour vous @MarkHeath ?

0 votes

En multipliant le mixte par 0,8... ne faites-vous pas que rapprocher votre niveau de bruit de la "moyenne" ? Si vous multipliez une valeur négative pour le mixage (disons -0.5) par 0.8, il se rapprochera de 0, en d'autres termes, il deviendra PLUS ÉLEVÉ... donc soit vous devez convertir en une gamme 0+ avant de multiplier, soit les commentaires de "réduire un peu le volume" ne sont tout simplement pas exacts.

10voto

Mark Ransom Points 132545

"Plus silencieux de moitié" n'est pas tout à fait correct. En raison de la réponse logarithmique de l'oreille, diviser les échantillons par deux les rendra plus silencieux de 6 dB, ce qui est certes perceptible, mais pas désastreux.

Vous pouvez faire un compromis en multipliant par 0,75. Cela rendra le système plus silencieux de 3 dB, mais réduira le risque de débordement et la distorsion lorsqu'il se produit.

0 votes

3 dB plus silencieux, c'est la moitié de la puissance, donc diviser les valeurs de l'échantillon par sqrt(2). Cela revient à multiplier par 0,707 (1/sqrt(2)) plutôt que par 0,75. Je suis d'accord qu'une multiplication par 0,75 est plus facile à réaliser avec des décalages de bits, cependant.

0 votes

@Gauthier, j'étais approximatif.

0 votes

Le 0,707 provient de 10^(-3/20) et n'a rien à voir avec 1/sqrt(2), si ce n'est que l'expansion décimale partage certains chiffres de tête (si vous voulez être précis :).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X