【问题标题】:openAL streaming & interruptionsopenAL 流媒体和中断
【发布时间】:2011-01-14 00:26:29
【问题描述】:

我制作了一个使用 OpenAL 播放许多声音的 iphone 应用程序。 这些声音在 mp3 中,非常重(超过 1 百万),我将它们流式传输(每个声音 2 个缓冲区)以使用更少的内存。 为了管理中断,我使用以下代码:

在 OpenALSupport.c 文件中:

  //used to disable openAL during a call
    void openALInterruptionListener ( void   *inClientData, UInt32 inInterruptionState) 
    {
        if (inInterruptionState == kAudioSessionBeginInterruption) 
        {
            alcMakeContextCurrent (NULL);
        }
    }

    //used to restore openAL after a call
    void restoreOpenAL(void* a_context)
    {
        alcMakeContextCurrent(a_context);
    }

在我的 SoundManager.m 文件中:

 - (void) restoreOpenAL
    {
        restoreOpenAL(mContext);
    }

    //OPENAL initialization
    - (bool) initOpenAL
    {   
        // Initialization
        mDevice = alcOpenDevice(NULL);
        if (mDevice) {
    ...

            // use the device to make a context
            mContext=alcCreateContext(mDevice,NULL);
            // set my context to the currently active one
            alcMakeContextCurrent(mContext);

            AudioSessionInitialize (NULL, NULL, openALInterruptionListener, mContext);

            NSError *activationError = nil;
            [[AVAudioSession sharedInstance] setActive: YES error: &activationError];

            NSError *setCategoryError = nil;

            [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: &setCategoryError];

            ...
    }

最后在我的 AppDelegate 中:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [[CSoundManager getInstance] restoreOpenAL];
    ...
}

使用此方法,通话后声音会返回,但流似乎是随机播放的。 是否有特定的方法来管理流声音的中断?我没有找到任何关于此的文章。

感谢您的帮助。

【问题讨论】:

    标签: iphone streaming openal interrupt-handling


    【解决方案1】:

    好的,我回答我自己的问题。

    我通过管理流媒体方法的错误解决了这个问题:

    - (void) updateStream
    {
    ALint processed;    
    alGetSourcei(sourceID, AL_BUFFERS_PROCESSED, &processed);
    
    while(processed--)
    {
        oldPosition = position;
    
        NSUInteger buffer;
    
        alSourceUnqueueBuffers(sourceID, 1, &buffer);
    
        ////////////////////
        //code freshly added
        ALint err = alGetError();
        if (err != 0) 
        {
            NSLog(@"Error Calling alSourceUnQueueBuffers: %d",err);
            processed++;
            //restore old position for the next buffer
            position = oldPosition;
            usleep(10000);
            continue;
        }
        ////////////////////    
    
        [self stream:buffer];
    
        alSourceQueueBuffers(sourceID, 1, &buffer);
    
        ////////////////////
        //code freshly added
        err = alGetError();
        if (err != 0) 
        {
            NSLog(@"Error Calling alSourceQueueBuffers: %d",err);
            processed++;
            usleep(10000);
            //restore old position for the next buffer 
            position = oldPosition;
        }
        ///////////////////
    }
    

    }

    【讨论】:

    • 总体思路很有帮助,谢谢。但是在其中一种情况下,位置/旧位置分配不是交换了吗?
    • 现在是旧代码,我不再使用它了。但不,我不交换任何任务。如果你愿意,我可以把全班都发给你。
    • 啊,我没有注意到顶部的第一个 oldPosition = 位置分配。现在一切都清楚了。谢谢!
    猜你喜欢
    • 2017-09-16
    • 2012-05-09
    • 1970-01-01
    • 2012-06-07
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2016-08-30
    相关资源
    最近更新 更多