Example #1
0
		/// <summary>
		/// WaveStream to resample using the DMO Resampler
		/// </summary>
		/// <param name="inputProvider">Input Stream</param>
		/// <param name="outputFormat">Desired Output Format</param>
		public ResamplerDmoStream(IWaveProvider inputProvider, WaveFormat outputFormat)
		{
			this.inputProvider = inputProvider;
			inputStream = inputProvider as WaveStream;
			this.outputFormat = outputFormat;
			resampler = new Resampler();
			if (!resampler.MediaObject.SupportsInputWaveFormat(0, inputStream.WaveFormat))
			{
				throw new ArgumentException("Unsupported Input Stream format", "inputStream");
			}

			resampler.MediaObject.SetInputWaveFormat(0, inputStream.WaveFormat);
			if (!resampler.MediaObject.SupportsOutputWaveFormat(0, outputFormat))
			{
				throw new ArgumentException("Unsupported Output Stream format", "outputStream");
			}

			resampler.MediaObject.SetOutputWaveFormat(0, outputFormat);
			if (inputStream != null)
			{
				position = InputToOutputPosition(inputStream.Position);
			}
			inputMediaBuffer = new MediaBuffer(inputProvider.WaveFormat.AverageBytesPerSecond);
			outputBuffer = new DmoOutputDataBuffer(outputFormat.AverageBytesPerSecond);
		}
		/// <summary>
		/// Creates a stream that can convert to PCM
		/// </summary>
		/// <param name="sourceStream">The source stream</param>
		/// <returns>A PCM stream</returns>
		public static WaveStream CreatePcmStream(WaveStream sourceStream)
		{
			if (sourceStream.WaveFormat.Encoding == WaveFormatEncoding.Pcm)
			{
				return sourceStream;
			}
			WaveFormat pcmFormat = AcmStream.SuggestPcmFormat(sourceStream.WaveFormat);
			return new WaveFormatConversionStream(pcmFormat, sourceStream);
		}
		/// <summary>
		/// Create a new simple compressor stream
		/// </summary>
		/// <param name="sourceStream">Source stream</param>
		public SimpleCompressorStream(WaveStream sourceStream)
		{
			this.sourceStream = sourceStream;
			channels = sourceStream.WaveFormat.Channels;
			bytesPerSample = sourceStream.WaveFormat.BitsPerSample/8;
			simpleCompressor = new SimpleCompressor(5.0, 10.0, sourceStream.WaveFormat.SampleRate);
			simpleCompressor.Threshold = 16;
			simpleCompressor.Ratio = 6;
			simpleCompressor.MakeUpGain = 16;
		}
		/// <summary>
		/// Create a new WaveFormat conversion stream
		/// </summary>
		/// <param name="targetFormat">Desired output format</param>
		/// <param name="sourceStream">Source stream</param>
		public WaveFormatConversionStream(WaveFormat targetFormat, WaveStream sourceStream)
		{
			this.sourceStream = sourceStream;
			this.targetFormat = targetFormat;

			conversionStream = new AcmStream(sourceStream.WaveFormat, targetFormat);
			// work out how many bytes the entire input stream will convert to
			length = SourceToDest((int) sourceStream.Length);
			blockAlign = SourceToDest(sourceStream.BlockAlign);
			position = 0;
		}
Example #5
0
		/// <summary>
		/// Creates a new Wave32To16Stream
		/// </summary>
		/// <param name="sourceStream">the source stream</param>
		public Wave32To16Stream(WaveStream sourceStream)
		{
			if (sourceStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
				throw new ApplicationException("Only 32 bit Floating point supported");
			if (sourceStream.WaveFormat.BitsPerSample != 32)
				throw new ApplicationException("Only 32 bit Floating point supported");

			waveFormat = new WaveFormat(sourceStream.WaveFormat.SampleRate, 16, sourceStream.WaveFormat.Channels);
			volume = 1.0f;
			this.sourceStream = sourceStream;
			length = sourceStream.Length/2;
			position = sourceStream.Position/2;
		}
Example #6
0
		/// <summary>
		/// Creates a new WaveOffsetStream
		/// </summary>
		/// <param name="sourceStream">the source stream</param>
		/// <param name="startTime">the time at which we should start reading from the source stream</param>
		/// <param name="sourceOffset">amount to trim off the front of the source stream</param>
		/// <param name="sourceLength">length of time to play from source stream</param>
		public WaveOffsetStream(WaveStream sourceStream, TimeSpan startTime, TimeSpan sourceOffset, TimeSpan sourceLength)
		{
			if (sourceStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
				throw new ApplicationException("Only PCM supported");
			// TODO: add support for IEEE float + perhaps some others -
			// anything with a fixed bytes per sample

			this.sourceStream = sourceStream;
			position = 0;
			bytesPerSample = (sourceStream.WaveFormat.BitsPerSample/8)*sourceStream.WaveFormat.Channels;
			StartTime = startTime;
			SourceOffset = sourceOffset;
			SourceLength = sourceLength;
		}
Example #7
0
		/// <summary>
		/// Creates a new WaveChannel32
		/// </summary>
		/// <param name="sourceStream">the source stream</param>
		/// <param name="volume">stream volume (1 is 0dB)</param>
		/// <param name="pan">pan control (-1 to 1)</param>
		public WaveChannel32(WaveStream sourceStream, float volume, float pan)
		{
			PadWithZeroes = true;
			if (sourceStream.WaveFormat.Encoding != WaveFormatEncoding.Pcm)
				throw new ApplicationException("Only PCM supported");
			if (sourceStream.WaveFormat.BitsPerSample != 16)
				throw new ApplicationException("Only 16 bit audio supported");

			// always outputs stereo 32 bit
			waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sourceStream.WaveFormat.SampleRate, 2);
			destBytesPerSample = 8; // includes stereo factoring

			this.sourceStream = sourceStream;
			this.volume = volume;
			this.pan = pan;
			sourceBytesPerSample = sourceStream.WaveFormat.Channels*sourceStream.WaveFormat.BitsPerSample/8;

			length = SourceToDest(sourceStream.Length);
			position = 0;
		}
		/// <summary>
		/// Disposes this stream
		/// </summary>
		/// <param name="disposing">true if the user called this</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				// Release managed resources.
				if (sourceStream != null)
				{
					sourceStream.Dispose();
					sourceStream = null;
				}
			}
			// Release unmanaged resources.
			// Set large fields to null.
			// Call Dispose on your base class.
			base.Dispose(disposing);
		}
		/// <summary>
		/// Disposes this stream
		/// </summary>
		/// <param name="disposing">true if the user called this</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				// Release managed resources.
				if (conversionStream != null)
				{
					conversionStream.Dispose();
					conversionStream = null;
				}
				if (sourceStream != null)
				{
					sourceStream.Dispose();
					sourceStream = null;
				}
			}
			else
			{
				Debug.Assert(false, "WaveFormatConversionStream was not disposed");
			}
			// Release unmanaged resources.
			// Set large fields to null.
			// Call Dispose on your base class.
			base.Dispose(disposing);
		}
