Exemple #1
0
 /// <summary>Plays a car sound.</summary>
 /// <param name="sound">The car sound.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="train">The train the sound is attached to.</param>
 /// <param name="car">The car in the train the sound is attached to.</param>
 /// <param name="looped">Whether to play the sound in a loop.</param>
 /// <returns>The sound source.</returns>
 internal static void PlayCarSound(TrainManager.CarSound sound, double pitch, double volume, TrainManager.Train train, int car, bool looped)
 {
     if (sound.Buffer == null)
     {
         return;
     }
     if (train == null)
     {
         throw new InvalidDataException("A train and car must be specified");
     }
     sound.Source = PlaySound(sound.Buffer, pitch, volume, sound.Position, train, car, looped);
 }
Exemple #2
0
        /// <summary>Attempts to load an array of sound files into a car-sound array</summary>
        /// <param name="Folder">The folder the sound files are located in</param>
        /// <param name="FileStart">The first sound file</param>
        /// <param name="FileEnd">The last sound file</param>
        /// <param name="Position">The position the sound is to be emitted from within the car</param>
        /// <param name="Radius">The sound radius</param>
        /// <returns>The new car sound array</returns>
        internal static TrainManager.CarSound[] TryLoadSoundArray(string Folder, string FileStart, string FileEnd, Vector3 Position, double Radius)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
            TrainManager.CarSound[]          Sounds  = { };
            if (!System.IO.Directory.Exists(Folder))
            {
                //Detect whether the given folder exists before attempting to load from it
                return(Sounds);
            }
            string[] Files = System.IO.Directory.GetFiles(Folder);
            for (int i = 0; i < Files.Length; i++)
            {
                string a = System.IO.Path.GetFileName(Files[i]);
                if (a == null)
                {
                    return(Sounds);
                }

                if (a.Length > FileStart.Length + FileEnd.Length)
                {
                    if (a.StartsWith(FileStart, StringComparison.OrdinalIgnoreCase) & a.EndsWith(FileEnd, StringComparison.OrdinalIgnoreCase))
                    {
                        string b = a.Substring(FileStart.Length, a.Length - FileEnd.Length - FileStart.Length);
                        int    n; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, Culture, out n))
                        {
                            if (n >= 0)
                            {
                                int m = Sounds.Length;
                                if (n >= m)
                                {
                                    Array.Resize <TrainManager.CarSound>(ref Sounds, n + 1);
                                    for (int j = m; j < n; j++)
                                    {
                                        Sounds[j]        = TrainManager.CarSound.Empty;
                                        Sounds[j].Source = null;
                                    }
                                }
                                Sounds[n] = new TrainManager.CarSound(Files[i], Position, Radius);
                            }
                        }
                    }
                }
            }
            return(Sounds);
        }
Exemple #3
0
 /// <summary>Parses an XML node containing a list of sounds into a car sound array</summary>
 /// <param name="node">The node to parse</param>
 /// <param name="Sounds">The car sound array</param>
 /// <param name="Position">The default position of the sound (May be overriden by any node)</param>
 /// <param name="Radius">The default radius of the sound (May be overriden by any node)</param>
 private static void ParseArrayNode(XmlNode node, out TrainManager.CarSound[] Sounds, Vector3 Position, double Radius)
 {
     Sounds = new TrainManager.CarSound[0];
     foreach (XmlNode c in node.ChildNodes)
     {
         int idx = -1;
         if (c.Name.ToLowerInvariant() != "sound")
         {
             Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array node " + c.Name + " in XML node " + node.Name);
         }
         else
         {
             for (int i = 0; i < c.ChildNodes.Count; i++)
             {
                 if (c.ChildNodes[i].Name.ToLowerInvariant() == "index")
                 {
                     if (!NumberFormats.TryParseIntVb6(c.ChildNodes[i].InnerText.ToLowerInvariant(), out idx))
                     {
                         Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name);
                         return;
                     }
                     break;
                 }
             }
             if (idx >= 0)
             {
                 int l = Sounds.Length;
                 Array.Resize(ref Sounds, idx + 1);
                 while (l < Sounds.Length)
                 {
                     Sounds[l] = TrainManager.CarSound.Empty;
                     l++;
                 }
                 ParseNode(c, out Sounds[idx], Position, Radius);
             }
             else
             {
                 Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name);
             }
         }
     }
 }
