//Delete a source bool SoundManager::DeleteSource(unsigned int source) { //Find this source in vector SourcesVector::iterator srcitr; ALuint src = static_cast<ALuint>(source); //LOOP - Search requested source for(srcitr = mSources.begin(); srcitr != mSources.end();++srcitr) { if(src == (*srcitr).source) { break; } }//LOOP //IF - Found if(srcitr != mSources.end()) { StopSource((*srcitr).source); (*srcitr).reserved = false; (*srcitr).actionplayed = ""; return true; }//IF //Not found return false; }
void UOpenALAudioSubsystem::SetViewport( UViewport* InViewport ) { guard(UOpenALAudioSubsystem::SetViewport); // Stop all sources. StopMusic(); for( INT i=0; i<NumSources; i++ ) StopSource( i ); Viewport = InViewport; unguard; }
BOOLEAN _ReleaseSoundBankData (void *Snd) { STRING_TABLE fxTab = Snd; if (fxTab) { int snd_ct, index; TFB_SoundSample **sptr; snd_ct = fxTab->size; index = 0; while (snd_ct--) { int i; sptr = (TFB_SoundSample **)(fxTab->strings[index].data); for (i = 0; i < NUM_SOUNDSOURCES; ++i) { if (soundSource[i].sample == (*sptr)) { StopSource (i); soundSource[i].sample = NULL; } } if ((*sptr)->decoder) SoundDecoder_Free ((*sptr)->decoder); audio_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer); HFree ((*sptr)->buffer); if ((*sptr)->buffer_tag) HFree ((*sptr)->buffer_tag); HFree (*sptr); *sptr = 0; index++; } FreeStringTable (Snd); return (TRUE); } return (FALSE); }
BOOLEAN _ReleaseSoundBankData (MEM_HANDLE Snd) { STRING_TABLEPTR fxTab; LockStringTable (Snd, &fxTab); if (fxTab) { int snd_ct; TFB_SoundSample **sptr; snd_ct = fxTab->StringCount; sptr = (TFB_SoundSample **)((BYTE *)fxTab + fxTab->StringOffsets[0]); while (snd_ct--) { int i; for (i = 0; i < NUM_SOUNDSOURCES; ++i) { if (soundSource[i].sample == (*sptr)) { StopSource (i); soundSource[i].sample = NULL; } } if ((*sptr)->decoder) SoundDecoder_Free ((*sptr)->decoder); audio_DeleteBuffers ((*sptr)->num_buffers, (*sptr)->buffer); HFree ((*sptr)->buffer); if ((*sptr)->buffer_tag) HFree ((*sptr)->buffer_tag); HFree (*sptr); *sptr++ = 0; } UnlockStringTable (Snd); FreeStringTable (Snd); return (TRUE); } return (FALSE); }
void PlayChannel (COUNT channel, PVOID sample, SoundPosition pos, void *positional_object, unsigned char priority) { TFB_SoundSample *tfb_sample = *(TFB_SoundSample**) sample; StopSource (channel); // all finished (stopped) channels can be cleaned up at this point // since this is the only func that can initiate an sfx sound CheckFinishedChannels (); soundSource[channel].sample = tfb_sample; soundSource[channel].positional_object = positional_object; if (optStereoSFX) UpdateSoundPosition (channel, pos); audio_Sourcei (soundSource[channel].handle, audio_BUFFER, tfb_sample->buffer[0]); audio_SourcePlay (soundSource[channel].handle); (void) priority; }
void UOpenALAudioSubsystem::NoteDestroy( AActor* Actor ) { guard(UOpenALAudioSubsystem::NoteDestroy); check(Actor); check(Actor->IsValid()); // Stop referencing actor. for( INT i=0; i<NumSources; i++ ) { FAudioSource& Source = Sources[i]; if( Source.Actor==Actor ) { // Stop ambient sound when actor dies. if( (Source.Slot&14)==SLOT_Ambient*2 ) StopSource( Source ); // Unbind regular sounds from their actors. else Source.Actor = NULL; } } unguard; }
void UOpenALAudioSubsystem::Update( FPointRegion Region, FCoords& Coords ) { guard(UOpenALAudioSubsystem::Update); if( !Viewport ) return; AActor *ViewActor = FindViewActor(); guard(UpdateMusic); if( Viewport->Actor->Song != PlayingSong ) { StopMusic(); PlayingSong = Viewport->Actor->Song; if( PlayingSong != NULL ) { MODULE* Module = GetModuleFromUMusic( PlayingSong ); Player_Start( Module ); } } if( Player_Active() ) MikMod_Update(); unguard; // Update the listener. { FVector At = ViewActor->Rotation.Vector(); FVector Up = -(GMath.UnitCoords / ViewActor->Rotation).ZAxis; FLOAT Orientation[6] = { At.X, At.Y, At.Z, Up.X, Up.Y, Up.Z }; alListenerfv( AL_POSITION, &ViewActor->Location.X ); alListenerfv( AL_VELOCITY, &ViewActor->Velocity.X ); alListenerfv( AL_ORIENTATION, Orientation ); } // See if any new ambient sounds need to be started. UBOOL Realtime = Viewport->IsRealtime() && Viewport->Actor->Level->Pauser==TEXT(""); if( Realtime ) { guard(StartAmbience); for( INT i=0; i<Viewport->Actor->GetLevel()->Actors.Num(); i++ ) { AActor* Actor = Viewport->Actor->GetLevel()->Actors(i); if ( Actor && Actor->AmbientSound && FDistSquared(ViewActor->Location,Actor->Location)<=Square(Actor->WorldSoundRadius()) ) { INT Slot = Actor->GetIndex()*16+SLOT_Ambient*2; INT j; // See if there's already an existing slot. for( j=0; j<NumSources; j++ ) if( Sources[j].Slot==Slot ) break; // If not, start playing. if( j==NumSources ) PlaySound( Actor, Slot, Actor->AmbientSound, Actor->Location, AmbientFactor*Actor->SoundVolume/255.0, Actor->WorldSoundRadius(), Actor->SoundPitch/64.0, 1 ); } } unguard; } // Update all playing ambient sounds. guard(UpdateAmbience); for( INT i=0; i<NumSources; i++ ) { FAudioSource& Source = Sources[i]; if( (Source.Slot&14)==SLOT_Ambient*2 ) { check(Source.Actor); if ( FDistSquared(ViewActor->Location,Source.Actor->Location)>Square(Source.Actor->WorldSoundRadius()) || Source.Actor->AmbientSound!=Source.Sound || !Realtime ) { // Ambient sound went out of range. StopSource( Source ); } else { // Update basic sound properties. FLOAT Volume = 2.0 * (AmbientFactor*Source.Actor->SoundVolume/255.0); // XXX: Huh? What does light brightness have to do with it? if( Source.Actor->LightType!=LT_None ) Volume *= Source.Actor->LightBrightness/255.0; Source.Volume = Volume; Source.Radius = Source.Actor->WorldSoundRadius(); const ALuint Id = Source.Id; alSourcef( Id, AL_GAIN, Source.Volume ); alSourcef( Id, AL_MAX_DISTANCE, Source.Radius ); alSourcef( Id, AL_PITCH, Source.Actor->SoundPitch/64.0 ); } } } unguard; // Update all active sounds. guard(UpdateSounds); for( INT Index=0; Index<NumSources; Index++ ) { FAudioSource& Source = Sources[Index]; // We should've been notified about this. if( Source.Actor ) check(Source.Actor->IsValid()); // Check if the sound is playing. if( Source.Slot==0 ) continue; // Check if the sound is finished. ALint state; alGetSourcei( Source.Id, AL_SOURCE_STATE, &state ); if( state==AL_STOPPED ) { StopSource( Source ); continue; } // Update positioning from actor, if available. if( Source.Actor ) { Source.Location = Source.Actor->Location; alSourcefv( Source.Id, AL_POSITION, &Source.Actor->Location.X ); alSourcefv( Source.Id, AL_VELOCITY, &Source.Actor->Velocity.X ); } // Update the priority. Source.Priority = SoundPriority( Source.Location, Source.Volume, Source.Radius ); } unguard; unguard; }
void ship_death (ELEMENT *ShipPtr) { STARSHIP *StarShipPtr; STARSHIP *VictoriousStarShipPtr; HELEMENT hElement, hNextElement; ELEMENT *ElementPtr; StopDitty (); StopMusic (); GetElementStarShip (ShipPtr, &StarShipPtr); // JMS: Make sure the Foon-foon's spinning blade sound ends when the ship dies. if (StarShipPtr->SpeciesID == FOONFOON_ID) { COUNT i; for (i = FIRST_SFX_CHANNEL; i <= LAST_SFX_CHANNEL; ++i) { ELEMENT *posobj; if (!ChannelPlaying(i)) continue; posobj = GetPositionalObject (i); if (posobj) StopSource (i); } } if (ShipPtr->mass_points <= MAX_SHIP_MASS) { // Not running away and not reincarnating (Pkunk) // When a ship tries to run away, it is (dis)counted in DoRunAway(), // so when it dies while running away, we will not count it again assert (StarShipPtr->playerNr >= 0); battle_counter[StarShipPtr->playerNr]--; } VictoriousStarShipPtr = NULL; for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { LockElement (hElement, &ElementPtr); if ((ElementPtr->state_flags & PLAYER_SHIP) && ElementPtr != ShipPtr /* and not running away */ && ElementPtr->mass_points <= MAX_SHIP_MASS) { GetElementStarShip (ElementPtr, &VictoriousStarShipPtr); if (VictoriousStarShipPtr->RaceDescPtr->ship_info.crew_level == 0) VictoriousStarShipPtr = NULL; UnlockElement (hElement); break; } hNextElement = GetSuccElement (ElementPtr); UnlockElement (hElement); } StarShipPtr->cur_status_flags &= ~PLAY_VICTORY_DITTY; DeltaEnergy (ShipPtr, -(SIZE)StarShipPtr->RaceDescPtr->ship_info.energy_level); ShipPtr->life_span = NUM_EXPLOSION_FRAMES * 3; ShipPtr->state_flags &= ~DISAPPEARING; ShipPtr->state_flags |= FINITE_LIFE | NONSOLID; ShipPtr->postprocess_func = PostProcessStatus; ShipPtr->death_func = cleanup_dead_ship; ShipPtr->hTarget = 0; ZeroVelocityComponents (&ShipPtr->velocity); if (ShipPtr->crew_level) /* only happens for shofixti self-destruct */ { PlaySound (SetAbsSoundIndex ( StarShipPtr->RaceDescPtr->ship_data.ship_sounds, 1), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); DeltaCrew (ShipPtr, -(SIZE)ShipPtr->crew_level); if (VictoriousStarShipPtr == NULL) { // No ships left alive after a Shofixti Glory device, // thus Shofixti wins VictoriousStarShipPtr = StarShipPtr; } } else { ShipPtr->preprocess_func = explosion_preprocess; PlaySound (SetAbsSoundIndex (GameSounds, SHIP_EXPLODES), CalcSoundPosition (ShipPtr), ShipPtr, GAME_SOUND_PRIORITY + 1); } if (VictoriousStarShipPtr != NULL) VictoriousStarShipPtr->cur_status_flags |= PLAY_VICTORY_DITTY; // The winner is set once per battle. If both ships die, this function is // called twice, once for each ship. We need to preserve the winner // determined on the first call. if (winnerStarShip == NULL) winnerStarShip = VictoriousStarShipPtr; if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) MeleeShipDeath (StarShipPtr); }
void StopChannel (COUNT channel, unsigned char Priority) { StopSource (channel); (void)Priority; // ignored }
//Play a source 3D bool SoundManager::PlaySource(unsigned int source, const std::string& action, bool loop) { if (mSoundON) { if (source >= 0 && (unsigned int)source<mSources.size() && mSources[source].reserved) { if (mBuffers.find(action)==mBuffers.end()) { SingletonLogMgr::Instance()->AddNewLine("SoundManager::PlaySource","Action " + action + " not found",LOGEXCEPTION); return false; } ALboolean alloop; //If it has to loop, and it is playing, dont do it again if (loop) { //Get state of source ALenum state; alGetSourcei(mSources[source].source, AL_SOURCE_STATE, &state); //Playing? if(state == AL_PLAYING && mSources[source].actionplayed == action) return true; //Just return, playing with loop StopSource(source); alloop = AL_TRUE; } else { StopSource(source); alloop = AL_FALSE; } //Memorize what is it playing mSources[source].actionplayed = action; alSourcei (mSources[source].source, AL_SOURCE_RELATIVE, AL_FALSE); alSourcei (mSources[source].source, AL_BUFFER, mBuffers[action]); alSourcef (mSources[source].source, AL_PITCH, 1.0); alSourcef (mSources[source].source, AL_GAIN, 1.0); alSourcei (mSources[source].source, AL_LOOPING, alloop); //Check errors ALenum error(alGetError()); if(error != AL_NO_ERROR) { SingletonLogMgr::Instance()->AddNewLine("SoundManager::PlaySource","Failure while Setting source attributes!(" + GetALErrorString(error,false) + ")",LOGEXCEPTION); } alSourcePlay(mSources[source].source); if((error = alGetError() != AL_NO_ERROR)) { SingletonLogMgr::Instance()->AddNewLine("SoundManager::PlaySource","Failure while Playing source!(" + GetALErrorString(error,false) + ")",LOGEXCEPTION); } return true; } else { SingletonLogMgr::Instance()->AddNewLine("SoundManager::PlaySource","Can't play source. Invalid source " + source,LOGEXCEPTION); return false; } } return true; }