mirror of
https://github.com/SDRSharpR/SDRSharper.git
synced 2025-12-06 04:12:02 +01:00
642 lines
18 KiB
C#
642 lines
18 KiB
C#
using SDRSharp.Radio.PortAudio;
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
|
|
namespace SDRSharp.Radio
|
|
{
|
|
public sealed class StreamControl : IDisposable
|
|
{
|
|
private const int WaveBufferSize = 65536;
|
|
|
|
private const int MaxDecimationFactor = 1024;
|
|
|
|
private static readonly int _processorCount = Utils.ProcessorCount;
|
|
|
|
private int _minOutputSampleRate = Utils.GetIntSetting("minOutputSampleRate", 18000);
|
|
|
|
private unsafe float* _dspOutPtr;
|
|
|
|
private UnsafeBuffer _dspOutBuffer;
|
|
|
|
private unsafe Complex* _iqInPtr;
|
|
|
|
private UnsafeBuffer _iqInBuffer;
|
|
|
|
private unsafe Complex* _dspInPtr;
|
|
|
|
private UnsafeBuffer _dspInBuffer;
|
|
|
|
private WavePlayer _wavePlayer;
|
|
|
|
private WaveRecorder _waveRecorder;
|
|
|
|
private WaveDuplex _waveDuplex;
|
|
|
|
private WaveFile _waveFile;
|
|
|
|
private string _fileName;
|
|
|
|
private ComplexFifoStream _iqStream;
|
|
|
|
private FloatFifoStream _audioStream;
|
|
|
|
private Thread _waveReadThread;
|
|
|
|
private Thread _dspThread;
|
|
|
|
private DateTime _waveStart;
|
|
|
|
private float _audioGain;
|
|
|
|
private float _outputGain;
|
|
|
|
private int _inputDevice;
|
|
|
|
private double _inputSampleRate;
|
|
|
|
private int _inputBufferSize;
|
|
|
|
private int _bufferSizeInMs;
|
|
|
|
private int _outputDevice;
|
|
|
|
private double _outputSampleRate;
|
|
|
|
private int _outputBufferSize;
|
|
|
|
private double _soundCardRatio = 1.0;
|
|
|
|
private int _decimationStageCount;
|
|
|
|
private bool _swapIQ;
|
|
|
|
private bool _useASIO;
|
|
|
|
private InputType _inputType;
|
|
|
|
private IFrontendController _frontend;
|
|
|
|
private bool _isBuffering;
|
|
|
|
private float _clipLevel;
|
|
|
|
public DateTime WaveStart
|
|
{
|
|
get
|
|
{
|
|
return this._waveStart;
|
|
}
|
|
set
|
|
{
|
|
this._waveStart = value;
|
|
}
|
|
}
|
|
|
|
public string FileName => this._fileName;
|
|
|
|
public WaveFile WaveFile => this._waveFile;
|
|
|
|
public int MinOutputSampleRate
|
|
{
|
|
get
|
|
{
|
|
return this._minOutputSampleRate;
|
|
}
|
|
set
|
|
{
|
|
this._minOutputSampleRate = value;
|
|
}
|
|
}
|
|
|
|
public double SoundCardRatio => this._soundCardRatio;
|
|
|
|
public int AudioStreamSize
|
|
{
|
|
get
|
|
{
|
|
if (this._audioStream == null)
|
|
{
|
|
return 0;
|
|
}
|
|
return this._audioStream.Length;
|
|
}
|
|
}
|
|
|
|
public float AudioGain
|
|
{
|
|
get
|
|
{
|
|
return this._audioGain;
|
|
}
|
|
set
|
|
{
|
|
this._audioGain = value;
|
|
this._outputGain = (float)Math.Pow((double)value / 10.0, 10.0);
|
|
this._outputGain = (float)Math.Pow(10.0, (double)value / 10.0);
|
|
}
|
|
}
|
|
|
|
public bool SwapIQ
|
|
{
|
|
get
|
|
{
|
|
return this._swapIQ;
|
|
}
|
|
set
|
|
{
|
|
this._swapIQ = value;
|
|
}
|
|
}
|
|
|
|
public bool UseASIO
|
|
{
|
|
get
|
|
{
|
|
return this._useASIO;
|
|
}
|
|
set
|
|
{
|
|
this._useASIO = value;
|
|
}
|
|
}
|
|
|
|
public double SampleRate => this._inputSampleRate;
|
|
|
|
public bool IsPlaying => this._inputSampleRate != 0.0;
|
|
|
|
public bool IsBuffering
|
|
{
|
|
get
|
|
{
|
|
return this._isBuffering;
|
|
}
|
|
set
|
|
{
|
|
this._isBuffering = false;
|
|
}
|
|
}
|
|
|
|
public int BufferSize => this._inputBufferSize;
|
|
|
|
public int BufferSizeInMs => this._bufferSizeInMs;
|
|
|
|
public int DecimationStageCount => this._decimationStageCount;
|
|
|
|
public InputType InputType => this._inputType;
|
|
|
|
public float ClipLevel => this._clipLevel;
|
|
|
|
public event ProcessBufferDelegate ProcessBufferPtr;
|
|
|
|
public StreamControl()
|
|
{
|
|
this.AudioGain = 0f;
|
|
}
|
|
|
|
~StreamControl()
|
|
{
|
|
this.Dispose();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
this.Stop();
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private unsafe void DuplexFiller(float* buffer, int frameCount)
|
|
{
|
|
if (this._dspInBuffer == null || this._dspInBuffer.Length != frameCount)
|
|
{
|
|
this._dspInBuffer = UnsafeBuffer.Create(frameCount, sizeof(Complex));
|
|
this._dspInPtr = (Complex*)(void*)this._dspInBuffer;
|
|
}
|
|
if (this._dspOutBuffer == null || this._dspOutBuffer.Length != this._dspInBuffer.Length * 2)
|
|
{
|
|
this._dspOutBuffer = UnsafeBuffer.Create(this._dspInBuffer.Length * 2, 4);
|
|
this._dspOutPtr = (float*)(void*)this._dspOutBuffer;
|
|
}
|
|
Utils.Memcpy(this._dspInPtr, buffer, frameCount * sizeof(Complex));
|
|
this.ProcessBuffer();
|
|
this.ScaleBuffer(this._dspOutPtr, this._dspOutBuffer.Length);
|
|
Utils.Memcpy(buffer, this._dspOutPtr, this._dspOutBuffer.Length * 4);
|
|
}
|
|
|
|
private unsafe void PlayerFiller(float* buffer, int frameCount)
|
|
{
|
|
int num = frameCount * 2;
|
|
int num2 = this._audioStream.Read(buffer, num);
|
|
this.ScaleBuffer(buffer, num2);
|
|
this._clipLevel = 0f;
|
|
for (int i = 0; i < num2; i++)
|
|
{
|
|
this._clipLevel = Math.Max(this._clipLevel, Math.Abs(buffer[i]));
|
|
}
|
|
for (int j = num2; j < num; j++)
|
|
{
|
|
buffer[j] = 0f;
|
|
}
|
|
}
|
|
|
|
private unsafe void RecorderFiller(float* buffer, int frameCount)
|
|
{
|
|
if (this._iqStream.Length <= this._inputBufferSize * 2)
|
|
{
|
|
if (this._iqInBuffer == null || this._iqInBuffer.Length != frameCount)
|
|
{
|
|
this._iqInBuffer = UnsafeBuffer.Create(frameCount, sizeof(Complex));
|
|
this._iqInPtr = (Complex*)(void*)this._iqInBuffer;
|
|
}
|
|
Utils.Memcpy(this._iqInPtr, buffer, frameCount * sizeof(Complex));
|
|
this._iqStream.Write(this._iqInPtr, frameCount);
|
|
}
|
|
}
|
|
|
|
private unsafe void FrontendFiller(IFrontendController sender, Complex* samples, int len)
|
|
{
|
|
if (this._iqStream.Length < this._inputBufferSize * 4)
|
|
{
|
|
this._iqStream.Write(samples, len);
|
|
}
|
|
}
|
|
|
|
private unsafe void WaveFileFiller()
|
|
{
|
|
Complex[] array = new Complex[65536];
|
|
int num = 0;
|
|
Complex[] array2 = array;
|
|
fixed (Complex* ptr = array2)
|
|
{
|
|
Console.WriteLine("WaveFiller started");
|
|
while (this.IsPlaying)
|
|
{
|
|
if (this._iqStream.Length < this._inputBufferSize * 4)
|
|
{
|
|
int num2 = this._waveFile.Read(ptr, array.Length, ref num);
|
|
this._iqStream.Write(ptr, num2);
|
|
if (num2 < array.Length)
|
|
{
|
|
string fileName = this._waveFile.FileName;
|
|
int num3 = fileName.ToLower().LastIndexOf(".wav");
|
|
if (int.TryParse(fileName.Substring(num3 - 2, 2), out int num4))
|
|
{
|
|
num3 -= 2;
|
|
}
|
|
string str = fileName.Substring(0, num3);
|
|
int num5 = ++num4;
|
|
string text = str + num5.ToString("00") + ".wav";
|
|
if (!File.Exists(text))
|
|
{
|
|
text = this._fileName;
|
|
this._waveStart = DateTime.Now;
|
|
}
|
|
this._waveFile.Close();
|
|
this._waveFile.Dispose();
|
|
this._waveFile = new WaveFile(text);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Thread.Sleep(2);
|
|
}
|
|
}
|
|
Console.WriteLine("WaveFiller stopped");
|
|
}
|
|
}
|
|
|
|
private unsafe void ScaleBuffer(float* buffer, int length)
|
|
{
|
|
for (int i = 0; i < length; i++)
|
|
{
|
|
buffer[i] *= this._outputGain;
|
|
}
|
|
}
|
|
|
|
private unsafe void DSPProc()
|
|
{
|
|
if (this._dspInBuffer == null || this._dspInBuffer.Length != this._inputBufferSize)
|
|
{
|
|
this._dspInBuffer = UnsafeBuffer.Create(this._inputBufferSize, sizeof(Complex));
|
|
this._dspInPtr = (Complex*)(void*)this._dspInBuffer;
|
|
}
|
|
if (this._dspOutBuffer == null || this._dspOutBuffer.Length != this._outputBufferSize)
|
|
{
|
|
this._dspOutBuffer = UnsafeBuffer.Create(this._outputBufferSize, 4);
|
|
this._dspOutPtr = (float*)(void*)this._dspOutBuffer;
|
|
}
|
|
Console.WriteLine("DSPPROC started");
|
|
while (this.IsPlaying)
|
|
{
|
|
int num = 0;
|
|
while (this.IsPlaying && num < this._dspInBuffer.Length)
|
|
{
|
|
int count = this._dspInBuffer.Length - num;
|
|
num += this._iqStream.Read(this._dspInPtr, num, count);
|
|
}
|
|
int count2 = this.ProcessBuffer();
|
|
this._audioStream.Write(this._dspOutPtr, count2);
|
|
}
|
|
this._isBuffering = false;
|
|
Console.WriteLine("DSPPROC stopped");
|
|
}
|
|
|
|
private unsafe int ProcessBuffer()
|
|
{
|
|
if (this.ProcessBufferPtr == null)
|
|
{
|
|
return 0;
|
|
}
|
|
if (this._swapIQ)
|
|
{
|
|
this.swapIQBuffer();
|
|
}
|
|
this._isBuffering = true;
|
|
var x = this.ProcessBufferPtr(this._dspInPtr, this._dspOutPtr, this._dspInBuffer.Length, this._dspOutBuffer.Length);
|
|
return x;
|
|
}
|
|
|
|
private unsafe void swapIQBuffer()
|
|
{
|
|
for (int i = 0; i < this._dspInBuffer.Length; i++)
|
|
{
|
|
float real = this._dspInPtr[i].Real;
|
|
this._dspInPtr[i].Real = this._dspInPtr[i].Imag;
|
|
this._dspInPtr[i].Imag = real;
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (this._inputType == InputType.Plugin && this._frontend != null)
|
|
{
|
|
this._frontend.Stop();
|
|
this._frontend = null;
|
|
}
|
|
if (this._wavePlayer != null)
|
|
{
|
|
this._wavePlayer.Dispose();
|
|
this._wavePlayer = null;
|
|
}
|
|
if (this._waveRecorder != null)
|
|
{
|
|
this._waveRecorder.Dispose();
|
|
this._waveRecorder = null;
|
|
}
|
|
if (this._waveDuplex != null)
|
|
{
|
|
this._waveDuplex.Dispose();
|
|
this._waveDuplex = null;
|
|
}
|
|
this._inputSampleRate = 0.0;
|
|
if (this._waveReadThread != null)
|
|
{
|
|
this._waveReadThread.Join();
|
|
this._waveReadThread = null;
|
|
}
|
|
if (this._iqStream != null)
|
|
{
|
|
this._iqStream.Close();
|
|
}
|
|
if (this._audioStream != null)
|
|
{
|
|
this._audioStream.Close();
|
|
}
|
|
if (this._dspThread != null)
|
|
{
|
|
this._dspThread.Join();
|
|
this._dspThread = null;
|
|
}
|
|
if (this._waveFile != null)
|
|
{
|
|
this._waveFile.Dispose();
|
|
this._waveFile = null;
|
|
}
|
|
if (this._iqStream != null)
|
|
{
|
|
this._iqStream.Dispose();
|
|
this._iqStream = null;
|
|
}
|
|
this._audioStream = null;
|
|
this._dspOutBuffer = null;
|
|
this._iqInBuffer = null;
|
|
}
|
|
|
|
public unsafe void Play()
|
|
{
|
|
if (this._wavePlayer == null && this._waveDuplex == null)
|
|
{
|
|
if (this._inputType != InputType.WaveFile)
|
|
{
|
|
this._waveStart = DateTime.Now.AddYears(1);
|
|
}
|
|
double sampleRate = this._outputSampleRate;
|
|
int framesPerBuffer = this._outputBufferSize / 2;
|
|
if (this._soundCardRatio > 1.0)
|
|
{
|
|
sampleRate = (double)this._minOutputSampleRate;
|
|
framesPerBuffer = (int)((double)this._outputBufferSize / (2.0 * this._soundCardRatio));
|
|
}
|
|
switch (this._inputType)
|
|
{
|
|
case InputType.SoundCard:
|
|
if (this._inputDevice == this._outputDevice)
|
|
{
|
|
this._waveDuplex = new WaveDuplex(this._inputDevice, this._inputSampleRate, this._inputBufferSize, this.DuplexFiller);
|
|
}
|
|
else
|
|
{
|
|
this._iqStream = new ComplexFifoStream(BlockMode.BlockingRead);
|
|
ComplexFifoStream iqStream2 = this._iqStream;
|
|
bool read2 = false;
|
|
iqStream2.SetLog("_iqStream", 20000, read2, true);
|
|
this._audioStream = new FloatFifoStream(BlockMode.BlockingWrite, this._outputBufferSize);
|
|
Console.WriteLine("_audioStream created with size " + this._outputBufferSize.ToString());
|
|
FloatFifoStream audioStream3 = this._audioStream;
|
|
bool write3 = false;
|
|
audioStream3.SetLog("_audioStream", this._outputBufferSize, true, write3);
|
|
this._waveRecorder = new WaveRecorder(this._inputDevice, this._inputSampleRate, this._inputBufferSize, this.RecorderFiller);
|
|
this._wavePlayer = new WavePlayer(this._outputDevice, sampleRate, framesPerBuffer, this.PlayerFiller);
|
|
this._dspThread = new Thread(this.DSPProc);
|
|
this._dspThread.Start();
|
|
}
|
|
break;
|
|
case InputType.WaveFile:
|
|
{
|
|
this._iqStream = new ComplexFifoStream(BlockMode.BlockingRead);
|
|
this._iqStream.SetLog("_iqStream", 20000, true, true);
|
|
this._audioStream = new FloatFifoStream(BlockMode.BlockingWrite, this._outputBufferSize * 2);
|
|
Console.WriteLine("_audioStream created with size " + (this._outputBufferSize * 2).ToString());
|
|
FloatFifoStream audioStream2 = this._audioStream;
|
|
bool write2 = false;
|
|
audioStream2.SetLog("_audioStream", this._outputBufferSize, true, write2);
|
|
this._wavePlayer = new WavePlayer(this._outputDevice, sampleRate, framesPerBuffer, this.PlayerFiller);
|
|
this._waveReadThread = new Thread(this.WaveFileFiller);
|
|
this._waveReadThread.Start();
|
|
this._dspThread = new Thread(this.DSPProc);
|
|
this._dspThread.Start();
|
|
break;
|
|
}
|
|
case InputType.Plugin:
|
|
{
|
|
this._iqStream = new ComplexFifoStream(BlockMode.BlockingRead);
|
|
ComplexFifoStream iqStream = this._iqStream;
|
|
bool read = false;
|
|
iqStream.SetLog("_iqStream", 20000, read, true);
|
|
this._audioStream = new FloatFifoStream(BlockMode.BlockingWrite, this._outputBufferSize * 2);
|
|
Console.WriteLine("_audioStream created with size " + (this._outputBufferSize * 2).ToString());
|
|
FloatFifoStream audioStream = this._audioStream;
|
|
bool write = false;
|
|
audioStream.SetLog("_audioStream", 0, true, write);
|
|
this._wavePlayer = new WavePlayer(this._outputDevice, sampleRate, framesPerBuffer, this.PlayerFiller);
|
|
this._frontend.Start(this.FrontendFiller);
|
|
this._dspThread = new Thread(this.DSPProc);
|
|
this._dspThread.Start();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void OpenSoundDevice(int inputDevice, int outputDevice, double inputSampleRate, int latency)
|
|
{
|
|
this.Stop();
|
|
this._inputType = InputType.SoundCard;
|
|
this._inputDevice = inputDevice;
|
|
this._outputDevice = outputDevice;
|
|
this._inputSampleRate = inputSampleRate;
|
|
this._bufferSizeInMs = latency;
|
|
this._inputBufferSize = (int)((double)this._bufferSizeInMs * this._inputSampleRate / 1000.0);
|
|
if (this._inputDevice == this._outputDevice)
|
|
{
|
|
this._decimationStageCount = 0;
|
|
this._inputBufferSize = this._inputBufferSize / StreamControl._processorCount * StreamControl._processorCount;
|
|
int num = (int)Math.Log((double)this._inputBufferSize, 2.0);
|
|
this._inputBufferSize = (int)Math.Pow(2.0, (double)num);
|
|
this._bufferSizeInMs = (int)Math.Round((double)this._inputBufferSize / this._inputSampleRate * 1000.0);
|
|
this._outputSampleRate = this._inputSampleRate;
|
|
this._outputBufferSize = this._inputBufferSize * 2;
|
|
this._soundCardRatio = 1.0;
|
|
}
|
|
else
|
|
{
|
|
this._decimationStageCount = this.GetDecimationStageCount();
|
|
int num2 = (int)Math.Pow(2.0, (double)this._decimationStageCount);
|
|
this._inputBufferSize = this._inputBufferSize / num2 * num2;
|
|
this._inputBufferSize = this._inputBufferSize / StreamControl._processorCount * StreamControl._processorCount;
|
|
int num3 = (int)Math.Log((double)this._inputBufferSize, 2.0);
|
|
this._inputBufferSize = (int)Math.Pow(2.0, (double)num3);
|
|
this._bufferSizeInMs = (int)Math.Round((double)this._inputBufferSize / this._inputSampleRate * 1000.0);
|
|
this._outputSampleRate = this._inputSampleRate / (double)num2;
|
|
this._outputBufferSize = this._inputBufferSize / num2 * 2;
|
|
if (this._outputSampleRate > 192000.0)
|
|
{
|
|
this._soundCardRatio = this._outputSampleRate / 192000.0;
|
|
}
|
|
else
|
|
{
|
|
this._soundCardRatio = (this._useASIO ? (this._outputSampleRate / (double)this._minOutputSampleRate) : 1.0);
|
|
}
|
|
}
|
|
Console.WriteLine("_inputBuffersize (complex) set to " + (Utils.FastConvolve ? "power of 2 : " : ": ") + this._inputBufferSize.ToString());
|
|
Console.WriteLine("_outputBuffersize (real) set to : " + this._outputBufferSize.ToString());
|
|
Console.WriteLine("_soundCardRatio set to : " + this._soundCardRatio.ToString());
|
|
}
|
|
|
|
public int OpenFile(string filename, int outputDevice, int latency)
|
|
{
|
|
this.Stop();
|
|
try
|
|
{
|
|
this._inputType = InputType.WaveFile;
|
|
this._fileName = filename;
|
|
this._waveFile = new WaveFile(filename);
|
|
this._waveStart = DateTime.Now;
|
|
this._outputDevice = outputDevice;
|
|
this._bufferSizeInMs = latency;
|
|
this._inputSampleRate = (double)this._waveFile.SampleRate;
|
|
this._decimationStageCount = this.GetDecimationStageCount();
|
|
this._inputBufferSize = (int)((double)this._bufferSizeInMs * this._inputSampleRate / 1000.0);
|
|
int num = (int)Math.Pow(2.0, (double)this._decimationStageCount);
|
|
this._inputBufferSize = this._inputBufferSize / num * num;
|
|
this._inputBufferSize = this._inputBufferSize / StreamControl._processorCount * StreamControl._processorCount;
|
|
int num2 = (int)Math.Log((double)this._inputBufferSize, 2.0);
|
|
this._inputBufferSize = (int)Math.Pow(2.0, (double)num2);
|
|
this._bufferSizeInMs = (int)Math.Round((double)this._inputBufferSize / this._inputSampleRate * 1000.0);
|
|
this._outputSampleRate = this._inputSampleRate / (double)num;
|
|
this._outputBufferSize = this._inputBufferSize / num * 2;
|
|
if (this._outputSampleRate > 192000.0)
|
|
{
|
|
this._soundCardRatio = this._outputSampleRate / 192000.0;
|
|
}
|
|
else
|
|
{
|
|
this._soundCardRatio = (this._useASIO ? (this._outputSampleRate / (double)this._minOutputSampleRate) : 1.0);
|
|
}
|
|
Console.WriteLine("_inputBuffersize (complex) set to " + (Utils.FastConvolve ? "power of 2 : " : ": ") + this._inputBufferSize.ToString());
|
|
Console.WriteLine("_outputBuffersize (real) set to : " + this._outputBufferSize.ToString());
|
|
Console.WriteLine("_soundCardRatio set to : " + this._soundCardRatio.ToString());
|
|
return this._waveFile.Duration;
|
|
}
|
|
catch
|
|
{
|
|
this.Stop();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public void OpenPlugin(IFrontendController frontend, int outputDevice, int latency)
|
|
{
|
|
this.Stop();
|
|
try
|
|
{
|
|
this._inputType = InputType.Plugin;
|
|
this._frontend = frontend;
|
|
this._inputSampleRate = this._frontend.Samplerate;
|
|
this._outputDevice = outputDevice;
|
|
this._bufferSizeInMs = latency;
|
|
this._inputBufferSize = (int)((double)this._bufferSizeInMs * this._inputSampleRate / 1000.0);
|
|
this._decimationStageCount = this.GetDecimationStageCount();
|
|
int num = (int)Math.Pow(2.0, (double)this._decimationStageCount);
|
|
this._inputBufferSize = this._inputBufferSize / num * num;
|
|
this._inputBufferSize = this._inputBufferSize / StreamControl._processorCount * StreamControl._processorCount;
|
|
int num2 = (int)Math.Log((double)this._inputBufferSize, 2.0);
|
|
this._inputBufferSize = (int)Math.Pow(2.0, (double)num2);
|
|
this._bufferSizeInMs = (int)Math.Round((double)this._inputBufferSize / this._inputSampleRate * 1000.0);
|
|
this._outputSampleRate = this._inputSampleRate / (double)num;
|
|
this._outputBufferSize = this._inputBufferSize / num * 2;
|
|
if (this._outputSampleRate > 192000.0)
|
|
{
|
|
this._soundCardRatio = this._outputSampleRate / 192000.0;
|
|
}
|
|
else
|
|
{
|
|
this._soundCardRatio = (this._useASIO ? (this._outputSampleRate / (double)this._minOutputSampleRate) : 1.0);
|
|
}
|
|
Console.WriteLine("_inputBuffersize (complex) set to " + (Utils.FastConvolve ? "power of 2 : " : ": ") + this._inputBufferSize.ToString());
|
|
Console.WriteLine("_outputBuffersize (real) set to : " + this._outputBufferSize.ToString());
|
|
Console.WriteLine("_soundCardRatio set to : " + this._soundCardRatio.ToString());
|
|
}
|
|
catch
|
|
{
|
|
this.Stop();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private int GetDecimationStageCount()
|
|
{
|
|
if (this._inputSampleRate <= (double)this._minOutputSampleRate)
|
|
{
|
|
return 0;
|
|
}
|
|
int num = 1024;
|
|
while (this._inputSampleRate < (double)(this._minOutputSampleRate * num) && num > 0)
|
|
{
|
|
num /= 2;
|
|
}
|
|
return (int)Math.Log((double)num, 2.0);
|
|
}
|
|
}
|
|
}
|