SoundMgr.cpp

Go to the documentation of this file.
00001 /*
00002  * SoundMgr.cpp
00003  *
00004  *  Created on: Oct 30, 2013
00005  *      Author: sushil
00006  */
00007 
00008 #include <SoundMgr.h>
00009 
00010 using namespace OgreSND;
00011 
00012 
00013 SoundMgr::SoundMgr(OgreGFX::GraphicsInteractionManager *gim){
00014         this->gim = gim;
00015 
00016 }
00017 
00018 SoundMgr::~SoundMgr(){
00019 
00020         std::cout << "Deleting Sound Manager" << std::endl;
00021 
00022 
00023         //Destroy sounds
00024         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00025                 if(alIsSource(this->sourceInfo[i].source)){
00026                         alDeleteSources(1, &this->sourceInfo[i].source);
00027                 }
00028         }
00029 
00030         //Destroy buffers
00031         for(int i = 0; i < OgreSND::maxAudioBuffers; i++){
00032                 if(alIsBuffer(this->bufferInfo[i].buffer)){
00033                         alDeleteBuffers(1, &this->bufferInfo[i].buffer);
00034                 }
00035         }
00036 
00037         int ret;
00038         ret = alcMakeContextCurrent(NULL);
00039         if (!ret) {
00040                 std::cerr << "Null current context" << std::endl;
00041         }
00042         alcDestroyContext(context);
00043         //printError("Destroy Context");
00044 
00045         //close device
00046         alcCloseDevice(device);
00047         //printError("Device close");
00048         std::cout << "Bye audio. ....   Sounds good, bye" << std::endl;
00049 }
00050 
00051 void SoundMgr::initialize(void){
00052         this->device = alcOpenDevice(NULL);
00053         if(!device){
00054                 std::cerr << "Sound ERROR: Bye, could not open default sound device" << std::endl;
00055         }
00056         alGetError();
00057         this->context = alcCreateContext(this->device, NULL);
00058         if (!alcMakeContextCurrent(this->context)) {
00059                 std::cerr << "Sound ERROR: Cannot make default context" << std::endl;
00060         }
00061         //this->buffersInfo.buffersInUseCount = 0;
00062         for(int i = 0; i < OgreSND::maxAudioBuffers; i++){
00063                 this->bufferInfo[i].buffer = i+1; // this is because openAl returns true for alIsBuffer(0) no matter what!
00064                 //I'm also using bufferFilename == "" to check if the buffer is in use.
00065                 this->bufferInfo[i].bufferFilename = "";
00066         }
00067 
00068         //this->sourcesInfo.sourcesInUseCount = 0;
00069         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00070                 this->sourceInfo[i].source = 0;
00071                 this->sourceInfo[i].inUse = false;
00072                 this->sourceDictionary.push_back("");
00073         }
00074 
00075         //alGenBuffers(OgreSND::maxAudioBuffers, this->buffersInfo.buffers);
00076         //printError("Generating buffers");
00077 
00078         //alGenSources(OgreSND::maxAudioSources, this->sourcesInfo.sources);
00079         //printError("Generating sources");
00080 
00081         //syncListenerToCamera(); //setup listener
00082         
00083         isEnabled = true;
00084         
00085         //initialize vectors
00086         for (int i = 0; i < FastEcslent::NENTITYTYPES; i++){
00087             for (int j = 0; j < soundPerEnt; j++){
00088                 this->battleSoundsDictionary[i][j] = -1;
00089                 this->creationSoundsDictionary[i][j] = -1;
00090                 this->selectionSoundsDictionary[i][j] = -1;
00091             }
00092         }
00093 
00094 
00095         unsigned int sid;
00096         //background music
00097         std::string filename = "data/watercraft/sounds/backgroundMusic.wav";
00098         if (this->reserveAudio(filename, true, sid)){
00099                 backgroundMusicSource = sourceInfo[sid].source;
00100                 this->loadStartBackground();
00101         }
00102         
00103         initWatercraftSounds();
00104   
00105         filename = "data/watercraft/sounds/explosion.wav";
00106         //default explosion sound for all entities
00107         if (this->reserveAudio(filename, false, sid)){
00108             battleSoundSource = sourceInfo[sid].source;
00109             alSourcei(this->battleSoundSource, AL_REFERENCE_DISTANCE, 2000.0f);
00110             alSourcei(this->battleSoundSource, AL_MAX_DISTANCE, 8000.0f);
00111         }
00112 
00113         return;
00114 
00115 }
00116 
00117 bool SoundMgr::initWatercraftSounds(){
00118         //registering all sounds
00119         std::string selectionFilename = "data/watercraft/sounds/takeYourOrder.wav";
00120         std::string selection2Filename = "data/watercraft/sounds/GoodDay.wav";
00121         std::string createShipFilename = "data/watercraft/sounds/boatMoving.wav";
00122         std::string createBuildingFilename = "data/watercraft/sounds/clong.wav";
00123         for (int i = 0; i < FastEcslent::NENTITYTYPES; i++){
00124             FastEcslent::EntityType et = static_cast<FastEcslent::EntityType>(i);
00125             //this->registerBattleSound(et, battleFilename);
00126             if (isEntityShip(et)){
00127                 if (et == FastEcslent::MARINE){ //marine has 2 different selection sounds and chooses randomly. just to illustrate.
00128                         this->registerSelection(et, selectionFilename);
00129                         this->registerSelection(et, selection2Filename);
00130                 }
00131                 else{
00132                         this->registerSelection(et, selectionFilename);
00133                 }
00134                 this->registerCreate(et, createShipFilename);
00135             }
00136             else{
00137                 //no selection sound for buildings right now
00138                 this->registerCreate(et, createBuildingFilename);
00139             }
00140         }
00141         
00142         return true;
00143 }
00144 
00145 bool SoundMgr::isEntityShip(FastEcslent::EntityType et){
00146     if (et < 7)
00147         return true;
00148     else
00149         return false;
00150 }
00151 
00152 void SoundMgr::enable(){
00153     isEnabled = true;
00154     resumeBackground();
00155 }
00156 
00157 void SoundMgr::disable(){
00158     isEnabled = false;
00159     stopAllAudio();
00160     stopBackground();
00161 }
00162 
00163 void SoundMgr::syncListenerToCamera(){
00164         //position from camera scene node
00165         Ogre::Vector3 cameraPosition = gim->uiMgr->cameraMgr->cameraNode->getPosition();
00166         this->position[0] = cameraPosition.x;
00167         this->position[1] = cameraPosition.y;
00168         this->position[2] = cameraPosition.z;
00169         alListener3f(AL_POSITION, cameraPosition.x, cameraPosition.y, cameraPosition.z);
00170         printError("Cannot set listener position");
00171 
00172         Ogre::Vector3 cameraVelocity = gim->uiMgr->cameraMgr->velocity; // not set by graphics
00173         this->velocity[0] = 0;
00174         this->velocity[1] = 0;
00175         this->velocity[2] = 0;
00176         alListener3f(AL_VELOCITY, 0, 0, 0); // or we will use
00177         //alListener3f(AL_VELOCITY, cameraVelocity.x, cameraVelocity.y, cameraVelocity.z);// Don't use both:-)
00178         printError("Cannot set listener velocity");
00179 
00180         //need to set orientation from camera scene node
00181         Ogre::Quaternion q = gim->uiMgr->cameraMgr->cameraNode->getOrientation();
00182         Ogre::Vector3 vDirection = q.zAxis();
00183         Ogre::Vector3 vUp = q.yAxis();
00184 
00185         this->orientation[0] = -vDirection.x;
00186         this->orientation[1] = -vDirection.y;
00187         this->orientation[2] = -vDirection.z;
00188         this->orientation[3] = vUp.x;
00189         this->orientation[4] = vUp.y;
00190         this->orientation[5] = vUp.z;
00191 
00192         alListenerfv(AL_ORIENTATION, this->orientation);
00193         printError("Cannot set listener orientation!");
00194 
00195 
00196 }
00197 
00198 
00199 bool SoundMgr::frameRenderingQueued(const Ogre::FrameEvent& evt)
00200 {
00201         tick(evt.timeSinceLastFrame);
00202         return true;
00203 }
00204 bool SoundMgr::frameStarted(const Ogre::FrameEvent& evt){
00205         return true;
00206 }
00207 bool SoundMgr::frameEnded(const Ogre::FrameEvent& evt){
00208         return true;
00209 }
00210 
00211 
00212 
00213 void SoundMgr::crosslink(void){
00214         syncListenerToCamera();
00215         return;
00216 }
00217 
00218 void SoundMgr::loadLevel(void){
00219         syncListenerToCamera();
00220         //load sounds, bind buffers, start background music
00221         //read sound files
00222 
00223         //load background, start, loop
00224         //loadStartBackground();
00225 
00226 
00227         return;
00228 }
00229 double static tmpT = 0.0;
00230 bool static paused = false;
00231 
00232  
00233 void SoundMgr::attachSelectedNodeToSoundIndex(OgreGFX::GFXNode *gfxNode, unsigned int index){
00234         if (index == -1) //if there is no defined sound for the specified type, don't do anything
00235                 return;
00236         
00237         this->playAudio(this->sourceInfo[index].source, true);  //second argument is added as true since it was causing nonresponsiveness when method is called again before the sound ends
00238         Ogre::Vector3 pos = gfxNode->node->getPosition();
00239         setSoundPosition(this->sourceInfo[index].source, pos);  
00240 }
00241 
00242 void SoundMgr::tick(double dtime){
00243 
00244         syncListenerToCamera();
00245         
00246         //selection sound
00247         for(int i = 0; i < gim->nGFXNodes; i++){
00248             FastEcslent::Entity *ent = gim->engine->entityMgr->ents[i];
00249             //only play for selection of current player's entities
00250             if (ent->engine->options.player != ent->entityId.player){
00251                         continue;
00252             }
00253             else {
00254                         FastEcslent::EntityType et = ent->entityType;
00255                         if (ent->isSelected && !ent->didSelectSoundPlayed){
00256                                 playSelectionSound(et, &(gim->gfxNodes[i]));
00257                                 ent->didSelectSoundPlayed = true;
00258                         }
00259                         else if (!ent->isSelected && ent->didSelectSoundPlayed){
00260                                 ent->didSelectSoundPlayed = false;
00261                             }
00262             }
00263         }
00264         
00265         //new born or new built sound
00266         for(int i = 0; i < gim->nGFXNodes; i++){
00267             FastEcslent::Entity *ent = gim->engine->entityMgr->ents[i];
00268             //only play for creation of entities belonging to current player
00269             if (ent->engine->options.player != ent->entityId.player){
00270                         continue;
00271             }
00272             else {
00273                         FastEcslent::EntityType et = ent->entityType;
00274                         if (ent->isNewBorn){
00275                                 playEntityBornSound(et, &(gim->gfxNodes[i]));
00276                                 ent->isNewBorn = false;
00277                         }
00278             }
00279         }
00280         
00281         //this was for moving sound but playing sound for all moving objects does not seem to be a good idea
00282         //copySoundState();
00283         
00284         
00285 //      tmpT += dtime;
00286 //      if(tmpT > 5.0 && !paused && tmpT < 6.0){
00287 //              this->pauseBackground();
00288 //              paused = true;
00289 //      }
00290 //      if(tmpT > 10.0 && paused){
00291 //              paused = false;
00292 //              this->resumeBackground();
00293 //      }
00294 //      return;
00295 }
00296 
00297 bool SoundMgr::playSelectionSound(FastEcslent::EntityType et, OgreGFX::GFXNode *gfxNode){
00298         Ogre::Vector3 pos = gfxNode->node->getPosition();
00299         
00300         int sounds = 0;
00301         int arrayIndex = 0;
00302         for (int i = 0; i < soundPerEnt; i++){
00303             if (selectionSoundsDictionary[et][i] != -1)
00304                 sounds++;
00305             else
00306                 break;
00307         }
00308         if (sounds == 0){
00309             std::cout << "There is no registered selection sounds for this entity type" << std::endl;
00310             return false; //there is no sound to play
00311         }
00312         else if (sounds == 1)
00313             arrayIndex = 0;
00314         else{
00315             arrayIndex = rand() % sounds; //randomly choose
00316         }
00317         int sourceIndex = selectionSoundsDictionary[et][arrayIndex];
00318         this->playAudioSourceIndex(sourceIndex);
00319         setSoundPosition(sourceInfo[sourceIndex].source, pos);
00320         
00321         return true;
00322 }
00323 
00324 bool SoundMgr::playEntityBornSound(FastEcslent::EntityType et, OgreGFX::GFXNode *gfxNode){
00325         Ogre::Vector3 pos = gfxNode->node->getPosition();
00326         
00327         int sounds = 0;
00328         int arrayIndex = 0;
00329         for (int i = 0; i < soundPerEnt; i++){
00330             if (creationSoundsDictionary[et][i] != -1)
00331                 sounds++;
00332             else
00333                 break;
00334         }
00335         if (sounds == 0){
00336             std::cout << "There is no registered new born sounds for this entity type" << std::endl;
00337             return false; //there is no sound to play
00338         }
00339         else if (sounds == 1)
00340             arrayIndex = 0;
00341         else{
00342             arrayIndex = rand() % sounds; //randomly choose
00343         }
00344         int sourceIndex = creationSoundsDictionary[et][arrayIndex];
00345         this->playAudioSourceIndex(sourceIndex, true);
00346         setSoundPosition(sourceInfo[sourceIndex].source, pos);
00347         
00348         return true;
00349 }
00350 
00351 bool SoundMgr::playExplosionSound(FastEcslent::EntityType et, OgreGFX::GFXNode *gfxNode){
00352         Ogre::Vector3 pos = gfxNode->node->getPosition();
00353         int sounds = 0;
00354         int arrayIndex = 0;
00355         for (int i = 0; i < soundPerEnt; i++){
00356             if (battleSoundsDictionary[et][i] != -1)
00357                 sounds++;
00358             else
00359                 break;
00360         }
00361         if (sounds == 0){
00362             std::cout << "There is no registered battle sounds for this entity type" << std::endl;
00363             return false; //there is no sound to play
00364         }
00365         else if (sounds == 1)
00366             arrayIndex = 0;
00367         else{
00368             arrayIndex = rand() % sounds; //randomly choose
00369         }
00370         int sourceIndex = battleSoundsDictionary[et][arrayIndex];
00371         this->playAudioSourceIndex(sourceIndex, true);
00372         setSoundPosition(sourceInfo[sourceIndex].source, pos);
00373         
00374         return true;
00375 }
00376 
00377 bool SoundMgr::playExplosionSound(OgreGFX::GFXNode *gfxNode){
00378         Ogre::Vector3 pos = gfxNode->node->getPosition();
00379         
00380         if (this->playAudio(battleSoundSource, true)){
00381                 return setSoundPosition(battleSoundSource, pos);
00382         }
00383         else
00384             return false;
00385 }
00386 
00387 void SoundMgr::releaseLevel(void){
00388         // release stuff loaded for this level
00389         return;
00390 }
00391 
00392 void SoundMgr::cleanup(void){
00393         return;
00394 }
00395 
00396 void SoundMgr::printAudioDevices(const ALCchar *devices){
00397 
00398         const ALCchar *device = devices;
00399         const ALCchar *next   = devices+1;
00400         size_t len = 0;
00401 
00402         std::cout << "Devices list:" << std::endl;
00403         while(device && *device != '\0' && next && *next != '\0') {
00404                 std::cout << device << std::endl;
00405                 len = strlen(device);
00406                 device += len + 1;
00407                 next   += len + 2;
00408         }
00409         std::cout << "------------------" << std::endl;
00410 }
00411 
00412 int SoundMgr::printError(const char *ermsg){
00413         ALCenum error = alGetError();
00414         if (error != AL_NO_ERROR){
00415                 std::cerr << "SoundManager: ERROR: "<< ermsg << std::endl;
00416                 return -1;
00417         }
00418         return 0;
00419 }
00420 
00421 inline ALenum SoundMgr::toALFormat(short channels, short samples) {
00422         bool stereo = (channels > 1);
00423         switch (samples){
00424         case 16:
00425                 if (stereo) {
00426                         return AL_FORMAT_STEREO16;
00427                 } else {
00428                         return AL_FORMAT_MONO16;
00429                 }
00430 
00431         case 8:
00432                 if (stereo) {
00433                         return AL_FORMAT_STEREO8;
00434                 } else {
00435                         return AL_FORMAT_MONO8;
00436                 }
00437 
00438         default:
00439                 return -1;
00440 
00441         }
00442 }
00443 
00444 
00445 int SoundMgr::getBufferId(std::string filename){
00446         // two cases
00447         //1. sound is already in a buffer, then return the buffer's index
00448         //2. sound is not already in a buffer, then load it into an unused buffer index and return it
00449         //Case 1:
00450         for (int i = 0; i < OgreSND::maxAudioBuffers; i++){
00451                 if (this->bufferInfo[i].bufferFilename == filename){
00452                         return i;
00453                 }
00454         }
00455         std::cout << "Cannot find buffer, attempting to load file: " << filename << std::endl;
00456         //Case 2
00457         for (int i = 0; i < OgreSND::maxAudioBuffers; i++){
00458                 if (this->bufferInfo[i].bufferFilename == ""){
00459                         if (loadAudio(filename, i)){
00460                                 return i;
00461                         } else {
00462                                 std::cerr << "getBufferId::cannot load audio from file: " << filename << std::endl;
00463                                 return -1;
00464                         }
00465                 }
00466         }
00467 
00468         return -1;
00469 }
00470 
00471 int SoundMgr::getEmptySourceIndex(){
00472         for (int i = 0; i < OgreSND::maxAudioSources; i++){
00473                 if (!this->sourceInfo[i].inUse){
00474                         return i;
00475                 }
00476         }
00477         return -1;
00478 }
00479 
00480 bool SoundMgr::registerCreate(FastEcslent::EntityType et, std::string filename){
00481     unsigned int sid;
00482     //check if that file is already assigned to a source
00483     for (int j = 0; j < maxAudioSources; j++){
00484         if (std::strcmp(sourceDictionary[j].c_str(), filename.c_str()) == 0){
00485                 int lastIndex = -1;
00486                 for (int i = 0; i < soundPerEnt; i++){
00487                     if (this->creationSoundsDictionary[et][i] == -1){
00488                         lastIndex = i;
00489                         break;
00490                     }
00491                 }
00492                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00493                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00494                     return false;
00495                 }
00496                 this->creationSoundsDictionary[et][lastIndex] = j;
00497                 return true;
00498         }
00499     }
00500     if (this->reserveAudio(filename, false, sid)){
00501                 int lastIndex = -1;
00502                 for (int i = 0; i < soundPerEnt; i++){
00503                     if (this->creationSoundsDictionary[et][i] == -1){
00504                         lastIndex = i;
00505                         break;
00506                     }
00507                 }
00508                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00509                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00510                     return false;
00511                 }
00512                 this->creationSoundsDictionary[et][lastIndex] = sid;
00513                 alSourcei(this->sourceInfo[sid].source, AL_REFERENCE_DISTANCE, 2000.0f);
00514                 alSourcei(this->sourceInfo[sid].source, AL_MAX_DISTANCE, 8000.0f);
00515                 
00516                 sourceDictionary[sid] = filename;
00517                 return true;
00518     }
00519     else
00520         return false;
00521 }
00522 
00523 bool SoundMgr::registerSelection(FastEcslent::EntityType et, std::string filename){
00524     unsigned int sid;
00525     //check if that file is already assigned to a source
00526     for (int j = 0; j < maxAudioSources; j++){
00527         if (std::strcmp(sourceDictionary[j].c_str(), filename.c_str()) == 0){
00528                 int lastIndex = -1;
00529                 for (int i = 0; i < soundPerEnt; i++){
00530                     if (this->selectionSoundsDictionary[et][i] == -1){
00531                         lastIndex = i;
00532                         break;
00533                     }
00534                 }
00535                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00536                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00537                     return false;
00538                 }
00539                 this->selectionSoundsDictionary[et][lastIndex] = j;
00540                 return true;
00541         }
00542     }
00543     if (this->reserveAudio(filename, false, sid)){
00544                 int lastIndex = -1;
00545                 for (int i = 0; i < soundPerEnt; i++){
00546                     if (this->selectionSoundsDictionary[et][i] == -1){
00547                         lastIndex = i;
00548                         break;
00549                     }
00550                 }
00551                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00552                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00553                     return false;
00554                 }
00555                 this->selectionSoundsDictionary[et][lastIndex] = sid;
00556                 alSourcei(this->sourceInfo[sid].source, AL_REFERENCE_DISTANCE, 2000.0f);
00557                 alSourcei(this->sourceInfo[sid].source, AL_MAX_DISTANCE, 8000.0f);
00558                 
00559                 sourceDictionary[sid] = filename;
00560                 return true;
00561     }
00562     else
00563         return false;
00564 }
00565 
00566 bool SoundMgr::registerBattleSound(FastEcslent::EntityType et, std::string filename){
00567     unsigned int sid;
00568     //check if that file is already assigned to a source
00569     for (int j = 0; j < maxAudioSources; j++){
00570         if (std::strcmp(sourceDictionary[j].c_str(), filename.c_str()) == 0){
00571                 int lastIndex = -1;
00572                 for (int i = 0; i < soundPerEnt; i++){
00573                     if (this->battleSoundsDictionary[et][i] == -1){
00574                         lastIndex = i;
00575                         break;
00576                     }
00577                 }
00578                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00579                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00580                     return false;
00581                 }
00582                 this->battleSoundsDictionary[et][lastIndex] = j;
00583                 return true;
00584         }
00585     }
00586     if (this->reserveAudio(filename, false, sid)){
00587                 int lastIndex = -1;
00588                 for (int i = 0; i < soundPerEnt; i++){
00589                     if (this->battleSoundsDictionary[et][i] == -1){
00590                         lastIndex = i;
00591                         break;
00592                     }
00593                 }
00594                 if (lastIndex == -1){ //all permitted number of sounds for this type are already assigned
00595                     std::cout << "Could not register new sound, max allowed number per entity reached" << std::endl;
00596                     return false;
00597                 }
00598                 
00599                 this->battleSoundsDictionary[et][lastIndex] = sid;
00600                 alSourcei(this->sourceInfo[sid].source, AL_REFERENCE_DISTANCE, 2000.0f);
00601                 alSourcei(this->sourceInfo[sid].source, AL_MAX_DISTANCE, 8000.0f);
00602                 
00603                 sourceDictionary[sid] = filename;
00604                 return true;
00605     }
00606     else
00607         return false;
00608 }
00609 
00610 //specific for sound managers everywhere
00615 bool SoundMgr::reserveAudio(std::string filename, bool loop, unsigned int &sourceInfoIndex){
00616 //bool SoundMgr::reserveAudio(std::string filename, bool loop){ //
00617 
00618         alGetError();
00619         int bufferId = this->getBufferId(filename); // if buffer not generated - it is generated in loadAudio
00620         if(bufferId < 0) {
00621                 std::cout << "GetBufferId: Error loading: " << filename << std::endl;
00622                 std::cout << "All buffers in use, you will need to release buffers before you can get this sound to play: " << filename << std::endl;
00623                 return false;
00624         }
00625 
00626         int index = getEmptySourceIndex();
00627         if (index < 0) {
00628                 std::cout << "All sources in use, you will need to release sources before you can get this sound to play: " << filename << std::endl;
00629                 return false;
00630         }
00631         if (!alIsSource(this->sourceInfo[index].source)){
00632                 alGenSources(1, &this->sourceInfo[index].source);
00633                 if(printError("ReserveAudio::Cannot Generate source") < 0){
00634                         return false;
00635                 }
00636                 std::cout << "Generated Source " << std::endl;
00637         }
00638 
00639         resetSource(this->sourceInfo[index].source);
00640 
00641         if(loop){
00642                 alSourcei(this->sourceInfo[index].source, AL_LOOPING, AL_TRUE);
00643                 if(printError("Source looping") < 0){
00644                         return false;
00645                 }
00646         }
00647         /*******************************************************************************************/
00648         sourceInfoIndex = index; // to be returned**************************************
00649         /*******************************************************************************************/
00650         this->sourceInfo[index].inUse = true;
00651         alSourcei(this->sourceInfo[sourceInfoIndex].source, AL_BUFFER, this->bufferInfo[bufferId].buffer);
00652         if (printError("Error in binding source to buffer for ") < 0){
00653                 return false;
00654         }
00655         return true; //return error code
00656 }
00657 
00658 bool SoundMgr::resetSource(ALuint sourceId){
00659 
00660         alSourcef(sourceId, AL_PITCH, 1);
00661         if (printError("Source pitch") < 0)
00662                 return false;
00663 
00664         alSourcef(sourceId, AL_GAIN, 1);
00665         if(printError("Source Gain") < 0)
00666                 return false;
00667 
00668         alSource3f(sourceId, AL_POSITION, 0, 0, 0);
00669         if(printError("Source position") < 0)
00670                 return false;
00671 
00672         alSource3f(sourceId, AL_VELOCITY, 0, 0, 0);
00673         if (printError("Source velocity") < 0)
00674                 return false;
00675 
00676         return true;
00677 }
00678 
00684 bool SoundMgr::releaseSourceIndex(int sid){
00685 
00686         ALuint source = this->sourceInfo[sid].source;
00687         if (! alIsSource(source)){
00688                 std::cerr << "ReleaseSource:: is not a source!" << source << std::endl;
00689                 return false;
00690         }
00691         if(!stopAudio(source)){
00692                 std::cerr << "ReleaseSource:: Could not stop audio before release" << source << std::endl;
00693                 return false;
00694         }
00695         alDeleteSources(1, &this->sourceInfo[sid].source);
00696         if (printError("ReleaseAudio::Cannot delete source") < 0){
00697                 return false;
00698         }
00699         this->sourceInfo[sid].inUse = false;
00700         return true;
00701 }
00702 
00703 bool SoundMgr::releaseSource(ALuint audioId){
00704         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00705                 if (this->sourceInfo[i].source == audioId){
00706                         return releaseSourceIndex(i);
00707                 }
00708         }
00709         return false;
00710 }
00711 
00712 
00713 
00714 std::string SoundMgr::getFQFNFromFilename(std::string filename){
00715 //      Ogre::FileInfoListPtr files = Ogre::ResourceGroupManager::getSingletonPtr()->findResourceFileInfo("Essential", filename, true);
00716 //      Ogre::ConstVectorIterator<Ogre::FileInfoList> fileInfoIter(files.get()->begin(), files.get()->end());
00717 //      std::string pathname, fname;
00718 //      while(fileInfoIter.hasMoreElements()) {
00719 //              pathname = fileInfoIter.peekNext().archive->getName();
00720 //              fname = fileInfoIter.peekNext().filename;
00721 //      }
00722 //      return pathname+fname;
00723         return filename;
00724 }
00725 
00726 //specific to FastEcslsent------------------------------------------------------------------------------------
00727 
00728 bool SoundMgr::stopBackground(){
00729 
00730         alSourceStop(this->backgroundMusicSource);
00731         if (printError("Stop background music") < 0){
00732                 return false;
00733         } else {
00734                 return true;
00735         }
00736 
00737 
00738 }
00739 
00740 bool SoundMgr::pauseBackground(){
00741         alSourcePause(this->backgroundMusicSource);
00742         if(printError("PauseBackground Source") < 0){
00743                 return false;
00744         } else {
00745                 return true;
00746         }
00747 }
00748 
00749 bool SoundMgr::resumeBackground(){
00750         alSourcePlay(this->backgroundMusicSource);
00751         if(printError("Resume background Source") < 0){
00752                 return false;
00753         } else {
00754                 return true;
00755         }
00756 }
00757 
00758 bool SoundMgr::loadAudio(std::string filename, int index){
00759         alGetError();//init errors
00760         std::string fqfn = getFQFNFromFilename(filename);
00761         std::cout << "SoundManager Music file: " << fqfn << " is being readied" << std::endl;
00762         if(fqfn == "")
00763                 return false;
00764 
00765         this->bufferInfo[index].wave = WaveOpenFileForReading(fqfn.c_str());
00766 
00767         if(!this->bufferInfo[index].wave){
00768                 std::cerr << "SoundMgr::loadAudio::ERROR: Cannot open wave file for reading" << std::endl;
00769                 return false;
00770         }
00771         int ret = WaveSeekFile(0, this->bufferInfo[index].wave);
00772         if (ret) {
00773                 std::cerr << "SoundMgr::loadAudio::ERROR: Cannot seek" << std::endl;
00774                 return false;
00775         }
00776         char *tmpBuf = (char *) malloc(this->bufferInfo[index].wave->dataSize);
00777         //this->backgroundBufferData = (char *) malloc(this->backgroundWaveInfo->dataSize);
00778         if(!tmpBuf){
00779                 std::cerr << "SoundMgr::loadAudio::ERROR: in malloc" << std::endl;
00780                 return false;
00781         }
00782         ret = WaveReadFile(tmpBuf, this->bufferInfo[index].wave->dataSize, this->bufferInfo[index].wave);
00783         if(ret != (int) this->bufferInfo[index].wave->dataSize){
00784                 std::cerr << "ERROR: SoundMgr::loadAudio: short read " << ret << " wanted: " << this->bufferInfo[index].wave->dataSize << std::endl;
00785                 return false;
00786         }
00787 
00788         if(!alIsBuffer(this->bufferInfo[index].buffer) || this->bufferInfo[index].bufferFilename == ""){
00789                 //bufferFilename == "" means not a buffer
00790                 alGenBuffers(1, &this->bufferInfo[index].buffer);
00791                 if (printError("Cannot generate buffers") < 0) {
00792                         return false;
00793                 }
00794                 std::cout << "Generated Buffer " << std::endl;
00795         }
00796 
00797         alBufferData(this->bufferInfo[index].buffer,
00798                         toALFormat(this->bufferInfo[index].wave->channels, this->bufferInfo[index].wave->bitsPerSample),
00799                         tmpBuf, this->bufferInfo[index].wave->dataSize, this->bufferInfo[index].wave->sampleRate);
00800         free(tmpBuf);
00801         if(printError("Failed to load bufferData") < 0){
00802                 return false;
00803         }
00804 
00805         this->bufferInfo[index].bufferFilename = filename;
00806 
00807         return true;
00808 }
00809 
00810 bool SoundMgr::loadStartBackground(){
00811         //WaveInfo *wave;
00812 
00813 
00814         alGenSources((ALuint)1, &this->backgroundMusicSource);
00815         printError("Cannot generate source with id 1");
00816 
00817         alSourcef(this->backgroundMusicSource, AL_PITCH, 1);
00818         printError("Source pitch");
00819 
00820         alSourcef(this->backgroundMusicSource, AL_GAIN, 1);
00821         printError("Source Gain");
00822 
00823         alSource3f(this->backgroundMusicSource, AL_POSITION, 0, 0, 0);
00824         printError("Source position");
00825 
00826         alSource3f(this->backgroundMusicSource, AL_VELOCITY, 0, 0, 0);
00827         printError("Source velocity");
00828 
00829         alSourcei(this->backgroundMusicSource, AL_LOOPING, AL_TRUE);
00830         printError("Source looping");
00831 
00832         alGenBuffers(1, &this->backgroundMusicBuffer);
00833         printError("Buffer generation");
00834 
00835         std::string fqfn = getFQFNFromFilename(OgreSND::backgroundMusicFilename);
00836         std::cout << "SoundManager backgroundMusic file: " << fqfn << " is being readied" << std::endl;
00837         if(fqfn == "")
00838                 return false;
00839 
00840         this->backgroundWaveInfo = WaveOpenFileForReading(fqfn.c_str());
00841         if(!this->backgroundWaveInfo){
00842                 std::cerr << "ERROR: Cannot open wave file for reading" << std::endl;
00843                 return false;
00844         }
00845         int ret = WaveSeekFile(0, this->backgroundWaveInfo);
00846         if (ret) {
00847                 std::cerr << "ERROR: Cannot seek" << std::endl;
00848                 return false;
00849         }
00850         char *tmpBuf = (char *) malloc(this->backgroundWaveInfo->dataSize);
00851         //this->backgroundBufferData = (char *) malloc(this->backgroundWaveInfo->dataSize);
00852         if(!tmpBuf){
00853                 std::cerr << "ERROR: in malloc" << std::endl;
00854                 return false;
00855         }
00856         ret = WaveReadFile(tmpBuf, this->backgroundWaveInfo->dataSize, this->backgroundWaveInfo);
00857         if(ret != (int) this->backgroundWaveInfo->dataSize){
00858                 std::cerr << "ERROR: short read " << ret << " wanted: " << this->backgroundWaveInfo->dataSize << std::endl;
00859                 return false;
00860         }
00861         alBufferData(this->backgroundMusicBuffer,
00862                         toALFormat(this->backgroundWaveInfo->channels, this->backgroundWaveInfo->bitsPerSample),
00863                         tmpBuf, this->backgroundWaveInfo->dataSize, this->backgroundWaveInfo->sampleRate);
00864         if(printError("Failed to load bufferData") < 0){
00865                 return false;
00866         }
00867 
00868         free(tmpBuf);
00869 
00870         alSourcei(this->backgroundMusicSource, AL_BUFFER, this->backgroundMusicBuffer);
00871         printError("Source binding");
00872 
00873         alSourcePlay(this->backgroundMusicSource);
00874         printError("Playing");
00875 
00876 
00877         return true;
00878 }
00879 
00880 
00881 // Returns true if we can play the sound. Rewinds sound if already playing and forceRestart is true,
00882 // false if error
00883 bool SoundMgr::playAudio(ALuint audioId, bool forceRestart ){
00884         if (!this->isEnabled)
00885                 return false;
00886         if (!alIsSource(audioId))
00887                 return false;
00888 
00889         ALint source_state;
00890         alGetSourcei(audioId, AL_SOURCE_STATE, &source_state);
00891         if(printError("Get source state") < 0)
00892                 return false;
00893         if(source_state == AL_PLAYING){
00894                 if (forceRestart){
00895                         stopAudio(audioId);
00896                         if (printError("PlayAudio:: Could not stop already playing song") < 0){
00897                                 return false;
00898                         }
00899                         alSourcePlay(audioId);
00900                 }
00901                 return true;
00902         }
00903         alSourcePlay(audioId);
00904         if(printError("PlayAudio:: Could not play") < 0)
00905                 return false;
00906         return true;
00907 }
00908 
00909 bool SoundMgr::playAudio(ALuint audioId){
00910         return playAudio(audioId, false);
00911 }
00912 
00913 bool SoundMgr::playAudioSourceIndex(int sid, bool forceRestart){
00914         return playAudio(this->sourceInfo[sid].source, forceRestart);
00915 }
00916 
00917 bool SoundMgr::playAudioSourceIndex(int sid){
00918         return playAudio(this->sourceInfo[sid].source, false);
00919 }
00920 
00921 bool SoundMgr::stopAudio(ALuint audioId){
00922         if (alIsSource(audioId)){
00923                 alSourceStop(audioId);
00924                 if (printError("StopAudio::cannot stop source: " + audioId) < 0){
00925                         return false;
00926                 }
00927         } else {
00928                 std::cerr << "StopAudio:: Is not a source: " << audioId << std::endl;
00929                 return false;
00930         }
00931         return true;
00932 }
00933 
00934 bool SoundMgr::stopAudioSourceIndex(int sid){
00935         return this->stopAudio(this->sourceInfo[sid].source);
00936 }
00937 
00938 bool SoundMgr::isAudioPlaying(ALuint audioId){
00939         if (!alIsSource(audioId))
00940                 return false;
00941 
00942         ALint source_state;
00943         alGetSourcei(audioId, AL_SOURCE_STATE, &source_state);
00944         if(printError("Get source state") < 0)
00945                 return false;
00946         if(source_state == AL_PLAYING){
00947                 return true;
00948         }
00949         if(printError("PlayAudio:: Could not play") < 0)
00950                 return false;
00951 }
00952 
00953 bool SoundMgr::stopAllAudio( void ){
00954         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00955                 stopAudio(this->sourceInfo[i].source);
00956         }
00957         return true;
00958 }
00959 
00960 bool SoundMgr::pauseAudioSourceIndex(int sid){
00961 
00962         pauseAudio(this->sourceInfo[sid].source);
00963         return true;
00964 }
00965 bool SoundMgr::pauseAudio(ALuint audioId ){
00966         if(!alIsSource(audioId))
00967                 return false;
00968         alSourcePause(audioId);
00969         if (printError("PauseAudio::Cannot pause: " + audioId) < 0){
00970                 return false;
00971         }
00972         return true;
00973 }
00974 
00975 bool SoundMgr::pauseAllAudio( void ){
00976         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00977                 pauseAudio(this->sourceInfo[i].source);
00978         }
00979         return true;
00980 }
00981 
00982 bool SoundMgr::resumeAudio(ALuint audioId){
00983         return playAudio(audioId);
00984 }
00985 
00986 bool SoundMgr::resumeAllAudio( void ){
00987         for(int i = 0; i < OgreSND::maxAudioSources; i++){
00988                 playAudio(this->sourceInfo[i].source);
00989         }
00990         return true;
00991 }
00992 
00993 bool SoundMgr::setSoundPosition(ALuint audioId, Ogre::Vector3 position ){
00994 
00995         alSourcef(audioId, AL_GAIN, 1.0);
00996         if(printError("Source Gain") < 0)
00997                 return false;
00998 
00999 
01000         alSource3f(audioId, AL_POSITION, position.x, position.y, position.z);
01001         if (printError("SetSoundPosition::Source position") < 0) return false;
01002         return true;;
01003 }
01004 
01005 
01006 bool SoundMgr::setSoundDisposition( ALuint audioId, Ogre::Vector3 position, Ogre::Vector3 velocity, Ogre::Vector3 direction ){
01007         alSource3f(audioId, AL_POSITION, position.x, position.y, position.z);
01008         if (printError("SetSoundDisPosition::Source position") < 0) return false;
01009 
01010         alSource3f(audioId, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
01011         if (printError("SetSoundDisPosition::Source velocity") < 0) return false;
01012 
01013         return true;
01014 }
01015 
01016 
01017 bool SoundMgr::setSound( ALuint audioID, Ogre::Vector3 position,
01018     Ogre::Vector3 velocity, Ogre::Vector3 direction, float maxDistance,
01019     bool playNow, bool forceRestart, float minGain ){
01020         return false;
01021 }
01022 
01023 
01024 bool SoundMgr::setListenerDisposition( Ogre::Vector3 position, Ogre::Vector3 velocity, Ogre::Quaternion orientation ){
01025         return false;
01026 }
01027 
01028 void SoundMgr::copySoundState(){
01029         for(int i = 0; i < gim->nGFXNodes; i++){
01030                 FastEcslent::UnitAI* ai = dynamic_cast<FastEcslent::UnitAI*>(gim->engine->entityMgr->ents[i]->getAspect(FastEcslent::UNITAI));
01031                 for(std::deque<FastEcslent::Command*>::iterator it = ai->commands.begin(); it!= ai->commands.end();it++){
01032                     if((*it)->commandType == FastEcslent::MoveCommand){// || (*it)->commandType == FastEcslent::GatherCommand){
01033                         FastEcslent::EntityType et = gim->engine->entityMgr->ents[i]->entityType;
01034                         attachSelectedNodeToSoundIndex(&(gim->gfxNodes[i]), /*scvId, soundDictionary[et],*/ (*it)->commandType);
01035                     }
01036                 }
01037         }
01038 }

Generated on Fri Dec 13 14:54:18 2013 for FastECSLent by  doxygen 1.5.4