Exemple #4
0
 private static TrainManager.CarSound[] TryLoadSoundArray(string Folder, string FileStart, string FileEnd, Vector3 Position, double Radius)
 {
     System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
     TrainManager.CarSound[] Sounds = new TrainManager.CarSound[] { };
     string[] Files = System.IO.Directory.GetFiles(Folder);
     for (int i = 0; i < Files.Length; i++) {
         string a = System.IO.Path.GetFileName(Files[i]);
         if (a.Length > FileStart.Length + FileEnd.Length) {
             if (a.StartsWith(FileStart, StringComparison.OrdinalIgnoreCase) & a.EndsWith(FileEnd, StringComparison.OrdinalIgnoreCase)) {
                 string b = a.Substring(FileStart.Length, a.Length - FileEnd.Length - FileStart.Length);
                 int n; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, Culture, out n)) {
                     if (n >= 0) {
                         int m = Sounds.Length;
                         if (n >= m) {
                             Array.Resize<TrainManager.CarSound>(ref Sounds, n + 1);
                             for (int j = m; j < n; j++) {
                                 Sounds[j] = TrainManager.CarSound.Empty;
                                 Sounds[j].Source = null;
                             }
                         }
                         Sounds[n] = TryLoadSound(Files[i], Position, Radius);
                     }
                 }
             }
         }
     }
     return Sounds;
 }
Exemple #5
0
        /// <summary>Parses a single XML node into a car sound</summary>
        /// <param name="node">The node to parse</param>
        /// <param name="Sound">The car sound</param>
        /// <param name="Position">The default position of this sound (May be overriden by the node)</param>
        /// <param name="Radius">The default radius of this sound (May be overriden by the node)</param>
        private static void ParseNode(XmlNode node, out TrainManager.CarSound Sound, Vector3 Position, double Radius)
        {
            string fileName = null;

            foreach (XmlNode c in node.ChildNodes)
            {
                switch (c.Name.ToLowerInvariant())
                {
                case "filename":
                    try
                    {
                        fileName = OpenBveApi.Path.CombineFile(currentPath, c.InnerText);
                        if (!System.IO.File.Exists(fileName))
                        {
                            //Valid path, but the file does not exist
                            Interface.AddMessage(Interface.MessageType.Error, false, "The sound path " + c.InnerText + " in XML node " + node.Name + " does not exist.");
                            Sound = TrainManager.CarSound.Empty;
                            return;
                        }
                    }
                    catch
                    {
                        //Probably invalid filename characters
                        Interface.AddMessage(Interface.MessageType.Error, false, "The sound path " + c.InnerText + " in XML node " + node.Name + " is invalid.");
                        Sound = TrainManager.CarSound.Empty;
                        return;
                    }
                    break;

                case "position":
                    string[] Arguments = c.InnerText.Split(',');
                    double   x = 0.0, y = 0.0, z = 0.0;
                    if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out x))
                    {
                        Interface.AddMessage(Interface.MessageType.Error, false, "Sound radius X " + Arguments[0] + " in XML node " + node.Name + " is invalid.");
                        x = 0.0;
                    }
                    if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out y))
                    {
                        Interface.AddMessage(Interface.MessageType.Error, false, "Sound radius Y " + Arguments[1] + " in XML node " + node.Name + " is invalid.");
                        y = 0.0;
                    }
                    if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out z))
                    {
                        Interface.AddMessage(Interface.MessageType.Error, false, "Sound radius Z " + Arguments[2] + " in XML node " + node.Name + " is invalid.");
                        z = 0.0;
                    }
                    Position = new Vector3(x, y, z);
                    break;

                case "radius":
                    if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out Radius))
                    {
                        Interface.AddMessage(Interface.MessageType.Error, false, "The sound radius " + c.InnerText + " in XML node " + node.Name + " is invalid.");
                    }
                    break;
                }
            }
            if (fileName == null)
            {
                //No valid filename node specified
                Interface.AddMessage(Interface.MessageType.Error, false, "XML node " + node.Name + " does not point to a valid sound file.");
                Sound = TrainManager.CarSound.Empty;
                return;
            }
            Sound = new TrainManager.CarSound(fileName, Position, Radius);
        }
