2011-08-23 4 views
1

Donc, je pense que c'est une question difficile à poser correctement, mais voici mon meilleur tir. J'écris une application iPhone en obj-c, mais elle implique une synthèse sonore, et le tutoriel en core audio que j'ai fait utilise la synthèse sonore programmée dans ce que je crois être C (ou peut-être C++, j'ai demandé à quelqu'un que je connais utilise C++ et il ne l'a pas reconnu, mais le tutoriel m'a dit de changer les noms de fichiers en .mm pour C++). Le problème qui se pose est que j'ai d'énormes fuites de mémoire, très probablement parce que je ne sais pas comment appeler correctement les choses.Fuites de mémoire avec synthèse sonore

Chaque fois que cette partie du code est utilisé, je reçois une tonne d'erreurs qui se lisent comme ceci: 2011-08-23 10: 18: 08,769 MyProgram [451: 5e03] * __NSAutoreleaseNoPool(): Object 0x171e90 de la classe _NSCallStackArray a libéré sans pool en place - juste fuite

En utilisant des instruments, j'ai trouvé où la fuite se produit et j'ai mis un commentaire dedans pour le représenter.

est ici la fonction où toutes les fuites viennent:

static OSStatus renderInput(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) 
{ 
// Get a reference to the object that was passed with the callback 
// In this case, the AudioController passed itself so 
// that you can access its data. 
AudioController *THIS = (AudioController*)inRefCon; 

// Get a pointer to the dataBuffer of the AudioBufferList 
AudioSampleType *outA = (AudioSampleType *)ioData->mBuffers[0].mData; 

// Calculations to produce a 600 Hz sinewave 
// A constant frequency value, you can pass in a reference vary this. 

float sinSignal; 

for (UInt32 i = 0; i < inNumberFrames; ++i) {  
    outA[i] = 0; 
} 


THIS->theBall = [[THIS->navDelegate ballsG] objectAtIndex:0]; 


THIS->amtPlaying = [[THIS->theBall playingLines] count]; 

//NSLog(@"%i", THIS->amtPlaying); 


for (int i = 0; i < THIS->amtPlaying; i++) 
{ 
    // Loop through the callback buffer, generating samples 
    for (UInt32 i = 0; i < inNumberFrames; ++i) {  

     // calculate the next sample 
     sinSignal = sin( [[[THIS->theBall playingLines] objectAtIndex:i] theta] ); //leak here 

     sinSignal *= [[[THIS->theBall playingLines] objectAtIndex:i] volume] ; 

     sinSignal /= THIS->amtPlaying; 

     // Put the sample into the buffer 
     // Scale the -1 to 1 values float to 
     // -32767 to 32767 and then cast to an integer 
     outA[i] += (SInt16)(sinSignal * 32767.0f); 
     // calculate the phase for the next sample 

     [[[THIS->theBall playingLines] objectAtIndex:i] increaseTheta: [[[THIS->theBall playingLines] objectAtIndex:i] incrementer]]; 
    } 

} 

return noErr; 
} 

Si je peux fournir plus d'informations pour vous aider à comprendre ma question, s'il vous plaît laissez-moi savoir dans un commentaire. Merci!

+0

Si vous tentez d'effectuer votre traitement en arrière-plan, vous devez ajouter un 'NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init] 'au début de la fonction, puis' [pool drain] 'à la fin vous utilisez des objets auto-libérés possibles. ('ballsG',' objectAtIndex: ',' ​​playLines') – Joe

+0

Qui s'est débarrassé des autres fuites, maintenant les instruments montrent que je fuis NSAutoReleasePool. – turbo

+0

Et vous avez ajouté '[pool drain]' juste avant 'return noErr;'? De plus, quelle que soit la méthode utilisée quand vous lancez un nouveau thread, le 'NSAutoreleasePool' devrait être la première chose créée ici, alors la dernière chose à faire devrait être de le 'drainer' dans la même méthode. – Joe

Répondre

2

Vous ne devez utiliser aucun code d'objet dans le fil de rendu audio. Le code Objc peut se verrouiller et nécessite généralement une allocation/désallocation de la mémoire. Ceux-ci ne devraient jamais se produire dans le fil audio car il s'agit d'un fil de haute priorité. Il y a une grande ressource de discussion sur la liste d'email de core-audio-api. Vous pouvez essayer de faire fonctionner objc mais c'est un cauchemar. L'utilisation de c/C++ fonctionne aussi bien sans ces problèmes.

+0

Désolé pour une réponse si tardive, mais le projet devait arriver le lendemain, donc je ne l'ai pratiquement pas touché depuis. Je ne connais pas grand chose en ce qui concerne le c/C++, donc je ne sais pas combien cela aurait été bon pour moi de toute façon. Merci de me l'avoir signalé, je le garderai à l'esprit dans le futur ou lorsque je reviendrai au projet. – turbo