static private IsPlaying ( SoundSource source ) : bool | ||
source | SoundSource | The sound source, or a null reference. |
Résultat | bool |
/// <summary>Called by the controls loop to stop playback of this horn</summary> internal void Stop() { //Reset loop control variable LoopStarted = false; if (!StartEndSounds & !Loop) { //Don't stop horns which are play-once single part sounds return; } if (!StartEndSounds & Loop) { //This sound is a toggle music horn sound return; } if (Sounds.IsPlaying(Source)) { //Stop the loop sound playing Sounds.StopSound(Source); } if (StartEndSounds && !Sounds.IsPlaying(Source) && EndSound != null) { //If our end sound is defined and in use, play once Source = Sounds.PlaySound(EndSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false); } }
protected override void Elapse(ElapseData data) { try { double time = data.TotalTime.Milliseconds; Win32VehicleState win32State; win32State.Location = data.Vehicle.Location; win32State.Speed = (float)data.Vehicle.Speed.KilometersPerHour; win32State.Time = (int)Math.Floor(time - 2073600000.0 * Math.Floor(time / 2073600000.0)); win32State.BcPressure = (float)data.Vehicle.BcPressure; win32State.MrPressure = (float)data.Vehicle.MrPressure; win32State.ErPressure = (float)data.Vehicle.ErPressure; win32State.BpPressure = (float)data.Vehicle.BpPressure; win32State.SapPressure = (float)data.Vehicle.SapPressure; win32State.Current = 0.0f; Win32Handles win32Handles; win32Handles.Brake = data.Handles.BrakeNotch; win32Handles.Power = data.Handles.PowerNotch; win32Handles.Reverser = data.Handles.Reverser; win32Handles.ConstantSpeed = data.Handles.ConstSpeed ? ConstSpeedInstructions.Enable : ConstSpeedInstructions.Disable; Win32Elapse(ref win32Handles.Brake, ref win32State.Location, ref base.Panel[0], ref this.Sound[0]); data.Handles.Reverser = win32Handles.Reverser; data.Handles.PowerNotch = win32Handles.Power; data.Handles.BrakeNotch = win32Handles.Brake; if (win32Handles.ConstantSpeed == ConstSpeedInstructions.Enable) { data.Handles.ConstSpeed = true; } else if (win32Handles.ConstantSpeed == ConstSpeedInstructions.Disable) { data.Handles.ConstSpeed = false; } else if (win32Handles.ConstantSpeed != ConstSpeedInstructions.Continue) { this.PluginValid = false; } /* * Process the sound instructions * */ for (int i = 0; i < this.Sound.Length; i++) { if (this.Sound[i] != this.LastSound[i]) { if (this.Sound[i] == SoundInstructions.Stop) { if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length) { Sounds.StopSound(base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source); } } else if (this.Sound[i] > SoundInstructions.Stop & this.Sound[i] <= SoundInstructions.PlayLooping) { if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length) { Sounds.SoundBuffer buffer = base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Buffer; if (buffer != null) { double volume = (double)(this.Sound[i] - SoundInstructions.Stop) / (double)(SoundInstructions.PlayLooping - SoundInstructions.Stop); if (Sounds.IsPlaying(base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source)) { base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source.Volume = volume; } else { base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source = Sounds.PlaySound(buffer, 1.0, volume, base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Position, base.Train, base.Train.DriverCar, true); } } } } else if (this.Sound[i] == SoundInstructions.PlayOnce) { if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length) { Sounds.SoundBuffer buffer = base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Buffer; if (buffer != null) { base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source = Sounds.PlaySound(buffer, 1.0, 1.0, base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Position, base.Train, base.Train.DriverCar, false); } } this.Sound[i] = SoundInstructions.Continue; } else if (this.Sound[i] != SoundInstructions.Continue) { this.PluginValid = false; } this.LastSound[i] = this.Sound[i]; } else { if ((this.Sound[i] < SoundInstructions.Stop | this.Sound[i] > SoundInstructions.PlayLooping) && this.Sound[i] != SoundInstructions.PlayOnce & this.Sound[i] != SoundInstructions.Continue) { this.PluginValid = false; } } } } catch (Exception ex) { base.LastException = ex; throw; } }
internal override void Update(double TimeElapsed, bool ForceUpdate) { const double extraRadius = 10.0; const double Radius = 25.0; double pa = currentTrackPosition + Radius - extraRadius; double pb = currentTrackPosition + Radius + extraRadius; double ta = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z - World.BackgroundImageDistance - World.ExtraViewingDistance; double tb = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z + World.BackgroundImageDistance + World.ExtraViewingDistance; bool visible = pb >= ta & pa <= tb; if (visible | ForceUpdate) { if (Game.MinimalisticSimulation || TimeElapsed > 0.05) { return; } TrainManager.Train train = null; double trainDistance = double.MaxValue; for (int j = 0; j < TrainManager.Trains.Length; j++) { if (TrainManager.Trains[j].State == TrainState.Available) { double distance; if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < this.Follower.TrackPosition) { distance = this.Follower.TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition; } else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > this.Follower.TrackPosition) { distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - this.Follower.TrackPosition; } else { distance = 0; } if (distance < trainDistance) { train = TrainManager.Trains[j]; trainDistance = distance; } } } if (this.TrackFollowerFunction != null) { double delta = this.TrackFollowerFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0); this.Follower.Update(this.currentTrackPosition + delta, true, true); this.Follower.UpdateWorldCoordinates(false); } if (this.VolumeFunction != null) { this.currentVolume = this.VolumeFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0); } if (this.PitchFunction != null) { this.currentPitch = this.PitchFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0); } if (this.Source != null) { this.Source.Pitch = this.currentPitch; this.Source.Volume = this.currentVolume; } //Buffer should never be null, but check it anyways if (!Sounds.IsPlaying(Source) && this.Buffer != null) { Source = Sounds.PlaySound(Buffer, 1.0, 1.0, Follower.WorldPosition + Position, this, true); } } else { if (Sounds.IsPlaying(Source)) { Sounds.StopSound(Source); } } }
/// <summary>Called by the controls loop to start playback of this horn</summary> internal void Play() { if (StartEndSounds == true) { //New style three-part sounds if (LoopStarted == false) { if (!Sounds.IsPlaying(Source)) { if (StartSound != null) { //The start sound is not currently playing, so start it Source = Sounds.PlaySound(StartSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false); //Set the loop control variable to started LoopStarted = true; } else { Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true); } } } else { if (!Sounds.IsPlaying(Source)) { //Start our loop sound playing if the start sound is finished Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true); } } } else { //Original single part sounds if (LoopSound != null) { //Loop is ONLY true if this is a Music Horn if (Loop) { if (!Sounds.IsPlaying(Source) && !LoopStarted) { //On the first keydown event, start the sound source playing and trigger the loop control variable Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true); LoopStarted = true; } else { if (!LoopStarted) { //Our loop control variable is reset by the keyup event so this code will only trigger on the //second keydown meaning our horn toggles Sounds.StopSound(Source); LoopStarted = true; } } } else { if (!LoopStarted) { Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false); } LoopStarted = true; } } } }
/// <summary>Updates the brake system for a car within this train</summary> /// <remarks>This must remain a property of the train, for easy access to various base properties</remarks> /// <param name="CarIndex">The induvidual car</param> /// <param name="TimeElapsed">The frame time elapsed</param> /// <param name="DecelerationDueToBrake">The total brake deceleration this car provides</param> /// <param name="DecelerationDueToMotor">The total motor deceleration this car provides</param> private void UpdateBrakeSystem(int CarIndex, double TimeElapsed, out double DecelerationDueToBrake, out double DecelerationDueToMotor) { DecelerationDueToBrake = 0.0; // air compressor if (Cars[CarIndex].CarBrake.brakeType == BrakeType.Main) { if (Cars[CarIndex].CarBrake.airCompressor.Enabled) { if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure > Cars[CarIndex].CarBrake.mainReservoir.MaximumPressure) { Cars[CarIndex].CarBrake.airCompressor.Enabled = false; Cars[CarIndex].Sounds.CpLoopStarted = false; Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpEnd.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpEnd.Position; Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); } buffer = Cars[CarIndex].Sounds.CpLoop.Buffer; if (buffer != null) { Sounds.StopSound(Cars[CarIndex].Sounds.CpLoop.Source); } } else { Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure += Cars[CarIndex].CarBrake.airCompressor.Rate * TimeElapsed; if (!Cars[CarIndex].Sounds.CpLoopStarted && Game.SecondsSinceMidnight > Cars[CarIndex].Sounds.CpStartTimeStarted + 5.0) { Cars[CarIndex].Sounds.CpLoopStarted = true; Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpLoop.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpLoop.Position; Cars[CarIndex].Sounds.CpLoop.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, true); } } } } else { if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure < Cars[CarIndex].CarBrake.mainReservoir.MinimumPressure) { Cars[CarIndex].CarBrake.airCompressor.Enabled = true; Cars[CarIndex].Sounds.CpStartTimeStarted = Game.SecondsSinceMidnight; Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpStart.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpStart.Position; Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); } } } } if (CarIndex == DriverCar && Handles.HasLocoBrake) { switch (Handles.LocoBrakeType) { case LocoBrakeType.Independant: //With an independant Loco brake, we always want to use this handle Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); break; case LocoBrakeType.Combined: if (Handles.LocoBrake is LocoBrakeHandle && Handles.Brake is NotchedHandle) { //Both handles are of the notched type if (Handles.Brake.MaximumNotch == Handles.LocoBrake.MaximumNotch) { //Identical number of notches, so return the handle with the higher setting if (Handles.LocoBrake.Actual >= Handles.Brake.Actual) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } } else if (Handles.Brake.MaximumNotch > Handles.LocoBrake.MaximumNotch) { double nc = ((double)Handles.LocoBrake.Actual / Handles.LocoBrake.MaximumNotch) * Handles.Brake.MaximumNotch; if (nc > Handles.Brake.Actual) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } } else { double nc = ((double)Handles.Brake.Actual / Handles.Brake.MaximumNotch) * Handles.LocoBrake.MaximumNotch; if (nc > Handles.LocoBrake.Actual) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } } } else if (Handles.LocoBrake is LocoAirBrakeHandle && Handles.Brake is AirBrakeHandle) { if (Handles.LocoBrake.Actual < Handles.Brake.Actual) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } } else { double p, tp; //Calculate the pressure differentials for the two handles if (Handles.LocoBrake is LocoAirBrakeHandle) { //Air brake handle p = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.Brake.MaximumNotch) * Handles.Brake.Actual; } else { //Notched handle p = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.LocoBrake.MaximumNotch) * Handles.LocoBrake.Actual; } if (p < tp) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } } break; case LocoBrakeType.Blocking: if (Handles.LocoBrake.Actual != 0) { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } break; } } else { Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } switch (Cars[CarIndex].CarBrake.airSound) { case AirSound.AirZero: { Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirZero.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirZero.Position; Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); } break; } case AirSound.Air: { Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Air.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Air.Position; Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); } break; } case AirSound.AirHigh: { Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirHigh.Buffer; if (buffer != null) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirHigh.Position; Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); } break; } } // deceleration provided by motor if (!(Cars[CarIndex].CarBrake is AutomaticAirBrake) && Math.Abs(Cars[CarIndex].Specs.CurrentSpeed) >= Cars[CarIndex].CarBrake.brakeControlSpeed & Handles.Reverser.Actual != 0 & !Handles.EmergencyBrake.Actual) { double f; if (Handles.LocoBrake.Actual != 0 && CarIndex == DriverCar) { f = (double)Handles.LocoBrake.Actual / (double)Handles.Brake.MaximumNotch; } else { f = (double)Handles.Brake.Actual / (double)Handles.Brake.MaximumNotch; } double a = Cars[CarIndex].Specs.MotorDeceleration; DecelerationDueToMotor = f * a; } else { DecelerationDueToMotor = 0.0; } // hold brake Cars[CarIndex].Specs.HoldBrake.Update(ref DecelerationDueToMotor, Handles.HoldBrake.Actual); { // rub sound Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Rub.Buffer; if (buffer != null) { double spd = Math.Abs(Cars[CarIndex].Specs.CurrentSpeed); double pitch = 1.0 / (spd + 1.0) + 1.0; double gain = Cars[CarIndex].Derailed ? 0.0 : Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; if (spd < 1.38888888888889) { double t = spd * spd; gain *= 1.5552 * t - 0.746496 * spd * t; } else if (spd > 12.5) { double t = spd - 12.5; const double fadefactor = 0.1; gain *= 1.0 / (fadefactor * t * t + 1.0); } if (Sounds.IsPlaying(Cars[CarIndex].Sounds.Rub.Source)) { if (pitch > 0.01 & gain > 0.001) { Cars[CarIndex].Sounds.Rub.Source.Pitch = pitch; Cars[CarIndex].Sounds.Rub.Source.Volume = gain; } else { Sounds.StopSound(Cars[CarIndex].Sounds.Rub.Source); } } else if (pitch > 0.02 & gain > 0.01) { OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Rub.Position; Cars[CarIndex].Sounds.Rub.Source = Sounds.PlaySound(buffer, pitch, gain, pos, this, CarIndex, true); } } } }