openAL потоковое вещание и прерывания - PullRequest
4 голосов
/ 13 января 2011

Я сделал приложение для iPhone, которое использует OpenAL для воспроизведения множества звуков. Эти звуки в формате 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];
    ...
}

При использовании этого метода звуки возвращаются после вызова, но потоки воспроизводятся в случайном порядке. Есть ли конкретный способ управления прерыванием потоковыми звуками? Я не нахожу статьи об этом.

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 13 января 2011

Хорошо, я отвечаю на свой вопрос.

Я решил проблему, исправив ошибку в методе потоковой передачи:

- (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;
    }
    ///////////////////
}

}

...