Mise en œuvre simple et filtres passe-bas en C
En essayant d'utiliser portaudio à enregistrer certaines données, puis utiliser un algorithme de filtre pour modifier la voix enregistrée et ensuite le lire. J'ai vérifié beaucoup de lui (à venir à partir de l'exemple), mais je suis assez novice en C et je pense que dans mon filtre de mise en œuvre que j'ai fait quelque chose de stupide.
#if LOW_PASS
{
float RC = 1.0/(CUTOFF*2*3.14);
float dt = 1.0/SAMPLE_RATE;
float alpha = dt/(RC+dt);
float filteredArray[numSamples];
filteredArray[0] = data.recordedSamples[0];
for(i=1; i<numSamples; i++){
filteredArray[i] = filteredArray[i-1] + (alpha*(data.recordedSamples[i] - filteredArray[i-1]));
}
data.recordedSamples = filteredArray;
}
#endif
#if HIGH_PASS
{
float RC = 1.0/(CUTOFF*2*3.14);
float dt = 1.0/SAMPLE_RATE;
float alpha = RC/(RC + dt);
float filteredArray[numSamples];
filteredArray[0] = data.recordedSamples[0];
for (i = 1; i<numSamples; i++){
filteredArray[i] = alpha * (filteredArray[i-1] + data.recordedSamples[i] - data.recordedSamples[i-1]);
}
data.recordedSamples = filteredArray;
}
#endif
Lorsque le signal enregistré essaie de passer au travers de ces filtres que j'obtiens quelque chose d'erreur suivant:
*** glibc detected *** ./paex_record: free(): invalid pointer: 0xbfd68600 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb75e2ee2]
./paex_record[0x8048fe5]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75864d3]
./paex_record[0x80487f1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:05 2363767 /home/svictoroff/Documents/CompArch/portaudio/examples/paex_record
...
bfd68000-bff1a000 rw-p 00000000 00:00 0 [stack]
Aborted (core dumped)
Je suis vraiment pas sûr de ce qui se passe ici. Toutes les pensées?
Gratuit est appelé à partir de la fin du script à mettre fin ici:
Pa_Terminate();
if( data.recordedSamples ) /* Sure it is NULL or valid. */
free( data.recordedSamples );
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1; /* Always return 0 or 1, but no other return codes. */
}
return err;
Quelle est la taille de recordedSamples ?
L'erreur semble se produire à l'intérieur d'un appel à
RecordedSamples est d'environ 200k
Ah, trouvé de la liberté, de l'affichage dès maintenant.
Pouvez-vous montrer la ligne de code, l'erreur se produit à alors s'il vous plaît? Vous pourriez déterminer à l'aide d'un débogueur ou par l'ajout de
L'erreur semble se produire à l'intérieur d'un appel à
free
. Pouvez-vous montrer le code qui appelle free
trop s'il vous plaît?RecordedSamples est d'environ 200k
Ah, trouvé de la liberté, de l'affichage dès maintenant.
Pouvez-vous montrer la ligne de code, l'erreur se produit à alors s'il vous plaît? Vous pourriez déterminer à l'aide d'un débogueur ou par l'ajout de
printf
états par le biais de votre code
OriginalL'auteur Slater Victoroff | 2012-12-14
Vous devez vous connecter pour publier un commentaire.
Le problème est que les données.recordedSamples maintenant (au moment de la
free()
) pointe vers une structure allouée sur la pile, pas sur le tas!Depuis que vous avez eu cette instruction:
La
est d'aucune utilité, puisque l'adresse id valide, mais n'est pas conforme: il n'est jamais alloué avec
malloc()
et il n'est pas sur le tas, mais sur la pile!Au moment où vous appelez
free()
, cette adresse pourrait bien pointer vers la pile d'une autre fonction.Copier vos données filtrées en arrière par rapport à l'original
recordedSamples
si vous le souhaitez, il suffit de ne pas ré-affecter le pointeur.edit:
utiliser ceci:
pour remplacer les données, utilisez une boucle for() et copie flottant float; ou utiliser memcpy() (vous devez inclure <string.h>); for(i = 0; i<numSamples; i++) {données.recordedSamples[i] = filteredArray[i]}
voir ma réponse mis à jour
Ah, fantastique. Merci beaucoup!
OriginalL'auteur user1284631
Il semble que vous essayez de libérer une pile variable. Le seul moment où vous devez appeler
free
, c'est quand vous avez déjà appelémalloc
(ou l'un de ses amis commecalloc
) ou lorsque les documents d'une bibliothèque de fonction vous êtes d'appel dit que vous avez besoin de libérer un pointeur qui il retourne.D'ailleurs, tout le temps de vous faire libérer un pointeur, une bonne pratique est de le mettre à NULL immédiatement après.
Pile variables disparaissent dès qu'ils sont hors de portée. Cette pourrait vous aider à mieux comprendre.
OriginalL'auteur nmichaels