private void SetNotesTimesMap()
        {
            GetMIDIPlayData();
            IBarEnumerator      m_current_bar_iter = midiPlayData_cache.GetBarEnumerator();
            List <NoteWithTime> notes = new List <NoteWithTime>();
            int cumBarDuration        = 0;

            while (!m_current_bar_iter.IsLast())
            {
                m_current_bar_iter.MoveNext();
                IBar bar = m_current_bar_iter.CurrentBar();

                if (midiPlayData_cache.NumParts() > 1)
                {
                    throw new System.InvalidOperationException("Should have one part only");
                }

                IPart part = bar.Part(0);
                foreach (Note note in part)
                {
                    int noteTime = note.start + cumBarDuration;
                    notes.Add(new NoteWithTime(note, noteTime));
                }
                cumBarDuration = cumBarDuration + bar.Duration();
            }

            // sort in order of time
            notes.Sort(new NoteTimeComparer());

            // Remove duplicate times (in case of equality, take the first note available)
            List <NoteWithTime> uniqueNotesTimes = new List <NoteWithTime>();

            uniqueNotesTimes.Add(notes[0]);
            for (int k = 1; k < notes.Count; k++)
            {
                //if (notes[k].noteTime != uniqueNotesTimes[uniqueNotesTimes.Count - 1].noteTime)
                //{
                //    uniqueNotesTimes.Add(notes[k]);
                //}
                uniqueNotesTimes.Add(notes[k]);
            }

            // TODO : remove negative times?
            notesTimesMap = uniqueNotesTimes;
        }