MIDI tick resolution

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

MIDI tick resolution

Gilberto Agostinho
Hi all,

Does anyone know if it possible to change the tick resolution of LilyPond's
MIDI output to a value other than the default 384? One reason for wanting
this change is due to the fact that 384 cannot be divided by 5 and so
quintuplets on a crotchet are not precise. For instance, the default
settings in my DAW of choice is 960.

This has been asked before but the OP got no solution to this:
lilypond.1069038.n5.nabble.com/MIDI-output-Possible-to-change-PPQ-td156345.html

Cheers,
Gilberto



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karl Hammar
Giberto:
> Does anyone know if it possible to change the tick resolution of LilyPond's
> MIDI output to a value other than the default 384? One reason for wanting
> this change is due to the fact that 384 cannot be divided by 5 and so
> quintuplets on a crotchet are not precise. For instance, the default
> settings in my DAW of choice is 960.

It seems pretty hardcoded:
===============
In lily/audio-item.cc:

int
moment_to_ticks (Moment m)
{
  return int (moment_to_real (m) * 384 * 4);
}
===============
In lily/midi-walker.cc:

void
Midi_walker::do_start_note (Midi_note *note)
{
  Audio_item *ptr = items_[index_];
  assert (note->audio_ == ptr);
  int now_ticks = ptr->audio_column_->ticks ();
  int stop_ticks = int (moment_to_real (note->audio_->length_mom_) *
                        Real (384 * 4)) + now_ticks;
===============

You could try the attached rudimentary patch and recompile your
lilypond source, see if that solves your problem, and report back.

BTW,
 384 = 128 * 3
 960 =  64 * 3 * 5

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

tick.patch (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Malte Meyn-3


Am 19.03.2018 um 14:47 schrieb [hidden email]:
> You could try the attached rudimentary patch and recompile your
> lilypond source, see if that solves your problem, and report back.

Would it be possible to make a patch that reads this from a context
property so that the user could input something like

        \set Score.midiTickResolution = 960

?

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

David Kastrup
In reply to this post by Karl Hammar
[hidden email] writes:

> Giberto:
>> Does anyone know if it possible to change the tick resolution of LilyPond's
>> MIDI output to a value other than the default 384? One reason for wanting
>> this change is due to the fact that 384 cannot be divided by 5 and so
>> quintuplets on a crotchet are not precise. For instance, the default
>> settings in my DAW of choice is 960.
>
> It seems pretty hardcoded:
> ===============
> In lily/audio-item.cc:
>
> int
> moment_to_ticks (Moment m)
> {
>   return int (moment_to_real (m) * 384 * 4);
> }
> ===============
> In lily/midi-walker.cc:
>
> void
> Midi_walker::do_start_note (Midi_note *note)
> {
>   Audio_item *ptr = items_[index_];
>   assert (note->audio_ == ptr);
>   int now_ticks = ptr->audio_column_->ticks ();
>   int stop_ticks = int (moment_to_real (note->audio_->length_mom_) *
>                         Real (384 * 4)) + now_ticks;
> ===============
>
> You could try the attached rudimentary patch and recompile your
> lilypond source, see if that solves your problem, and report back.
>
> BTW,
>  384 = 128 * 3
>  960 =  64 * 3 * 5

The patch is pretty awful.  I think we'd rather want this value to be
read from some \midi layout block variable when Midi is getting
initialized.

By the way, that value is also written out in the SMF file header (which
you don't appear to do).  This is initialized in

lily/performance.cc:  midi_stream.write (Midi_header (1, tracks_, 384));

and changing MIDI_CLOCK elsewhere but not here is going to wreak serious
havoc.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

David Kastrup
In reply to this post by Malte Meyn-3
Malte Meyn <[hidden email]> writes:

> Am 19.03.2018 um 14:47 schrieb [hidden email]:
>> You could try the attached rudimentary patch and recompile your
>> lilypond source, see if that solves your problem, and report back.
>
> Would it be possible to make a patch that reads this from a context
> property so that the user could input something like
>
> \set Score.midiTickResolution = 960
>
> ?

I think it belongs in the \midi block since you cannot change it in
mid-file.  Well, you probably can, but LilyPond is even less prepared to
do that.

Someone™ really needs to check where this can occur and then decide how
to implement it as how variable.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Malte Meyn-3
In reply to this post by David Kastrup


Am 19.03.2018 um 14:59 schrieb David Kastrup:
> I think we'd rather want this value to be
> read from some \midi layout block variable when Midi is getting
> initialized.

That would be better than reading from a context property of course.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karl Hammar
In reply to this post by David Kastrup
David:
> [hidden email] writes:
...
> > You could try the attached rudimentary patch and recompile your
...
> The patch is pretty awful.

Please, don't be rude, I did write it was rudimentary, you don't need
to restate that.

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57



_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

David Kastrup
[hidden email] writes:

> David:
>> [hidden email] writes:
> ...
>> > You could try the attached rudimentary patch and recompile your
> ...
>> The patch is pretty awful.
>
> Please, don't be rude, I did write it was rudimentary, you don't need
> to restate that.

Hm, though my proposals seem to cut at best half-way either.  It would
likely make more sense if scorification bothered to figure out the
proper value to use here.  There is no real point to having this
manually specifiable except for rather special applications.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Ivan Kuznetsov
In reply to this post by Gilberto Agostinho
Gilberto Agostinho <[hidden email]> wrote:
>
> Does anyone know if it possible to change the tick resolution of LilyPond's
> MIDI output to a value other than the default 384? One reason for wanting
> this change is due to the fact that 384 cannot be divided by 5 and so
> quintuplets on a crotchet are not precise.

No, they would not be precise but they would perceptually be
exact enough.  Without knowing precisely how these midi clock
values work, I would imagine that the five notes of a quintuplet
in a MIDI file would have the following clock durations: 77 77 77 77 76.

So what if four notes are of length 77 and one note is length 76?
No one can hear the difference.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karlin High
On 3/19/2018 8:49 PM, Ivan Kuznetsov wrote:
> So what if four notes are of length 77 and one note is length 76?
> No one can hear the difference.

I'd say so, too. But human-listening is only one use case for a MIDI
file, and in this area I don't know what others would surprise me.

Example: Humdrum
<http://www.humdrum.org/guide/ch01/#what-can-humdrum-do>

I looked at that, and found it sort of staggering. I'd probably have to
study for several years to do any good with it.

Or maybe the proper response to certain such use cases would be, "If
you're going to be so technical, go further yet and develop an AI of
some sort that can pattern-recognize the format limitations and
determine what to do with them."
--
Karlin High
Missouri, USA

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

David Wright
On Mon 19 Mar 2018 at 21:04:47 (-0500), Karlin High wrote:

> On 3/19/2018 8:49 PM, Ivan Kuznetsov wrote:
> >So what if four notes are of length 77 and one note is length 76?
> >No one can hear the difference.
>
> I'd say so, too. But human-listening is only one use case for a MIDI
> file, and in this area I don't know what others would surprise me.
>
> Example: Humdrum
> <http://www.humdrum.org/guide/ch01/#what-can-humdrum-do>
>
> I looked at that, and found it sort of staggering. I'd probably have
> to study for several years to do any good with it.

Well, I've only glanced at the reference given above, but it looks
as though it can quantise note lengths in two different ways.
The Record command handles input from a MIDI instrument with the
-q option. The Recode command processes information already in
files: its description calls note lengths that have been quantised
“rhythmically justified”.

> Or maybe the proper response to certain such use cases would be, "If
> you're going to be so technical, go further yet and develop an AI of
> some sort that can pattern-recognize the format limitations and
> determine what to do with them."

Cheers,
David.

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Thomas Morley-2
In reply to this post by Ivan Kuznetsov
2018-03-20 2:49 GMT+01:00 Ivan Kuznetsov <[hidden email]>:

> Gilberto Agostinho <[hidden email]> wrote:
>>
>> Does anyone know if it possible to change the tick resolution of LilyPond's
>> MIDI output to a value other than the default 384? One reason for wanting
>> this change is due to the fact that 384 cannot be divided by 5 and so
>> quintuplets on a crotchet are not precise.
>
> No, they would not be precise but they would perceptually be
> exact enough.  Without knowing precisely how these midi clock
> values work, I would imagine that the five notes of a quintuplet
> in a MIDI file would have the following clock durations: 77 77 77 77 76.
>
> So what if four notes are of length 77 and one note is length 76?
> No one can hear the difference.

I tested two files

(1)
\score {
  {
    \time 2/4
    \tuplet 3/2 { c'8 8 8 8 8 8 }
  }
  \layout {}
  \midi {}
}

(2)
\score {
  {
    \time 2/4
    \tuplet 5/4 { c'8 8 8 8 8 }
  }
  \layout {}
  \midi {}
}

with the sequence

lilypond file.ly
mid2ly file.midi
lilypond file-midi.ly

The resulting file-midi.ly shows (only excerpts)
(1)
trackBchannelB = \relative c {
  c'4*128/384 c c c c c
  | % 2

}

Looks correct.

(2)
trackBchannelB = \relative c {
  c'4*153/384 c r4*1/384 c4*153/384 c r4*1/384 c4*153/384
}

Inserting rests here is surely not that nice.


So I'd say there are use-cases where the midi-tick has direct and
visible impact.

Cheers,
  Harm

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

David Kastrup
Thomas Morley <[hidden email]> writes:

> 2018-03-20 2:49 GMT+01:00 Ivan Kuznetsov <[hidden email]>:
>> Gilberto Agostinho <[hidden email]> wrote:
>>>
>>> Does anyone know if it possible to change the tick resolution of LilyPond's
>>> MIDI output to a value other than the default 384? One reason for wanting
>>> this change is due to the fact that 384 cannot be divided by 5 and so
>>> quintuplets on a crotchet are not precise.
>>
>> No, they would not be precise but they would perceptually be
>> exact enough.  Without knowing precisely how these midi clock
>> values work, I would imagine that the five notes of a quintuplet
>> in a MIDI file would have the following clock durations: 77 77 77 77 76.
>>
>> So what if four notes are of length 77 and one note is length 76?
>> No one can hear the difference.
>
> I tested two files
>
> (2)
> \score {
>   {
>     \time 2/4
>     \tuplet 5/4 { c'8 8 8 8 8 }
>   }
>   \layout {}
>   \midi {}
> }

[...]

> Looks correct.
>
> (2)
> trackBchannelB = \relative c {
>   c'4*153/384 c r4*1/384 c4*153/384 c r4*1/384 c4*153/384
> }
>
> Inserting rests here is surely not that nice.
>
>
> So I'd say there are use-cases where the midi-tick has direct and
> visible impact.

"visible" is the key here.  "audible" not so much, but for better or
worse, Midi files are also being used as an information exchange format
without ever passing through a physical Midi interface.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Gilberto Agostinho
Hi all, thanks for all replies.

I will not enter on the merit of what can be perceived by ear or not at a
reasonable tempo, we already have plenty of that in the audio parameter wars
(44100 vs 48000 Hz, 16 vs 24 bit, etc.) But akin to those, it's a fact that
modern DAWs have much higher MIDI tick resolution by default than what
LilyPond outputs, and since these files have insignificant sizes (in
particular in the context of hard drive sizes today) and given that modern
sound cards can play them back with ease (unlike , I just don't see why to
limit the MIDI outputs to a lower value than the 'standards' you find out
there.

Also keep in mind that tick resolution is given in pulses per quarter note
(PPQ), not seconds. This means that a slow piece will have a lower
resolution /in true time/, i.e. ticks per second. Finally note that the
reference is a quarter note, so if you have 384 PPQ, you then have 192 ticks
per eighth note, 96 per sixteenth note, 48 per thirty-second-notes. Given
that contemporary music can very much look like the image below, I think
there is a strong case for higher PPQ in order to have decent
representations of tuplets of very short note values:

<http://lilypond.1069038.n5.nabble.com/file/t4165/maxresdefault.jpg>

My 2 cents.

Cheers,
Gilberto



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Gilberto Agostinho
Just one more example, this time from old music, from Beethoven's/ Sonata
Pathétique/. Look at the last beat of the last bar in the image below:

<http://lilypond.1069038.n5.nabble.com/file/t4165/625px-Introduction_sonate_path%25C3%25A9tique.png>

At 384 PPQ, the very last beat is a quarter note and therefore has 384
ticks. This means that each group totalling a sixteenth-note has 96.
Therefore the last group, the tuplet of 9 notes, has 96 ticks to be
executed. Since 96 / 9 = 10.6667, this will likely be divided as 11 11 10 11
11 10 11 11 10 or something similar.

Cheers,
Gilberto



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karl Hammar
In reply to this post by Gilberto Agostinho
Gilberto:
...
> Also keep in mind that tick resolution is given in pulses per quarter note
> (PPQ), not seconds. This means that a slow piece will have a lower
> resolution /in true time/, i.e. ticks per second.

I don't think resolution /in true time/ matters, since each tick is
"exact" in some sense.

What matters is the smallest subdivision of a quarter note used
(unless you use the smpte time format).

> Finally note that the
> reference is a quarter note, so if you have 384 PPQ, you then have 192 ticks
> per eighth note, 96 per sixteenth note, 48 per thirty-second-notes. Given
> that contemporary music can very much look like the image below, I think
> there is a strong case for higher PPQ in order to have decent
> representations of tuplets of very short note values:
>
> <http://lilypond.1069038.n5.nabble.com/file/t4165/maxresdefault.jpg>

(My wild guess is that music would need a tick value of 64*9*5*7.)

The technical limitation of midi file format is that the tick is a
15bit quantity, i.e. the maximum value is 2^15-1 = 32767.
(Instead of "ticks" you could use a time code based time, guess that
that is more for film making, don't know much about that.)

So you can't get 128*9*5*7 = 40320, but 64*9*5*7 = 20160 is possible,
and if you really need 128*9*5*7*11 or whatever, then you either need
 to choose a format other than midi,
 accept (smallish) time errors or
 you have to scale the notes, say make a quarter a whole note or longa
  (that would gain you a factor of 4 or 16).

All note times in the file is delta times, and they are of variable
length; the largest number allowed is 0x0FFFFFFF = 268435455, so if your
tick is 2^15 (finest subdivision), the longest time is slightly less
than 8192 quarter notes, which should be sufficient for most (all?)
music.

In effect, there is no need to choose a small tick value unless you
want smaller midi files (a consern which should be irrelevant today)
or perhaps due to some misbehaving midi equipment.

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57



_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karl Hammar
In reply to this post by David Kastrup
David:
> Malte Meyn <[hidden email]> writes:
>
> > Am 19.03.2018 um 14:47 schrieb [hidden email]:
> >> You could try the attached rudimentary patch and recompile your
> >> lilypond source, see if that solves your problem, and report back.
> > Would it be possible to make a patch that reads this from a context
> > property so that the user could input something like
> >
> > \set Score.midiTickResolution = 960

(The word resolution is not suitable since the resolution of the
midi tick is 1, it is a 15 bit int.)

Yes, if someone points to directions to go from \set to variable.

The second question is in what namespace or class to have the variable.
One possibility is to have it globally, another is to have it in the
Midi_header class.

> I think it belongs in the \midi block since you cannot change it in
> mid-file.  Well, you probably can, but LilyPond is even less prepared to
> do that.

The tick value can only be set once in the midi file, in the
last 16bits of the header chunk (the first so called "chunk"
of the file). See e.g. lily/midi-chunk.cc:Midi_header::Midi_header()

My current awful patch looks like in the attachment.

BTW, it is called "division" in the midi docs, and the word tick is
about the duration of one delta-time, or to cite the std:

 If bit 15 of <division> is zero, the bits 14 thru 0 represent the number
 of delta time "ticks" which make up a quarter-note. For instance, if
 division is 96, then a time interval of an eighth-note between two
 events in the file would be 48.

Perhaps we should call the value Midi_division or something similar.

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

tick.patch (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Gilberto Agostinho
In reply to this post by Karl Hammar
Hi Karl, thanks for your reply!


Karl Hammar wrote
> The technical limitation of midi file format is that the tick is a
> 15bit quantity, i.e. the maximum value is 2^15-1 = 32767.
>
> [...]
>
> So you can't get 128*9*5*7 = 40320, but 64*9*5*7 = 20160 is possible,
> and if you really need 128*9*5*7*11 or whatever, then you either need
> to choose a format other than midi

The only issue of going overboard with that value is that some DAWs might
then complain when opening these files (I never tried importing a .mid file
with larger PPQ than REAPER's default to see what happens though). REAPER's
default of 960 is a quite reasonable value: 3 × 5 × 64. This way, triplets
and quintuplets and all note down to a 64th-note can be exactly represented,
and everything else has a quite fine grid to be adjusted to. I've also read
here that Cubase handles anything from 24 to 960 (source:
https://steinberg.help/cubase_elements_le_ai/v9.5/en/cubase_nuendo/topics/track_handling/track_handling_export_options_for_midi_files_r.html
)
 

Karl Hammar wrote
> Perhaps we should call the value Midi_division or something similar.

The terminology I find the most is Pulses Per Quarter Note (PPQN),Pulses Per
Quarter (PPQ) and Ticks Per Quarter Note (TPQN). I am surprised this is not
on the official specifications as it's what most DAWs use.

Cheers,
Gilberto



--
Sent from: http://lilypond.1069038.n5.nabble.com/User-f3.html

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: MIDI tick resolution

Karl Hammar
Gilberto:
> Karl Hammar wrote
> > The technical limitation of midi file format is that the tick is a
> > 15bit quantity, i.e. the maximum value is 2^15-1 = 32767.
...
> The only issue of going overboard with that value is that some DAWs might
> then complain when opening these files (I never tried importing a .mid file
...

If lilypond defaults to 384, and user sets it to something that a device cannot
handle, that is a user problem I guess.

> Karl Hammar wrote
> > Perhaps we should call the value Midi_division or something similar.
>
> The terminology I find the most is Pulses Per Quarter Note (PPQN),Pulses Per
> Quarter (PPQ) and Ticks Per Quarter Note (TPQN). I am surprised this is not
> on the official specifications as it's what most DAWs use.

I don't know about thoose, one just have to choose a name and
possible mention other names used. Usually I tend to use names from
standard papers because then I can point to paper X page n. I don't
know what the regular developers think about this, but if you
know your stuff, I wouldn't mind if you choose the name.

What we are missing now is some info of how to do handle

\midi {
 \divisions = 960 % or
 \ppq = 960
}

in the source.

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57



_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user