Compare commits

..

2 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
4 changed files with 49 additions and 30 deletions

View File

@@ -1 +1 @@
June 17 2025 November 26 2025

View File

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

View File

@@ -6,7 +6,7 @@ abc2abc version 2.22 April 30 2024
yaps version 1.94 April 30 2024 yaps version 1.94 April 30 2024
abcmatch version 1.83 February 19 2024 abcmatch version 1.83 February 19 2024
midicopy version 1.40 August 11 2024 midicopy version 1.40 August 11 2024
midistats version 0.99 June 17 2025 midistats version 1.00 June 27 2025
24th January 2002 24th January 2002
Copyright James Allwright Copyright James Allwright

View File

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