Compare commits

..

2 Commits

Author SHA1 Message Date
sshlien
4e0266179b 2023.10.25 2023-10-25 19:43:27 -04:00
sshlien
2bf0052eb8 2023.08.13 2023-09-13 17:36:44 -04:00
5 changed files with 41 additions and 8 deletions

View File

@@ -1,2 +1,2 @@
September 11 2023 October 25 2023

View File

@@ -15103,4 +15103,7 @@ stats_noteon(). In function, output_track_summary(), suppressed
notemeanpitch for percussion channel. notemeanpitch for percussion channel.
October 25 2023
Midistats returns track activity (note on/off) for every track.

View File

@@ -1,4 +1,4 @@
.TH MIDISTATS 1 "9 December 2022" .TH MIDISTATS 1 "25 October 2023"
.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
@@ -43,6 +43,7 @@ the maximum pitch value
the minimum note length in pulses the minimum note length in pulses
the maximum note length in pulses the maximum note length in pulses
the number of gaps in the channel the number of gaps in the channel
the entropy of the pitch class histogram for that channel
.PP .PP
After processing all the individual tracks, the following information After processing all the individual tracks, the following information
applies to the entire midi file. applies to the entire midi file.
@@ -76,6 +77,10 @@ that occur in the midi file.
pitchact is a similar histogram but is weighted by the length of pitchact is a similar histogram but is weighted by the length of
the notes. the notes.
.PP .PP
chnact returns the amount of note activity in each channel.
.PP
trkact returns the number of notes in each track.
.PP
totalrhythmpatterns is the total number of bar rhythm patterns for totalrhythmpatterns is the total number of bar rhythm patterns for
all channels except the percussion channel. all channels except the percussion channel.
.PP .PP

View File

@@ -6,7 +6,7 @@ abc2abc version 2.20 February 07 2023
yaps version 1.92 January 06 2023 yaps version 1.92 January 06 2023
abcmatch version 1.82 June 14 2022 abcmatch version 1.82 June 14 2022
midicopy version 1.38 May 06 2022 midicopy version 1.38 May 06 2022
midistats version 0.74 September 11 2023 midistats version 0.77 October 25 2023
24th January 2002 24th January 2002
Copyright James Allwright Copyright James Allwright

View File

