public DiscreteSignal GetSignal() { stopwatch.Restart(); // unique NoteSegments Dictionary <(int Track, byte Channel, int DurationSamples, byte Note, byte Velocity), NoteSegment> noteSegmentsToRender = new Dictionary <(int Track, byte Channel, int DurationSamples, byte Note, byte Velocity), NoteSegment>(); // find unique note segments foreach (var segment in Interpretation.NoteSegments) { // If the dictionary does not contain the segment's identifierr, add the segment if (!noteSegmentsToRender.ContainsKey(segment.ReuseIdentifier)) { noteSegmentsToRender[segment.ReuseIdentifier] = segment; // cache the first of a repeated signal } } OnProgressChanged(new GenerationProgressChangedEventArgs(1, 5, "Duplicate note consolidation", stopwatch.Elapsed)); stopwatch.Restart(); int notesRendered = 0; int totalToRender = noteSegmentsToRender.Count; // unique DiscreteSignals ConcurrentDictionary <(int Track, byte Channel, int DurationSamples, byte Note, byte Velocity), DiscreteSignal> signalCache = new ConcurrentDictionary <(int Track, byte Channel, int DurationSamples, byte Note, byte Velocity), DiscreteSignal>(); // generate unique signals in parallel Parallel.ForEach(noteSegmentsToRender, segment => { signalCache[segment.Value.ReuseIdentifier] = Render(segment.Value); Interlocked.Increment(ref notesRendered); OnProgressChanged(new NoteRenderedEventArguments(notesRendered, totalToRender, "Note rendered in parallel")); }); OnProgressChanged(new GenerationProgressChangedEventArgs(2, 5, "Unique note rendering", stopwatch.Elapsed)); stopwatch.Restart(); float[] samples = new float[Interpretation.TotalDurationSamples]; // assemble the final wav foreach (NoteSegment segment in Interpretation.NoteSegments) { DiscreteSignal segmentSignal = signalCache[segment.ReuseIdentifier]; long startSample = segment.StartSample; for (long i = 0; i < segmentSignal.Samples.Length; i++) { samples[startSample + i] = samples[startSample + i] + segmentSignal.Samples[i]; // add the samples together } } OnProgressChanged(new GenerationProgressChangedEventArgs(3, 5, "Wave assembly", stopwatch.Elapsed)); stopwatch.Restart(); DiscreteSignal signal = new DiscreteSignal(44100, samples); signal.ScaleAmplitude(0.9f); // adjust the samples to fit between [-1, 1] (using a value of 1 sometimes seems to cause clipping) OnProgressChanged(new GenerationProgressChangedEventArgs(4, 5, "Wave normalization", stopwatch.Elapsed)); stopwatch.Stop(); return(signal); }