예제 #1
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;
                }
            }
        }
예제 #2
0
        /// <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;
        }
예제 #3
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;
                }
            }
        }