anchor.diff:  	Handler ! {send, jsx:encode(#{ type => Type, content => Message })},
   	ok.
   
  -midiEvent(#{ interval := Interval }, {Type, Delay, Data}) ->
  -	erlang:send_after(round(Interval * (Delay / (192*1000))), self(), {midi, Type, Data}),
  +midiEvent(#{ interval := Interval, tpqs := TPQN }, {Type, Delay, Data}) ->
  +	SecondsPerQuarterNote = Interval / 1000,
  +	SecondsPerTick = SecondsPerQuarterNote / TPQN,
  +	EventDelay = round(Delay * SecondsPerTick),
  +
  +	erlang:send_after(EventDelay, self(), {midi, Type, Data}),
   	ok.
   
   %% ------------------------------------------------------------------
  
positive.code: 
  init(Req, Opts) ->
  	{ok, Req2, State} = initSession(Req, Opts),
  	{cowboy_websocket, Req2, State#{ interval => 500000 }}.
  
  websocket_init(State) ->
  	File = filename:join(code:priv_dir(maestro_web), "static/midi/bumble_bee.mid"),
  	Data = midifile:read(File),
  	{seq, _, {track, [First |Track]}, OtherTracks} = Data,
  	%io:format("~p~n", [Data]),
  	midiEvent(State, First),
  	{ok, State#{ track => lists:flatten([Track, [ TrackData || {track, TrackData} <- OtherTracks ]]) }}.
  
  websocket_handle({text, JSON}, State) ->
  	case jsx:decode(JSON, [return_maps]) of
  
negative.code: 	{ok, Req, State}.
  
  
  handleMIDI(time_signature, [<<Num, Denom, _, _>>], State) ->
  	{ok, State#{ ts_denom := math:pow(2, Denom), ts_num => Num }};
  handleMIDI(tempo, [TICKS], State) ->
  	{ok, State#{ interval := TICKS }};
  handleMIDI(on, [Channel, Note, Velocity], State) ->
  