2012-03-21 74 views
1

我的音频单元分析项目存在一些内存问题,每当音频单元被渲染时(或其周围的某处),它会分配一堆未释放的内存,导致内存使用量膨胀和应用程序最终崩溃。核心音频存储器问题

在仪表,我注意到发生反复的32个字节mallocs下面的字符串,并且它们保持住:

BufferedAudioConverter :: AllocateBuffers()5233 BufferedInputAudioConverter:BufferedInputAudioConverter(StreamDescPair常量&)×3

任何问题可能存在的想法?流程中分配的内存何时分配以及如何安全释放?

非常感谢。

的代码是基于一些非苹果的示例代码,PitchDetector从sleepyleaf.com

一些代码提取哪里的问题可能在于.....请让我知道,如果需要更多的代码。

renderErr = AudioUnitRender(rioUnit, ioActionFlags, 
          inTimeStamp, bus1, inNumberFrames, THIS->bufferList); //128 inNumberFrames 
if (renderErr < 0) { 
    return renderErr; 
} 

// Fill the buffer with our sampled data. If we fill our buffer, run the 
// fft. 
int read = bufferCapacity - index; 
if (read > inNumberFrames) { 
    memcpy((SInt16 *)dataBuffer + index, THIS->bufferList->mBuffers[0].mData, inNumberFrames*sizeof(SInt16)); 
    THIS->index += inNumberFrames; 
} else { DO ANALYSIS 

memset(outputBuffer,0,n * sizeof(SInt16));


- (void)createAUProcessingGraph { 
OSStatus err; 
// Configure the search parameters to find the default playback output unit 
// (called the kAudioUnitSubType_RemoteIO on iOS but 
// kAudioUnitSubType_DefaultOutput on Mac OS X) 
AudioComponentDescription ioUnitDescription; 
ioUnitDescription.componentType = kAudioUnitType_Output; 
ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO; 
ioUnitDescription.componentManufacturer = kAudioUnitManufacturer_Apple; 
ioUnitDescription.componentFlags = 0; 
enter code here 

ioUnitDescription.componentFlagsMask = 0; 

// Declare and instantiate an audio processing graph 
NewAUGraph(&processingGraph); 

// Add an audio unit node to the graph, then instantiate the audio unit. 
/* 
An AUNode is an opaque type that represents an audio unit in the context 
of an audio processing graph. You receive a reference to the new audio unit 
instance, in the ioUnit parameter, on output of the AUGraphNodeInfo 
function call. 
*/ 
AUNode ioNode; 
AUGraphAddNode(processingGraph, &ioUnitDescription, &ioNode); 

AUGraphOpen(processingGraph); // indirectly performs audio unit instantiation 

// Obtain a reference to the newly-instantiated I/O unit. Each Audio Unit 
// requires its own configuration. 
AUGraphNodeInfo(processingGraph, ioNode, NULL, &ioUnit); 

// Initialize below. 
AURenderCallbackStruct callbackStruct = {0}; 
UInt32 enableInput; 
UInt32 enableOutput; 

// Enable input and disable output. 
enableInput = 1; enableOutput = 0; 
callbackStruct.inputProc = RenderFFTCallback; 
callbackStruct.inputProcRefCon = (__bridge void*)self; 

err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_EnableIO, 
          kAudioUnitScope_Input, 
          kInputBus, &enableInput, sizeof(enableInput)); 

err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_EnableIO, 
          kAudioUnitScope_Output, 
          kOutputBus, &enableOutput, sizeof(enableOutput)); 

err = AudioUnitSetProperty(ioUnit, kAudioOutputUnitProperty_SetInputCallback, 
          kAudioUnitScope_Input, 
          kOutputBus, &callbackStruct, sizeof(callbackStruct)); 


// Set the stream format. 
size_t bytesPerSample = [self ASBDForSoundMode]; 

err = AudioUnitSetProperty(ioUnit, kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Output, 
          kInputBus, &streamFormat, sizeof(streamFormat)); 

err = AudioUnitSetProperty(ioUnit, kAudioUnitProperty_StreamFormat, 
          kAudioUnitScope_Input, 
          kOutputBus, &streamFormat, sizeof(streamFormat)); 




// Disable system buffer allocation. We'll do it ourselves. 
UInt32 flag = 0; 
err = AudioUnitSetProperty(ioUnit, kAudioUnitProperty_ShouldAllocateBuffer, 
          kAudioUnitScope_Output, 
          kInputBus, &flag, sizeof(flag)); 


// Allocate AudioBuffers for use when listening. 
// TODO: Move into initialization...should only be required once. 
    bufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer)); 
    bufferList->mNumberBuffers = 1; 
    bufferList->mBuffers[0].mNumberChannels = 1; 

    bufferList->mBuffers[0].mDataByteSize = 512*bytesPerSample; 
    bufferList->mBuffers[0].mData = calloc(512, bytesPerSample); 

}

+0

请张贴代码。 – 2012-03-21 10:28:39

+0

嗨,Eric,我已经发布了一些代码...将非常欢迎你有任何建议!谢谢 – Spinoxa 2012-03-21 11:50:22

回答

0

我设法找到并修复问题,这是在上面没有贴码的区域。

在接下来的步骤中,使用AudioConverter对象将输出缓冲区转换为不同的数字格式。但是,转换器对象没有被处理掉,而是一直活在内存中。我通过使用AudioConverterDispose修复它如下:

err = AudioConverterNew(&inFormat, &outFormat, &converter); 
err = AudioConverterConvertBuffer(converter, inSize, buf, &outSize, outputBuf); 

err = AudioConverterDispose (converter);