【问题标题】:Memory Leaks with sound synthesis带有声音合成的内存泄漏
【发布时间】:2011-08-23 15:01:57
【问题描述】:

所以我觉得这是一个很难正确提出的问题,但这是我最好的选择。

我正在用 obj-c 编写一个 iPhone 应用程序,但它涉及声音合成,而我在核心音频中的教程使用了我认为是 C(或者可能是 C++)编程的声音合成,我问了一个我认识的人使用C++,他不认识它,但教程告诉我将文件名更改为 .mm 用于 C++)。出现的问题是我有巨大的内存泄漏,很可能是因为我不知道如何正确调用事物。

当使用这部分代码时,我会收到大量错误,如下所示: 2011-08-23 10:18:08.769 myProgram[451:5e03] * __NSAutoreleaseNoPool(): _NSCallStackArray 类的对象 0x171e90 自动释放,没有适当的池 - 只是泄漏

使用仪器,我找到了泄漏发生的位置,并在其中发表了评论。

这是所有泄漏出现的函数:

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;
}

如果我可以提供更多信息来帮助您理解我的问题,请在评论中告诉我。谢谢!

【问题讨论】:

  • 如果您尝试在后台进行处理,您需要在函数的开头添加NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init],然后在末尾添加[pool drain],因为您正在使用可能的自动释放对象。 (ballsG, objectAtIndex:, playingLines)
  • 消除了其他泄漏,现在仪器显示我正在泄漏 NSAutoReleasePool。
  • 你在return noErr;之前添加了[pool drain]?此外,无论您在启动新线程时调用哪种方法,NSAutoreleasePool 都应该是在那里创建的第一件事,然后做的最后一件事应该是在同一方法中调用drain
  • 是的,[pool drain] 语句就在 return no Err 之前;并且 NSAutoreleasePool 在方法中首先被调用。

标签: objective-c c ios xcode core-audio


【解决方案1】:

您不应该在音频渲染线程中使用任何 objc 代码。 Objc 代码可以锁定并且通常需要一些内存分配/释放。这些也不应该出现在音频线程中,因为它是一个高优先级线程。 core-audio-api 电子邮件列表上有一个大型讨论资源。您可以尝试使 objc 工作,但这是一场噩梦。使用 c/c++ 也没有这些问题。

【讨论】:

  • 很抱歉这么晚才回复,但是项目第二天就到期了,所以从那以后我几乎没有碰过它。我对 c/c++ 了解不多,所以我不知道它对我有多大好处。感谢您向我指出这一点,我会在以后或回到项目时牢记这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 2013-01-28
  • 2011-11-06
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
相关资源
最近更新 更多