func (t *Timeline) ZeroStarting() *Timeline {
	if t.Len() == 0 {
		return t
	}
	result := NewTimeline()
	zero := time.Time{}
	t.EventsDo(func(event TimelineEvent, when time.Time) {
		d := when.Sub(t.head.when)
		result.schedule(&scheduledTimelineEvent{
			when:  zero.Add(d),
			event: event,
		})
	})
	return result
}
ZeroStarting returns a new one in which all events are shifted back in time starting at time 0.
package core
import (
	"fmt"
	"sync"
	"time"
	"github.com/emicklei/melrose/notify"
)
type Timeline struct {
	head       *scheduledTimelineEvent  
	tail       *scheduledTimelineEvent  
	protection sync.RWMutex
	isPlaying  bool
	resume     chan bool
}
func NewTimeline() *Timeline {
	return &Timeline{
		protection: sync.RWMutex{},
	}
}
type TimelineEvent interface {
	Handle(tim *Timeline, when time.Time)
	NoteChangesDo(block func(NoteChange))
}
type scheduledTimelineEvent struct {
	event TimelineEvent
	when  time.Time
	next  *scheduledTimelineEvent
}
var (
	wait = 50 * time.Millisecond  
)
func (t *Timeline) Len() int64 {
	t.protection.RLock()
	defer t.protection.RUnlock()
	var count int64
	here := t.head
	for here != nil {
		here = here.next
		count++
	}
	return count
}
func (t *Timeline) Play() {
	t.resume = make(chan bool)
	t.isPlaying = true
	for {
		t.protection.RLock()
		here := t.head
		t.protection.RUnlock()
		if here == nil {
			<-t.resume
			continue
		}
		now := time.Now()
		for now.After(here.when) {
			here.event.Handle(t, now)
			t.protection.Lock()
			t.head = t.head.next
			here = t.head
			t.protection.Unlock()
			if here == nil {
				break
			}
		}
		if here != nil {
			untilNext := here.when.Sub(now)
			if wait < untilNext {
				time.Sleep(wait)  
			} else {
				time.Sleep(untilNext)  
			}
		}
	}
}
func (t *Timeline) Reset() {
	if IsDebug() {
		notify.Debugf("core.timeline: flushing all scheduled MIDI events")
	}
	t.protection.Lock()
	defer t.protection.Unlock()
	t.head = nil
	t.tail = nil
}
func (t *Timeline) Schedule(event TimelineEvent, when time.Time) error {
	now := time.Now()
	diff := when.Sub(now)
	if diff < -wait {
		return fmt.Errorf("core.timeline: cannot schedule in the past:%v", now.Sub(when))
	}
	t.schedule(&scheduledTimelineEvent{
		when:  when,
		event: event,
	})
	return nil
}
func (t *Timeline) schedule(event *scheduledTimelineEvent) {
	t.protection.Lock()
	if t.head == nil {
		t.head = event
		t.tail = event
		t.protection.Unlock()
		if t.isPlaying {
			t.resume <- true
		}
		return
	}
	defer t.protection.Unlock()
	if event.when.After(t.tail.when) {
		t.tail.next = event
		t.tail = event
		return
	}
	if t.head.when.After(event.when) {
		event.next = t.head
		t.head = event
		return
	}
	if t.head.next == nil {
		t.head.next = event
		t.tail = event
		return
	}
	if t.tail.when == event.when {
		t.tail.next = event
		t.tail = event
		return
	}
	previous := t.head
	here := t.head.next
	for event.when.After(here.when) {
		previous = here
		here = here.next
	}
	previous.next = event
	event.next = here
}
func (t *Timeline) EventsDo(block func(event TimelineEvent, when time.Time)) {
	t.protection.Lock()
	defer t.protection.Unlock()
	here := t.head
	for here != nil {
		block(here.event, here.when)
		here = here.next
	}
}