L'application de Baiser FFT sur des échantillons audio et prise NaN sortie?
Le titre explique mon problème.
Ce que je suis en train de faire est assez simple:
- Charge MP3 (via libmpg123)
- Des échantillons de lecture
- Appliquer Baiser FFT sur les échantillons
Ce que j'ai essayé jusqu'à présent
inline float scale(kiss_fft_scalar val)
{
int g = 0;
return val < 0 ? val*(1/32768.0f ) : val*(1/32767.0f);
}
void main()
{
mpg123_handle *m = NULL;
int channels = 0, encoding = 0;
long rate = 0;
int err = MPG123_OK;
err = mpg123_init();
m = mpg123_new(NULL, &err);
mpg123_open(m, "L:\\audio-io\\audio-analysis\\samples\\zero.mp3");
mpg123_getformat(m, &rate, &channels, &encoding);
err = mpg123_format_none(m);
err = mpg123_format(m, rate, channels, encoding);
//Get 2048 samples
const int TIME = 2048;
//16-bit integer encoded in bytes, hence x2 size
unsigned char* buffer = new unsigned char[TIME*2];
size_t done = 0;
err = mpg123_read(m, buffer, TIME*2, &done);
short* samples = new short[done/2];
int index = 0;
//Iterate 2 bytes at a time
for (int i = 0; i < done; i += 2)
{
unsigned char first = buffer[i];
unsigned char second = buffer[i + 1];
samples[index++] = (first | (second << 8));
}
//Array to store the calculated data
int speclen = TIME / 2 + 1;
float* output = new float[speclen];
kiss_fftr_cfg config;
kiss_fft_cpx* spectrum;
config = kiss_fftr_alloc(TIME, 0, NULL, NULL);
spectrum = (kiss_fft_cpx*) malloc(sizeof(kiss_fft_cpx) * TIME);
//Right here...
kiss_fftr(config, (kiss_fft_scalar*) samples, spectrum);
for (int i = 0; i < speclen; i++)
{
float re = scale(spectrum[i].r) * TIME;
float im = scale(spectrum[i].i) * TIME;
output[i] = sqrtf(re*re + im*im);
}
return;
}
Le problème se produit à cette ligne kiss_fftr(config, (kiss_fft_scalar*) samples, spectrum);
Où samples
contient les échantillons audio (16 bits), et spectrum
est supposé détenir les données de sortie.
Une fois que la fonction est terminée, voici ce qui se passe dans la fenêtre du débogueur.
Quelqu'un peut me donner un exemple simple de la façon d'appliquer Baiser FFT fonctions audio (16 bits codés) des échantillons?
- N'est-ce pas là toute la documentation ou des exemples d'utilisation du code dans KissFFT???
- Pourquoi le downvote?
- Ce n'était pas la mienne, mais, peut-être, reflète le manque apparent d'effort de votre côté?
- L'exemple joint montre le code que j'ai essayé. J'ai été incapable de trouver une affaire similaire à ce que je suis en train de vivre sur Google. Le code, je crois, est plus ou moins la façon dont il devrait être fait. Je suis à essayer de comprendre pourquoi j'obtiens des valeurs NaN.
- Vous pouvez essayer en utilisant de simples signaux d'abord: tous les zéros, tous ceux, une onde sinusoïdale, etc pour voir que FFT elle-même travaille. Je ne peux pas croire il n'y a pas assez de code de l'échantillon ou de la documentation, de comprendre comment le KissFFT les routines doivent être utilisés dans les cas les plus simples comme celles-ci. Une fois que vous avez que de travail, vous pouvez commencer à jouer avec des données mp3. Venez sur.
- Oui, j'ai essayé aussi. (Dans l'exemple de code, zéro.le mp3 est un fichier rempli de zéro fréquences) Croyez le ou non, le même résultat (NaN) se produit toujours.
- Bonjour je m struglling avec le même problème.. j'ai testé avec l'ensemble des zéros et des uns, il donne un parfait o/p). bt quand j'essaie de vivre de l'audio ça me donne mal o/p...
Vous devez vous connecter pour publier un commentaire.
Quand j'ai commencé à regarder cette réponse, je me demandais pourquoi le -8.0 a été tourner dans l'imaginaire plutôt que sur la partie réelle. C'est alors re-lecture d'un article imprimé sur la FFT, que j'ai réalisé que j'avais été de penser à la grandeur.
Donc j'ai modifié la réponse dans le Complexe de code pour modifier le printf comme suit
Qui produit une réponse montrant l'ampleur ainsi.
J'ai aussi joué autour de la modification de la fréquence dans la boucle qui génère l'onde sinusoïdale.
Et aussi longtemps que je suis resté avec des multiples de 1.0 et en vertu de la fréquence de Nyquist 16/2 = 8 le résultat décalé à partir d'une cellule à l'autre tout à fait bien. Bien sûr, réglage de fréquence à valeurs fractionnaires voit son ampleur répartis dans les bacs et sans l'application d'une fonction de fenêtrage nous obtenons la fuite. Si vous êtes encore du mal avec la FFT, comme je suis à jouer avec ce code où vous pouvez voir tous les résultats sur un seul écran pendant un certain temps et les choses commencent à devenir plus claire.
Enfin un vote de remerciements à Alexey pour la réponse qui m'a aidé à commencer à Baiser la FFT.
Essayez ceci: