pad pickup measure in hum2mid?

5 views
Skip to first unread message

Malcolm Sailor

unread,
Apr 26, 2022, 4:00:25 PMApr 26
to starstarhug
Hello Craig et al.,

I'd like to do the following: 
1. convert kern files to midi
2. but in such a way that, if the piece begins with a pickup, there is an appropriate amount of silence at the start of the midi file such that if we start "counting" at the outset of the file, the pickup will occur in the appropriate place. (I.e., if the piece starts with an 8th note pickup in 4/4, the midi file will begin with 3.5 beats of rest.)

Is there a way of doing this with hum2mid? I notice that the command-line help includes the following:

> fp|fill-pickup|fill-pickups=b   Fill in rests to make pickup bars complete

However, that doesn't seem to do anything when I invoke it (although I'm not completely sure that I'm invoking it in the right way).

And I don't see any mention of the fill-pickup option in the online man page at http://extras.humdrum.org/man/hum2mid/

Any help is appreciated! Thanks.

Malcolm


Craig Sapp

unread,
Apr 27, 2022, 7:16:24 AMApr 27
to stars...@googlegroups.com
Hi Malcolm,

I have checked the --fill-pickup option for hum2mid and it is working for me on the following test file:

**kern

*M4/4

8c

=1

4d

4e

4f

4g

==

*-


The first test is to run the score through the Humdrum Extras beat program:

beat -p file.krn

**beat **kern

*M4/4 *M4/4

4.5 8c

=1 =1

1 4d

2 4e

3 4f

4 4g

== ==

*- *-


Notice that the first measure starts at beat 4.5.  (for 6/8 and other time signatures, the beats will still be reported in quarter notes, which can be fixed with some additional options, but should not be important for this analysis since MIDI files are only in quarter note units as well).

One potential problem is that if you add a barline before the pickup measure, it will not be processed as a pickup measure:

**beat **kern

*M4/4 *M4/4

= =

1 8c

=1 =1

1 4d

2 4e

3 4f

4 4g

== ==

*- *-


(Now the 8c is on beat 1 instead of 4.5).   A second caveat is that you need to have a time signature (otherwise there is no reasonable way for the computer to calculate the duration of the measure/pickup):

**beat **kern

1 8c

= =

1 4c

2 4d

3 4e

4 4f

= =

*- *-


Going back to the original test file, here is the non --fill-pickup use of hum2mid, outputting as ASCII MIDI:

hum2mid file.krn

"MThd" ; MIDI header chunk marker

4'6 ; bytes to follow in header chunk

2'1 ; file format: Type-1 (multitrack)

2'2 ; number of tracks

2'120 ; ticks per quarter note


;;; TRACK 0 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'12 ; bytes to follow in track chunk

v0 ff 58 v4 '4 '2 '24 '8 ; time signature

v0 ff 2f v0 ; end-of-track


;;; TRACK 1 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'48 ; bytes to follow in track chunk

v0 90 '60 '64 ; note-on C4

v60 80 '60 '64 ; note-off C4

v0 90 '62 '64 ; note-on D4

v120 80 '62 '64 ; note-off D4

v0 90 '64 '64 ; note-on E4

v120 80 '64 '64 ; note-off E4

v0 90 '65 '64 ; note-on F4

v120 80 '65 '64 ; note-off F4

v0 90 '67 '64 ; note-on G4

v120 80 '67 '64 ; note-off G4

v119 90 '0 '0 ; note-off C-1

v0 ff 2f v0 ; end-of-track


I made the important numbers bold and larger.  v0 means that the pickup note is starting immediately at the start of the MIDI file with no pickup-measure padding.

Now trying:

hum2mid --fill-pickup file.krn

"MThd" ; MIDI header chunk marker

4'6 ; bytes to follow in header chunk

2'1 ; file format: Type-1 (multitrack)

2'2 ; number of tracks

2'120 ; ticks per quarter note


;;; TRACK 0 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'13 ; bytes to follow in track chunk

v420 ff 58 v4 '4 '2 '24 '8 ; time signature

v0 ff 2f v0 ; end-of-track


;;; TRACK 1 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'49 ; bytes to follow in track chunk

v420 90 '60 '64 ; note-on C4

v60 80 '60 '64 ; note-off C4

v0 90 '62 '64 ; note-on D4

v120 80 '62 '64 ; note-off D4

v0 90 '64 '64 ; note-on E4

v120 80 '64 '64 ; note-off E4

v0 90 '65 '64 ; note-on F4

v120 80 '65 '64 ; note-off F4

v0 90 '67 '64 ; note-on G4

v120 80 '67 '64 ; note-off G4

v119 90 '0 '0 ; note-off C-1

v0 ff 2f v0 ; end-of-track


Now the first note starts at tick 420.  There are 120 ticks in a quarter note, so 420/120 = 3.5 of added rests to fill in the missing part of the pickup measure.

In doing this analysis, I found a bug in the pickup calculation: I was using the value of "1" for beat one when calculating the fill amount, but I should have subtracted one to start beat 1 at "0" instead (otherwise an extra quarter note rest was being added to the pickup fill).

So you will have to update from the humdrum-tools repository (or humextra by itself).  There are some recent changes in one of the external libraries (PCRE for regular expressions), so here is the best way to update (and hopefully works for non-Mac computers since the new PCRE stuff has only been checked on a mac computer):

