There are many benefits to using and developing MIDI Transformations/Generators.
- MIDI Tools can obtain information on notes within user selection much more easily than using Live Object Model (LOM) API.
- You can use MIDI Tools in the MIDI Clip View without changing to other view.
- By changing parameters of MIDI Tools, you can see the results of transformation/generation immediately.
- Classic MIDI Effect, which handles notes in real-time, devices cannot obtain the length of notes until receiving note off events. MIDI Tools can obtain the length of whole notes in the MIDI clip.
- Classic MIDI Effect often have the limit for the number of poly notes. (e.g. Bouncy Notes)
MIDI Tools would handle 10, 20, or more notes at a time.
There are further discussions in Mind The Complexity! section.
At the moment of June 2024, there are a few disadvantages for MIDI Tools. :(
- Parameters in MIDI Tools are not able to be automated.
- MIDI Tools are not available for Push.
- MIDI Tools cannot use messages from Node for Max (as known as N4M, the
node.script
object) to trigger transform/generation. It is because the process of Max and inner Node.js are not synchronized.jweb
is as the same.
The official document discusses the basics of MIDI Tool development.
It is recommended to read it first before the further information below.
The help patches of live.miditool.in
and live.miditool.out
object are also the fundamental examples of MIDI Tools with pure Max patch.
The note dictionaries from the first outlet of live.miditool.in
are the same as of Clip class's get_notes_extended
function in LOM API.
Also, be aware that velocity
values are float.
The dictionary from the second outlet of live.miditool.in
is like below.
{
clip: {
time_selection_start: 0.5,
time_selection_end: 0.75,
insert_marker_time: 0.5,
first_note_start: 0.5,
last_note_end: 0.75,
lowest_pitch: 64,
highest_pitch: 71
},
scale: {
scale_mode: 1,
root_note: 0,
scale_intervals: [0, 2, 4, 5, 7, 9, 11],
scale_name: 'Major'
},
grid: {
interval: 0.25,
enabled: 1
}
}
As the same as dictionaries in notes
, the unit of time is beat. (1.0 = quarter note)
insert_maker_time
only appears when the user selects outside of any notes in MIDI clip.
Further discussions on scale
in Fitting the Scale section.
scale_name
was added since Live 12.0.5.
The built-in MIDI Tools seem to ignore if the grid
was enabled
but use the interval
of grid
whenever the length parameter was set to Grid
. Thus enabled
in grid
might not matter in most cases.
live.miditool.in
has the 3rd outlet since Max 8.6.3.
It have not documented yet in 8.6.5 that the 3rd outlet outputs pitch_range
messages when dragging key area in piano roll.
We have scale context from live.miditool.in
like below.
{
// ...
scale: {
scale_mode: 1,
root_note: 0,
scale_intervals: [0, 2, 4, 5, 7, 9, 11]
},
// ...
}
This section discusses how to apply scale to notes with this information.
The easiest calculations for fitting notes to the scale are below.
However, this method is not equivalent for the behavior of "Fit to Scale" button in "Pitch and Time" of Live. Most cases live Major scales such as major
The scaled notes after Fit to Scale are a set of nearest note to scale note and the lowest note like below.
See fit2scale.js in Scale Viewer sample device.
You can easily get the scaled pitch number by coll
with scale information.
MIDI Tools handle much more notes at a time than classic MIDI Effect devices.
The number will raise to 10, 20, 50 or more in a MIDI clip.
Dealing with too much process, it might suffer the performance of Live.
Introduces factors which may lead to bad scenarios and those solutions in this section.
You can apply transform/generate on changing parameters by sending bang to live.miditool.in
. Rotating live.dial
with many steps causes a number of bangs to live.miditool.in
.
You might compare a note and other notes in the MIDI clip.
It is bad idea nests of array.foreach
or array.iter
like below.
The calculation complexity of a nest, a loop in a loop, is represented by
A nest of loops must be avoided because it is common there might be dozens of notes in a MIDI clip.
There is the qlim
object to reduce interval of bang.
It would reduce the complexity but not solve the root of problems.
Sometimes, sorting order of items in arrays may reduce the complexity.
The complexity of array.sort
is
It costs to handle the array of input notes or the dictionary of scale but those are not varied in a short span.
dict.compare
object can detect the changes of dictionary content like usual change
object.
You can execute heavier procedure only when the input array of notes or the dictionary of scale has been changed.
It can be implemented by js
, but dict.compare
would be more efficient because there are no deep comparison method in native methods of JavaScript and you have to iterate every element in objects.2
Off course, dict.compare
object itself produces some computation costs.
TODO: research if we should use @unordered
-
js
object can receive dictionary messages by the function nameddictionary()
.dictionary [dict name]
message from outlets oflive.miditool.in
is a single symbol (string), however, it becomes a list of symbols after throughout prepend objects or message objects likeset $1
. -
In your JavaScript source, you can handle dictionaries of
live.miditool.in
as normal JavaScript objects like below.
var outputDict = new Dict();
function dictionary(dictName) {
var inputDict = JSON.parse(new Dict(dictName).stringify());
var outputArray = [];
// some transform logic
for (var i = 0; i < inputDict.notes.length; i++) {
outputArray.push( {
// pitch: ..., start_time: ..., duration: ...
} );
}
outputDict.parse(JSON.stringify({notes: outputArray}));
outlet(0, 'dictionary', outputDict.name);
}
- When input values from UI parameters, don't send bang directly from UI parameters, but send from
js
like below.
If the MIDI Tool M4L is in trouble, error messages are shown in the status bar of of Live.
It's the most common message during MIDI tool developments. It appears when live.miditool.out
received no dictionary messages although live.miditool.in
has sent a note message.
It would appear when live.miditool.out
receives a message which was not a dictionary one, too.
As it says, it appears when the dictionary sent to live.miditool.out
has no essential items; notes
of top level, pitch
, start_time
, or duration
in a note item in array of notes
.
It appears when live.miditool.out
receives dictionary messages when no input from live.miditool.in
.
The author has encountered this message when trying to output from messages from jweb
object.
-
You can not open Max Window from the UI of MIDI Tools, however, you can see the print outputs by a Max Window window which is opened from usual M4L Instrument, MIDI effect, or Audio effect devices.
(update) While Live 12.0.5, you can open Max window with keyboard shortcut. (Release Notes) -
You can obtain the global scale settings by LOM API with
get root_note
,get scale_name
, andscale_intervals
from pathlive_set
. -
You can use the picture
scale.svg
in Max for scale-switching button. Other than the scale pic, there are new 60 SVG files added in Max 8.6.
Seepictures
page in the help patch oflive.tab
for built-in SVG files. -
You can obtain the 'scale_awareness' color since Max 8.6.5.
- Max for Live MIDI Tools
- The help patches of
live.miditool.in
andlive.miditool.out
- LOM - The Live Object Model
Footnotes
-
see patch array-sort-computation.maxpat ↩
-
see patch dict-change-benchmark.maxpat ↩