J'utilise audiorecorder pour enregistrer le son et faire un peu de traitement en pseudo-temps sur le téléphone android. Je suis confronté à un problème entre la FFT et la convolution du signal audio: J'effectue FFT sur un signal connu (une forme d'onde sinusoïdale), et je trouve toujours correctement la tonalité unique qu'il contient, en utilisant la FFT.convolution du signal audio
Maintenant, je veux faire la même chose en utilisant une convolution (c'est un exercice): J'effectue 5000 convolutions de ce signal en utilisant 5000 filtres. Chaque filtre est une forme d'onde sinusoïdale sur une fréquence différente entre 0 et 5000 Hz. Puis, je recherche le pic pour chaque sortie de convolution. De cette façon, je devrais trouver le pic maximum quand j'utilise le filtre avec le même ton contenu sur le signal. Enfait avec une tonalité de 2kHz je peux trouver le maximum avec le filtre 2kHz. Le problème est que quand je reçois une tonalité de 4kHz, je trouve le maximum sur la convolution avec le filtre 4200Hz (alors que la FFT fonctionne toujours bien) Est-ce mathématiquement possible? quel est le problème dans ma convolution?
C'est la fonction de convolution que je l'ai écrit:
//i do the convolution and return the max
//IN is the array with the signal
//DATASIZE is the size of the array IN
//KERNEL is the filter containing the sine at the selected frequency
int convolveAndGetPeak(short[] in,int dataSize, double[] kernel) {
//per non rischiare l'overflow, il kernel deve avere un ampiezza massima pari a 1/10 del max
int i, j, k;
int kernelSize=kernel.length;
int tmpSignalAfterFilter=0;
double out;
// convolution from out[0] to out[kernelSize-2]
//iniziamo
for(i=0; i < kernelSize - 1; ++i)
{
out = 0; // init to 0 before sum
for(j = i, k = 0; j >= 0; --j, ++k)
out += in[j] * kernel[k];
if (Math.abs((int) out)>tmpSignalAfterFilter){
tmpSignalAfterFilter=Math.abs((int) out);
}
}
// start convolution from out[kernelSize-1] to out[dataSize-1] (last)
//iniziamo da dove eravamo arrivati
for(; i < dataSize; ++i)
{
out = 0; // initialize to 0 before accumulate
for(j = i, k = 0; k < kernelSize; --j, ++k)
out += in[j] * kernel[k];
if (Math.abs((int) out)>tmpSignalAfterFilter){
tmpSignalAfterFilter=Math.abs((int) out);
}
}
return tmpSignalAfterFilter;
}
le noyau, utilisé comme filtre, est généré de cette façon:
//curFreq is the frequency of the filter in Hz
//kernelSamplesSize is the desired length of the filter (number of samples), for time precision reasons i'm using 20 samples length.
//sampleRate is the sampling frequency
double[] generateKernel(int curFreq,int kernelSamplesSize,int sampleRate){
double[] curKernel= new double[kernelSamplesSize] ;
for (int kernelIndex=0;kernelIndex<curKernel.length;kernelIndex++){
curKernel[kernelIndex]=Math.sin((double)kernelIndex * ((double)(2*Math.PI) * (double)curFreq/(double)sampleRate)); //the part that makes this a sine wave....
}
return curKernel;
}
si vous voulez essayer une convolution, les données contenues dans le réseau IN est la suivante: http://www.tr3ma.com/Dati/signal.txt
Note 1: la fréquence d'échantillonnage est 44100Hz
Note2: la tonalité contenue dans le signal est une tonalité unique de 4 kHz (même si la convolution a le pic maximal avec un filtre 4200Hz.
EDIT: J'ai également répété le test sur une feuille Excel. le résultat est le même (bien sûr, j'utilise le même algorithme) et les algorithmes me semblent être corrects ... c'est la feuille excel que j'ai préparée, si vous préférez travailler sur excel: http://www.tr3ma.com/Dati/convolutions.xlsm
VRAIMENT INTÉRESSANT. MERCI DE VOTRE CONTRIBUTION, JE CONTINUERAIS D'ETUDIER. J'ai trouvé comment calculer la bande passante quelques jours après avoir posé la question, et la solution. JE N'AI PAS BIEN COMPRIS LE DEUXIÈME NOYAU AVEC COSINE. Je vais étudier à nouveau. MERCI – Gaucho
MAINTENANT JE VOUS compris pourquoi parler CONVOLUTION AVEC UN DEUXIÈME COSINUS, mais dans mon cas, j'ai juste besoin IDENTIFIER LE PREMIER SOMMET DE LA SORTIE Convolution, JE NE BESOIN D'UNE SORTIE CONTINUE. – Gaucho
EN OUTRE, UNE SECONDE CONVOLUTION AUGMENTE TROP LE TEMPS DE TRAITEMENT. CONSIDERONS QUE JUSQU'A MAINTENANT JE CONSERVE PLUS DE TEMPS POUR TRAITER LE SIGNAL, QUE LE TEMPS DES ECHANTILLONS REÇUS. SO À convolve TOUS LES STREAMING JE FORCÉ SAUTER QUELQUES PIECES DE SIGNAL, RÉDUIRE MA PRECISION TIME – Gaucho