Comment rééchantillonner l'audio en utilisant FFT ou DFT

12

Je suis en train d'échantillonner l'audio de la voix en effectuant d'abord une FFT, puis en ne prenant que les parties du résultat dont j'ai besoin, puis en effectuant une FFT inverse. Cependant, cela ne fonctionne correctement que lorsque j'utilise des fréquences à la fois deux, disons un sous-échantillonnage de 32768 à 8192. J'effectue une FFT sur les données 32k, jette les 3/4 supérieurs des données, puis FFT inverse sur le 1/4 restant.

Cependant, chaque fois que j'essaie de le faire avec des données qui ne s'alignent pas correctement, deux choses se produisent: la bibliothèque mathématique que j'utilise (Aforge.Math) lance un ajustement, car mes échantillons ne sont pas une puissance de deux. Si j'essaie de mettre à zéro les échantillons pour qu'ils deviennent deux fois plus puissants, cela fait du charabia à l'autre bout. J'ai également essayé d'utiliser un DFT à la place, mais cela finit par être incroyablement lent (cela doit être fait en temps réel).

Comment pourrais-je me mettre à zéro correctement les données FFT, à la fois sur la FFT initiale et la FFT inverse à la fin? En supposant que j'ai un échantillon à 44,1 kHz qui doit atteindre 16 kHz, j'essaie actuellement quelque chose comme ça, l'échantillon étant de 1000.

  1. Remplissez les données d'entrée à 1024 à la fin
  2. Effectuer FFT
  3. Lisez les 512 premiers éléments dans un tableau (j'ai seulement besoin des 362 premiers, mais j'ai besoin de ^ 2)
  4. Effectuer une FFT inverse
  5. Lisez les 362 premiers éléments dans le tampon de lecture audio

De cela, je sors des ordures à la fin. Faire la même chose mais sans avoir à remplir les étapes 1 et 3 car les échantillons sont déjà ^ 2, donne un résultat correct.


la source
9
La FFT n'est vraiment pas la bonne façon de procéder. Vous voulez un banc de filtres polyphasés pour une efficacité maximale, mais si vous voulez juste résoudre le problème, suréchantillonnez d'abord au GCD, puis sur passe-bas, puis sous-échantillonnez.
Bjorn Roche du
Salut Bjorn: qu'est-ce que "GCD"?
SpeedCoder5

Réponses:

16

La première étape consiste à vérifier que votre taux d'échantillonnage de départ et votre taux d'échantillonnage cible sont des nombres rationnels . Comme ce sont des entiers, ce sont automatiquement des nombres rationnels. Si l'un d'eux n'était pas un nombre rationnel, il serait toujours possible de modifier la fréquence d'échantillonnage, mais c'est un processus très différent et plus difficile.

L'étape suivante consiste à factoriser les deux taux d'échantillonnage. Le taux d'échantillonnage de départ, dans ce cas, est de 44100, ce qui donne . Le taux d'échantillonnage cible, 16000, correspond à . Ainsi, pour passer du taux d'échantillonnage de départ au taux cible, nous devons décimer de et interpoler de .223252sept22sept5332sept2255

Les étapes précédentes doivent être effectuées quelle que soit la manière dont vous souhaitez rééchantillonner les données. Voyons maintenant comment le faire avec les FFT. L'astuce pour rééchantillonner avec des FFT est de choisir des longueurs FFT qui font que tout fonctionne bien. Cela signifie choisir une longueur FFT qui est un multiple du taux de décimation (441, dans ce cas). Pour les besoins de l'exemple, prenons une longueur FFT de 441, bien que nous aurions pu choisir 882, ou 1323, ou tout autre multiple positif de 441.

Pour comprendre comment cela fonctionne, il est utile de le visualiser. Vous commencez avec un signal audio qui ressemble, dans le domaine fréquentiel, à quelque chose comme la figure ci-dessous. Fréquence d'échantillonnage de 44,1 kHz

Lorsque vous avez terminé votre traitement, vous voulez réduire la fréquence d'échantillonnage à 16 kHz, mais vous voulez aussi peu de distorsion que possible. En d'autres termes, vous voulez simplement garder tout de l'image ci-dessus de -8 kHz à +8 kHz et supprimer tout le reste. Cela se traduit dans l'image ci-dessous. entrez la description de l'image ici

Veuillez noter que les taux d'échantillonnage ne sont pas à l'échelle, ils sont juste là pour illustrer les concepts.

La beauté de choisir une longueur FFT qui est un multiple du facteur de décimation est que vous pouvez rééchantillonner simplement en supprimant des parties du résultat FFT, puis en inversant FFT ce qui reste. Dans le cas de notre exemple, vous FFT 441 échantillons de données, ce qui vous donne 441 échantillons complexes dans le domaine fréquentiel. Nous voulons décimer de 441 et interpoler de 160 ( ), nous gardons donc les 160 échantillons qui représentent les fréquences de -8 kHz à +8 kHz. Nous inversons ensuite FFT ces échantillons et hop! Vous disposez de 160 échantillons de domaine temporel échantillonnés à 16 kHz.255

