I'm wondering what all is possible with the new K5 ksp stuff... particularly the new midi sequencing stuff. Anyone script anything using the new features yet? Is there any documentation on the new ksp features?
Theres midi file load
There is *NO* mid file player
..but there are commands to read first, next, previous events from midi files and the ability to ascertain the number of clicks (96 ppqn I think) to the next event.
Theres a new wait command wait_clicks(nnn).
With the above its pretty clear that you can read in a midi file and use a loop to move thru it "playing" events as you go...
Theres corresponding commands to alter midi events in a file and to save the file...
There's more. But that about covers it for the MIDI stuff in a five sentence overview..
..but there are commands to read first, next, previous events from midi files...
With the above its pretty clear that you can read in a midi file and use a loop to move thru it "playing" events as you go...
That's a very cool looking utility, Peter.I don't have K5 yet, but do the new commands sort of kill my pet project? (KSP2MIDI), or is there a niche for it yet?Theres midi file load
There is *NO* mid file player
..but there are commands to read first, next, previous events from midi files and the ability to ascertain the number of clicks (96 ppqn I think) to the next event.
Theres a new wait command wait_clicks(nnn).
With the above its pretty clear that you can read in a midi file and use a loop to move thru it "playing" events as you go...
Theres corresponding commands to alter midi events in a file and to save the file...
There's more. But that about covers it for the MIDI stuff in a five sentence overview..
https://peteroregan.com/scripts.html
Peter
on init
message("")
make_perfview
declare @filepath
{MAC}
@filepath := "/Users/<username>/Documents/Native Instruments/Kontakt 5/MIDI Files/test.mid"
{PC:= C:\Users\username\Desktop\Kontakt 5\MIDI\test files\test.mid"}
declare $TRACK_IDX := -1
declare const $LISTENER_RESOL := 16
declare const $LISTENER_BEAT_LENGTH_TICKS := 960 / $LISTENER_RESOL
{playback related variables}
declare $mf_length := -1 {midi file length - in ticks}
declare $cur_listener_id
declare $prev_ext_song_pos {keeping track of the incoming song position}
declare $cur_song_pos
declare $diff {wait time between events - in ticks}
declare $last_pos {position of the previously triggered event}
declare $end_of_beat {end position for all events that need handled by the current "on listener" callback}
declare %num_events_per_note[128] {number of active events per note - to keep track of their IDs and match Note-On and Note-Off events}
declare %event_ids_per_note[128 * 10]
{/playback related variables}
declare ui_button $get_first
declare ui_button $get_next
declare ui_button $get_next_at
declare ui_button $get_last
declare ui_button $get_prev
declare ui_button $get_prev_at
declare ui_button $scan
declare ui_button $move
declare ui_value_edit $pos (0, 5000, 1)
declare ui_button $play_in_loop
move_control($play_in_loop, 6, 6)
declare $count
declare ui_label $monitor (3, 6)
set_listener($NI_SIGNAL_TIMER_BEAT, $LISTENER_RESOL)
end on
on ui_control ($scan)
$scan := 0
add_text_line($monitor, "scan")
mf_get_first($TRACK_IDX)
while (mf_get_command() # 0)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
mf_get_next($TRACK_IDX)
end while
end on
on ui_control ($move)
$move := 0
add_text_line($monitor, "move")
mf_set_pos($pos)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_next)
$get_next := 0
add_text_line($monitor, "get_next")
mf_get_next($TRACK_IDX)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_next_at)
$get_next_at := 0
add_text_line($monitor, "get_next_at")
mf_get_next_at($TRACK_IDX, $pos)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_prev)
$get_prev := 0
add_text_line($monitor, "get_prev")
mf_get_prev($TRACK_IDX)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_first)
$get_first := 0
add_text_line($monitor, "get_first")
mf_get_first($TRACK_IDX)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_last)
$get_last := 0
add_text_line($monitor, "get_last")
mf_get_last($TRACK_IDX)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($get_prev_at)
$get_prev_at := 0
add_text_line($monitor, "get_prev_at")
mf_get_next_at($TRACK_IDX, $pos)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
end on
on ui_control ($play_in_loop)
if ($play_in_loop = 1)
add_text_line($monitor, "playback start")
else
add_text_line($monitor, "playback end")
end if
end on
on listener
$cur_listener_id := $NI_CALLBACK_ID
if ($play_in_loop = 1)
if ($mf_length = -1)
mf_get_last($TRACK_IDX)
$mf_length := mf_get_pos()
end if
{is the clock running or not? if not "emulate" it}
if ($prev_ext_song_pos = $NI_SONG_POSITION)
$cur_song_pos := $cur_song_pos + $LISTENER_BEAT_LENGTH_TICKS
else
$cur_song_pos := $NI_SONG_POSITION
end if
$prev_ext_song_pos := $NI_SONG_POSITION
{definition of the time window this "on listener" callback is handling}
mf_get_next_at($TRACK_IDX, $cur_song_pos mod $mf_length)
$end_of_beat := $cur_song_pos mod $mf_length + $LISTENER_BEAT_LENGTH_TICKS
$last_pos := $cur_song_pos mod $mf_length
while (mf_get_pos() < $end_of_beat and $play_in_loop = 1 and $cur_listener_id = $NI_CALLBACK_ID)
if (mf_get_command() = 0)
$end_of_beat := $end_of_beat mod $mf_length
mf_get_first($TRACK_IDX)
$diff := $mf_length - $last_pos + mf_get_pos()
else
$diff := mf_get_pos() - $last_pos
end if
if (ticks_to_ms($diff) > 0)
wait_ticks($diff)
end if
if ($play_in_loop = 1)
if (mf_get_command() = $MIDI_COMMAND_NOTE_ON and mf_get_byte_two() # 0)
%event_ids_per_note[mf_get_byte_one() * 10 + %num_events_per_note[mf_get_byte_one()]] := play_note(mf_get_byte_one(),mf_get_byte_two(),0,0)
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
inc(%num_events_per_note[mf_get_byte_one()])
else
if (mf_get_command() = $MIDI_COMMAND_NOTE_OFF or (mf_get_command() = $MIDI_COMMAND_NOTE_ON and mf_get_byte_two() = 0))
add_text_line($monitor, mf_get_pos() & " " & mf_get_command() & " " & mf_get_byte_one() & " " & mf_get_byte_two())
dec(%num_events_per_note[mf_get_byte_one()])
note_off(%event_ids_per_note[mf_get_byte_one() * 10 + %num_events_per_note[mf_get_byte_one()]])
end if
end if
end if
$last_pos := mf_get_pos()
mf_get_next($TRACK_IDX)
end while
end if
end on
i think it not working because it has no function to load the midi fileThis script is not working on my macbook. I think the file path is wrong. In my macbook documents, sync with icloud drive.
users / <user> / iCloud Drive / Documents / ..... I am writing this but does not see the midi file. Can you help me?