@@ -18,7 +18,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.74 September 11 2023 midistats" #define VERSION "0.77 October 25 2023 midistats"
#include <limits.h> #include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */ /* Microsoft Visual C++ Version 6.0 or higher */
@@ -63,6 +63,7 @@ static FILE *F;
static FILE *outhandle; /* for producing the abc file */ static FILE *outhandle; /* for producing the abc file */
int tracknum=0; /* track number */ int tracknum=0; /* track number */
int lasttrack = 0; /* lasttrack */
int division; /* pulses per quarter note defined in MIDI header */ int division; /* pulses per quarter note defined in MIDI header */
int quietLimit; /* minimum number of pulses with no activity */ int quietLimit; /* minimum number of pulses with no activity */
long tempo = 500000; /* the default tempo is 120 quarter notes/minute */ long tempo = 500000; /* the default tempo is 120 quarter notes/minute */
@@ -149,6 +150,7 @@ struct trkstat {
int quietTime[17]; int quietTime[17];
int rhythmpatterns[17]; int rhythmpatterns[17];
int numberOfGaps[17]; int numberOfGaps[17];
float pitchEntropy[17];
} trkdata; } trkdata;
/* The trkstat references the individual channels in the midi file. /* The trkstat references the individual channels in the midi file.
@@ -170,8 +172,10 @@ int pitchhistogram[12]; /* pitch distribution for non drum notes */
int channel2prog[17]; /* maps channel to program */ int channel2prog[17]; /* maps channel to program */
int channel2nnotes[17]; /*maps channel to note count */ int channel2nnotes[17]; /*maps channel to note count */
int chnactivity[17]; /* [SS] 2018-02-02 */ int chnactivity[17]; /* [SS] 2018-02-02 */
int trkactivity[40]; /* [SS] 2023-10-25 */
int progactivity[128]; /* [SS] 2018-02-02 */ int progactivity[128]; /* [SS] 2018-02-02 */
int pitchclass_activity[12]; /* [SS] 2018-02-02 */ int pitchclass_activity[12]; /* [SS] 2018-02-02 */
int chanpitchhistogram[204]; /* [SS] 2023-09-13 */
/* [SS] 2017-11-01 */ /* [SS] 2017-11-01 */
@@ -415,6 +419,7 @@ void stats_header (int format, int ntrks, int ldivision)
quietLimit = ldivision*8; quietLimit = ldivision*8;
divisionsPerBar = division*beatsPerBar; divisionsPerBar = division*beatsPerBar;
unitDivision = divisionsPerBar/24; unitDivision = divisionsPerBar/24;
lasttrack = ntrks; /* [SS] 2023-10-25 */
printf("ntrks %d\n",ntrks); printf("ntrks %d\n",ntrks);
printf("ppqn %d\n",ldivision); printf("ppqn %d\n",ldivision);
chordthreshold = ldivision/16; /* [SS] 2018-01-21 */ chordthreshold = ldivision/16; /* [SS] 2018-01-21 */
@@ -437,6 +442,7 @@ void stats_header (int format, int ntrks, int ldivision)
for (i=0;i<12;i++) pitchhistogram[i] = 0; /* [SS] 2017-11-01 */ for (i=0;i<12;i++) pitchhistogram[i] = 0; /* [SS] 2017-11-01 */
for (i=0;i<12;i++) pitchclass_activity[i] = 0; /* [SS] 2018-02-02 */ for (i=0;i<12;i++) pitchclass_activity[i] = 0; /* [SS] 2018-02-02 */
for (i=0;i<128;i++) progactivity[i] = 0; /* [SS] 2018-02-02 */ for (i=0;i<128;i++) progactivity[i] = 0; /* [SS] 2018-02-02 */
for (i=0;i<40;i++) trkactivity[i]=0; /* [SS] 2023-10-25 */
} }
void determine_progcolor () void determine_progcolor ()
@@ -522,9 +528,13 @@ else
for (i=0;i<12;i++) printf("%5.2f ",(double) pitchclass_activity[i]); for (i=0;i<12;i++) printf("%5.2f ",(double) pitchclass_activity[i]);
printf("\nchnact "); /* [SS] 2018-02-08 */ printf("\nchnact "); /* [SS] 2018-02-08 */
if (npulses > 0) if (npulses > 0)
for (i=1;i<17;i++) printf("%5.2f ",chnactivity[i]/(double) trkdata.npulses[0]); for (i=1;i<17;i++) printf("%5.3f ",chnactivity[i]/(double) trkdata.npulses[0]);
else else
for (i=0;i<17;i++) printf("%5.2f ",(double) chnactivity[i]); for (i=0;i<17;i++) printf("%5.3f ",(double) chnactivity[i]);
printf("\ntrkact ");
lasttrack++;
for (i=0;i<lasttrack;i++) printf("% 5d",trkactivity[i]);
printf("\npitchentropy %f\n",histogram_entropy(pitchclass_activity,12)); printf("\npitchentropy %f\n",histogram_entropy(pitchclass_activity,12));
printf("totalrhythmpatterns =%d\n",nrpatterns); printf("totalrhythmpatterns =%d\n",nrpatterns);
printf("collisions = %d\n",ncollisions); printf("collisions = %d\n",ncollisions);
@@ -541,8 +551,10 @@ float histogram_entropy (int *histogram, int size)
float e,p; float e,p;
total = 0; total = 0;
entropy = 0.0; entropy = 0.0;
//printf("\nhistogram_entropy of:");
for (i=0;i<size;i++) { for (i=0;i<size;i++) {
total += histogram[i]; total += histogram[i];
//printf(" %d",histogram[i]);
} }
for (i=0;i<size;i++) { for (i=0;i<size;i++) {
if (histogram[i] < 1) continue; if (histogram[i] < 1) continue;
@@ -550,6 +562,7 @@ float histogram_entropy (int *histogram, int size)
e = p*log(p); e = p*log(p);
entropy = entropy + e; entropy = entropy + e;
} }
//printf("\n");
return -entropy/log(2.0); return -entropy/log(2.0);
} }
@@ -590,8 +603,9 @@ for (i=1;i<17;i++) {
printf("-1 0 "); printf("-1 0 ");
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]);
else printf(" %f",trkdata.pitchEntropy[i]);
} else
printf("-1 0"); printf("-1 0");
trkdata.quietTime[i] = 0; /* in case channel i is used in another track */ trkdata.quietTime[i] = 0; /* in case channel i is used in another track */
trkdata.numberOfGaps[i] = 0; trkdata.numberOfGaps[i] = 0;
@@ -625,14 +639,21 @@ void stats_trackstart()
for (i=0;i<2048;i++) lastTick[i] = -1; for (i=0;i<2048;i++) lastTick[i] = -1;
for (i=0;i<17;i++) channel_used_in_track[i] = 0; /* [SS] 2023-09-06 */ for (i=0;i<17;i++) channel_used_in_track[i] = 0; /* [SS] 2023-09-06 */
for (i=0;i<204;i++) chanpitchhistogram[i] = 0; /* [SS] 2023-09-13 */
} }
void stats_trackend() void stats_trackend()
{ {
int chan; int chan;
int i;
float entropy;
if (trkdata.npulses[0] < Mf_currtime) trkdata.npulses[0] = Mf_currtime; if (trkdata.npulses[0] < Mf_currtime) trkdata.npulses[0] = Mf_currtime;
for (chan = 1; chan < 17; chan++) /* [SS] 2023-09-06 */ for (chan = 1; chan < 17; chan++) /* [SS] 2023-09-06 */
if (channel_used_in_track[chan] > 0) trkdata.quietTime[chan] += (trkdata.npulses[0] - trkdata.lastNoteOff[chan]); if (channel_used_in_track[chan] > 0) trkdata.quietTime[chan] += (trkdata.npulses[0] - trkdata.lastNoteOff[chan]);
for (chan=0;chan<16;chan++) { /* 2023-09-13 */
if (chan == 9 || channel_used_in_track[chan+1] == 0) continue;
trkdata.pitchEntropy[chan+1] = histogram_entropy(chanpitchhistogram +chan*12,11);
}
output_track_summary(); output_track_summary();
} }
@@ -645,7 +666,9 @@ int chan, pitch, vol;
int barnum; int barnum;
int unit; int unit;
int dithermargin; /* [SS] 2023-08-22 */ int dithermargin; /* [SS] 2023-08-22 */
int cpitch; /* [SS] 2023-09-13 */
cpitch = pitch % 12;
channel_used_in_track[chan+1]++; /* [SS] 2023-09-06 */ channel_used_in_track[chan+1]++; /* [SS] 2023-09-06 */
dithermargin = unitDivision/2 - 1; dithermargin = unitDivision/2 - 1;
if (vol == 0) { if (vol == 0) {
@@ -686,6 +709,7 @@ int chan, pitch, vol;
unit = ((Mf_currtime+dithermargin) % divisionsPerBar)/unitDivision; unit = ((Mf_currtime+dithermargin) % divisionsPerBar)/unitDivision;
//printf("unit = %d pattern = %d \n",unit,barChn[chan].rhythmPattern); //printf("unit = %d pattern = %d \n",unit,barChn[chan].rhythmPattern);
barChn[chan].rhythmPattern = barChn[chan].rhythmPattern |= (1UL << unit); barChn[chan].rhythmPattern = barChn[chan].rhythmPattern |= (1UL << unit);
chanpitchhistogram[chan*12+cpitch]++; /* [SS] 2023-09-13 */
} }
@@ -718,6 +742,7 @@ void stats_noteoff(int chan,int pitch,int vol)
//if (length < 3) printf("chan = %d lasttick = %d currtime = %ld\n",chan,lastTick[chan*128+pitch],Mf_currtime); //if (length < 3) printf("chan = %d lasttick = %d currtime = %ld\n",chan,lastTick[chan*128+pitch],Mf_currtime);
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */ trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
chnactivity[chan+1] += length; chnactivity[chan+1] += length;
trkactivity[tracknum]++;
if (chan == 9) return; /* drum channel */ if (chan == 9) return; /* drum channel */
pitchclass_activity[pitch % 12] += length; pitchclass_activity[pitch % 12] += length;
program = trkdata.program[chan+1]; program = trkdata.program[chan+1];