Iphone 在C++中的含义

Iphone 在C++中的含义,iphone,c++,ios,Iphone,C++,Ios,我一直在学习iPhone上的核心音频,在浏览苹果的示例代码时,我发现: #include "AQPlayer.h" void AQPlayer::AQBufferCallback(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCom

我一直在学习iPhone上的核心音频,在浏览苹果的示例代码时,我发现:

#include "AQPlayer.h"

void AQPlayer::AQBufferCallback(void *                  inUserData,
                                AudioQueueRef           inAQ,
                                AudioQueueBufferRef     inCompleteAQBuffer) 
{
    AQPlayer *THIS = (AQPlayer *)inUserData;

    if (THIS->mIsDone) return;

    UInt32 numBytes;
    UInt32 nPackets = THIS->GetNumPacketsToRead();
    OSStatus result = AudioFileReadPackets(THIS->GetAudioFileID(), false, &numBytes, inCompleteAQBuffer->mPacketDescriptions, THIS->GetCurrentPacket(), &nPackets, 
                                           inCompleteAQBuffer->mAudioData);
    if (result)
        printf("AudioFileReadPackets failed: %d", result);
    if (nPackets > 0) {
        inCompleteAQBuffer->mAudioDataByteSize = numBytes;      
        inCompleteAQBuffer->mPacketDescriptionCount = nPackets;     
        AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL);
        THIS->mCurrentPacket = (THIS->GetCurrentPacket() + nPackets);
    } 

    else 
    {
        if (THIS->IsLooping())
        {
            THIS->mCurrentPacket = 0;
            AQBufferCallback(inUserData, inAQ, inCompleteAQBuffer);
        }
        else
        {
            // stop
            THIS->mIsDone = true;
            AudioQueueStop(inAQ, false);
        }
    }
}

void AQPlayer::isRunningProc (  void *              inUserData,
                                AudioQueueRef           inAQ,
                                AudioQueuePropertyID    inID)
{
    AQPlayer *THIS = (AQPlayer *)inUserData;
    UInt32 size = sizeof(THIS->mIsRunning);
    OSStatus result = AudioQueueGetProperty (inAQ, kAudioQueueProperty_IsRunning, &THIS->mIsRunning, &size);

    if ((result == noErr) && (!THIS->mIsRunning))
        [[NSNotificationCenter defaultCenter] postNotificationName: @"playbackQueueStopped" object: nil];
}

void AQPlayer::CalculateBytesForTime (CAStreamBasicDescription & inDesc, UInt32 inMaxPacketSize, Float64 inSeconds, UInt32 *outBufferSize, UInt32 *outNumPackets)
{
    // we only use time here as a guideline
    // we're really trying to get somewhere between 16K and 64K buffers, but not allocate too much if we don't need it
    static const int maxBufferSize = 0x10000; // limit size to 64K
    static const int minBufferSize = 0x4000; // limit size to 16K

    if (inDesc.mFramesPerPacket) {
        Float64 numPacketsForTime = inDesc.mSampleRate / inDesc.mFramesPerPacket * inSeconds;
        *outBufferSize = numPacketsForTime * inMaxPacketSize;
    } else {
        // if frames per packet is zero, then the codec has no predictable packet == time
        // so we can't tailor this (we don't know how many Packets represent a time period
        // we'll just return a default buffer size
        *outBufferSize = maxBufferSize > inMaxPacketSize ? maxBufferSize : inMaxPacketSize;
    }

    // we're going to limit our size to our default
    if (*outBufferSize > maxBufferSize && *outBufferSize > inMaxPacketSize)
        *outBufferSize = maxBufferSize;
    else {
        // also make sure we're not too small - we don't want to go the disk for too small chunks
        if (*outBufferSize < minBufferSize)
            *outBufferSize = minBufferSize;
    }
    *outNumPackets = *outBufferSize / inMaxPacketSize;
}

AQPlayer::AQPlayer() :
    mQueue(0),
    mAudioFile(0),
    mFilePath(NULL),
    mIsRunning(false),
    mIsInitialized(false),
    mNumPacketsToRead(0),
    mCurrentPacket(0),
    mIsDone(false),
    mIsLooping(false) { }

AQPlayer::~AQPlayer() 
{
    DisposeQueue(true);
}

OSStatus AQPlayer::StartQueue(BOOL inResume)
{   
    // if we have a file but no queue, create one now
    if ((mQueue == NULL) && (mFilePath != NULL))
        CreateQueueForFile(mFilePath);

    mIsDone = false;

    // if we are not resuming, we also should restart the file read index
    if (!inResume)
        mCurrentPacket = 0; 

    // prime the queue with some data before starting
    for (int i = 0; i < kNumberBuffers; ++i) {
        AQBufferCallback (this, mQueue, mBuffers[i]);           
    }
    return AudioQueueStart(mQueue, NULL);
}

OSStatus AQPlayer::StopQueue()
{
    OSStatus result = AudioQueueStop(mQueue, true);
    if (result) printf("ERROR STOPPING QUEUE!\n");

    return result;
}

OSStatus AQPlayer::PauseQueue()
{
    OSStatus result = AudioQueuePause(mQueue);

    return result;
}

