web-dev-qa-db-fra.com

Battements par minute de l'entrée audio en temps réel

J'aimerais écrire une simple application en C # pour surveiller l'audio d'entrée de ligne et me donner les battements actuels (ainsi que la moyenne mobile) par minute.

J'ai vu cet article de gamedev , et ce n'était absolument aucune aide. J'ai traversé et essayé de mettre en œuvre ce qu'il faisait mais cela ne fonctionnait tout simplement pas.

Je sais qu'il doit y avoir une multitude de solutions pour cela, car de nombreux logiciels de DJ le font, mais je n'ai aucune chance de trouver une bibliothèque open-source ou des instructions pour le faire moi-même.

42
Karl

Calculer un PowerSpectrum avec une fenêtre coulissante FFT: Prendre 1024 échantillons: 

double[] signal = stream.Take(1024);

Chargez-le dans un algorithme FFT: 

double[] real = new double[signal.Length];
double[] imag = new double[signal.Length);
FFT(signal, out real, out imag);

Vous obtiendrez une partie réelle et une partie imaginaire. Ne jetez pas la partie imaginaire. Faites la même chose pour la partie réelle que l'imaginaire. S'il est vrai que la partie imaginaire est déphasée de pi/2 par rapport au réel, elle contient quand même 50% des informations du spectre.

MODIFIER:

Calculez la puissance, par opposition à l’amplitude, de manière à avoir un nombre élevé quand il est fort et proche de zéro quand il est calme:

for (i=0; i < real.Length; i++) real[i] = real[i] * real[i];

De même pour la partie imaginaire.

for (i=0; i < imag.Length; i++) imag[i] = imag[i] * imag[i];

Vous avez maintenant un spectre de puissance pour les 1024 derniers échantillons. Où la première partie du spectre se compose des basses fréquences et la dernière partie du spectre se compose des hautes fréquences.

Si vous voulez trouver du BPM dans la musique populaire, vous devriez probablement vous concentrer sur la basse. Vous pouvez mesurer l’intensité des graves en faisant la somme de la partie inférieure du spectre de puissance. Les nombres à utiliser dépendent de la fréquence d'échantillonnage:

double bassIntensity = 0;
for (i=8; i < 96; i++) bassIntensity += real[i];

Répétez l'opération maintenant, mais déplacez la fenêtre de 256 échantillons avant de calculer un nouveau spectre. Maintenant, vous vous retrouvez avec le calcul de la bassIntensity pour 256 échantillons. 

C'est une bonne entrée pour votre analyse BPM. Lorsque les basses sont faibles, vous n’avez pas de battement et quand elles sont fortes, vous l’avez. 

Bonne chance!

26
Hallgrim

Il existe un excellent projet appelé Dancing Monkeys, qui génère de la musique des pas de danse DDR de manière procédurale. Une grande partie de son travail repose sur une analyse de battements (nécessairement très précise), et le document de leur projet décrit de manière très détaillée les divers algorithmes de détection de battements et leur adéquation à la tâche. Ils incluent des références aux articles originaux pour chacun des algorithmes. Ils ont également publié le code matlab de leur solution. Je suis sûr qu'entre ceux-là, vous pouvez trouver ce dont vous avez besoin.

Tout est disponible ici: http://monket.net/dancing-monkeys-v2/Main_Page

15
Nick Johnson

Ce n’est pas que j’ai la moindre idée de la façon de mettre en œuvre cela, mais d’un point de vue technique, il faudrait d’abord filtrer. Les coups de grosse caisse seraient les premiers à vérifier. Un filtre passe-bas qui vous donne quelque chose en dessous de 200Hz devrait vous donner une image assez claire de la grosse caisse. Une porte peut également être nécessaire pour nettoyer tout encombrement d’autres instruments avec des harmoniques aussi faibles.

Le prochain à vérifier serait des coups de caisse claire. Vous auriez à EQ celui-ci. La "fissure" d'un caisse claire se situe à environ 1,5 kHz de la mémoire, mais vous devez absolument le verrouiller.

Le prochain défi serait de mettre au point un algorithme pour les rythmes funky. Comment trouveriez-vous le battement 1 par programmation? Je suppose que vous garderiez une trace des temps précédents et utiliseriez un motif correspondant à quelque chose. Donc, vous aurez probablement besoin de quelques mesures pour trouver le battement avec précision. Ensuite, il y a des problèmes de synchronisation comme 4/4, 3/4, 6/8, wow, je ne peux pas imaginer ce qui serait nécessaire pour faire cela avec précision! Je suis sûr que cela vaudrait de l'argent aux entreprises de matériel audio/logiciel.

8
Dan Harper

Ce n'est pas un problème facile. Je vais essayer de vous donner un aperçu seulement.

Ce que vous pouvez faire est quelque chose comme ceci:

  1. Calcule le volume moyen du signal sur des blocs de 5 millisecondes, par exemple. (N'ayant jamais fait cela auparavant, je ne sais pas ce que serait une bonne taille de bloc.)
  2. Prenez la transformée de Fourier du signal "bloqué", en utilisant l'algorithme FFT.
  3. Recherchez le composant du signal transformé ayant la plus grande magnitude.

Une transformée de Fourier est fondamentalement une manière de calculer la force de toutes les fréquences présentes dans le signal. Si vous faites cela sur le signal "bloqué", la fréquence du battement sera, espérons-le, la plus forte.

Peut-être devriez-vous d'abord appliquer un filtre afin de vous concentrer sur des fréquences spécifiques (comme les basses) qui contiennent généralement le plus d'informations sur le BPM.

6
Thomas

J'ai trouvé cette bibliothèque qui semble avoir une implémentation assez solide pour détecter Beats per Minute . http://soundtouchdotnet.codeplex.com/

Il est basé sur http://www.surina.net/soundtouch/index.html qui est utilisé dans de nombreux projets DJ http://www.surina.net/soundtouch/applications.html

5
eandersson

Tout d'abord, Hallgrim ne produit pas la fonction de densité spectrale de puissance. Les périodicités statistiques dans n'importe quel signal peuvent être mises en évidence via une fonction d'autocorrélation. La transformée de Fourier du signal d'autocorrélation est la densité spectrale de puissance. Les pics dominants dans la PSD autres qu'à 0 Hz correspondront à la périodicité effective du signal (en Hz) ... 

1
pete

Je vous recommande de consulter la bibliothèque audio BASS et le wrapper BASS.NET. Il a une classe BPMCounter intégrée. 

Les détails de cette fonction spécifique sont disponibles à l’adresse http://bass.radio42.com/help/html/0833aa5a-3be9-037c-66f2-9adfd42a8512.htm .

0
Matt Williams

Le moyen le plus simple consiste à demander à l'utilisateur d'appuyer sur un bouton en rythme avec le temps et de compter le nombre d'appuis divisé par le temps.

0
Lucius Kwok