Compare commits

...

3 Commits

Author SHA1 Message Date
sshlien
2bf0052eb8 2023.08.13 2023-09-13 17:36:44 -04:00
sshlien
1394cd96c5 2023.09.11 2023-09-11 09:41:32 -04:00
sshlien
8a2ec3a898 2023.09.06 2023-09-06 17:37:58 -04:00
4 changed files with 38 additions and 23 deletions

View File

@@ -1,2 +1,2 @@
August 31 2023 September 13 2023

View File

@@ -36,11 +36,14 @@ the sum of the MIDI pitches for all the notes,
the sum of the note durations in MIDI pulse units, the sum of the note durations in MIDI pulse units,
the number of control parameter messages, the number of control parameter messages,
the number of pressure messages. the number of pressure messages.
and the number of distinct rhythm patterns for each channel the number of distinct rhythm patterns for each channel
the number of pulses the channel was inactive
the minimum pitch value the minimum pitch value
the maximum pitch value 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 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.
@@ -74,10 +77,6 @@ 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
quietTime is used to compute the track/channel spread in midiexplorer.
It is computed by summing up all the midi pulses which occur
in gaps greater than 8 beats.
.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.72 August 31 2023 midistats version 0.75 September 13 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.72 August 31 2023 midistats" #define VERSION "0.75 September 13 2023 midistats"
#include <limits.h> #include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */ /* Microsoft Visual C++ Version 6.0 or higher */
@@ -118,6 +118,7 @@ int notechan[2048],notechanvol[2048]; /*for linking on and off midi
int lastTick[2048]; /* for getting last pulse number for chan (0-15) and pitch (0-127) in MIDI file */ int lastTick[2048]; /* for getting last pulse number for chan (0-15) and pitch (0-127) in MIDI file */
int last_on_tick[17]; /* for detecting chords [SS] 2019-08-02 */ int last_on_tick[17]; /* for detecting chords [SS] 2019-08-02 */
int channel_active[17]; /* for dealing with chords [SS] 2023-08-30 */ int channel_active[17]; /* for dealing with chords [SS] 2023-08-30 */
int channel_used_in_track[17]; /* for dealing with quietTime [SS] 2023-09-06 */
int histogram[256]; int histogram[256];
unsigned char drumpat[8000]; unsigned char drumpat[8000];
@@ -147,6 +148,8 @@ struct trkstat {
int lastNoteOff[17]; int lastNoteOff[17];
int quietTime[17]; int quietTime[17];
int rhythmpatterns[17]; int rhythmpatterns[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,6 +173,7 @@ int channel2nnotes[17]; /*maps channel to note count */
int chnactivity[17]; /* [SS] 2018-02-02 */ int chnactivity[17]; /* [SS] 2018-02-02 */
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 */
@@ -425,6 +429,7 @@ void stats_header (int format, int ntrks, int ldivision)
trkdata.cntlparam[i] = 0; /* [SS] 2022-03-04 */ trkdata.cntlparam[i] = 0; /* [SS] 2022-03-04 */
trkdata.pressure[i] = 0; /* [SS] 2022-03-04 */ trkdata.pressure[i] = 0; /* [SS] 2022-03-04 */
trkdata.quietTime[i] = 0; /* [SS] 2022-08-22 */ trkdata.quietTime[i] = 0; /* [SS] 2022-08-22 */
trkdata.numberOfGaps[i] = 0; /* [SS] 2023-09-07 */
progcolor[i] = 0; progcolor[i] = 0;
channel2prog[i] = 0; /* [SS] 2023-06-25-8/ channel2prog[i] = 0; /* [SS] 2023-06-25-8/
channel2nnotes[i] = 0; channel2nnotes[i] = 0;
@@ -522,15 +527,6 @@ 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.2f ",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.2f ",(double) chnactivity[i]);
printf("\nquietTime ");
for (i=1;i<17;i++) {
delta = trkdata.npulses[0] - trkdata.quietTime[i];
if (trkdata.quietTime[i] < quietLimit) delta = 0;
delta = delta / (double) trkdata.npulses[0];
/* printf (" %5.3f ", delta); */
printf (" %d ", trkdata.quietTime[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);
@@ -547,8 +543,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;
@@ -556,6 +554,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);
} }
@@ -596,10 +595,12 @@ 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",trkdata.notepitchmin[i], trkdata.notepitchmax[i] ,trkdata.notelengthmin[i], trkdata.notelengthmax[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; trkdata.quietTime[i] = 0; /* in case channel i is used in another track */
trkdata.numberOfGaps[i] = 0;
printf("\n"); printf("\n");
channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i]; channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i];
@@ -629,12 +630,22 @@ void stats_trackstart()
printf("trk %d \n",tracknum); printf("trk %d \n",tracknum);
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<204;i++) chanpitchhistogram[i] = 0; /* [SS] 2023-09-13 */
} }
void stats_trackend() void stats_trackend()
{ {
trkdata.npulses[tracknum] = Mf_currtime; 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 */
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();
} }
@@ -647,7 +658,10 @@ 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 */
dithermargin = unitDivision/2 - 1; dithermargin = unitDivision/2 - 1;
if (vol == 0) { if (vol == 0) {
/* treat as noteoff */ /* treat as noteoff */
@@ -660,9 +674,10 @@ int chan, pitch, vol;
trkdata.notepitchmin[chan+1] = min(trkdata.notepitchmin[chan+1],pitch); trkdata.notepitchmin[chan+1] = min(trkdata.notepitchmin[chan+1],pitch);
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];
trkdata.lastNoteOff[chan+1] = -1; /* in case of chord */
if (delta > quietLimit) { if (delta > quietLimit) {
trkdata.quietTime[chan+1] += delta; trkdata.quietTime[chan+1] += delta;
trkdata.numberOfGaps[chan+1]++;
trkdata.lastNoteOff[chan+1] = -1; /* in case of chord */
} }
} }
@@ -686,6 +701,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 */
} }
@@ -715,7 +731,7 @@ void stats_noteoff(int chan,int pitch,int vol)
trkdata.notelength[chan+1] += length; trkdata.notelength[chan+1] += length;
trkdata.notelengthmax[chan+1] = max(trkdata.notelengthmax[chan+1],length); trkdata.notelengthmax[chan+1] = max(trkdata.notelengthmax[chan+1],length);
trkdata.notelengthmin[chan+1] = min(trkdata.notelengthmin[chan+1],length); trkdata.notelengthmin[chan+1] = min(trkdata.notelengthmin[chan+1],length);
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;
if (chan == 9) return; /* drum channel */ if (chan == 9) return; /* drum channel */