void AQPlayer::CreateQueueForFile(CFStringRef inFilePath) 
{   
    CFURLRef sndFile = NULL; 

    try {                   
        if (mFilePath == NULL)
        {
            mIsLooping = false;

            sndFile = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, inFilePath, kCFURLPOSIXPathStyle, false);
            if (!sndFile) { printf("can't parse file path\n"); return; }

            XThrowIfError(AudioFileOpenURL (sndFile, kAudioFileReadPermission, 0/*inFileTypeHint*/, &mAudioFile), "can't open file");

            UInt32 size = sizeof(mDataFormat);
            XThrowIfError(AudioFileGetProperty(mAudioFile, 
                                           kAudioFilePropertyDataFormat, &size, &mDataFormat), "couldn't get file's data format");
            mFilePath = CFStringCreateCopy(kCFAllocatorDefault, inFilePath);
        }
        SetupNewQueue();        
    }
    catch (CAXException e) {
        char buf[256];
        fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
    }
    if (sndFile)
        CFRelease(sndFile);
}

void AQPlayer::SetupNewQueue() 
{
    XThrowIfError(AudioQueueNewOutput(&mDataFormat, AQPlayer::AQBufferCallback, this, 
                                        CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &mQueue), "AudioQueueNew failed");
    UInt32 bufferByteSize;      
    // we need to calculate how many packets we read at a time, and how big a buffer we need
    // we base this on the size of the packets in the file and an approximate duration for each buffer
    // first check to see what the max size of a packet is - if it is bigger
    // than our allocation default size, that needs to become larger
    UInt32 maxPacketSize;
    UInt32 size = sizeof(maxPacketSize);
    XThrowIfError(AudioFileGetProperty(mAudioFile, 
                                       kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize), "couldn't get file's max packet size");

    // adjust buffer size to represent about a half second of audio based on this format
    CalculateBytesForTime (mDataFormat, maxPacketSize, kBufferDurationSeconds, &bufferByteSize, &mNumPacketsToRead);

        //printf ("Buffer Byte Size: %d, Num Packets to Read: %d\n", (int)bufferByteSize, (int)mNumPacketsToRead);

    // (2) If the file has a cookie, we should get it and set it on the AQ
    size = sizeof(UInt32);
    OSStatus result = AudioFileGetPropertyInfo (mAudioFile, kAudioFilePropertyMagicCookieData, &size, NULL);

    if (!result && size) {
        char* cookie = new char [size];     
        XThrowIfError (AudioFileGetProperty (mAudioFile, kAudioFilePropertyMagicCookieData, &size, cookie), "get cookie from file");
        XThrowIfError (AudioQueueSetProperty(mQueue, kAudioQueueProperty_MagicCookie, cookie, size), "set cookie on queue");
        delete [] cookie;
    }

    // channel layout?
    result = AudioFileGetPropertyInfo(mAudioFile, kAudioFilePropertyChannelLayout, &size, NULL);
    if (result == noErr && size > 0) {
        AudioChannelLayout *acl = (AudioChannelLayout *)malloc(size);
        XThrowIfError(AudioFileGetProperty(mAudioFile, kAudioFilePropertyChannelLayout, &size, acl), "get audio file's channel layout");
        XThrowIfError(AudioQueueSetProperty(mQueue, kAudioQueueProperty_ChannelLayout, acl, size), "set channel layout on queue");
        free(acl);
    }

    XThrowIfError(AudioQueueAddPropertyListener(mQueue, kAudioQueueProperty_IsRunning, isRunningProc, this), "adding property listener");

    bool isFormatVBR = (mDataFormat.mBytesPerPacket == 0 || mDataFormat.mFramesPerPacket == 0);
    for (int i = 0; i < kNumberBuffers; ++i) {
        XThrowIfError(AudioQueueAllocateBufferWithPacketDescriptions(mQueue, bufferByteSize, (isFormatVBR ? mNumPacketsToRead : 0), &mBuffers[i]), "AudioQueueAllocateBuffer failed");
    }   

    // set the volume of the queue
    XThrowIfError (AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, 1.0), "set queue volume");

    mIsInitialized = true;
}

void AQPlayer::DisposeQueue(Boolean inDisposeFile)
{
    if (mQueue)
    {
        AudioQueueDispose(mQueue, true);
        mQueue = NULL;
    }
    if (inDisposeFile)
    {
        if (mAudioFile)
        {       
            AudioFileClose(mAudioFile);
            mAudioFile = 0;
        }
        if (mFilePath)
        {
            CFRelease(mFilePath);
            mFilePath = NULL;
        }
    }
    mIsInitialized = false;
}
有人知道为什么每个函数在函数名之前都有这个::吗?我已经习惯了目标C,以前从未见过


提前感谢

嗯,我知道::是一个范围解析操作符……但这可能只是符号的一部分

操作符类似于。但它正在处理类型结构/类,而不是该类的对象实例


AQPlayer似乎是某种类型的类。若要访问该类的方法而不实际拥有对象,则要编写AQPosi::MultMyNo.< /P> < P>该代码看起来像C++,绝对不是C.</P>
<>::在C++中,令牌用于范围解析,以指定类或命名空间的成员。这里指定要定义的函数是AQPlayer类的成员函数。

谢谢!现在完全有道理了!虽然本质上是正确的,但在这种情况下并不成立。代码显然是C++,只需寻找构造函数和DESTRTCOR实现,这里所发生的只是AQPrPrReR中声明的C++类的定义。我假设它是C++,它是这样标记的,我对iPhone一无所知。他们对C++做出了一些改变吗?我的答案是错误的。对于一个非常通用的方法,你的答案是正确的,因此对学习者来说不是很好的描述。C没有::运算符,所以你应该从问题中删除标签。去掉了那个标签。