/// <summary> /// Initialises to play /// </summary> /// <param name="waveProvider"></param> public void Init(IWaveProvider waveProvider) { sourceStream = waveProvider; waveFormat = waveProvider.WaveFormat; // Select the correct sample convertor from WaveFormat -> ASIOFormat convertor = ASIOSampleConvertor.SelectSampleConvertor(waveFormat, driver.Capabilities.OutputChannelInfos[0].type); if (!driver.IsSampleRateSupported(waveFormat.SampleRate)) { throw new ArgumentException("SampleRate is not supported. TODO, implement Resampler"); } if (driver.Capabilities.SampleRate != waveFormat.SampleRate) { driver.SetSampleRate(waveFormat.SampleRate); } // Plug the callback driver.FillBufferCalback = driver_BufferUpdate; // Used Prefered size of ASIO Buffer nbSamples = driver.CreateBuffers(waveFormat.Channels, false); // make a buffer big enough to read enough from the sourceStream to fill the ASIO buffers waveBuffer = new byte[nbSamples * waveFormat.Channels * waveFormat.BitsPerSample / 8]; }
/// <summary> /// Initialises to play /// </summary> /// <param name="waveProvider">Source wave provider</param> public void Init(IWaveProvider waveProvider) { if (this.sourceStream != null) { throw new InvalidOperationException("Already initialised this instance of AsioOut - dispose and create a new one"); } sourceStream = waveProvider; waveFormat = waveProvider.WaveFormat; // Select the correct sample convertor from WaveFormat -> ASIOFormat convertor = ASIOSampleConvertor.SelectSampleConvertor(waveFormat, driver.Capabilities.OutputChannelInfos[0].type); if (!driver.IsSampleRateSupported(waveFormat.SampleRate)) { throw new ArgumentException("SampleRate is not supported. TODO, implement Resampler"); } if (driver.Capabilities.SampleRate != waveFormat.SampleRate) { driver.SetSampleRate(waveFormat.SampleRate); } // Plug the callback driver.FillBufferCallback = driver_BufferUpdate; // Used Prefered size of ASIO Buffer nbSamples = driver.CreateBuffers(waveFormat.Channels, false); driver.SetChannelOffset(channelOffset); // will throw an exception if channel offset is too high // make a buffer big enough to read enough from the sourceStream to fill the ASIO buffers waveBuffer = new byte[nbSamples * waveFormat.Channels * waveFormat.BitsPerSample / 8]; }
/// <summary> /// Initialises to play, with optional recording /// </summary> /// <param name="waveProvider">Source wave provider - set to null for record only</param> /// <param name="recordChannels">Number of channels to record</param> /// <param name="recordOnlySampleRate">Specify sample rate here if only recording, ignored otherwise</param> public void InitRecordAndPlayback(IWaveProvider waveProvider, int recordChannels, int recordOnlySampleRate) { if (this.sourceStream != null) { throw new InvalidOperationException("Already initialised this instance of AsioOut - dispose and create a new one"); } int desiredSampleRate = waveProvider != null ? waveProvider.WaveFormat.SampleRate : recordOnlySampleRate; if (waveProvider != null) { sourceStream = waveProvider; this.NumberOfOutputChannels = waveProvider.WaveFormat.Channels; // Select the correct sample convertor from WaveFormat -> ASIOFormat convertor = ASIOSampleConvertor.SelectSampleConvertor(waveProvider.WaveFormat, driver.Capabilities.OutputChannelInfos[0].type); } else { this.NumberOfOutputChannels = 0; } if (!driver.IsSampleRateSupported(desiredSampleRate)) { throw new ArgumentException("SampleRate is not supported"); } if (driver.Capabilities.SampleRate != desiredSampleRate) { driver.SetSampleRate(desiredSampleRate); } // Plug the callback driver.FillBufferCallback = driver_BufferUpdate; this.NumberOfInputChannels = recordChannels; // Used Prefered size of ASIO Buffer nbSamples = driver.CreateBuffers(NumberOfOutputChannels, NumberOfInputChannels, false); driver.SetChannelOffset(ChannelOffset, InputChannelOffset); // will throw an exception if channel offset is too high if (waveProvider != null) { // make a buffer big enough to read enough from the sourceStream to fill the ASIO buffers waveBuffer = new byte[nbSamples * NumberOfOutputChannels * waveProvider.WaveFormat.BitsPerSample / 8]; } }
public static ASIOSampleConvertor.SampleConvertor SelectSampleConvertor(WaveFormat waveFormat, AsioSampleType asioType) { ASIOSampleConvertor.SampleConvertor result = null; bool flag = waveFormat.Channels == 2; switch (asioType) { case AsioSampleType.Int16LSB: { int bitsPerSample = waveFormat.BitsPerSample; if (bitsPerSample != 16) { if (bitsPerSample == 32) { result = (flag ? new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorFloatToShort2Channels) : new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorFloatToShortGeneric)); } } else { result = (flag ? new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorShortToShort2Channels) : new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorShortToShortGeneric)); } break; } case AsioSampleType.Int24LSB: { int bitsPerSample2 = waveFormat.BitsPerSample; if (bitsPerSample2 == 16) { throw new ArgumentException("Not a supported conversion"); } if (bitsPerSample2 == 32) { result = new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConverterFloatTo24LSBGeneric); } break; } case AsioSampleType.Int32LSB: { int bitsPerSample3 = waveFormat.BitsPerSample; if (bitsPerSample3 != 16) { if (bitsPerSample3 == 32) { result = (flag ? new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorFloatToInt2Channels) : new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorFloatToIntGeneric)); } } else { result = (flag ? new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorShortToInt2Channels) : new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConvertorShortToIntGeneric)); } break; } case AsioSampleType.Float32LSB: { int bitsPerSample4 = waveFormat.BitsPerSample; if (bitsPerSample4 == 16) { throw new ArgumentException("Not a supported conversion"); } if (bitsPerSample4 == 32) { result = new ASIOSampleConvertor.SampleConvertor(ASIOSampleConvertor.ConverterFloatToFloatGeneric); } break; } default: throw new ArgumentException(string.Format("ASIO Buffer Type {0} is not yet supported.", Enum.GetName(typeof(AsioSampleType), asioType))); } return(result); }