Пример #1
0
 public AudioSampleHistoryBuffer(float bufferTime)
 {
     size = (int)(bufferTime * WaveOutput.InternalFormat.SampleRate);
     AudioEngine.Log($"AudioSampleHistoryBuffer: Create buffer for {bufferTime}s -> {size} samples");
     buffer = new float[size];
 }
Пример #2
0
 public void Dispose()
 {
     AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Disposed ");
     Processor = null;
 }
Пример #3
0
 public AudioSampleBuffer(WaveFormat format)
 {
     AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Created {format}");
     WaveFormat = format;
 }
Пример #4
0
        public void Update(WaveOutputDevice device, AudioSampleBuffer input, out string status,
                           out WaveFormat waveFormat, out int latency, out float cpuUsage,
                           out int bufferUnderRuns, int sampleRate = 44100,
                           int driverLatency = 200, int internalLatency = 300, int bufferSize = 512, bool reset = false)
        {
            bool hasDeviceChanged = device?.Value != Device?.Value ||
                                    sampleRate != SampleRate ||
                                    driverLatency != DriverLatency ||
                                    bufferSize != BufferSize ||
                                    reset;

            Device          = device;
            Input           = input;
            SampleRate      = sampleRate;
            InternalLatency = internalLatency;
            DriverLatency   = driverLatency;
            BufferSize      = bufferSize;

            if (hasDeviceChanged)
            {
                processor?.Dispose();
                processor = null;

                if (waveOut != null)
                {
                    AudioEngine.Log("Stopping WaveOut...");
                    waveOut.Stop();
                    waveOut.Dispose();
                }
            }

            if (processor == null)
            {
                processor = new AudioThread.AudioThreadProcessor(BufferSize);
            }

            processor.EnsureThreadIsRunning();
            processor.RequestedLatency = InternalLatency;

            if (hasDeviceChanged)
            {
                InternalFormat      = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, 2);
                SingleChannelFormat = WaveFormat.CreateIeeeFloatWaveFormat(sampleRate, 1);

                processor.WaveFormat = InternalFormat;

                if (device != null)
                {
                    AudioEngine.Log(
                        $"WaveOutput: Configuration changed, device={device.Value}, sampleRate={sampleRate}, latency={InternalLatency} {HotSwapped} ");
                    try
                    {
                        waveOut = ((IWaveOutputFactory)device.Tag).Create(DriverLatency);
                        var wave16 = new SampleToWaveProvider16(processor);
                        waveOut.Init(wave16);
                        waveOut.Play();
                        AudioEngine.Log("WaveOutput: Started");
                        OutputFormat = wave16.WaveFormat;
                    }
                    catch (Exception e)
                    {
                        AudioEngine.Log(e);
                        waveOut = null;
                    }
                }
            }

            processor.Input = Input;

            status = waveOut != null?waveOut.PlaybackState.ToString() : "Uninitialized";

            waveFormat      = OutputFormat;
            latency         = processor.Latency;
            cpuUsage        = processor.CpuUsage;
            bufferUnderRuns = processor.BufferUnderRuns;
        }
Пример #5
0
        public AudioSampleBuffer Update(WaveInputDevice device, out string status,
                                        out WaveFormat waveFormat, out int latency, out float cpuUsage, out int bufferUnderRuns,
                                        int driverLatency = 150, int internalLatency = 8, int bufferSize = 512, bool reset = false)
        {
            bool hasDeviceChanged = Device?.Value != device?.Value ||
                                    DriverLatency != driverLatency ||
                                    BufferSize != bufferSize ||
                                    reset;

            Device          = device;
            DriverLatency   = driverLatency;
            InternalLatency = internalLatency;
            BufferSize      = bufferSize;

            if (hasDeviceChanged)
            {
                processor?.Dispose();
                processor = null;

                if (waveIn != null)
                {
                    AudioEngine.Log("Stopping WaveIn...");
                    waveIn.StopRecording();
                    waveIn.Dispose();
                }
            }


            if (processor == null)
            {
                processor = new AudioThread.AudioThreadProcessor(bufferSize);
            }

            processor.EnsureThreadIsRunning();
            processor.RequestedLatency = internalLatency;

            if (hasDeviceChanged)
            {
                if (device != null)
                {
                    AudioEngine.Log(
                        $"WaveInput: Configuration changed, device={device.Value}, requested latency={DriverLatency}");
                    try
                    {
                        waveIn       = ((IWaveInputFactory)device.Tag).Create(DriverLatency);
                        bufferedWave = new BufferedWaveProvider(waveIn.WaveFormat);
                        bufferedWave.DiscardOnBufferOverflow = true;
                        sampleProvider       = new WaveToSampleProvider(bufferedWave);
                        OutputFormat         = sampleProvider.WaveFormat;
                        processor.WaveFormat = OutputFormat;
                        processor.Input      = sampleProvider;

                        waveIn.DataAvailable += (s, a) => { bufferedWave.AddSamples(a.Buffer, 0, a.BytesRecorded); };
                        waveIn.StartRecording();
                        AudioEngine.Log("WaveInput: Started");

                        output = new AudioSampleBuffer(OutputFormat)
                        {
                            Processor = processor
                        };
                    }
                    catch (Exception e)
                    {
                        AudioEngine.Log(e);
                        waveIn = null;
                    }
                }
            }


            status          = waveIn != null ? "Recording" : "Uninitialized";
            waveFormat      = OutputFormat;
            latency         = processor.Latency;
            cpuUsage        = processor.CpuUsage;
            bufferUnderRuns = processor.BufferUnderRuns;
            return(output);
        }
Пример #6
0
            private void RunInThread()
            {
                float[] buffer      = new float[bufferSize];
                var     stopWatch   = Stopwatch.StartNew();
                var     clock       = Stopwatch.StartNew();
                var     lastElapsed = 0.0;

                AudioEngine.Log($"Starting AudioThread {GetHashCode()}...");
                try
                {
                    while (Running)
                    {
                        if (playBuffer.IsValid && Input != null)
                        {
                            if (playBuffer.BufferedDuration.Milliseconds < RequestedLatency)
                            {
                                try
                                {
                                    stopWatch.Stop();
                                    var idleTime = stopWatch.ElapsedTicks;
                                    stopWatch.Restart();

                                    while (playBuffer.BufferedDuration.Milliseconds < RequestedLatency)
                                    {
                                        Input?.Read(buffer, 0, buffer.Length);
                                        playBuffer.AddSamples(buffer, 0, buffer.Length);
                                    }

                                    Latency = playBuffer.BufferedDuration.Milliseconds;
                                    stopWatch.Stop();
                                    var calcTime = stopWatch.ElapsedTicks;
                                    stopWatch.Restart();

                                    CpuUsage = (float)calcTime / (idleTime + calcTime);
                                }
                                catch (Exception e)
                                {
                                    AudioEngine.Log(e);
                                }
                            }
                            else
                            {
                                if (RunWithoutOutput)
                                {
                                    var elapsed = clock.Elapsed.TotalSeconds;
                                    var delta   = elapsed - lastElapsed;
                                    lastElapsed = elapsed;
                                    playBuffer.Advance(TimeSpan.FromSeconds(delta));
                                    Thread.Sleep(RequestedLatency);
                                }
                            }
                        }
                        else
                        {
                            Thread.Sleep(100);
                        }
                    }
                }
                catch (Exception e)
                {
                    AudioEngine.Log(e);
                }

                AudioEngine.Log($"AudioThread {GetHashCode()} terminated");
            }