Je recherche un algorithme de réverbération simple ou commenté, même en pseudocode aiderait beaucoup.
J'en ai trouvé quelques-uns, mais le code a tendance à être plutôt ésotérique et difficile à suivre.
Voici une implémentation très simple d'une "ligne à retard" qui produira un effet de réverbération dans un tableau existant (C #, buffer
is short[]
):
int delayMilliseconds = 500; // half a second
int delaySamples =
(int)((float)delayMilliseconds * 44.1f); // assumes 44100 Hz sample rate
float decay = 0.5f;
for (int i = 0; i < buffer.length - delaySamples; i++)
{
// WARNING: overflow potential
buffer[i + delaySamples] += (short)((float)buffer[i] * decay);
}
Fondamentalement, vous prenez la valeur de chaque échantillon, la multipliez par le paramètre decay et ajoutez le résultat à la valeur du tampon delaySamples
.
Cela produira un véritable effet de "réverbération", car chaque son sera entendu plusieurs fois avec une amplitude décroissante. Pour obtenir un effet d'écho plus simple (où chaque son n'est répété qu'une seule fois), vous utilisez essentiellement le même code, exécutez uniquement la boucle for
en sens inverse.
pdate: le mot "reverb" dans ce contexte a deux usages communs. Mon exemple de code ci-dessus produit un effet de réverbération classique courant dans les dessins animés, alors que dans une application musicale, le terme est utilisé pour signifier la réverbération, ou plus généralement la création d'effets spatiaux artificiels.
Une grande raison pour laquelle la littérature sur la réverbération est si difficile à comprendre est que la création d'un bon effet spatial nécessite des algorithmes beaucoup plus compliqués que ma méthode d'échantillonnage ici. Cependant, la plupart des effets spatiaux électroniques sont construits à l'aide de plusieurs lignes à retard, donc cet échantillon illustre, espérons-le, les bases de ce qui se passe. Pour produire un très bon effet, vous pouvez (ou devriez) également brouiller la sortie de la réverbération en utilisant FFT ou même un simple flou.
pdate 2: Voici quelques conseils pour la conception d'une réverbération à plusieurs lignes de retard:
Choisissez des valeurs de retard qui n'interfèrent pas positivement les unes avec les autres (au sens des vagues). Par exemple, si vous avez un retard à 500 ms et un second à 250 ms, il y aura de nombreux spots qui auront des échos des deux lignes, produisant un effet irréaliste. Il est courant de multiplier un retard de base par différents nombres premiers afin d'éviter que ce chevauchement ne se produise.
Dans une grande pièce (dans le monde réel), lorsque vous faites du bruit, vous aurez tendance à entendre quelques échos aigus immédiats (quelques millisecondes) qui sont relativement sans distorsion, suivis d'un "nuage" d'échos plus grand et plus faible. Vous pouvez obtenir cet effet à moindre coût en utilisant quelques lignes de retard à rebours pour créer les échos initiaux et quelques lignes de réverbération complètes, plus un peu de flou pour créer le "nuage".
L'astuce absolue la meilleure (et j'ai presque l'impression que je ne veux pas abandonner celle-ci, mais que diable) ne fonctionne que si votre audio est stéréo. Si vous modifiez légèrement les paramètres de vos lignes à retard entre les canaux gauche et droit (par exemple, 490 ms pour le canal gauche et 513 ms pour la droite, ou .273 decay pour la gauche et .2631 pour la droite), vous produirez beaucoup réverbération plus réaliste.
Les réverbérations numériques se présentent généralement sous deux formes.
Réverbes à convolution convolve an réponse impulsionnelle et un signal d'entrée. La réponse impulsionnelle est souvent un enregistrement d'une pièce réelle ou d'une autre source de réverbération. Le caractère de la réverbération est défini par la réponse impulsionnelle. En tant que telles, les réverbérations à convolution fournissent généralement des moyens limités d'ajuster le caractère de réverbération.
Réverbérations algorithmiques imitent la réverbération avec un réseau de retards, de filtres et de feedback. Différents schémas combineront ces éléments de base de différentes manières. Une grande partie de l'art consiste à savoir comment régler le réseau. Les réverbérations algorithmiques exposent généralement plusieurs paramètres à l'utilisateur final afin que le caractère de réverbération puisse être ajusté en fonction.
Le A Bit About Reverb post sur EarLevel est une excellente introduction au sujet. Il explique les différences entre la convolution et les réverbérations algorithmiques et montre quelques détails sur la façon dont chacun pourrait être implémenté.
Physical Audio Signal Processing par Julius O. Smith a un chapitre sur les algorithmes de réverbération, y compris une section dédiée à l'algorithme Freeverb. Le survol de ce qui pourrait aider lors de la recherche d'exemples de code source.
Le blog de Sean Costello Valhalla regorge d'intéressants réverbérations.
Ce dont vous avez besoin, c'est de la réponse impulsionnelle de la pièce ou de la chambre de réverbération que vous souhaitez modéliser ou simuler. La réponse impulsionnelle complète comprendra tous les échos à voies multiples et multiples. La longueur de la réponse impulsionnelle sera à peu près égale à la durée (en échantillons) nécessaire à un son impulsionnel pour se désintégrer complètement en dessous du seuil audible ou du bruit de fond donné.
Étant donné un vecteur d'impulsion de longueur N, vous pouvez produire un échantillon de sortie audio par multiplication vectorielle du vecteur d'entrée (constitué de l'échantillon d'entrée audio actuel concaténé avec les échantillons d'entrée N-1 précédents) par le vecteur d'impulsion, avec une mise à l'échelle appropriée.
Certaines personnes simplifient cela en supposant que la plupart des taps (jusqu'à tous sauf 1) dans la réponse impulsionnelle sont nuls, et en utilisant simplement quelques lignes de retard mises à l'échelle pour les échos restants qui sont ensuite ajoutés à la sortie.
Pour une réverbération encore plus réaliste, vous souhaiterez peut-être utiliser des réponses d'impulsion différentes pour chaque oreille, et faire en sorte que la réponse varie un peu selon la position de la tête. Un mouvement de la tête d'aussi peu qu'un quart de pouce pourrait faire varier la position des pics de la réponse impulsionnelle d'un échantillon (à des taux de 44,1 k).
Vous pouvez utiliser GVerb. Obtenez le code de ici . GVerb est un plug-in LADSPA, vous pouvez aller ici si vous voulez en savoir plus sur LADSPA.
Ici est le wiki de GVerb, y compris l'explication des paramètres et de certains réglages de réverbération instantanée.
Nous pouvons également l'utiliser directement dans Objc:
ty_gverb *_verb;
_verb = gverb_new(16000.f, 41.f, 40.0f, 7.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f);
AudioSampleType *samples = (AudioSampleType*)dataBuffer.mBuffers[0].mData;//Audio Data from AudioUnit Render or ExtAuidoFileReader
float lval,rval;
for (int i = 0; i< fileLengthFrames; i++) {
float value = (float)samples[i] / 32768.f;//from SInt16 to float
gverb_do(_verb, value, &lval, &rval);
samples[i] = (SInt16)(lval * 32767.f);//float to SInt16
}
GVerb est un effet mono mais si vous voulez un effet stéréo, vous pouvez faire passer chaque canal à travers l'effet séparément, puis effectuer un panoramique et mélanger les signaux traités avec les signaux secs comme requis