Exemplo n.º 1
0
        public AudioSampleBuffer Update(Spread <AudioSampleBuffer> inputs, Spread <int> outputMap)
        {
            var arrayInputs = inputs?.ToList();
            var arrayMap    = outputMap?.ToArray();

            HasChanges = !AudioEngine.SequenceEquals(Inputs, arrayInputs) ||
                         !AudioEngine.ArrayEquals(OutputMap, arrayMap);

            Inputs    = arrayInputs;
            OutputMap = arrayMap;

            if (HasChanges || HotSwapped)
            {
                AudioEngine.Log($"AudioMixer: configuration changed");

                if (IsValid())
                {
                    processor = new AudioMixerProcessor(Inputs, OutputMap);
                    output    = processor.Build();
                }
                else
                {
                    output?.Dispose();
                    output = null;
                }

                HotSwapped = false;
            }

            return(output);
        }
Exemplo n.º 2
0
 private void BuildOversampling()
 {
     AudioEngine.Log($"AudioSampleLoop: {state} oversampling enabled {oversampling}");
     decimators        = new Decimator[outputChannels];
     oversampleBuffer  = new float[oversampling * outputChannels];
     oversampleBuffer2 = new float[oversampling];
     for (int i = 0; i < outputChannels; i++)
     {
         decimators[i] = new Decimator(oversampling, oversampling);
     }
 }
Exemplo n.º 3
0
 public Decimator(int oversample, int quality, float cutoff = 0.9f)
 {
     AudioEngine.Log($"Decimator: New Decimator created size={oversample * quality}");
     Oversample   = oversample;
     this.quality = quality;
     this.cutoff  = cutoff;
     kernel       = new float[oversample * quality];
     inBuffer     = new float[oversample * quality];
     BoxcarLowpassIR(kernel, cutoff * 0.5f / oversample);
     BlackmanHarrisWindow(kernel);
 }
Exemplo n.º 4
0
 public void Swapped(object newInstance)
 {
     try
     {
         var s = RuntimeReflectionExtensions.GetRuntimeField(newInstance.GetType(), "HotSwapped");
         s.SetValue(newInstance, true);
     }
     catch (Exception e)
     {
         AudioEngine.Log(e.Message);
     }
 }
Exemplo n.º 5
0
        public AudioSampleBuffer Update(
            bool reset,
            AudioSampleBuffer input,
            Func <IFrameClock, TState> create,
            Func <TState, AudioSampleAccessor, TState> update,
            int outputChannels = 1,
            int oversample     = 1)
        {
            if (reset || state == null)
            {
                state = create(sampleClock);
                AudioEngine.Log($"AudioSampleLoop: Created {state}");
            }

            hasChanges = reset != this.reset ||
                         input != this.input ||
                         outputChannels != this.outputChannels ||
                         oversample != oversampling;

            this.reset          = reset;
            this.input          = input;
            createFunc          = create;
            updateFunc          = update;
            this.outputChannels = outputChannels;
            oversampling        = oversample;

            if (hasChanges || reset || HotSwapped)
            {
                AudioEngine.Log(
                    $"AudioSampleLoop({state}) configuration changed outChannels={outputChannels}, oversampling={oversample}");

                if (IsValid())
                {
                    processor = new AudioSampleLoopProcessor(state, input, sampleClock, update, outputChannels,
                                                             oversample);
                    output = processor.Build();
                }
                else
                {
                    output?.Dispose();
                    output = null;
                }

                HotSwapped = false;
            }

            processor.updateFunc = update;

            return(output);
        }
Exemplo n.º 6
0
        public IWavePlayer Create(int latency)
        {
            var asioOut = new AsioOut(driverName);

            AudioEngine.Log($"{asioOut.DriverInputChannelCount}");
            AudioEngine.Log($"{asioOut.DriverOutputChannelCount}");
            AudioEngine.Log($"{asioOut.PlaybackLatency}");
            AudioEngine.Log($"{asioOut.NumberOfInputChannels}");
            AudioEngine.Log($"{asioOut.NumberOfOutputChannels}");
            AudioEngine.Log($"{asioOut.ChannelOffset}");
            AudioEngine.Log($"{asioOut.InputChannelOffset}");
//            AudioEngine.Log($"{asioOut.}");
//            AudioEngine.Log($"{asioOut.}");
            return(asioOut);
        }
Exemplo n.º 7
0
        public Spread <AudioSampleBuffer> Update(AudioSampleBuffer input, Spread <int> channelMap)
        {
            var arrayMap = channelMap?.ToArray();

            hasChanges = input != this.input || !AudioEngine.ArrayEquals(this.channelMap, arrayMap);

            this.input      = input;
            this.channelMap = arrayMap;

            if (hasChanges)
            {
                AudioEngine.Log($"AudioSplitter configuration changed!");

                if (IsValid())
                {
                    var outputsBefore = outputs?.Length ?? 0;

                    Build();

                    // Send nulls to update connected pins
                    var fillOutputs = outputsBefore - (outputs?.Length ?? 0);
                    if (fillOutputs > 0)
                    {
                        var builder = output.ToBuilder();
                        for (int i = 0; i < fillOutputs; i++)
                        {
                            builder.Add(null);
                        }

                        output = builder.ToSpread();
                    }
                }
                else
                {
                    foreach (var buffer in outputs)
                    {
                        buffer.Dispose();
                    }

                    // Send nulls to update connected pins
                    var results = outputs.Select(o => (AudioSampleBuffer)null);
                    return(results.ToSpread());
                }
            }

            return(output);
        }
Exemplo n.º 8
0
            public AudioSampleBuffer Build()
            {
                BuildOutputMap();

                multiplexer = new MultiplexingSampleProvider(inputs, outputMap.Length);
                for (int i = 0; i < outputMap.Length; i++)
                {
                    var input = outputMap[i];
                    multiplexer.ConnectInputToOutput(input, i);
                    AudioEngine.Log($" ch: {input} ==> {i}");
                }

                return(new AudioSampleBuffer(multiplexer.WaveFormat)
                {
                    Processor = this
                });
            }
Exemplo n.º 9
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];
 }
Exemplo n.º 10
0
 public void Dispose()
 {
     AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Disposed ");
     Processor = null;
 }
Exemplo n.º 11
0
 public AudioSampleBuffer(WaveFormat format)
 {
     AudioEngine.Log($"AudioSampleBuffer({GetHashCode()}): Created {format}");
     WaveFormat = format;
 }
Exemplo n.º 12
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;
        }
Exemplo n.º 13
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);
        }
Exemplo n.º 14
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");
            }