private void RunSimulation(int Count, Audio.SampleBuffer[] In, Audio.SampleBuffer[] Out, double Rate) { try { // If the sample rate changed, we need to kill the simulation and let the foreground rebuild it. if (Rate != (double)simulation.SampleRate) { simulation = null; Dispatcher.InvokeAsync(() => RebuildSolution()); return; } List <double[]> ins = new List <double[]>(inputs.Count); foreach (Channel i in inputs.Values) { if (i is InputChannel) { ins.Add(In[((InputChannel)i).Index].LockSamples(true, false)); } else if (i is SignalChannel) { ins.Add(((SignalChannel)i).Buffer(Count, simulation.Time, simulation.TimeStep)); } } List <double[]> outs = new List <double[]>(probes.Count + Out.Length); foreach (Probe i in probes) { outs.Add(i.AllocBuffer(Count)); } for (int i = 0; i < Out.Length; ++i) { outs.Add(Out[i].LockSamples(false, true)); } // Process the samples! simulation.Run(Count, ins, outs); // Show the samples on the oscilloscope. long clock = Scope.Signals.Clock; foreach (Probe i in probes) { i.Signal.AddSamples(clock, i.Buffer); } } catch (Circuit.SimulationDiverged Ex) { // If the simulation diverged more than one second ago, reset it and hope it doesn't happen again. Log.WriteLine(MessageType.Error, "Error: " + Ex.Message); simulation = null; if ((double)Ex.At > Rate) { Dispatcher.InvokeAsync(() => RebuildSolution()); } foreach (Audio.SampleBuffer i in Out) { i.Clear(); } } catch (Exception Ex) { // If there was a more serious error, kill the simulation so the user can fix it. Log.WriteException(Ex); simulation = null; foreach (Audio.SampleBuffer i in Out) { i.Clear(); } } // Unlock sample buffers. foreach (Audio.SampleBuffer i in Out) { i.Unlock(); } foreach (Audio.SampleBuffer i in In) { i.Unlock(); } }