private void UpdateSimulation(bool Rebuild) { int id = Interlocked.Increment(ref update); new Task(() => { ComputerAlgebra.Expression h = (ComputerAlgebra.Expression) 1 / (stream.SampleRate * Oversample); Circuit.TransientSolution s = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Rebuild ? (ILog)Log : new NullLog()); lock (sync) { if (id > clock) { if (Rebuild) { simulation = new Circuit.Simulation(s) { Log = Log, Input = inputs.Keys, Output = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)), Oversample = Oversample, Iterations = Iterations, }; } else { simulation.Solution = s; clock = id; } } } }).Start(scheduler); }
private void RebuildSolution() { lock (sync) { simulation = null; ProgressDialog.RunAsync(this, "Building circuit solution...", () => { try { ComputerAlgebra.Expression h = (ComputerAlgebra.Expression) 1 / (stream.SampleRate * Oversample); Circuit.TransientSolution solution = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Log); simulation = new Circuit.Simulation(solution) { Log = Log, Input = inputs.Keys, Output = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)), Oversample = Oversample, Iterations = Iterations, }; } catch (Exception Ex) { Log.WriteException(Ex); } }); } }
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(); } }
private void UpdateSimulation(bool Rebuild) { int id = Interlocked.Increment(ref update); new Task(() => { ComputerAlgebra.Expression h = (ComputerAlgebra.Expression)1 / (stream.SampleRate * Oversample); Circuit.TransientSolution s = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Rebuild ? (ILog)Log : new NullLog()); lock (sync) { if (id > clock) { if (Rebuild) { simulation = new Circuit.Simulation(s) { Log = Log, Input = inputs.Keys, Output = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)), Oversample = Oversample, Iterations = Iterations, }; } else { simulation.Solution = s; clock = id; } } } }).Start(scheduler); }
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(); }
private void RebuildSolution() { lock (sync) { simulation = null; ProgressDialog.RunAsync(this, "Building circuit solution...", () => { try { ComputerAlgebra.Expression h = (ComputerAlgebra.Expression)1 / (stream.SampleRate * Oversample); Circuit.TransientSolution solution = Circuit.TransientSolution.Solve(circuit.Analyze(), h, Log); simulation = new Circuit.Simulation(solution) { Log = Log, Input = inputs.Keys, Output = probes.Select(i => i.V).Concat(OutputChannels.Select(i => i.Signal)), Oversample = Oversample, Iterations = Iterations, }; } catch (Exception Ex) { Log.WriteException(Ex); } }); } }