/// <summary> /// Applys the effects of the audio mixer to the given audio data. /// </summary> /// <param name="data">The Data.</param> /// <param name="format">The WaveFormat.</param> /// <remarks>Currently supports volume and panning for stereo sources and volume only for mono sources.</remarks> public void ApplyEffects(byte[] data, WaveFormat format) { if (format.BitsPerSample != 8 && format.BitsPerSample != 16 || format.Channels != 2) { return; } var left = System.Math.Min(1, Pan + 1); var right = System.Math.Abs(System.Math.Max(-1, Pan - 1)); left *= Volume; right *= Volume; if (format.Channels == 2) { switch (format.BitsPerSample) { case 8: for (var n = 0; n < data.Length; n += 2) { var leftChannel = data[n]; var rightChannel = data[n + 1]; data[n] = (byte) (leftChannel*left); data[n + 1] = (byte) (rightChannel*right); } break; case 16: for (int n = 0; n < data.Length; n += 4) { int leftChannel = BitConverter.ToInt16(data, n); int rightChannel = BitConverter.ToInt16(data, n + 2); byte[] sampleleft = BitConverter.GetBytes((short) (leftChannel*left)); byte[] sampleright = BitConverter.GetBytes((short) (rightChannel*right)); data[n] = sampleleft[0]; data[n + 1] = sampleleft[1]; data[n + 2] = sampleright[0]; data[n + 3] = sampleright[1]; } break; } } else if (format.Channels == 1) { switch (format.BitsPerSample) { case 8: for (var n = 0; n < data.Length; n += 1) { var channel = data[n]; data[n] = (byte) (channel*_volume); } break; case 16: for (int n = 0; n < data.Length; n += 2) { int channel = BitConverter.ToInt16(data, n); byte[] sample = BitConverter.GetBytes((short) (channel*_volume)); data[n] = sample[0]; data[n + 1] = sample[1]; } break; } } }
/// <summary> /// Reads the Header. /// </summary> private void ReadHeader() { var reader = new BinaryReader(_stream); if (ReadChunk(reader) != "RIFF") { throw new Exception("Invalid file format."); } reader.ReadInt32(); if (ReadChunk(reader) != "WAVE") { throw new Exception("Invalid file format."); } if (ReadChunk(reader) != "fmt ") { throw new Exception("Invalid file format."); } int len = reader.ReadInt32(); if (len < 16) { throw new Exception("Invalid file format."); } Format = new WaveFormat(22050, 16, 2) { Format = (WaveFormats) reader.ReadInt16(), Channels = reader.ReadInt16(), SamplesPerSec = reader.ReadInt32(), AvgBytesPerSec = reader.ReadInt32(), BlockAlign = reader.ReadInt16(), BitsPerSample = reader.ReadInt16() }; len -= 16; while (len > 0) { reader.ReadByte(); len--; } while (_stream.Position < _stream.Length && ReadChunk(reader) != "data") { } if (_stream.Position >= _stream.Length) throw new Exception("Invalid file format."); _length = reader.ReadInt32(); _position = _stream.Position; if (_length <= 0) { throw new Exception("Invalid WAV file."); } if (Format.Format != WaveFormats.Pcm && Format.Format != WaveFormats.Float) { throw new Exception("Only PCM files are supported."); } Position = 0; }
/// <summary> /// Applys the effects of the audio mixer to the given audio data. /// </summary> /// <param name="data">The Data.</param> /// <param name="format">The WaveFormat.</param> /// <remarks>Currently supports volume and panning for stereo sources and volume only for mono sources.</remarks> public void ApplyEffects(byte[] data, WaveFormat format) { if (format.BitsPerSample != 8 && format.BitsPerSample != 16 || format.Channels != 2) { return; } var left = System.Math.Min(1, Pan + 1); var right = System.Math.Abs(System.Math.Max(-1, Pan - 1)); left *= Volume; right *= Volume; if (format.Channels == 2) { switch (format.BitsPerSample) { case 8: for (var n = 0; n < data.Length; n += 2) { var leftChannel = data[n]; var rightChannel = data[n + 1]; data[n] = (byte)(leftChannel * left); data[n + 1] = (byte)(rightChannel * right); } break; case 16: for (int n = 0; n < data.Length; n += 4) { int leftChannel = BitConverter.ToInt16(data, n); int rightChannel = BitConverter.ToInt16(data, n + 2); byte[] sampleleft = BitConverter.GetBytes((short)(leftChannel * left)); byte[] sampleright = BitConverter.GetBytes((short)(rightChannel * right)); data[n] = sampleleft[0]; data[n + 1] = sampleleft[1]; data[n + 2] = sampleright[0]; data[n + 3] = sampleright[1]; } break; } } else if (format.Channels == 1) { switch (format.BitsPerSample) { case 8: for (var n = 0; n < data.Length; n += 1) { var channel = data[n]; data[n] = (byte)(channel * _volume); } break; case 16: for (int n = 0; n < data.Length; n += 2) { int channel = BitConverter.ToInt16(data, n); byte[] sample = BitConverter.GetBytes((short)(channel * _volume)); data[n] = sample[0]; data[n + 1] = sample[1]; } break; } } }