public override int Read(byte[] buffer, int offset, int count) { MixAudioStreamChannels channels = Channels; IntPtr pointer; using (buffer.Pin(out pointer, offset, count)) { int sourceCount = count * Source.Format.SampleChannelCount(); if (sourceCount > data.Length) { data = new byte[sourceCount]; } int read = Source.Read(data, offset, sourceCount); switch (Source.Format) { case AudioFormat.MonoByte: case AudioFormat.MonoInt16: case AudioFormat.MonoSingle: return(Source.Read(buffer, offset, count)); case AudioFormat.StereoByte: for (int index = 0; index < read - 1; index += 2) { switch (channels) { case MixAudioStreamChannels.Left: buffer[index / 2] = data[index]; break; case MixAudioStreamChannels.Right: buffer[index / 2] = data[index + 1]; break; case MixAudioStreamChannels.Mix: buffer[index / 2] = (byte)(((data[index] - 128) + (data[index + 1] - 128)) / 2 + 128); break; default: throw new NotSupportedException(); } } return(read / 2); case AudioFormat.StereoInt16: for (int index = 0; index < read - 3; index += 4) { short left = BitConverter.ToInt16(data, index); short right = BitConverter.ToInt16(data, index + 2); short output; switch (channels) { case MixAudioStreamChannels.Left: output = left; break; case MixAudioStreamChannels.Right: output = right; break; case MixAudioStreamChannels.Mix: output = (short)((left + right) / 2); break; default: throw new NotSupportedException(); } buffer[index / 2] = (byte)output; buffer[index / 2 + 1] = (byte)(output >> 8); } return(read / 2); case AudioFormat.StereoSingle: for (int index = 0; index < read - 7; index += 8) { float left = BitConverter.ToSingle(data, index); float right = BitConverter.ToSingle(data, index + 4); float output; switch (channels) { case MixAudioStreamChannels.Left: output = left; break; case MixAudioStreamChannels.Right: output = right; break; case MixAudioStreamChannels.Mix: output = (short)((left + right) / 2); break; default: throw new NotSupportedException(); } Marshal.WriteInt32(pointer + index / 2, output.ToBits()); } return(read / 2); default: throw new NotSupportedException(); } } }
public MixAudioStream(AudioStream source, bool closeSourceOnClose = false, MixAudioStreamChannels channels = MixAudioStreamChannels.Mix) : base(source, closeSourceOnClose) { Channels = channels; }