Represents a sound.
Example #1
0
        // --- sound ---

        /// <summary>Loads a sound and returns the sound data.</summary>
        /// <param name="path">The path to the file or folder that contains the sound.</param>
        /// <param name="sound">Receives the sound.</param>
        /// <returns>Whether loading the sound was successful.</returns>
        public override bool LoadSound(string path, out OpenBveApi.Sounds.Sound sound)
        {
            if (System.IO.File.Exists(path) || System.IO.Directory.Exists(path))
            {
                for (int i = 0; i < Program.CurrentHost.Plugins.Length; i++)
                {
                    if (Program.CurrentHost.Plugins[i].Sound != null)
                    {
                        try {
                            if (Program.CurrentHost.Plugins[i].Sound.CanLoadSound(path))
                            {
                                try {
                                    if (Program.CurrentHost.Plugins[i].Sound.LoadSound(path, out sound))
                                    {
                                        return(true);
                                    }
                                    Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " returned unsuccessfully at LoadSound");
                                } catch (Exception ex) {
                                    Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " raised the following exception at LoadSound:" + ex.Message);
                                }
                            }
                        } catch (Exception ex) {
                            Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " raised the following exception at CanLoadSound:" + ex.Message);
                        }
                    }
                }
                Interface.AddMessage(MessageType.Error, false, "No plugin found that is capable of loading sound " + path);
            }
            else
            {
                ReportProblem(OpenBveApi.Hosts.ProblemType.PathNotFound, path);
            }
            sound = null;
            return(false);
        }
Example #2
0
		/// <summary>Loads the specified sound.</summary>
		/// <param name="path">The path to the file or folder that contains the sound.</param>
		/// <param name="sound">Receives the sound.</param>
		/// <returns>Whether loading the sound was successful.</returns>
		public override bool LoadSound(string path, out Sound sound) {
			// --- decode file ---
			int sampleRate;
			int bitsPerSample;
			int[][] samples = Flac.Decoder.Decode(path, out sampleRate, out bitsPerSample);
			// --- format data for API structure ---
			byte[][] bytes = new byte[samples.Length][];
			unchecked {
				int bytesPerSample = (int)((bitsPerSample + 7) >> 3);
				for (int i = 0; i < samples.Length; i++) {
					bytes[i] = new byte[samples[i].Length * bytesPerSample];
					if (bitsPerSample <= 8) {
						for (int j = 0; j < samples[i].Length; j++) {
							int value = (samples[i][j] >> 24) + 128;
							bytes[i][j] = (byte)value;
						}
						bitsPerSample = 8;
					} else {
						for (int j = 0; j < samples[i].Length; j++) {
							int value = samples[i][j] >> 16;
							bytes[i][2 * j + 0] = (byte)value;
							bytes[i][2 * j + 1] = (byte)(value >> 8);
						}
						bitsPerSample = 16;
					}
				}
			}
			sound = new Sound(sampleRate, bitsPerSample, bytes);
			return true;
		}
			internal SoundBuffer(Sound sound, double radius) {
				this.Origin = new RawOrigin(sound);
				this.Radius = radius;
				this.Loaded = false;
				this.OpenAlBufferName = 0;
				this.Duration = 0.0;
				this.Ignore = false;
			}
Example #4
0
 /// <summary>Creates a new sound buffer</summary>
 /// <param name="sound">The raw sound source, loaded via an API plugin</param>
 /// <param name="radius">The radius of the sound</param>
 internal SoundBuffer(OpenBveApi.Sounds.Sound sound, double radius)
 {
     this.Origin           = new RawOrigin(sound);
     this.Radius           = radius;
     this.Loaded           = false;
     this.OpenAlBufferName = 0;
     this.Duration         = 0.0;
     this.Ignore           = false;
 }
Example #5
0
 /// <summary>Registers a sound buffer and returns a handle to the buffer.</summary>
 /// <param name="data">The raw sound data.</param>
 /// <param name="radius">The default effective radius.</param>
 /// <returns>The handle to the sound buffer.</returns>
 internal static SoundBuffer RegisterBuffer(OpenBveApi.Sounds.Sound data, double radius)
 {
     if (Buffers.Length == BufferCount)
     {
         Array.Resize <SoundBuffer>(ref Buffers, Buffers.Length << 1);
     }
     Buffers[BufferCount] = new SoundBuffer(data, radius);
     BufferCount++;
     return(Buffers[BufferCount - 1]);
 }