Comme vous vous en doutez, il y a quelques problèmes potentiels. Je vais passer en revue chacun d'eux et expliquer comment vous pouvez les surmonter.

  1. Que faites-vous si vos données ne sont pas un joli multiple du facteur de décimation? Vous pouvez facilement surmonter cela en remplissant la fin de vos données avec suffisamment de zéros pour en faire un multiple du facteur de décimation. Les données sont remplies AVANT d'être transférées par FFT.

  2. Même si la méthode que j'ai expliquée est très simple, elle n'est pas non plus idéale car elle peut introduire des sonneries et d'autres artefacts désagréables dans le domaine temporel. Vous pouvez éviter cela en filtrant les données du domaine fréquentiel avant de supprimer les données haute fréquence. Vous faites cela en FFT'ant votre filtre de longueur , en remplissant vos données (avant FFT'ing) avec au moinsll-1zéros (veuillez noter que le nombre d'échantillons de données et le nombre d'échantillons de remplissage doivent DEUX être un multiple positif du facteur de décimation - vous pouvez augmenter la longueur de remplissage pour respecter cette contrainte), FFT'ing les données rembourrées, multipliant le domaine de fréquence données et filtre, puis aliasing les résultats haute fréquence (> 8 kHz) vers le bas dans les résultats basse fréquence (<8 kHz) avant de supprimer les résultats haute fréquence. Malheureusement, comme le filtrage dans le domaine fréquentiel est un grand sujet à part entière, je ne pourrai pas entrer plus en détail dans cette réponse. Je dirai cependant que si vous filtrez et traitez les données en plusieurs morceaux, vous devrez implémenter Overlap-and-Add ou Overlap-and-Save pour rendre le filtrage continu.

J'espère que ça aide.

EDIT: La différence entre le nombre initial d'échantillons de domaine fréquentiel et le nombre cible d'échantillons de domaine fréquentiel doit être égale afin que vous puissiez supprimer le même nombre d'échantillons du côté positif des résultats que du côté négatif des résultats. Dans le cas de notre exemple, le nombre d'échantillons de départ était le taux de décimation, ou 441, et le nombre cible d'échantillons était le taux d'interpolation, ou 160. La différence est de 279, ce qui n'est pas pair. La solution consiste à doubler la longueur de la FFT à 882, ce qui fait que le nombre cible d'échantillons double également à 320. Maintenant, la différence est égale et vous pouvez supprimer sans problème les échantillons de domaine de fréquence appropriés.

Jim Clay
la source
Très agréable. Comment faites-vous de si belles figures à la volée, Jim?
Spacey
@Mohammad J'utilise habituellement Powerpoint. Dans ce cas, j'ai utilisé la version Libre Office de Powerpoint, qui je crois s'appelle "Impress".
Jim Clay
Bonjour, j'ai une question sur votre point (2). Que voulez-vous dire exactement dans cette étape: "... puis aliasing les résultats haute fréquence (> 8 kHz) vers le bas dans les résultats basse fréquence (<8 kHz) avant de supprimer les résultats haute fréquence." Je comprends les étapes avant cela. Après avoir multiplié mes données de domaine f avec le domaine f de mon filtre, alors quoi? De plus, cette méthode fonctionne-t-elle si vous souhaitez également suréchantillonner vos données? Je vous remercie.
TheGrapeBeyond
@TheGrapeBeyond Lorsque vous alias dans le domaine temporel, vous ajoutez toutes les zones de Nyquist ensemble. Les premiers éléments de toutes les zones de Nyquist sont additionnés et deviennent le nouveau premier élément de la première zone de Nyquist. Le deuxième élément de toutes les zones de Nyquist est additionné et devient le nouveau deuxième élément de la première zone de Nyquist, etc.
Jim Clay
Hmm, je ne suis pas sûr de comprendre comment vous faites le rééchantillonnage basé sur la FFT, car quand je l'essaye ici, j'obtiens des résultats très étranges. Je vais poser une question à ce sujet.
TheGrapeBeyond
3

Bien que la réponse ci-dessus soit vraiment complète:

Voici l'essentiel:

  1. pour sous-échantillonner un signal, il doit être un nombre entier. Avant l'échantillonnage vers le bas d'un signal, vous devez FILTRER le signal.
  2. vous pouvez obtenir un sous-échantillonnage rationnel des nombres en suréchantillonnant / interpolant d'abord le signal.
  3. Le suréchantillonnage consiste simplement à insérer des zéros, puis à FILTRER le signal.
  4. afin d'obtenir un taux d'échantillonnage de 3/4. suréchantillonner le signal en insérant 4 zéros entre chaque échantillon de signal. Appliquez un filtre. FILTRER ensuite le signal et supprimer tous les 3 échantillons de signal sur 4.

Détails à ce sujet:

http://www.ws.binghamton.edu/fowler/fowler%20personal%20page/EE523_files/Ch_14_1%20Subband%20Intro%20&%20Multirate%20(PPT).pdf

Aussi: à moins qu'il ne soit absolument nécessaire de NE PAS calculer la FFT pour calculer ensuite l'IFFT. C'est un processus incroyablement lent et considéré comme inapproprié pour la plupart des tâches de traitement du signal. la FFT est généralement utilisée pour analyser un problème ou appliquer un traitement du signal uniquement dans le domaine fréquentiel.

CyberMen
la source
1

Comme le disait Bjorn Roche, utiliser la FFT pour cela serait terriblement inefficace. Mais ici, cela se fait de manière très très simple en utilisant la méthode du filtre de suréchantillonnage et du sous-échantillonnage dans le domaine fréquentiel.

1 - Prendre le signal vectoriel souhaité de longueur N.

2 - Effectuer une FFT à point N

3 - Remplissez zéro la FFT avec 160 * N zéros au milieu du vecteur FFT.

4 - Effectuer IFFT

5 - Sélectionnez l'un des 441 échantillons en éliminant les 440 autres.

Vous vous retrouverez avec un vecteur de longueur N * 160/441, qui sera votre signal rééchantillonné.

Comme vous pouvez le voir, vous faites beaucoup de calculs inutiles, car la plupart des résultats seront ensuite jetés. Mais si vous avez accès au code exécutant la FFT, vous pouvez le modifier un peu pour qu'il calcule uniquement les résultats IFFT avec lesquels vous vous retrouverez et non ceux que vous jeterez.

J'espère que cela aide.

OS
la source