Changeset 7460 in orxonox.OLD for trunk/src/lib/sound/ogg_player.cc
- Timestamp:
- May 1, 2006, 12:30:34 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/sound/ogg_player.cc
r7314 r7460 32 32 #include "debug.h" 33 33 34 /** 35 * initializes an Ogg-player from a file 36 * @param fileName the file to load 37 */ 38 OggPlayer::OggPlayer(const std::string& fileName) 34 namespace OrxSound 39 35 { 40 this->setClassID(CL_SOUND_OGG_PLAYER, "OggPlayer"); 41 42 this->state = OggPlayer::None; 43 44 this->source = 0; 45 this->buffers[0] = 0; 46 this->buffers[1] = 0; 47 this->musicThreadID = NULL; 48 this->musicMutex = SDL_CreateMutex(); 49 50 if (!fileName.empty()) 51 { 52 if (this->open(fileName)) 53 this->setName(fileName); 54 } 55 56 } 57 58 /** 59 * @brief deletes the OggPlayer 60 */ 61 OggPlayer::~OggPlayer() 62 { 63 this->release(); 64 SDL_DestroyMutex(this->musicMutex); 65 } 66 67 /////////////// 68 // INTERFACE // 69 /////////////// 70 /** 71 * @brief opens a file for playback 72 * @param fileName the file to open 73 */ 74 bool OggPlayer::open(const std::string& fileName) 75 { 76 MutexLock(this->musicMutex); 77 // release old Ogg-File (if loaded) 78 if (this->state & OggPlayer::FileOpened) 79 this->release(); 80 81 // allocating Buffers 82 if (this->buffers[0] == 0) 83 alGenBuffers(2, this->buffers); 84 SoundEngine::checkError("Allocating Buffers", __LINE__); 85 if (this->buffers[0] != 0 && this->buffers[1] != 0) 86 state |= OggPlayer::BuffersAllocated; 87 else 88 { 89 PRINTF(2)("Unable to allocate al-Buffers\n"); 90 this->release(); 91 return false; 92 } 93 // allocating source 94 if (this->source == 0) 95 SoundEngine::getInstance()->popALSource(this->source); 96 if (this->source != 0) 97 state |= OggPlayer::SourceAllocated; 98 else 99 { 100 PRINTF(2)("No more Sources Availiable (maybe you should consider raising the source-count.)\n"); 101 this->release(); 102 return false; 103 } 104 105 // opening the FILE; 106 int result; 107 if(!(oggFile = fopen(fileName.c_str(), "rb"))) 108 { 109 PRINTF(2)("Could not open Ogg file."); 110 this->release(); 111 return false; 112 } 113 // reading the Stream. 114 if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0) 115 { 116 PRINTF(2)("Could not open Ogg stream. %s", getVorbisError(result)); 117 fclose(oggFile); 118 this->release(); 119 return false; 120 } 121 this->state |= OggPlayer::FileOpened; 122 123 // acquiring the vorbis-properties. 124 vorbisInfo = ov_info(&oggStream, -1); 125 vorbisComment = ov_comment(&oggStream, -1); 126 127 if(vorbisInfo->channels == 1) 128 format = AL_FORMAT_MONO16; 129 else 130 format = AL_FORMAT_STEREO16; 131 132 // setting the Source Properties. 133 alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0); 134 alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0); 135 alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0); 136 alSourcef (source, AL_ROLLOFF_FACTOR, 0.0 ); 137 alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE ); 138 alSourcef (source, AL_GAIN, SoundEngine::getInstance()->getMusicVolume()); 139 SoundEngine::checkError("OggPlayer::open()::SetSourceProperties", __LINE__); 140 141 // Set to State Stopped 142 this->state |= OggPlayer::Stopped; 143 return true; 144 } 145 146 147 /** 148 * @brief start Playing Music. 149 * @returns true on success false otherwise. 150 */ 151 bool OggPlayer::play() 152 { 153 if (!(this->state & OggPlayer::FileOpened)) 154 return false; 155 156 this->state &= ~(OggPlayer::Stopped | OggPlayer::Paused); 157 158 if (!this->playback()) 159 return false; 160 161 if (this->musicThreadID == NULL) 162 return ((this->musicThreadID = SDL_CreateThread(OggPlayer::musicThread, (void*)this)) != NULL); 163 return true; 164 } 165 166 /** 167 * @brief stop the OggPlayer from Playing. 168 */ 169 void OggPlayer::stop() 170 { 171 this->state &= ~(OggPlayer::Playing | OggPlayer::Paused); 172 this->state |= OggPlayer::Stopped; 173 174 this->suspend(); 175 this->rewind(); 176 } 177 178 /** 179 * @brief Pause the Playing. 180 */ 181 void OggPlayer::pause() 182 { 183 this->state &= ~OggPlayer::Playing; 184 185 if (!(this->state & OggPlayer::Stopped)) 186 this->state |= OggPlayer::Paused; 187 188 this->suspend(); 189 } 190 191 /** 192 * @brief rewind to the beginning, and play (if already playing) 193 */ 194 void OggPlayer::rewind() 195 { 196 this->jumpTo(0.0f); 197 } 198 199 /** 200 * @brief jump to Second timeCode in the MusicFile 201 * @param timeCode where to jump to. 202 */ 203 void OggPlayer::jumpTo(float timeCode) 204 { 205 206 if (this->state & OggPlayer::FileOpened) 207 { 208 SDL_mutexP(this->musicMutex); 209 ov_time_seek(&this->oggStream, timeCode); 210 SDL_mutexV(this->musicMutex); 211 } 212 } 213 214 /** 215 * @returns the Length of the Music in Seconds 216 */ 217 float OggPlayer::length() 218 { 219 if (this->state & OggPlayer::FileOpened) 220 return ov_time_total(&this->oggStream, -1); 221 else 222 return 0.0f; 223 } 224 225 226 /** 227 * @returns true if the file is playing 228 */ 229 bool OggPlayer::isPlaying() 230 { 231 if (!(this->state & OggPlayer::FileOpened)) 232 return false; 233 ALenum state; 234 235 alGetSourcei(this->source, AL_SOURCE_STATE, &state); 236 237 return (state == AL_PLAYING); 238 } 239 240 241 242 //////////////////////// 243 // INTERNAL FUNCTIONS // 244 //////////////////////// 245 /** 246 * @brief creates a Thread for Playing back the music even if the rest of the Engine is slow 247 * @param oggPlayer the OggPlayer to play back 248 * @returns -1 on error. 249 */ 250 int OggPlayer::musicThread(void* oggPlayer) 251 { 252 if (oggPlayer == NULL) 253 return -1; 254 OggPlayer* ogg = (OggPlayer*)oggPlayer; 255 256 PRINTF(4)("STARTIG AUDIO THREAD\n"); 257 while (ogg->state & OggPlayer::Playing) 258 { 259 SDL_mutexP(ogg->musicMutex); 260 ogg->update(); 261 SDL_mutexV(ogg->musicMutex); 262 SDL_Delay(1); 263 } 264 PRINTF(4)("End the AudioThread\n"); 265 } 266 267 268 /** 269 * @brief plays back the sound 270 * @return true if running, false otherwise 271 */ 272 bool OggPlayer::playback() 273 { 274 if (!(this->state & OggPlayer::FileOpened)) 275 return false; 276 277 if(this->state & OggPlayer::Playing) 278 return true; 279 this->state |= OggPlayer::Playing; 280 281 SDL_mutexP(this->musicMutex); 282 if(!this->stream(this->buffers[0]) || !this->stream(this->buffers[1])) 283 { 284 SDL_mutexV(this->musicMutex); 285 this->state &= ~OggPlayer::Playing; 286 return false; 287 } 288 289 alSourceQueueBuffers(this->source, 2, this->buffers); 290 if (DEBUG >= 3) 291 SoundEngine::checkError("OggPlayer::playback()::alSourceQueueBuffers", __LINE__); 292 293 alSourcePlay(this->source); 294 if (DEBUG >= 3) 295 SoundEngine::checkError("OggPlayer::playback()::alSourcePlay", __LINE__); 296 SDL_mutexV(this->musicMutex); 297 return true; 298 } 299 300 301 /** 302 * @brief waits for the AudioThread to be finished. 303 */ 304 void OggPlayer::suspend() 305 { 306 if (this->musicThreadID != NULL) 307 { 308 assert (!(this->state & Playing)); 309 SDL_WaitThread(this->musicThreadID, NULL); 310 this->musicThreadID = NULL; 311 } 312 if (this->state & OggPlayer::SourceAllocated) 313 { 314 alSourceStop(this->source); 315 alSourcei(this->source, AL_BUFFER, 0); 316 } 317 } 318 319 /** 320 * @brief updates the stream, this has to be done every few parts of a second, for sound-consistency 321 * @returns true, if the Sound is playing flawlessly 322 */ 323 bool OggPlayer::update() 324 { 325 int processed = 0; 326 bool active = true; 327 328 alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); 329 if (DEBUG >= 3) 330 SoundEngine::checkError("OggPlayer::update()::alGetSourceI", __LINE__); 331 332 while(processed--) 333 { 334 ALuint buffer; 335 336 alSourceUnqueueBuffers(source, 1, &buffer); 337 if (DEBUG >= 3) 338 SoundEngine::checkError("OggPlayer::update()::unqueue", __LINE__); 339 340 active = stream(buffer); 341 342 alSourceQueueBuffers(source, 1, &buffer); 343 if (DEBUG >= 3) 344 SoundEngine::checkError("OggPlayer::update()::queue", __LINE__); 345 } 346 347 return active; 348 } 349 350 /** 351 * @brief gets a new Stream from buffer 352 * @param buffer the buffer to get the stream from 353 * @return true, if everything worked as planed 354 */ 355 bool OggPlayer::stream(ALuint buffer) 356 { 357 if (unlikely(!(this->state & Playing))) 358 return false; 359 char pcm[OGG_PLAYER_BUFFER_SIZE]; 360 int size = 0; 361 int section; 362 int result; 363 364 while(size < OGG_PLAYER_BUFFER_SIZE) 365 { 366 result = ov_read(&this->oggStream, pcm + size, OGG_PLAYER_BUFFER_SIZE - size, 0, 2, 1, §ion); 367 368 if(result > 0) 369 size += result; 370 else if(result < 0) 371 throw getVorbisError(result); 372 else /* eof */ 373 ov_time_seek(&this->oggStream, 0.0); 374 } 375 376 if(size == 0) 377 return false; 378 379 alBufferData(buffer, format, pcm, size, vorbisInfo->rate); 380 if (DEBUG >= 3) 381 SoundEngine::checkError("OggPlayer::stream()::BUFFER", __LINE__); 382 383 return true; 384 } 385 386 387 /** 388 * @brief releases a stream 389 */ 390 void OggPlayer::release() 391 { 392 if (this->state & OggPlayer::SourceAllocated) 393 { 394 assert(alIsSource(this->source)); 395 if (this->state & OggPlayer::Playing); 396 { 397 // Kill the Music Thread. 398 this->state &= ~OggPlayer::Playing; 399 this->suspend(); 400 401 SoundEngine::checkError("OggPlayer::release()::alSourceStop", __LINE__); 402 } 403 empty(); 404 alSourcei(this->source, AL_BUFFER, 0); 405 SoundEngine::getInstance()->pushALSource(this->source); 36 /** 37 * initializes an Ogg-player from a file 38 * @param fileName the file to load 39 */ 40 OggPlayer::OggPlayer(const std::string& fileName) 41 { 42 this->setClassID(CL_SOUND_OGG_PLAYER, "OggPlayer"); 43 44 this->state = OggPlayer::None; 45 406 46 this->source = 0; 407 this->state &= ~SourceAllocated;408 }409 if (this->state & OggPlayer::BuffersAllocated)410 {411 assert (this->buffers[0] != 0 && this->buffers[1] != 0);412 alDeleteBuffers(2, buffers);413 SoundEngine::checkError("OggPlayer::release()::alDeleteBuffers", __LINE__);414 47 this->buffers[0] = 0; 415 48 this->buffers[1] = 0; 416 this->state &= ~OggPlayer::BuffersAllocated; 417 } 418 419 if (this->state & OggPlayer::FileOpened) 420 { 421 ov_clear(&oggStream); 422 this->state &= ~OggPlayer::FileOpened; 423 } 424 425 } 426 427 428 /** 429 * @brief empties the buffers 430 */ 431 void OggPlayer::empty() 432 { 433 int queued; 434 435 alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); 436 437 while(queued--) 438 { 439 ALuint buffer; 440 441 alSourceUnqueueBuffers(source, 1, &buffer); 442 SoundEngine::checkError("OggPlayer::empty()::unqueue Buffers", __LINE__); 443 } 444 } 445 446 447 ///////////////////// 448 // DEBUG FUNCTIONS // 449 ///////////////////// 450 /** 451 * displays some info about the ogg-file 452 */ 453 void OggPlayer::debug() const 454 { 455 cout 456 << "version " << vorbisInfo->version << "\n" 457 << "channels " << vorbisInfo->channels << "\n" 458 << "rate (hz) " << vorbisInfo->rate << "\n" 459 << "bitrate upper " << vorbisInfo->bitrate_upper << "\n" 460 << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n" 461 << "bitrate lower " << vorbisInfo->bitrate_lower << "\n" 462 << "bitrate window " << vorbisInfo->bitrate_window << "\n" 463 << "\n" 464 << "vendor " << vorbisComment->vendor << "\n"; 465 466 for(int i = 0; i < vorbisComment->comments; i++) 467 cout << " " << vorbisComment->user_comments[i] << "\n"; 468 469 cout << endl; 470 } 471 472 473 void OggPlayer::printState() const 474 { 475 PRINTF(0)("OggPlayer is in the following States: "); 476 if (this->state & OggPlayer::FileOpened) 477 PRINT(0)("FileOpened "); 478 if (this->state & OggPlayer::SourceAllocated) 479 PRINT(0)("SourceAllocated "); 480 if (this->state & OggPlayer::BuffersAllocated) 481 PRINT(0)("BuffersAllocated "); 482 if (this->state & OggPlayer::Stopped) 483 PRINT(0)("Stopped "); 484 if (this->state & OggPlayer::Playing) 485 PRINT(0)("Playing "); 486 if (this->state & OggPlayer::Paused) 487 PRINT(0)("Paused "); 488 if (this->state & OggPlayer::Error) 489 PRINT(0)("Error "); 490 PRINT(0)("\n"); 491 } 492 493 /** 494 * returns errors 495 * @param code the error-code 496 * @return the error as a String 497 */ 498 const char* OggPlayer::getVorbisError(int code) 499 { 500 switch(code) 501 { 49 this->musicThreadID = NULL; 50 this->musicMutex = SDL_CreateMutex(); 51 52 if (!fileName.empty()) 53 { 54 if (this->open(fileName)) 55 this->setName(fileName); 56 } 57 58 } 59 60 /** 61 * @brief deletes the OggPlayer 62 */ 63 OggPlayer::~OggPlayer() 64 { 65 this->release(); 66 SDL_DestroyMutex(this->musicMutex); 67 } 68 69 /////////////// 70 // INTERFACE // 71 /////////////// 72 /** 73 * @brief opens a file for playback 74 * @param fileName the file to open 75 */ 76 bool OggPlayer::open(const std::string& fileName) 77 { 78 MutexLock(this->musicMutex); 79 // release old Ogg-File (if loaded) 80 if (this->state & OggPlayer::FileOpened) 81 this->release(); 82 83 // allocating Buffers 84 if (this->buffers[0] == 0) 85 alGenBuffers(2, this->buffers); 86 SoundEngine::checkError("Allocating Buffers", __LINE__); 87 if (this->buffers[0] != 0 && this->buffers[1] != 0) 88 state |= OggPlayer::BuffersAllocated; 89 else 90 { 91 PRINTF(2)("Unable to allocate al-Buffers\n"); 92 this->release(); 93 return false; 94 } 95 // allocating source 96 if (this->source == 0) 97 SoundEngine::getInstance()->popALSource(this->source); 98 if (this->source != 0) 99 state |= OggPlayer::SourceAllocated; 100 else 101 { 102 PRINTF(2)("No more Sources Availiable (maybe you should consider raising the source-count.)\n"); 103 this->release(); 104 return false; 105 } 106 107 // opening the FILE; 108 int result; 109 if(!(oggFile = fopen(fileName.c_str(), "rb"))) 110 { 111 PRINTF(2)("Could not open Ogg file."); 112 this->release(); 113 return false; 114 } 115 // reading the Stream. 116 if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0) 117 { 118 PRINTF(2)("Could not open Ogg stream. %s", getVorbisError(result)); 119 fclose(oggFile); 120 this->release(); 121 return false; 122 } 123 this->state |= OggPlayer::FileOpened; 124 125 // acquiring the vorbis-properties. 126 vorbisInfo = ov_info(&oggStream, -1); 127 vorbisComment = ov_comment(&oggStream, -1); 128 129 if(vorbisInfo->channels == 1) 130 format = AL_FORMAT_MONO16; 131 else 132 format = AL_FORMAT_STEREO16; 133 134 // setting the Source Properties. 135 alSource3f(source, AL_POSITION, 0.0, 0.0, 0.0); 136 alSource3f(source, AL_VELOCITY, 0.0, 0.0, 0.0); 137 alSource3f(source, AL_DIRECTION, 0.0, 0.0, 0.0); 138 alSourcef (source, AL_ROLLOFF_FACTOR, 0.0 ); 139 alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE ); 140 alSourcef (source, AL_GAIN, SoundEngine::getInstance()->getMusicVolume()); 141 SoundEngine::checkError("OggPlayer::open()::SetSourceProperties", __LINE__); 142 143 // Set to State Stopped 144 this->state |= OggPlayer::Stopped; 145 return true; 146 } 147 148 149 /** 150 * @brief start Playing Music. 151 * @returns true on success false otherwise. 152 */ 153 bool OggPlayer::play() 154 { 155 if (!(this->state & OggPlayer::FileOpened)) 156 return false; 157 158 this->state &= ~(OggPlayer::Stopped | OggPlayer::Paused); 159 160 if (!this->playback()) 161 return false; 162 163 if (this->musicThreadID == NULL) 164 return ((this->musicThreadID = SDL_CreateThread(OggPlayer::musicThread, (void*)this)) != NULL); 165 return true; 166 } 167 168 /** 169 * @brief stop the OggPlayer from Playing. 170 */ 171 void OggPlayer::stop() 172 { 173 this->state &= ~(OggPlayer::Playing | OggPlayer::Paused); 174 this->state |= OggPlayer::Stopped; 175 176 this->suspend(); 177 this->rewind(); 178 } 179 180 /** 181 * @brief Pause the Playing. 182 */ 183 void OggPlayer::pause() 184 { 185 this->state &= ~OggPlayer::Playing; 186 187 if (!(this->state & OggPlayer::Stopped)) 188 this->state |= OggPlayer::Paused; 189 190 this->suspend(); 191 } 192 193 /** 194 * @brief rewind to the beginning, and play (if already playing) 195 */ 196 void OggPlayer::rewind() 197 { 198 this->jumpTo(0.0f); 199 } 200 201 /** 202 * @brief jump to Second timeCode in the MusicFile 203 * @param timeCode where to jump to. 204 */ 205 void OggPlayer::jumpTo(float timeCode) 206 { 207 208 if (this->state & OggPlayer::FileOpened) 209 { 210 SDL_mutexP(this->musicMutex); 211 ov_time_seek(&this->oggStream, timeCode); 212 SDL_mutexV(this->musicMutex); 213 } 214 } 215 216 /** 217 * @returns the Length of the Music in Seconds 218 */ 219 float OggPlayer::length() 220 { 221 if (this->state & OggPlayer::FileOpened) 222 return ov_time_total(&this->oggStream, -1); 223 else 224 return 0.0f; 225 } 226 227 228 /** 229 * @returns true if the file is playing 230 */ 231 bool OggPlayer::isPlaying() 232 { 233 if (!(this->state & OggPlayer::FileOpened)) 234 return false; 235 ALenum state; 236 237 alGetSourcei(this->source, AL_SOURCE_STATE, &state); 238 239 return (state == AL_PLAYING); 240 } 241 242 243 244 //////////////////////// 245 // INTERNAL FUNCTIONS // 246 //////////////////////// 247 /** 248 * @brief creates a Thread for Playing back the music even if the rest of the Engine is slow 249 * @param oggPlayer the OggPlayer to play back 250 * @returns -1 on error. 251 */ 252 int OggPlayer::musicThread(void* oggPlayer) 253 { 254 if (oggPlayer == NULL) 255 return -1; 256 OggPlayer* ogg = (OggPlayer*)oggPlayer; 257 258 PRINTF(4)("STARTIG AUDIO THREAD\n"); 259 while (ogg->state & OggPlayer::Playing) 260 { 261 SDL_mutexP(ogg->musicMutex); 262 ogg->update(); 263 SDL_mutexV(ogg->musicMutex); 264 SDL_Delay(1); 265 } 266 PRINTF(4)("End the AudioThread\n"); 267 } 268 269 270 /** 271 * @brief plays back the sound 272 * @return true if running, false otherwise 273 */ 274 bool OggPlayer::playback() 275 { 276 if (!(this->state & OggPlayer::FileOpened)) 277 return false; 278 279 if(this->state & OggPlayer::Playing) 280 return true; 281 this->state |= OggPlayer::Playing; 282 283 SDL_mutexP(this->musicMutex); 284 if(!this->stream(this->buffers[0]) || !this->stream(this->buffers[1])) 285 { 286 SDL_mutexV(this->musicMutex); 287 this->state &= ~OggPlayer::Playing; 288 return false; 289 } 290 291 alSourceQueueBuffers(this->source, 2, this->buffers); 292 if (DEBUG >= 3) 293 SoundEngine::checkError("OggPlayer::playback()::alSourceQueueBuffers", __LINE__); 294 295 alSourcePlay(this->source); 296 if (DEBUG >= 3) 297 SoundEngine::checkError("OggPlayer::playback()::alSourcePlay", __LINE__); 298 SDL_mutexV(this->musicMutex); 299 return true; 300 } 301 302 303 /** 304 * @brief waits for the AudioThread to be finished. 305 */ 306 void OggPlayer::suspend() 307 { 308 if (this->musicThreadID != NULL) 309 { 310 assert (!(this->state & Playing)); 311 SDL_WaitThread(this->musicThreadID, NULL); 312 this->musicThreadID = NULL; 313 } 314 if (this->state & OggPlayer::SourceAllocated) 315 { 316 alSourceStop(this->source); 317 alSourcei(this->source, AL_BUFFER, 0); 318 } 319 } 320 321 /** 322 * @brief updates the stream, this has to be done every few parts of a second, for sound-consistency 323 * @returns true, if the Sound is playing flawlessly 324 */ 325 bool OggPlayer::update() 326 { 327 int processed = 0; 328 bool active = true; 329 330 alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); 331 if (DEBUG >= 3) 332 SoundEngine::checkError("OggPlayer::update()::alGetSourceI", __LINE__); 333 334 while(processed--) 335 { 336 ALuint buffer; 337 338 alSourceUnqueueBuffers(source, 1, &buffer); 339 if (DEBUG >= 3) 340 SoundEngine::checkError("OggPlayer::update()::unqueue", __LINE__); 341 342 active = stream(buffer); 343 344 alSourceQueueBuffers(source, 1, &buffer); 345 if (DEBUG >= 3) 346 SoundEngine::checkError("OggPlayer::update()::queue", __LINE__); 347 } 348 349 return active; 350 } 351 352 /** 353 * @brief gets a new Stream from buffer 354 * @param buffer the buffer to get the stream from 355 * @return true, if everything worked as planed 356 */ 357 bool OggPlayer::stream(ALuint buffer) 358 { 359 if (unlikely(!(this->state & Playing))) 360 return false; 361 char pcm[OGG_PLAYER_BUFFER_SIZE]; 362 int size = 0; 363 int section; 364 int result; 365 366 while(size < OGG_PLAYER_BUFFER_SIZE) 367 { 368 result = ov_read(&this->oggStream, pcm + size, OGG_PLAYER_BUFFER_SIZE - size, 0, 2, 1, §ion); 369 370 if(result > 0) 371 size += result; 372 else if(result < 0) 373 throw getVorbisError(result); 374 else /* eof */ 375 ov_time_seek(&this->oggStream, 0.0); 376 } 377 378 if(size == 0) 379 return false; 380 381 alBufferData(buffer, format, pcm, size, vorbisInfo->rate); 382 if (DEBUG >= 3) 383 SoundEngine::checkError("OggPlayer::stream()::BUFFER", __LINE__); 384 385 return true; 386 } 387 388 389 /** 390 * @brief releases a stream 391 */ 392 void OggPlayer::release() 393 { 394 if (this->state & OggPlayer::SourceAllocated) 395 { 396 assert(alIsSource(this->source)); 397 if (this->state & OggPlayer::Playing); 398 { 399 // Kill the Music Thread. 400 this->state &= ~OggPlayer::Playing; 401 this->suspend(); 402 403 SoundEngine::checkError("OggPlayer::release()::alSourceStop", __LINE__); 404 } 405 empty(); 406 alSourcei(this->source, AL_BUFFER, 0); 407 SoundEngine::getInstance()->pushALSource(this->source); 408 this->source = 0; 409 this->state &= ~SourceAllocated; 410 } 411 if (this->state & OggPlayer::BuffersAllocated) 412 { 413 assert (this->buffers[0] != 0 && this->buffers[1] != 0); 414 alDeleteBuffers(2, buffers); 415 SoundEngine::checkError("OggPlayer::release()::alDeleteBuffers", __LINE__); 416 this->buffers[0] = 0; 417 this->buffers[1] = 0; 418 this->state &= ~OggPlayer::BuffersAllocated; 419 } 420 421 if (this->state & OggPlayer::FileOpened) 422 { 423 ov_clear(&oggStream); 424 this->state &= ~OggPlayer::FileOpened; 425 } 426 427 } 428 429 430 /** 431 * @brief empties the buffers 432 */ 433 void OggPlayer::empty() 434 { 435 int queued; 436 437 alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); 438 439 while(queued--) 440 { 441 ALuint buffer; 442 443 alSourceUnqueueBuffers(source, 1, &buffer); 444 SoundEngine::checkError("OggPlayer::empty()::unqueue Buffers", __LINE__); 445 } 446 } 447 448 449 ///////////////////// 450 // DEBUG FUNCTIONS // 451 ///////////////////// 452 /** 453 * displays some info about the ogg-file 454 */ 455 void OggPlayer::debug() const 456 { 457 std::cout 458 << "version " << vorbisInfo->version << "\n" 459 << "channels " << vorbisInfo->channels << "\n" 460 << "rate (hz) " << vorbisInfo->rate << "\n" 461 << "bitrate upper " << vorbisInfo->bitrate_upper << "\n" 462 << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n" 463 << "bitrate lower " << vorbisInfo->bitrate_lower << "\n" 464 << "bitrate window " << vorbisInfo->bitrate_window << "\n" 465 << "\n" 466 << "vendor " << vorbisComment->vendor << "\n"; 467 468 for(int i = 0; i < vorbisComment->comments; i++) 469 std::cout << " " << vorbisComment->user_comments[i] << "\n"; 470 471 std::cout << std::endl; 472 } 473 474 475 void OggPlayer::printState() const 476 { 477 PRINTF(0)("OggPlayer is in the following States: "); 478 if (this->state & OggPlayer::FileOpened) 479 PRINT(0)("FileOpened "); 480 if (this->state & OggPlayer::SourceAllocated) 481 PRINT(0)("SourceAllocated "); 482 if (this->state & OggPlayer::BuffersAllocated) 483 PRINT(0)("BuffersAllocated "); 484 if (this->state & OggPlayer::Stopped) 485 PRINT(0)("Stopped "); 486 if (this->state & OggPlayer::Playing) 487 PRINT(0)("Playing "); 488 if (this->state & OggPlayer::Paused) 489 PRINT(0)("Paused "); 490 if (this->state & OggPlayer::Error) 491 PRINT(0)("Error "); 492 PRINT(0)("\n"); 493 } 494 495 /** 496 * returns errors 497 * @param code the error-code 498 * @return the error as a String 499 */ 500 const char* OggPlayer::getVorbisError(int code) 501 { 502 switch(code) 503 { 502 504 case OV_EREAD: 503 505 return ("Read from media."); … … 512 514 default: 513 515 return ("Unknown Ogg error."); 514 } 516 } 517 } 518 515 519 } 516
Note: See TracChangeset
for help on using the changeset viewer.