   SOLVED Problem with Ogg Vorbis playback/buffering in OpenAL
  I've spent the past few days writing a new audio engine for my game in OpenAL. I've spent almost the entire day today trying to get Vorbis Ogg files to playback properly in OpenAL and I'm totally stumped on why it's not working (wav sound plays back fine). I'm using this tutorial as my guide and my source code largely follows it.Here's the main function of my test program (C++):int32 main(int32 argc, char *argv[]) {AudioManager = GameAudio::Create();AUDIO_DEBUG = true;if (!AudioManager->Initialize()) {cerr << "ERROR: unable to initialize AudioManager" << endl;return -1;}MusicDescriptor md;if (!md.LoadMusic("Overture_Cinematique"))return -1;md.PlayMusic();uint32 i = 0;while (i < 500) {i++;AudioManager->Update();SDL_Delay(10);}md.FreeMusic();GameAudio::Destroy();return 0;}The important things here are: md.LoadMusic, md.PlayMusic, and AudioManager->Update. (Update is where the code aborts). Here is the load music code:filename = fname;reference_count = 1;file_handle = fopen(("music/" + filename + ".ogg").c_str(), "rb");if (file_handle == NULL) {cerr << "AUDIO ERROR: Could not open music file: music/" << filename << ".ogg" << endl;return false;}int32 result;result = ov_open(file_handle, &file_stream, NULL, 0);if (result < 0) {fclose(file_handle);cerr << "AUDIO ERROR: Failed to open Vorbig Ogg file: music/" << filename << ".ogg.  Error message: ";switch (result) {case OV_EREAD:cout << "A read from media returned an error." << endl;break;case OV_ENOTVORBIS:cout << "The bitstream is not Vorbis data." << endl;break;case OV_EVERSION:cout << "Vorbis version mismatch." << endl;break;case OV_EBADHEADER:cout << "Invalid Vorbis bitstream header." << endl;break;case OV_EFAULT:cout << "Internal logic fault (possible heap/stack corruption)" << endl;break;default:cout << "Unknown error." << endl;break;}return false;}file_info = ov_info(&file_stream, -1);file_comment = ov_comment(&file_stream, -1);if(file_info->channels == 1)format = AL_FORMAT_MONO16;elseformat = AL_FORMAT_STEREO16;alGenBuffers(2, buffers);return true;}The loading function passes okay. And so does the play function below:void MusicDescriptor::PlayMusic() {if (_Buffer == NULL) { // Can't play music without datareturn;}if (_Source == NULL) {_Source = AudioManager->_AcquireMusicSource();if (_Source == NULL) {return;}}ALenum state;alGetSourcei(_Source->source, AL_SOURCE_STATE, &state);if (state == AL_PLAYING) {return;}_Buffer->RefillBuffer(_Buffer->buffers[0]);_Buffer->RefillBuffer(_Buffer->buffers[1]);alSourceQueueBuffers(_Source->source, 2, _Buffer->buffers);alSourcePlay(_Source->source);}That works fine as well. The RefillBuffer function just fills a buffer with streaming music data. I've omitted the error checking int he code above, but I know it works. Finally here is the update function, which causes the problem (gives a segmentation fault)void AudioManager::Update() {if (Owner == NULL) { // If nothing owns the source, it certainly has no data to stream inreturn;}int32 num_processed;alGetSourcei(source, AL_BUFFERS_PROCESSED, &num_processed);while(num_processed-- > 0) {ALuint buff;alSourceUnqueueBuffers(source, 1, &buff); // Unqueues one of the buffers in the MusicBuffer objectOwner->_Buffer->RefillBuffer(buff);alSourceQueueBuffers(source, 1, &buff); // Requeues one of the buffers in the Musicbuffer object}}What fails is the call to alSourceUnqueueBuffers. But I have no idea why! I checked that the source was valid with alIsSource(source) in my debugging efforts and it was indeed a valid source. I'm just totally clueless as to what could be wrong. If you can see my mistake, please help me out because I've been working on this problem for too long already. [sad] Thanks![Edited by - Roots on January 6, 2006 1:55:35 AM]
  Correction, the line is failing on the Refill buffer function, not the alUnqueueBuffer function. I was doing a "cout << "message";" statement and don't include an endl at the end, it wont print the message because it wasn't flushing the buffer. The RefillBuffer function is below, and somewhere in there is the cause of the problem. I may be able to figure out what is wrong now. [smile]// Refills the specified buffer with more audio datavoid MusicBuffer::RefillBuffer(ALuint buff) {char data[MUSIC_BUFFER_SIZE];int32 size = 0;int32 bitstream;int32 result;while(size < MUSIC_BUFFER_SIZE) {// ov_read function args: OggVorbis_File, char* buffer, int buffer_length, endianness (1 = big, 0 = little),//    int data_size (bytes, 1 or 2), int signed (1 = signed, 0 = unsigned), int* bitstream_numberresult = ov_read(&file_stream, data + size, MUSIC_BUFFER_SIZE - size, 0, 2, 1, &bitstream);if (result > 0) {size += result;}else if (result == 0) { // Indicates EOFbreak;}else { // (result < 0) == errorif (AUDIO_DEBUG) cerr << "AUDIO ERROR: Failure while streaming music data into buffer. Error message: ";switch(result) {case OV_EREAD:if (AUDIO_DEBUG) cerr << "read error from ogg file." << endl;break;case OV_ENOTVORBIS:if (AUDIO_DEBUG) cerr << "music file does not contain vorbis data." << endl;break;case OV_EVERSION:if (AUDIO_DEBUG) cerr << "vorbis version mismatch." << endl;break;case OV_EBADHEADER:if (AUDIO_DEBUG) cerr << "invalid vorbis header." << endl;break;case OV_EFAULT:if (AUDIO_DEBUG) cerr << "internal logic fault (possibly heap/stack corruption)." << endl;break;case OV_EINVAL:if (AUDIO_DEBUG) cerr << "invalidation error." << endl;break;default:if (AUDIO_DEBUG) cerr << "unknown ogg error; error code: " << result << endl;break;}break;}}if(size == 0) { // No data was buffered, either because of an error or EOFreturn;}alBufferData(buff, format, data, size, file_info->rate);cout << "DEBUG: Successfully buffered data!" << endl;// Check for OpenAL errors here}Specifically, the segfault is occuring on the call to ov_read.;  Nevermind, I found the error! It was a strange problem with my source object pointing to the wrong buffer object, so it was trying to play data on a buffer that wasn't have supposed to exist in the first place. I don't know why, but everytime I post for help on these forums after spending forever trying to get something to work, I always end up solving it myself minutes later. Is this the power of GameDev.net? [lol]   ;  Glad we could solve it for you ;-)   