2012-05-14 89 views
0

everyone,我在使用OpenAL Libaray時遇到了關於API-- alSourceUnqueueBuffers的問題。OpenAL alSourceUnqueueBuffers&alSourceUnqueueBuffers

我的問題如下:

1.I播放PCM-音樂雖然流機制。

2.應用程序可以使用alSourceQueueBuffers排隊一個或多個緩衝區名稱。

  1. 當緩衝區已被處理。我想在我的函數中填充新的音頻數據:getSourceState。但是當我使用OpenAL alSourceUnqueueBuffers的API時。它會返回一個錯誤 --- AL_INVALID_OPERATION。我將其作爲關於OpenAL的文檔來完成。 所以我測試了一種方法來解決這個問題。我在api alSourceUnqueueBuffers之前使用了alSourceStop(source),在使用alSourcePlay(source)之後,我填充了新的數據,但是alBufferData & alSourceQueueBuffers。但它很糟糕。因爲它打破了音樂。

誰能幫我找到這個問題?

和哪裏我可以找到更多關於openAL的信息和方法?

我在等你的幫助。感謝大家。

,所以我的代碼如下:

.H:

@interface myPlayback : NSObject 
    { 
    ALuint     source; 
    ALuint    * buffers; 
    ALCcontext*    context; 
    ALCdevice*    device; 
    unsigned long long  offset; 
    ALenum     m_format; 
    ALsizei     m_freq; 
    void*     data; 
    } 

@end 

.M

- (void)initOpenAL 
    { 
    ALenum   error; 

    // Create a new OpenAL Device 
    // Pass NULL to specify the system’s default output device 
    device = alcOpenDevice(NULL); 
    if (device != NULL) 
    { 
     // Create a new OpenAL Context 
     // The new context will render to the OpenAL Device just created 
     context = alcCreateContext(device, 0); 
     if (context != NULL) 
     { 
      // Make the new context the Current OpenAL Context 
      alcMakeContextCurrent(context); 

      // Create some OpenAL Buffer Objects 

      buffers = (ALuint*)malloc(sizeof(ALuint) * 5); 
      alGenBuffers(5, buffers); 
      if((error = alGetError()) != AL_NO_ERROR) { 
       NSLog(@"Error Generating Buffers: %x", error); 
       exit(1); 
      } 

      // Create some OpenAL Source Objects 
      alGenSources(1, &source); 
      if(alGetError() != AL_NO_ERROR) 
      { 
       NSLog(@"Error generating sources! %x\n", error); 
       exit(1); 
      } 

     } 
    } 
    // clear any errors 
    alGetError(); 

    [self initBuffer]; 
     [self initSource]; 
} 

    - (void) initBuffer 
    { 
    ALenum error = AL_NO_ERROR; 
    ALenum format; 
    ALsizei size; 
    ALsizei freq; 

    NSBundle*    bundle = [NSBundle mainBundle]; 

    // get some audio data from a wave file 
    CFURLRef fileURL = (CFURLRef)[[NSURL fileURLWithPath:[bundle pathForResource:@"4" ofType:@"caf"]] retain]; 

    if (fileURL) 
    { 
     data = MyGetOpenALAudioData(fileURL, &size, &format, &freq); 
     CFRelease(fileURL); 
     m_freq = freq; 
     m_format = format; 
     if((error = alGetError()) != AL_NO_ERROR) { 
      NSLog(@"error loading sound: %x\n", error); 
      exit(1); 
     } 

     alBufferData(buffers[0], format, data, READ_SIZE , freq); 
     offset += READ_SIZE; 
     alBufferData(buffers[1], format, data + offset, READ_SIZE, freq); 
     offset += READ_SIZE; 
     alBufferData(buffers[2], format, data + offset, READ_SIZE, freq); 
     offset += READ_SIZE; 
     alBufferData(buffers[3], format, data + offset, READ_SIZE, freq); 
     offset += READ_SIZE; 
     alBufferData(buffers[4], format, data + offset, READ_SIZE, freq); 
     offset += READ_SIZE; 

     if((error = alGetError()) != AL_NO_ERROR) { 
      NSLog(@"error attaching audio to buffer: %x\n", error); 
     }  
    } 
    else 
     NSLog(@"Could not find file!\n"); 
} 

    - (void) initSource 
    { 
    ALenum error = AL_NO_ERROR; 
    alGetError(); // Clear the error 

    // Turn Looping ON 
    alSourcei(source, AL_LOOPING, AL_TRUE); 

    // Set Source Position 
    float sourcePosAL[] = {sourcePos.x, kDefaultDistance, sourcePos.y}; 
    alSourcefv(source, AL_POSITION, sourcePosAL); 

    // Set Source Reference Distance 
    alSourcef(source, AL_REFERENCE_DISTANCE, 50.0f); 

    alSourceQueueBuffers(source, 5, buffers); 

    if((error = alGetError()) != AL_NO_ERROR) { 
     NSLog(@"Error attaching buffer to source: %x\n", error); 
     exit(1); 
    } 
} 





    - (void)startSound 
     { 
     ALenum error; 

     NSLog(@"Start!\n"); 
     // Begin playing our source file 
     alSourcePlay(source); 
     if((error = alGetError()) != AL_NO_ERROR) { 
      NSLog(@"error starting source: %x\n", error); 
     } else { 
      // Mark our state as playing (the view looks at this) 
      self.isPlaying = YES; 
     } 

     while (1) { 
      [self getSourceState]; 
     } 
} 
    -(void)getSourceState 
    { 
    int queued; 
    int processed; 
    int state; 
    alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); 
    alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); 
    alGetSourcei(source, AL_SOURCE_STATE, &state); 
    NSLog(@"%d", queued); 
    NSLog(@"%d", processed); 

    NSLog(@"==================================="); 

    while (processed > 0) { 
     for (int i = 0; i < processed; ++i) { 
      ALuint buf; 
      alGetError(); 
    //   alSourceStop(source); 
      ALenum y = alGetError(); 
      NSLog(@"%d", y); 
      alSourceUnqueueBuffers(source, 1, &buf); 
      ALenum i = alGetError(); 
      NSLog(@"%d", i); 
      processed --; 
      alBufferData(buf, m_format, data + offset, READ_SIZE, m_freq); 
      ALenum j = alGetError(); 
      NSLog(@"%d", j); 
      alSourceQueueBuffers(source, 1, &buf); 
      ALenum k = alGetError(); 
      NSLog(@"%d", k); 
      offset += READ_SIZE; 
//   alSourcePlay(source); 
     } 
    } 

// [self getSourceState]; 
} 

回答

0

,我發現這個問題的原因。

我打開循環ON的原因:alSourcei(source,AL_LOOPING,AL_TRUE);

如果你設置了這個,當源處理一個緩衝區時,你想要填充新的數據或從源中刪除緩衝區。你會得到錯誤。