Example #10
0
		/// <summary>
		/// Disposes this WaveStream
		/// </summary>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (sourceStream != null)
				{
					sourceStream.Dispose();
					sourceStream = null;
				}
			}
			base.Dispose(disposing);
		}
Example #11
0
		/// <summary>
		/// Creates a WaveOffsetStream with default settings (no offset or pre-delay,
		/// and whole length of source stream)
		/// </summary>
		/// <param name="sourceStream">The source stream</param>
		public WaveOffsetStream(WaveStream sourceStream)
			: this(sourceStream, TimeSpan.Zero, TimeSpan.Zero, sourceStream.TotalTime)
		{
		}
Example #12
0
		/// <summary>
		/// Disposes this WaveStream
		/// </summary>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (sourceStream != null)
				{
					sourceStream.Dispose();
					sourceStream = null;
				}
			}
			else
			{
				Debug.Assert(false, "WaveOffsetStream was not Disposed");
			}
			base.Dispose(disposing);
		}
		/// <summary>
		/// Creates a new BlockAlignReductionStream
		/// </summary>
		/// <param name="sourceStream">the input stream</param>
		public BlockAlignReductionStream(WaveStream sourceStream)
		{
			this.sourceStream = sourceStream;
			circularBuffer = new CircularBuffer(sourceStream.WaveFormat.AverageBytesPerSecond*4);
		}
		/// <summary>
		/// Disposes this WaveStream
		/// </summary>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (sourceStream != null)
				{
					sourceStream.Dispose();
					sourceStream = null;
				}
			}
			else
			{
				Debug.Assert(false, "BlockAlignReductionStream was not Disposed");
			}
			base.Dispose(disposing);
		}
Example #15
0
		/// <summary>
		/// Creates a WaveChannel32 with default settings
		/// </summary>
		/// <param name="sourceStream">The source stream</param>
		public WaveChannel32(WaveStream sourceStream)
			:
				this(sourceStream, 1.0f, 0.0f)
		{
		}
Example #16
0
		/// <summary>
		/// Add a new input to the mixer
		/// </summary>
		/// <param name="waveStream">The wave input to add</param>
		public void AddInputStream(WaveStream waveStream)
		{
			if (waveStream.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat)
				throw new ArgumentException("Must be IEEE floating point", "waveStream.WaveFormat");
			if (waveStream.WaveFormat.BitsPerSample != 32)
				throw new ArgumentException("Only 32 bit audio currently supported", "waveStream.WaveFormat");

			if (inputStreams.Count == 0)
			{
				// first one - set the format
				int sampleRate = waveStream.WaveFormat.SampleRate;
				int channels = waveStream.WaveFormat.Channels;
				waveFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, channels);
			}
			else
			{
				if (!waveStream.WaveFormat.Equals(waveFormat))
					throw new ArgumentException("All incoming channels must have the same format", "inputStreams.WaveFormat");
			}

			lock (this)
			{
				inputStreams.Add(waveStream);
				length = Math.Max(length, waveStream.Length);
				// get to the right point in this input file
				Position = Position;
			}
		}
Example #17
0
		/// <summary>
		/// Remove a WaveStream from the mixer
		/// </summary>
		/// <param name="waveStream">waveStream to remove</param>
		public void RemoveInputStream(WaveStream waveStream)
		{
			lock (this)
			{
				if (inputStreams.Remove(waveStream))
				{
					// recalculate the length
					length = 0;
					foreach (WaveStream inputStream in inputStreams)
					{
						length = Math.Max(length, waveStream.Length);
					}
				}
			}
		}
Example #18
0
		/// <summary>
		/// Creates a Wave file by reading all the data from a WaveStream
		/// </summary>
		/// <param name="filename">The filename to use</param>
		/// <param name="stream">The source WaveStream</param>
		public static void CreateWaveFile(string filename, WaveStream stream)
		{
			using (var writer = new WaveFileWriter(filename, stream.WaveFormat))
			{
				var buffer = new byte[stream.WaveFormat.SampleRate*stream.WaveFormat.Channels*16];
				while (true)
				{
					int bytesRead = stream.Read(buffer, 0, buffer.Length);
					if (bytesRead == 0)
						break;
					writer.WriteData(buffer, 0, bytesRead);
				}
			}
		}