ios - 核心音频内存问题

标签 ios xcode core-audio

我的音频单元分析项目存在一些内存问题,因此每次渲染音频单元(或附近的某处)时,它都会分配一堆未释放的内存,导致内存使用量膨胀和应用程序最终崩溃。

在工具中,我注意到以下 32 字节 malloc 字符串重复出现,并且它们仍然有效:

BufferedAudioConverter::AllocateBuffers() x6 BufferedInputAudioConverter:BufferedInputAudioConverter(StreamDescPair const&) x 3

您知道问题出在哪里吗?什么时候在进程中分配内存以及如何安全释放它?

非常感谢。

该代码基于一些非 Apple 示例代码,来自 sleepyleaf.com 的 PitchDetector

一些代码摘录可能是问题所在..... 如果需要更多代码,请告诉我。

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

最佳答案

我设法找到并解决了问题,该问题位于上面未发布的代码区域。

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

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

err = AudioConverterDispose (converter);

关于ios - 核心音频内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9802652/

相关文章:

ios - iPhone - 为什么全屏不起作用但在 iPad 上却可以?

ios - xcode:类不符合键值编码

macos - 将低延迟音频从一个 CoreAudio 设备路由到另一个

core-audio - iOS RemoteIO - AudioUnitAddRenderNotify 回调

iphone - 关闭应用内购买?

iphone - iPhone 实时音频循环切换

ios - ViewController 偶尔会错过响应链?

ios - 在 iOS 11 中播放音乐库时更改和隐藏音量 HUD(音量叠加)

ios - 需要创建一个带有 2 个小数位的 NSDecimalNumber 以存储在核心数据中,但最后一个小数点 (0) 被删除

ios - 异常 : CocoaPods not installed or not in valid state