Example #6
0
 /// <summary>Creates a new sound buffer</summary>
 /// <param name="sound">The raw sound source, loaded via an API plugin</param>
 /// <param name="radius">The radius of the sound</param>
 internal SoundBuffer(OpenBveApi.Sounds.Sound sound, double radius)
 {
     this.Origin               = new RawOrigin(sound);
     this.Radius               = radius;
     this.Loaded               = false;
     this.OpenAlBufferName     = 0;
     this.Duration             = 0.0;
     this.InternalVolumeFactor = 0.5;
     this.Ignore               = false;
     this.PitchFunction        = null;
     this.VolumeFunction       = null;
 }
Example #7
0
		/// <summary>Mixes all channels into a single channel.</summary>
		/// <param name="sound">The sound.</param>
		/// <returns>The mono mix in the same format as the original.</returns>
		/// <exception cref="System.NotSupportedException">Raised when the bits per sample are not supported.</exception>
		private static byte[] GetMonoMix(Sound sound) {
			if (sound.Bytes.Length == 1 || sound.Bytes[0].Length == 0)
				return sound.Bytes[0];
			/*
			 * Convert integer samples to floating-point samples.
			 */
			float[][] samples;
			if (sound.BitsPerSample == 8) {
				samples = new float[sound.Bytes.Length][];
				for (int i = 0; i < sound.Bytes.Length; i++) {
					samples[i] = new float[sound.Bytes[i].Length];
					for (int j = 0; j < sound.Bytes[i].Length; j++) {
						byte value = sound.Bytes[i][j];
						samples[i][j] = ((float)value - 128.0f) / (value < 128 ? 128.0f : 127.0f);
					}
				}
			} else if (sound.BitsPerSample == 16) {
				samples = new float[sound.Bytes.Length][];
				for (int i = 0; i < sound.Bytes.Length; i++) {
					samples[i] = new float[sound.Bytes[i].Length >> 1];
					for (int j = 0; j < sound.Bytes[i].Length; j += 2) {
						short value = (short)(ushort)((int)sound.Bytes[i][j] | ((int)sound.Bytes[i][j + 1] << 8));
						samples[i][j >> 1] = (float)value / (value < 0 ? 32768.0f : 32767.0f);
					}
				}
			} else {
				throw new NotSupportedException();
			}
			/*
			 * Mix floating-point samples to mono.
			 * */
			float[] mix = GetNormalizedMonoMix(samples);
			/*
			 * Convert floating-point samples to integer samples.
			 */
			byte[] result;
			if (sound.BitsPerSample == 8) {
				result = new byte[mix.Length];
				for (int i = 0; i < mix.Length; i++) {
					result[i] = (byte)((mix[i] < 0.0f ? 128.0f : 127.0f) * mix[i] + 128.0f);
				}
			} else if (sound.BitsPerSample == 16) {
				result = new byte[2 * mix.Length];
				for (int i = 0; i < mix.Length; i++) {
					int value = (int)(ushort)(short)((mix[i] < 0.0f ? 32768.0f : 32767.0f) * mix[i]);
					result[2 * i + 0] = (byte)value;
					result[2 * i + 1] = (byte)(value >> 8);
				}
			} else {
				throw new NotSupportedException();
			}
			return result;
		}
Example #8
0
 /// <summary>Registers a sound and returns a handle to the sound.</summary>
 /// <param name="sound">The sound data.</param>
 /// <param name="handle">Receives a handle to the sound.</param>
 /// <returns>Whether loading the sound was successful.</returns>
 public override bool RegisterSound(OpenBveApi.Sounds.Sound sound, out OpenBveApi.Sounds.SoundHandle handle)
 {
     handle = Program.Sounds.RegisterBuffer(sound, 0.0);
     return(true);
 }
Example #9
0
 /// <summary>Loads a sound and returns the sound data.</summary>
 /// <param name="path">The path to the file or folder that contains the sound.</param>
 /// <param name="sound">Receives the sound.</param>
 /// <returns>Whether loading the sound was successful.</returns>
 public virtual bool LoadSound(string path, out Sound sound)
 {
     sound = null;
     return false;
 }
Example #10
0
		/// <summary>Loads the specified sound.</summary>
		/// <param name="path">The path to the file or folder that contains the sound.</param>
		/// <param name="sound">Receives the sound.</param>
		/// <returns>Whether loading the sound was successful.</returns>
		public override bool LoadSound(string path, out Sound sound) {
			sound = LoadFromFile(path);
			return true;
		}
Example #11
0
		/// <summary>Loads the specified sound.</summary>
		/// <param name="path">The path to the file or folder that contains the sound.</param>
		/// <param name="sound">Receives the sound.</param>
		/// <returns>Whether loading the sound was successful.</returns>
		public abstract bool LoadSound(string path, out Sound sound);