Проблемы с памятью Core Audio - PullRequest
1 голос
/ 21 марта 2012

В проекте анализа моего аудиоустройства есть некоторые проблемы с памятью, в результате чего каждый раз, когда аудиоустройство воспроизводится (или где-то вокруг этого), оно выделяет кучу памяти, которая не освобождается, вызывая увеличение объема используемой памяти и приложения. в конечном итоге сбой.

В инструментах я заметил следующую строку из 32-байтовых malloc, встречающихся многократно, и они остаются живыми:

BufferedAudioConverter :: AllocateBuffers () x6 BufferedInputAudioConverter: BufferedInputAudioConverter (постоянная StreamDescPair &) x 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 (выходной буфер, 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);

}

1 Ответ

0 голосов
/ 23 марта 2012

Мне удалось найти и устранить проблему, которая была в области кода, не размещенного выше.

На следующем шаге выходной буфер преобразовывался в другой числовой формат с использованием объекта AudioConverter.Однако объект преобразователя не был утилизирован и остался в памяти.Я исправил это с помощью AudioConverterDispose, как показано ниже:

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

err = AudioConverterDispose (converter);
...