Compare commits

...

3 Commits

Author SHA1 Message Date
sshlien
0bbb7519cb 2025.11.26 2025-11-26 13:10:21 -05:00
sshlien
e392893a9a 2025.06.27 2025-06-27 13:20:43 -04:00
sshlien
1089104c37 2025.06.17 2025-06-17 09:04:37 -04:00
4 changed files with 51 additions and 32 deletions

View File

@@ -1 +1 @@
February 16 2025
November 26 2025

View File

@@ -1,4 +1,4 @@
.TH MIDISTATS 1 "18 March 2024"
.TH MIDISTATS 1 "26 November 2025"
.SH NAME
\fBmidistats\fP \- program to summarize the statistical properties of a midi file
.SH SYNOPSIS
@@ -36,26 +36,29 @@ number.
.PP
trkinfo is an array of 19 numbers which indicates the statistical properties
of the track of interest. The following data is given:
0 the channel number,
1 the first program assigned to this channel,
2 the number of notes for this channel counting any chords as one note,
3 the total number of notes for this for this channel,
4 the sum of the MIDI pitches for all the notes,
5 the sum of the note durations in MIDI pulse units,
6 the number of pitchbend messages,
7 the number of control parameter messages,
8 the number of pressure messages.
9 the number of distinct rhythm patterns for each channel
10 the number of pulses the channel was inactive
11 the minimum pitch value
12 the maximum pitch value
13 the minimum note length in pulses
14 the maximum note length in pulses
15 the number of gaps in the channel
16 the entropy of the pitch class histogram for that channel
17 the number of notes whose pitch were the same as the previous note
18 the number of notes whose pitch changed by less than 4 semitones
19 the number of notes whose pitch changed by 4 or more semitones
0 the channel number,
1 the first program assigned to this channel,
2 the number of notes for this channel counting any chords as one note,
3 the number of chord notes excluding the bass note,
4 the sum of the MIDI pitches for all the notes,
5 the sum of the note durations in MIDI pulse units,
6 the number of pitchbend messages,
7 the number of control parameter messages,
8 the number of pressure messages.
9 the number of distinct rhythm patterns for each channel
10 the number of pulses the channel was inactive
11 the minimum pitch value
12 the maximum pitch value
13 the minimum note length in pulses
14 the maximum note length in pulses
15 the number of gaps in the channel
16 the entropy of the pitch class histogram for that channel
17 the number of notes whose pitch were the same as the previous note
18 the number of notes whose pitch changed by less than 4 semitones
19 the number of notes whose pitch changed by 4 or more semitones
20 the average note velocity
21 the standard deviation of the note velocity
(In event of a chords the maximum pitches are compared.)
.PP
After processing all the individual tracks, the following information

View File

@@ -1,12 +1,12 @@
abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.63 February 13 2025
midi2abc version 3.64 June 14 2025
abc2midi version 5.02 February 16 2025
abc2abc version 2.22 April 30 2024
yaps version 1.94 April 30 2024
abcmatch version 1.83 February 19 2024
midicopy version 1.40 August 11 2024
midistats version 0.98 January 30 2025
midistats version 1.00 June 27 2025
24th January 2002
Copyright James Allwright

View File