Exemple #6
0
        /// <summary>Loads the sound set for a BVE2 based train</summary>
        /// <param name="train">The train</param>
        /// <param name="trainFolder">The absolute on-disk path to the train's folder</param>
        internal static void Parse(string trainFolder, TrainManager.Train train)
        {
            // set sound positions and radii
            Vector3 front  = new Vector3(0.0, 0.0, 0.5 * train.Cars[train.DriverCar].Length);
            Vector3 center = new Vector3(0.0, 0.0, 0.0);
            Vector3 left   = new Vector3(-1.3, 0.0, 0.0);
            Vector3 right  = new Vector3(1.3, 0.0, 0.0);
            Vector3 cab    = new Vector3(-train.Cars[train.DriverCar].Driver.X, train.Cars[train.DriverCar].Driver.Y, train.Cars[train.DriverCar].Driver.Z - 0.5);
            Vector3 panel  = new Vector3(train.Cars[train.DriverCar].Driver.X, train.Cars[train.DriverCar].Driver.Y, train.Cars[train.DriverCar].Driver.Z + 1.0);

            // load sounds for driver's car
            train.Cars[train.DriverCar].Sounds.Adjust          = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Adjust.wav"), panel, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Sounds.Brake           = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Brake.wav"), center, SoundCfgParser.smallRadius);
            train.Cars[train.DriverCar].Sounds.Halt            = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Halt.wav"), cab, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Horns[0].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon0.wav"), SoundCfgParser.smallRadius);
            train.Cars[train.DriverCar].Horns[0].Loop          = false;
            train.Cars[train.DriverCar].Horns[0].SoundPosition = front;
            if (train.Cars[train.DriverCar].Horns[0].LoopSound == null)
            {
                train.Cars[train.DriverCar].Horns[0].LoopSound = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon.wav"), SoundCfgParser.largeRadius);
            }
            train.Cars[train.DriverCar].Horns[1].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon1.wav"), SoundCfgParser.largeRadius);
            train.Cars[train.DriverCar].Horns[1].Loop          = false;
            train.Cars[train.DriverCar].Horns[1].SoundPosition = front;
            train.Cars[train.DriverCar].Horns[2].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon2.wav"), SoundCfgParser.mediumRadius);
            train.Cars[train.DriverCar].Horns[2].Loop          = true;
            train.Cars[train.DriverCar].Horns[2].SoundPosition = front;
            train.Cars[train.DriverCar].Sounds.PilotLampOn     = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Leave.wav"), cab, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Sounds.PilotLampOff    = TrainManager.CarSound.Empty;
            // load sounds for all cars
            for (int i = 0; i < train.Cars.Length; i++)
            {
                Vector3 frontaxle = new Vector3(0.0, 0.0, train.Cars[i].FrontAxle.Position);
                Vector3 rearaxle  = new Vector3(0.0, 0.0, train.Cars[i].RearAxle.Position);
                train.Cars[i].Sounds.Air     = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Air.wav"), center, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.AirHigh = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirHigh.wav"), center, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.AirZero = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirZero.wav"), center, SoundCfgParser.smallRadius);
                if (train.Cars[i].CarBrake.brakeType == BrakeType.Main)
                {
                    train.Cars[i].Sounds.CpEnd   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpEnd.wav"), center, SoundCfgParser.mediumRadius);
                    train.Cars[i].Sounds.CpLoop  = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpLoop.wav"), center, SoundCfgParser.mediumRadius);
                    train.Cars[i].Sounds.CpStart = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpStart.wav"), center, SoundCfgParser.mediumRadius);
                }
                train.Cars[i].Sounds.BreakerResume            = TrainManager.CarSound.Empty;
                train.Cars[i].Sounds.BreakerResumeOrInterrupt = TrainManager.CarSound.Empty;
                train.Cars[i].Sounds.BreakerResumed           = false;
                train.Cars[i].Doors[0].CloseSound             = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorClsL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Doors[1].CloseSound             = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorClsR.wav"), right, SoundCfgParser.smallRadius);
                if (train.Cars[i].Doors[0].CloseSound.Buffer == null)
                {
                    train.Cars[i].Doors[0].CloseSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorCls.wav"), left, SoundCfgParser.smallRadius);
                }
                if (train.Cars[i].Doors[1].CloseSound.Buffer == null)
                {
                    train.Cars[i].Doors[1].CloseSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorCls.wav"), right, SoundCfgParser.smallRadius);
                }
                train.Cars[i].Doors[0].OpenSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpnL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Doors[1].OpenSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpnR.wav"), right, SoundCfgParser.smallRadius);
                if (train.Cars[i].Doors[0].OpenSound.Buffer == null)
                {
                    train.Cars[i].Doors[0].OpenSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpn.wav"), left, SoundCfgParser.smallRadius);
                }
                if (train.Cars[i].Doors[1].OpenSound.Buffer == null)
                {
                    train.Cars[i].Doors[1].OpenSound = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpn.wav"), right, SoundCfgParser.smallRadius);
                }
                train.Cars[i].Sounds.EmrBrake       = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "EmrBrake.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.Flange         = SoundCfgParser.TryLoadSoundArray(trainFolder, "Flange", ".wav", center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.FlangeVolume   = new double[train.Cars[i].Sounds.Flange.Length];
                train.Cars[i].Sounds.Loop           = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Loop.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].FrontAxle.PointSounds = new TrainManager.CarSound[]
                {
                    new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Point.wav"), frontaxle, SoundCfgParser.smallRadius)
                };
                train.Cars[i].RearAxle.PointSounds = new TrainManager.CarSound[]
                {
                    new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Point.wav"), rearaxle, SoundCfgParser.smallRadius)
                };
                train.Cars[i].Sounds.Rub       = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Rub.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.Run       = SoundCfgParser.TryLoadSoundArray(trainFolder, "Run", ".wav", center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.RunVolume = new double[train.Cars[i].Sounds.Run.Length];
                train.Cars[i].Sounds.SpringL   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "SpringL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.SpringR   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "SpringR.wav"), right, SoundCfgParser.smallRadius);
                // motor sound
                if (train.Cars[i].Specs.IsMotorCar)
                {
                    System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                    train.Cars[i].Sounds.Motor.Position = center;
                    for (int j = 0; j < train.Cars[i].Sounds.Motor.Tables.Length; j++)
                    {
                        for (int k = 0; k < train.Cars[i].Sounds.Motor.Tables[j].Entries.Length; k++)
                        {
                            int idx = train.Cars[i].Sounds.Motor.Tables[j].Entries[k].SoundIndex;
                            if (idx >= 0)
                            {
                                TrainManager.CarSound snd = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Motor" + idx.ToString(Culture) + ".wav"), center, SoundCfgParser.mediumRadius);
                                train.Cars[i].Sounds.Motor.Tables[j].Entries[k].Buffer = snd.Buffer;
                            }
                        }
                    }
                }
            }
        }