3
votes

Comment puis-je effectuer une analyse FFT d'un fichier audio dans Chrome sans avoir besoin de lecture?

Il n'y a pas un seul exemple fonctionnel sur tout Internet de la façon d'effectuer une analyse FFT d'un fichier audio / tampon / tampon audio dans un navigateur sans avoir besoin de lecture. L'API Web audio a été trop modifiée pour pouvoir utiliser cette bibliothèque https://github.com/corbanbrook /dsp.js par exemple. Tous les autres indices ne mènent actuellement pas à une solution.

MODIFIER: Je n'ai pas besoin de manipuler les données, juste pour lire le spectre de fréquences à différents moments dans le temps de l'audio. L'entrée de la solution peut être n'importe quelle forme de données (fichier wav, arraybuffer, audiobuffer, n'importe quoi) mais pas de flux. La sortie attendue serait idéalement un tableau (moments dans le temps) de tableaux (amplitudes bin de fréquence).


13 commentaires

Essayez-vous de mesurer (échantillonner) la sortie audio réelle ou les données brutes? La question demande une analyse. Le fichier est statique; ne modifie pas les données sans action de l'utilisateur. Le but de l'analyse serait d'échantillonner la sortie audio réelle, c'est-à-dire que la sortie audio devrait être différente, ou du moins, l'enregistrement d'échantillonnage devrait être unique ou arbitraire pour chaque lecture multimédia, n'est-ce pas?


données brutes. Je dois éviter la sortie en raison d'une expérience utilisateur plus rapide.


À quoi servent les données brutes, un fichier statique non lu, analysé? Qu'entendez-vous par «sans besoin de lecture»? Quelle est l'exigence et les entrées et sorties attendues? Essayez-vous de manipuler un fichier pour filtrer certaines sorties audio avant de lire le fichier ou de devoir lire le contenu multimédia pour effectuer le filtrage?


afaik, vous avez raison. il serait en fait plus lent de ne pas utiliser les outils de l'API webaudiio accélérée en C, en essayant de monter et d'analyser les formes d'onde dans de purs userland js. Je ne sais même pas comment vous transformeriez le mp3 en une vague. Si vous avez utilisé tous les js, utilisez des webworkers pour éviter le ralentissement de l'interface utilisateur.


@okram Voir TensorFlow ; TensorFlow.js


Je n'ai pas besoin de manipuler quoi que ce soit, juste pour lire le spectre de fréquences à différents moments de l'audio. L'entrée peut être n'importe quelle forme de données (fichier wav, arraybuffer, audiobuffer, n'importe quoi) mais pas de flux. La sortie attendue serait idéalement un tableau (moments dans le temps) de tableaux (amplitudes de bin de fréquence).


@okram Avec l'exigence d'être sans lecture? Si vous créez un OfflineAudioContext , un ou plusieurs SourceBuffer peuvent être créés, fusionnés, analysés. Si vous disposez des modèles, vous pouvez comparer les données AudioBuffer ou TypedArray résultantes aux données du modèle. À moins de ne pas rassembler ce qu'est l'exigence?


Je ne comprends pas pourquoi j'aurais besoin de modèles ou d'apprentissage automatique pour cette tâche. Si vous pouvez fournir un exemple fonctionnel de ces outils (contexte hors ligne, analyse du tampon src) que vous proposez, ce serait génial. J'ai déjà essayé tout ce que je pouvais lire sur le site Web de Mozilla sur l'API audio.


@okram Vous ne savez toujours pas quel est le résultat attendu? Est-il possible de mélanger plusieurs fichiers audio les uns sur les autres de préférence avec javascript ; Comment utiliser l'URL Blob, MediaSource ou d'autres méthodes pour lire des Blobs concaténés de fragments multimédias? . Vous pouvez implémenter votre propre analyse dans le code. Vous ne savez toujours pas ce que vous entendez par analyse (échantillonnage) sans lecture.


@okram Nœud analyseur audio Web - exécuté à intervalle régulier "Oui, vous ne pouvez pas vraiment utiliser un analyseur. Il y a trop d'incertitude quant au moment où il sera exécuté, et vous ne pouvez pas garantir précisément quand il fonctionnera. Il vaut mieux utiliser un ScriptProcessor pour le moment (AudioWorklet éventuellement), et faire la FFT (ou un autre code de reconnaissance) vous-même. "


@okram Chez Chromium / Chrome, il est possible d'utiliser la messagerie native pour transférer les données vers un script shell pour les traiter, puis transférer la sortie vers la fenêtre Comment envoyer par programme une commande de socket unix à un serveur système généré automatiquement par le navigateur ou convertir JavaScript en code source C ++ pour Chromium? ; Messagerie Chrome native avec PHP . Vous pouvez implémenter le script shell dans n'importe quel langage répondant à l'exigence.


@okram "pourquoi j'aurais besoin de modèles ou d'apprentissage automatique pour cette tâche." Vous pouvez entraîner des modèles à faire correspondre avec des données brutes "En avril 2017, * oogle a publié un article, Tacotron: Towards Synthèse vocale de bout en bout, où ils présentent un modèle neuronal de synthèse vocale qui apprend à synthétiser la parole directement à partir de paires (texte, audio). " tacotron . Par exemple, l'implémentation de webkitSpeechRecognition chez Chromium enregistre l'audio de l'utilisateur, l'envoie au service distant, renvoie la transcription. Voir également ts-ebml ebml .


Vous pourriez également être intéressé par le code source de espeak-ng .


3 Réponses :


2
votes

Vous pouvez faire beaucoup avec un audiocontexte hors ligne, mais cela ne fera qu'exécuter tout le graphe de nœuds aussi vite que possible pour rendre un morceau audio résultant. Je ne vois pas comment un analysernode fonctionnerait même dans une telle situation (puisque sa sortie audio est inutile).

Il me semble que vous avez raison en ce sens que vous ne pouvez pas utiliser l'API Web Audio sans lire le fichier en temps réel. Vous devrez faire l'analyse vous-même, il devrait y avoir beaucoup de bibliothèques disponibles pour cela (car ce n'est que du nombre). Webworkers ou wasm est probablement la voie à suivre.


2 commentaires

Je ne peux trouver que des bibliothèques «Thin wrapper for web audio API». Avez-vous une recommandation personnelle pour la bibliothèque qui a une solution documentée à mon problème?


Je n'ai pas d'expérience avec ce que vous voulez faire, mais faire une analyse de fréquence consiste simplement à parcourir des nombres et n'est pas très obscur, il devrait donc y avoir des tonnes de code existant dans js. vous ne devriez pas chercher quoi que ce soit lié à l'API audio Web - nous avons tous les deux convenu que cela n'allait probablement pas fonctionner avec ça :)



1
votes

Vous avez besoin de 4 choses:

  • Code Javascript à lire dans un fichier WAV sous forme de blob binaire

  • Une implémentation Javascript d'une DFT ou FFT de tableaux de taille appropriée pour la résolution de temps et de fréquence que vous désirez

  • Code pour estimer vos paramètres de fréquence et d'amplitude souhaités lorsque vous répétez la FFT sur vos tranches de données

Les 3 premiers peuvent être trouvés à partir de recherches sur le Web (Github, ici, et.al.)


1 commentaires

C'est le point 3 qui est le problème. Connaissez-vous réellement une implémentation JS de la FFT qui fonctionne réellement dans le navigateur? Parce que bien sûr, alors cela devient presque trivialement facile (diable, utilisez un fichier mp3 avec AudioContext.decodeAudioData () même, car il n'y a pas besoin de fichiers wave PCM géants si nous allons utiliser de toute façon du JS pur au lieu de l'API audio)



1
votes

Si vous devez utiliser WebAudio, la façon de le faire est d'utiliser un OfflineAudioContext . Ensuite, lorsque vous avez besoin d'obtenir les données de fréquence, appelez suspend (time) . Quelque chose comme ce qui suit:

c = new OfflineAudioContext(....);
a = new AnalyserNode(c);
src.connect(a);  // src is the signal you want to analyze.

c.suspend(t1)
  .then(() => {
    a.getFloatFrequencyData(array1);
  })
  .then(() => c.resume());

c.suspend(t2)
  .then(() => {
    a.getFloatFrequencyData(array2);
  })
  .then(() => c.resume());

// More suspends if needed

// Render everything now
c.startRendering()
  .then((buffer => {
    // Maybe do something now that all the frequency data is available.
  })

Cependant, je pense que seul Chrome prend en charge la suspension avec un contexte hors ligne.


2 commentaires

Merci, intéressant d'en savoir plus sur cette option. Malheureusement, je dois opter pour la fonctionnalité multi-navigateurs et Firefox et Safari ne prennent actuellement pas en charge la méthode de suspension sur le contexte hors ligne selon developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext‌ /…


Ouais, c'est dommage. J'ai déposé un bug contre Firefox à propos de l'ajout de cela. Vous pouvez signaler un bogue pour Safari. Il sera peut-être mis en œuvre un jour.