@@ -17,7 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define VERSION "0.98 January 30 2025 midistats"
#define VERSION "1.01 November 26 2025 midistats"
/* midistrats.c is a descendent of midi2abc.c which was becoming to
large. The object of the program is to extract statistical characterisitic
@@ -182,6 +182,8 @@ struct trkstat {
int rhythmpatterns[17];
int numberOfGaps[17];
int chanvol[17];
int velocity[17]; /* 2025.11.26 */
int velocity2[17]; /* 2025.11.26 */
float pitchEntropy[17];
} trkdata;
@@ -729,28 +731,38 @@ if (sum != 0) {
void output_track_summary () {
int i;
int nnotes; /* 2025.11.26 */
float avgvel, varvel; /* 2025.11.26 */
/* find first channel containing data */
output_hasher_results();
for (i=1;i<17;i++) {
if(trkdata.notecount[i] == 0 && trkdata.chordcount[i] == 0) continue;
printf("trkinfo ");
printf("%d %d ",i,trkdata.program[i]); /* channel number and program*/
nnotes = trkdata.notecount[i]+trkdata.chordcount[i]; /* 2025.11.26 */
printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]);
/* [SS] 2023-08-22 */
if (i != 10) printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]);
else
printf("-1 0 ");
printf("%d ",trkdata.pitchbend[i]); /* [SS] 2024-07-26 */
printf("%d %d ",trkdata.cntlparam[i],trkdata.pressure[i]); /* [SS] 2022-03-04 */
printf("%d %d ",trkdata.quietTime[i],trkdata.rhythmpatterns[i]);
if (i != 10) {printf("%d %d %d %d %d",trkdata.notepitchmin[i], trkdata.notepitchmax[i] ,trkdata.notelengthmin[i], trkdata.notelengthmax[i], trkdata.numberOfGaps[i]);
printf(" %f",trkdata.pitchEntropy[i]);
} else
printf("-1 0");
if (lasttrack > 1) printf(" %d %d %d\n",tracknm.zeroCount,tracknm.stepCount,tracknm.jumpCount);
else
printf(" %d %d %d\n",nm[i-1].zeroCount,nm[i-1].stepCount,nm[i-1].jumpCount);
/* 2025.11.26 next 6 lines */
printf(" %d %d %d",nm[i-1].zeroCount,nm[i-1].stepCount,nm[i-1].jumpCount);
avgvel = (float) trkdata.velocity[i]/(float) nnotes;
varvel = ((float) trkdata.velocity2[i] / (float) nnotes) - avgvel*avgvel;
if (varvel < 0.01) varvel = 0.01;
printf(" %d %d",(int) round(avgvel),(int) round(sqrt(varvel)));
printf("\n");
} else
printf("-1 0\n");
if (lasttrack == 1) { /* 2025.11.26 */
printf(" %d %d %d\n",tracknm.zeroCount,tracknm.stepCount,tracknm.jumpCount);
}
channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i];
}
@@ -774,6 +786,8 @@ void stats_trackstart()
trkdata.notelengthmax[i] = 0;
trkdata.chordcount[i] = 0;
trkdata.cntlparam[i] = 0;
trkdata.velocity[i] = 0; /* 2025.11.26 */
trkdata.velocity2[i] = 0;
last_on_tick[i] = -1;
channel_active[i] = 0;
}
@@ -921,6 +935,8 @@ int chan, pitch, vol;
trkdata.notemeanpitch[chan+1] += pitch;
trkdata.notepitchmax[chan+1] = max(trkdata.notepitchmax[chan+1],pitch);
trkdata.notepitchmin[chan+1] = min(trkdata.notepitchmin[chan+1],pitch);
trkdata.velocity[chan+1] += vol; /* 2025.11.26 */
trkdata.velocity2[chan+1] += vol*vol;
if (trkdata.lastNoteOff[chan+1] >= 0) {
delta = Mf_currtime - trkdata.lastNoteOff[chan+1];
if (delta > quietLimit) {
@@ -1102,11 +1118,11 @@ long ltempo;
{
float beatnumber;
tempo = ltempo;
beatnumber = Mf_currtime/division;
beatnumber = (double) Mf_currtime/(double) division; /*[SS] 2025.06.27 */
trkdata.tempo[0]++;
if (noOutput == 1) return;
if (trkdata.tempo[0] == 1) printf("tempo %6.2f bpm\n",60000000.0/tempo);
else if (trkdata.tempo[0] < 10) printf("ctempo %6.2f %6.2f\n",60000000.0/tempo,beatnumber);
else if (trkdata.tempo[0] < 100) printf("ctempo %6.2f %6.2f\n",60000000.0/tempo,beatnumber);
}