在iPhonemixereqgraphtest应用程序中获取内存问题

时间:2014-04-25 11:58:03

标签: ios objective-c

我正在构建一个iOS应用程序。当我要去下一首歌时,我得到了记忆错误。我的代码是

    - (void)initializeAUGraph2:(int)songIndex url:(CFURLRef)urlVal
    {
        printf("initializeAUGraph\n");

        AUNode outputNode;
        AUNode eqNode;
        AUNode mixerNode;

        printf("create client ASBD\n");

        // client format audio goes into the mixer
        mClientFormat.SetCanonical(2, true);
        mClientFormat.mSampleRate = kGraphSampleRate;
        mClientFormat.Print();

        printf("create output ASBD\n");

        // output format
        mOutputFormat.SetAUCanonical(2, false);
        mOutputFormat.mSampleRate = kGraphSampleRate;
        mOutputFormat.Print();

        OSStatus result = noErr;

        // load up the audio data
        printf("load up audio data\n");
        [self loadFilesWIthUrl:songIndex url:urlVal];

        printf("\nnew AUGraph\n");

        // create a new AUGraph
        result = NewAUGraph(&mGraph);
        if (result) { printf("NewAUGraph result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        // create three Audio Component Descriptons for the AUs we want in the graph using the CAComponentDescription helper class

        // output unit
        CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);

        // iPodEQ unit
        CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);

        // multichannel mixer unit
        CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);

        printf("add nodes\n");

        // create a node in the graph that is an AudioUnit, using the supplied AudioComponentDescription to find and open that unit
        result = AUGraphAddNode(mGraph, &output_desc, &outputNode);
        if (result) { printf("AUGraphNewNode 1 result %lu %4.4s\n", result, (char*)&result); return; }

        result = AUGraphAddNode(mGraph, &eq_desc, &eqNode);
        if (result) { printf("AUGraphNewNode 2 result %lu %4.4s\n", result, (char*)&result); return; }

        result = AUGraphAddNode(mGraph, &mixer_desc, &mixerNode);
        if (result) { printf("AUGraphNewNode 3 result %lu %4.4s\n", result, (char*)&result); return; }

        // connect a node's output to a node's input
        // mixer -> eq -> output
        result = AUGraphConnectNodeInput(mGraph, mixerNode, 0, eqNode, 0);
        if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; }

        result = AUGraphConnectNodeInput(mGraph, eqNode, 0, outputNode, 0);
        if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; }

        // open the graph AudioUnits are open but not initialized (no resource allocation occurs here)
        result = AUGraphOpen(mGraph);
        if (result) { printf("AUGraphOpen result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        // grab the audio unit instances from the nodes
        result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
        if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        result = AUGraphNodeInfo(mGraph, eqNode, NULL, &mEQ);
        if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        // set bus count
        UInt32 numbuses = 1;

        printf("set input bus count %lu\n", numbuses);

        result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses, sizeof(numbuses));
        if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        //for (UInt32 i = 0; i < numbuses; ++i) {
        // setup render callback struct
        AURenderCallbackStruct rcbs;
        rcbs.inputProc = &renderInput;
        rcbs.inputProcRefCon = &mUserData;

        printf("set AUGraphSetNodeInputCallback\n");

        // set a callback for the specified node's specified input
        result = AUGraphSetNodeInputCallback(mGraph, mixerNode, songIndex, &rcbs);
        if (result) { printf("AUGraphSetNodeInputCallback result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        printf("set input bus %d, client kAudioUnitProperty_StreamFormat\n", (unsigned int)songIndex);

        // set the input stream format, this is the format of the audio for mixer input
        result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, songIndex, &mClientFormat, sizeof(mClientFormat));
        if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }
        //}

        printf("get EQ kAudioUnitProperty_FactoryPresets\n");

        // get the eq's factory preset list -- this is a read-only CFArray array of AUPreset structures
        // host owns the retuned array and should release it when no longer needed
        UInt32 size = sizeof(mEQPresetsArray);
        result = AudioUnitGetProperty(mEQ, kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &mEQPresetsArray, &size);
        if (result) { printf("AudioUnitGetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        /* this code can be used if you're interested in dumping out the preset list
         printf("iPodEQ Factory Preset List:\n");
         UInt8 count = CFArrayGetCount(mEQPresetsArray);
         for (int i = 0; i < count; ++i) {
         AUPreset *aPreset = (AUPreset*)CFArrayGetValueAtIndex(mEQPresetsArray, i);
         CFShow(aPreset->presetName);
         }*/

        printf("set output kAudioUnitProperty_StreamFormat\n");

        // set the output stream format of the mixer
        result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));
        if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        printf("set render notification\n");

        // add a render notification, this is a callback that the graph will call every time the graph renders
        // the callback will be called once before the graph’s render operation, and once after the render operation is complete
        result = AUGraphAddRenderNotify(mGraph, renderNotification, &mUserData);
        if (result) { printf("AUGraphAddRenderNotify result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        printf("AUGraphInitialize\n");

        // now that we've set everything up we can initialize the graph, this will also validate the connections
        result = AUGraphInitialize(mGraph);
        if (result) { printf("AUGraphInitialize result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        CAShow(mGraph);
    }

    // load up audio data from the demo files into mSoundBuffer.data used in the render proc
    - (void)loadFilesWIthUrl:(int)songIndex url:(CFURLRef)referenceURL
    {
        mUserData.frameNum = 0;
        mUserData.maxNumFrames = 0;

        printf("loadFiles, %d\n", songIndex);

        ExtAudioFileRef xafref = 0;

        // open one of the two source files
        OSStatus result = ExtAudioFileOpenURL(referenceURL, &xafref);
        if (result || 0 == xafref) { printf("ExtAudioFileOpenURL result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        // get the file data format, this represents the file's actual data format
        // for informational purposes only -- the client format set on ExtAudioFile is what we really want back
        CAStreamBasicDescription fileFormat;
        UInt32 propSize = sizeof(fileFormat);

        result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileDataFormat, &propSize, &fileFormat);

        if (result)
        {
            printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileDataFormat result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
        }

        printf("file %d, native file format\n", songIndex);
        fileFormat.Print();

        // set the client format to be what we want back
        // this is the same format audio we're giving to the the mixer input
        result = ExtAudioFileSetProperty(xafref, kExtAudioFileProperty_ClientDataFormat, sizeof(mClientFormat), &mClientFormat);

        if (result)
        {
            printf("ExtAudioFileSetProperty kExtAudioFileProperty_ClientDataFormat %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
        }

        // get the file's length in sample frames
        UInt64 numFrames = 0;
        propSize = sizeof(numFrames);
        result = ExtAudioFileGetProperty(xafref, kExtAudioFileProperty_FileLengthFrames, &propSize, &numFrames);

        if (result || numFrames == 0)
        {
            printf("ExtAudioFileGetProperty kExtAudioFileProperty_FileLengthFrames result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
        }

        memset(&mUserData.soundBuffer, 0, sizeof(mUserData.soundBuffer));

        // keep track of the largest number of source frames
        if (numFrames > mUserData.maxNumFrames) mUserData.maxNumFrames = numFrames;

        // set up our buffer
        mUserData.soundBuffer[songIndex].numFrames = numFrames;
        mUserData.soundBuffer[songIndex].asbd = mClientFormat;

        UInt32 samples = numFrames * mUserData.soundBuffer[songIndex].asbd.mChannelsPerFrame;
        mUserData.soundBuffer[songIndex].data = (AudioSampleType *)calloc(samples, sizeof(AudioSampleType));

        // set up a AudioBufferList to read data into
        AudioBufferList bufList;
        bufList.mNumberBuffers = 1;
        bufList.mBuffers[0].mNumberChannels = mUserData.soundBuffer[songIndex].asbd.mChannelsPerFrame;
        bufList.mBuffers[0].mData = mUserData.soundBuffer[songIndex].data;
        bufList.mBuffers[0].mDataByteSize = samples * sizeof(AudioSampleType);

        // perform a synchronous sequential read of the audio data out of the file into our allocated data buffer
        UInt32 numPackets = numFrames;
        result = ExtAudioFileRead(xafref, &numPackets, &bufList);

        if(result)
        {
            //printf("ExtAudioFileRead result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result);
            free(mUserData.soundBuffer[songIndex].data);
            mUserData.soundBuffer[songIndex].data = 0;
            return;
        }

        // close the file and dispose the ExtAudioFileRef
        ExtAudioFileDispose(xafref);
    }

-(IBAction)playSong
{
    [self stopAUGraph];
    [self initializeAUGraph2:0 url:url2];

    [self startAUGraph];

}

-(IBAction)nextSong
{
    [self stopAUGraph];
    [self initializeAUGraph2:0 url:url2];

    [self startAUGraph];

}
// stars render
- (void)startAUGraph
{
    printf("PLAY\n");

    OSStatus result = AUGraphStart(mGraph);

    if (result)
    {
        //printf("AUGraphStart result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
    }

    mIsPlaying = true;
}

// stops render
- (void)stopAUGraph
{
    printf("STOP\n");

    Boolean isRunning = false;

    OSStatus result = AUGraphIsRunning(mGraph, &isRunning);
    if (result)
    {
        //printf("AUGraphIsRunning result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
    }

    if (isRunning)
    {
        result = AUGraphStop(mGraph);

        if (result)
        {
            //printf("AUGraphStop result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return;
        }

        mIsPlaying = false;
    }
}

任何一个hlep都可以解决内存问题。请让我知道。任何想法都会感激不尽

0 个答案:

没有答案