(1) go to the directory where the humdrum-tools repository is located.  If you do not know where it is located, then try typing:
       cd $(which key | sed s/humdrum-tools.*//)
(this assumes that the key command can be found in the command path).

(2) Move humdrum-tools:
       mv humdrum-tools humdrum-tools-old

(3) Download humdrum tools again:

(4) Go into the new humdrum-tools directory update/compile the programs:
        cd humdrum-tools
        make update
        make

(5) If you do not have any personal files in the old humdrum-tools directory, then you can delete it.

The problem with no documentation for the --fill-pickup option is that I created the option after writing the hum2mid documentation (and obviously I was too lazy to add it :-).

-=+Craig

Malcolm Sailor

unread,
Apr 27, 2022, 9:14:14 AMApr 27
to stars...@googlegroups.com
Hi Craig,

Thanks for your help!

I was testing with this file:

On further investigation, I think the problem might happen when the pickup occurs after a line beginning '=', as it does in that file (where, prior to the pickup there is a line containing '=!|:'.

For instance, if I insert "=" before the first note of your test file, as follows

**kern
*M4/4
=

8c
=1
4d
4e
4f
4g
==
*-

Then I get the following output

(Note the initial v0 in track 1). 

I don't know whether preceding a pickup with a barline is proper humdrum syntax but apparently it is done in at least some files (and it seems necessary to include the pickup in a repeat, as done here).

Incidentally it seems that the `beat` command has a similar issue. It outputs the following for me on the above file:

**beat **kern
*M4/4 *M4/4
= =
1 8c
=1 =1
1 4d
2 4e
3 4f
4 4g
== ==
*- *- 

M
 
===
Malcolm Sailor
www.malcolmsailor.com


--
--
This is a message is from the **HUG newgroup.
To post to this group, send email to stars...@googlegroups.com
To unsubscribe from this group, send email to
starstarhug...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/starstarhug?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "starstarhug" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/starstarhug/ENrSK5prIvA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to starstarhug...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/starstarhug/CAPcjuFdp6QFpMGszP3nHtci4LeLE-m8L8KPGOmAC2sxqKSX8OA%40mail.gmail.com.

Craig Sapp

unread,
Apr 28, 2022, 5:03:11 AMApr 28
to stars...@googlegroups.com
Hi Malcolm et al.,

I have adjusted pickup beat analysis so that a barline before the pickup note(s) is now allowed.  In this case, if the first measure of music has a duration less than that of the time signature, it will be considered a pickup measure.

Here is my previous example of this situation with the old and new beat analyses:

**beat  **beat  **kern

!new    !old    !

*M4/4   *M4/4   *M4/4

=       =       =

4.5     1       8c

=1      =1      =1

1       1       4d

2       2       4e

3       3       4f

4       4       4g

==      ==      ==

*-      *-      *-


Now the pickup starts on beat 4.5 of the measure rather than 1.

Here is an example of the new system on the problematic example you provided:

beat -p file.krn

**beat **kern

*M6/8 *M6/8

=!|: =!|:

3.5 8f

=1 =1

1 4d

2 16d

2.25 16e

2.5 4f

3.5 8d

= =

*- *-


Now the pickup note is at quarter note 3.5 in the pickup measure.  This is correct since quarter notes are the units being used rather than 8 or 4., and the downbeat is set to 1 (rather than a more computer-friendly value of 0).

Converting this example into MIDI using the --fp option:

hum2mid --fp file.krn -o file.mid

"MThd" ; MIDI header chunk marker

4'6 ; bytes to follow in header chunk

2'1 ; file format: Type-1 (multitrack)

2'2 ; number of tracks

2'120 ; ticks per quarter note


;;; TRACK 0 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'13 ; bytes to follow in track chunk

v300 ff 58 v4 '6 '3 '36 '8 ; time signature

v0 ff 2f v0 ; end-of-track


;;; TRACK 1 ----------------------------------

"MTrk" ; MIDI track chunk marker

4'57 ; bytes to follow in track chunk

v300 90 '65 '64 ; note-on F4

v60 80 '65 '64 ; note-off F4

v0 90 '62 '64 ; note-on D4

v120 80 '62 '64 ; note-off D4

v0 90 '62 '64 ; note-on D4

v30 80 '62 '64 ; note-off D4

v0 90 '64 '64 ; note-on E4

v30 80 '64 '64 ; note-off E4

v0 90 '65 '64 ; note-on F4

v120 80 '65 '64 ; note-off F4

v0 90 '62 '64 ; note-on D4

v60 80 '62 '64 ; note-off D4

v119 90 '0 '0 ; note-off C-1

v0 ff 2f v0 ; end-of-track


300/120 = 2.5, so there is an extra 2.5 quarter notes worth of rests added to fill in the pickup measure as expected.

You will of course have to download and compile the humdrum-tools repository to get the updates (as described in my previous email).

The beat program will be useful for checking for other cases that cause problems, since the same pickup analysis is used by hum2mid for completing pickup measures.

-=+Craig

Malcolm Sailor

unread,
Apr 28, 2022, 11:10:30 AMApr 28
to stars...@googlegroups.com
Great, thanks!

===
Malcolm Sailor
www.malcolmsailor.com


--
--
This is a message is from the **HUG newgroup.
To post to this group, send email to stars...@googlegroups.com
To unsubscribe from this group, send email to
starstarhug...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/starstarhug?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "starstarhug" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/starstarhug/ENrSK5prIvA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to starstarhug...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages