2022.12.09

This commit is contained in:
Seymour Shlien
2022-12-09 13:31:50 -05:00
parent 80e8dbf505
commit c24f1ffdc1
10 changed files with 42 additions and 503 deletions

View File

@@ -1,2 +1,2 @@
December 07 2022 December 12 2022

View File

@@ -14865,3 +14865,7 @@ separate applications. Midistats is a new application that will replace
the midi2abc -midistats option. the midi2abc -midistats option.
December 9 2022
Cleaning out -stats code in midi2abc.

View File

@@ -172,23 +172,6 @@ the given string.
.B -origin \fistring\fP .B -origin \fistring\fP
Adds an O: field with the given string. Adds an O: field with the given string.
.TP .TP
.B -stats
Extracts the characteristics of the given midi file. They include
ntrks - the number of tracks, ppqn - pulses per quarter note,
timesig - time signature, keysig - key signature, program - mapping
between channel number and midi program, npulses - length of the
midi file in pulses, tempocmd - number of times the tempo has
been specified, pitchbends - number of pitchbends, pitchbendin -
number of pitchbends in each of the channels, programcmd - number of
times the midi program has been revised, progs and progsact - the
programs used and the number of pulses these programs used, drums -
the drum numbers that were used, drumhits - the number of times
each of those drums were hit, pitches - the number of times the
11 pitch classes (C C# etc...) were activated and a few other
complex variables. These characteristics are used in other
applications such as midiexplorer. More details are available
in the file midi2abc-stats.txt included in the doc/ folder
of the abcmidi distribution package.
.SS FEATURES .SS FEATURES

View File

@@ -1,4 +1,4 @@
.TH MIDISTATS 1 "3 December 2022" .TH MIDISTATS 1 "9 December 2022"
.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
@@ -35,17 +35,12 @@ the total number of notes for this for this channel,
the sum of the MIDI pitches for all the notes, 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,
and the number of pressure messages. the number of pressure messages.
and the number of distinct rhythm patterns for each 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.
.PP .PP
rhythmPatterns indicates the number of distinct rhythm patterns for each
channel. A large number likely implies that the melody line occurs in
this channel, while a small number indicates that this channel probably
is used for chordal support.
.PP
npulses is the length of the longest midi track in midi pulse units npulses is the length of the longest midi track in midi pulse units
.PP .PP
tempocmds specifies the number of times the tempo is changed in this tempocmds specifies the number of times the tempo is changed in this
@@ -74,7 +69,17 @@ that occur in the midi file.
.PP .PP
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
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
all channels except the percussion channel.
.PP
collisions. Midistats counts the bar rhythm patterns using a hashing
function. Presently collisions are ignored so occasionally two
distinct rhythm patterns are counted as one.
.SH AUTHOR .SH AUTHOR
Seymour Shlien <fy733@ncf.ca> Seymour Shlien <fy733@ncf.ca>

View File

@@ -1,6 +0,0 @@
/abc2midi.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/coding.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/midi2abc.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
/split.abc/1.1.1.1/Thu Sep 28 18:17:04 2006//
/yaps.txt/1.1.1.1/Thu Sep 28 18:17:04 2006//
D

View File

@@ -1 +0,0 @@
abcmidi/doc/programming

View File

@@ -1 +0,0 @@
/home/seymour/CVSREPOS

View File

@@ -1,12 +1,12 @@
abcMIDI : abc <-> MIDI conversion utilities abcMIDI : abc <-> MIDI conversion utilities
midi2abc version 3.57 September 01 2022 midi2abc version 3.58 December 09 2022
abc2midi version 4.76 August 01 2022 abc2midi version 4.76 August 01 2022
abc2abc version 2.18 June 14 2022 abc2abc version 2.18 June 14 2022
yaps version 1.90 June 14 2022 yaps version 1.90 June 14 2022
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.56 December 07 2022 midistats version 0.58 December 09 2022
24th January 2002 24th January 2002

View File

@@ -45,7 +45,7 @@
* based on public domain 'midifilelib' package. * based on public domain 'midifilelib' package.
*/ */
#define VERSION "3.57 September 01 2022 midi2abc" #define VERSION "3.58 December 09 2022 midi2abc"
#include <limits.h> #include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */ /* Microsoft Visual C++ Version 6.0 or higher */
@@ -79,12 +79,9 @@ extern char* strchr();
#define MIDDLE 72 #define MIDDLE 72
void initfuncs(); void initfuncs();
void setupkey(int); void setupkey(int);
void stats_finish();
int testtrack(int trackno, int barbeats, int anacrusis); int testtrack(int trackno, int barbeats, int anacrusis);
int open_note(int chan, int pitch, int vol); int open_note(int chan, int pitch, int vol);
int close_note(int chan, int pitch, int *initvol); int close_note(int chan, int pitch, int *initvol);
float histogram_entropy (int *histogram, int size);
void stats_noteoff(int chan,int pitch,int vol);
void reset_back_array (); /* [SS] 2019-05-08 */ void reset_back_array (); /* [SS] 2019-05-08 */
@@ -251,67 +248,7 @@ void txt_trackstart_type0();
void txt_noteon_type0(int,int,int); void txt_noteon_type0(int,int,int);
void txt_program_type0(int,int); void txt_program_type0(int,int);
/* The following variables are used by the -stats option
* which is used by a separate application called midiexplorer.tcl.
* The channel numbers go from 1 to 16 instead of 0 to 15
*/
struct trkstat {
int notecount[17];
int chordcount[17];
int notemeanpitch[17];
int notelength[17];
int pitchbend[17];
int pressure[17];
int cntlparam[17];
int program[17];
int tempo[17];
int npulses[17];
int lastNoteOff[17];
int quietTime[17];
} trkdata;
/* The trkstat references the individual channels in the midi file.
* notecount is the number of notes or bass notes in the chord.
* chordcount is the number of notes not counting the bass notes.
* notemeanpitch is the average pitch for the channel.
* notelength is the average note length.
* pitchbend is the number of pitch bends for the channel.
* pressure is the number of control pressure commands.
* cntlparam is the number of control parameter commands.
* program is number of times there is a program command for the channel.
* tempo is the number of times there is a tempo command.
* npulses is the number of pulses.
*/
int progcolor[17]; /* used by stats_program */
int drumhistogram[82]; /* counts drum noteons */
int pitchhistogram[12]; /* pitch distribution for non drum notes */
int channel2prog[17]; /* maps channel to program */
int channel2nnotes[17]; /*maps channel to note count */
int chnactivity[17]; /* [SS] 2018-02-02 */
int progactivity[128]; /* [SS] 2018-02-02 */
int pitchclass_activity[12]; /* [SS] 2018-02-02 */
/* [SS] 2017-11-01 */
static int progmapper[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 2,
3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 4, 4, 4, 4, 4, 2,
5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 2, 7, 10,
7, 7, 7, 7, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9,
11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15,
2, 2, 2, 2, 2, 12, 6, 12,
1, 1, 10, 10, 10, 10, 10, 1,
16, 16, 16, 16, 16, 16, 16, 16
};
/* Stage 1. Parsing MIDI file */ /* Stage 1. Parsing MIDI file */
@@ -609,15 +546,6 @@ char *s;
} }
/* [SS] 2017-11-19 */
void stats_error(s)
char *s;
{
fprintf(stderr,"Error: %s\n",s);
fprintf(stderr,"activetrack %d\n",tracknum);
stats_finish();
}
void txt_header(xformat,ntrks,ldivision) void txt_header(xformat,ntrks,ldivision)
@@ -731,12 +659,6 @@ int chan, pitch, press;
{ {
} }
void stats_pressure(chan,press)
int chan, press;
{
trkdata.pressure[0]++;
trkdata.pressure[chan+1]++; /* [SS] 2022.04.28 */
}
void txt_parameter(chan,control,value) void txt_parameter(chan,control,value)
int chan, control, value; int chan, control, value;
@@ -1140,145 +1062,7 @@ void mftxt_header (int format, int ntrks, int ldivision)
} }
void stats_header (int format, int ntrks, int ldivision)
{
int i;
division = ldivision;
quietLimit = ldivision*8;
printf("ntrks %d\n",ntrks);
printf("ppqn %d\n",ldivision);
chordthreshold = ldivision/16; /* [SS] 2018-01-21 */
trkdata.tempo[0] = 0;
trkdata.pressure[0] = 0;
trkdata.program[0] = 0;
for (i=0;i<17;i++) {
trkdata.npulses[i] = 0;
trkdata.pitchbend[i] = 0;
trkdata.cntlparam[i] = 0; /* [SS] 2022-03-04 */
trkdata.pressure[i] = 0; /* [SS] 2022-03-04 */
trkdata.quietTime[i] = 0; /* [SS] 2022-08-22 */
progcolor[i] = 0;
channel2prog[i] = -1;
channel2nnotes[i] = 0;
chnactivity[i] = 0; /* [SS] 2018-02-02 */
}
for (i=0;i<82;i++) drumhistogram[i] = 0;
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<128;i++) progactivity[i] = 0; /* [SS] 2018-02-02 */
}
void determine_progcolor ()
{
int i;
for (i=0;i<17;i++) progcolor[i] =0;
for (i=0;i<128;i++) {
progcolor[progmapper[i]] += progactivity[i];
}
}
/* [SS] 2018-04-24 */
void output_progs_data () {
int i;
/* check that there is valid progactivity */
printf("progs ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",i);
printf("\nprogsact ");
for (i=0;i<128;i++)
if(progactivity[i] > 0) printf(" %d",progactivity[i]);
}
void stats_finish()
{
int i; /* [SDG] 2020-06-03 */
int npulses;
int nprogs;
double delta;
npulses = trkdata.npulses[0];
printf("npulses %d\n",trkdata.npulses[0]);
printf("tempocmds %d\n",trkdata.tempo[0]);
printf("pitchbends %d\n",trkdata.pitchbend[0]);
for (i=1;i<17;i++) {
if (trkdata.pitchbend[i] > 0) {
printf("pitchbendin %d %d\n",i,trkdata.pitchbend[i]); }
}
if (trkdata.pressure[0] > 0)
printf("pressure %d\n",trkdata.pressure[0]);
printf("programcmd %d\n",trkdata.program[0]);
nprogs = 0; /* [SS] 2018-04-24 */
for (i=1;i<128;i++)
if(progactivity[i] >0) nprogs++;
if (nprogs > 0) output_progs_data();
else {
for (i=0;i<17;i++)
if(chnactivity[i] > 0)
progactivity[channel2prog[i]] = chnactivity[i];
output_progs_data();
}
determine_progcolor();
printf("\nprogcolor ");
if (npulses > 0)
for (i=0;i<17;i++) printf("%5.2f ",progcolor[i]/(double) npulses);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) progcolor[i]);
printf("\n");
printf("drums ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",i);
}
printf("\ndrumhits ");
for (i=35;i<82;i++) {
if (drumhistogram[i] > 0) printf("%d ",drumhistogram[i]);
}
printf("\npitches "); /* [SS] 2017-11-01 */
for (i=0;i<12;i++) printf("%d ",pitchhistogram[i]);
printf("\npitchact "); /* [SS] 2018-02-02 */
if (npulses > 0)
for (i=0;i<12;i++) printf("%5.2f ",pitchclass_activity[i]/(double) npulses);
else
for (i=0;i<12;i++) printf("%5.2f ",(double) pitchclass_activity[i]);
printf("\nchnact "); /* [SS] 2018-02-08 */
if (npulses > 0)
for (i=1;i<17;i++) printf("%5.2f ",chnactivity[i]/(double) trkdata.npulses[0]);
else
for (i=0;i<17;i++) printf("%5.2f ",(double) chnactivity[i]);
printf("\npitchentropy %f\n",histogram_entropy(pitchclass_activity,12));
printf("\n");
}
float histogram_entropy (int *histogram, int size)
{
int i;
int total;
float entropy;
float e,p;
total = 0;
entropy = 0.0;
for (i=0;i<size;i++) {
total += histogram[i];
}
for (i=0;i<size;i++) {
if (histogram[i] < 1) continue;
p = (float) histogram[i]/total;
e = p*log(p);
entropy = entropy + e;
}
return -entropy/log(2.0);
}
@@ -1291,70 +1075,9 @@ void mftxt_trackstart()
printf("Track %d contains %d bytes\n",tracknum,numbytes); printf("Track %d contains %d bytes\n",tracknum,numbytes);
} }
void output_count_trkdata(data_array,name)
int data_array[];
char *name;
{
int i,sum;
sum = 0;
for (i=1;i<17;i++) sum += data_array[i];
if (sum != 0) {
for (i=0;i<17;i++)
if(data_array[i]>0) {
printf("%s ",name);
printf("%d %d ",i,data_array[i]);
printf("\n");
}
}
}
void output_track_summary () {
int i;
/* find first channel containing data */
for (i=0;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*/
printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]);
printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]);
printf("%d %d ",trkdata.cntlparam[i],trkdata.pressure[i]); /* [SS] 2022-03-04 */
printf("%d ",trkdata.quietTime[i]); /* [SS] 2022.09.01 */
trkdata.quietTime[i] = 0;
printf("\n");
channel2nnotes[i] += trkdata.notecount[i] + trkdata.chordcount[i];
}
}
void stats_trackstart()
{
int i;
tracknum++;
for (i=0;i<17;i++) {
trkdata.notecount[i] = 0;
trkdata.notemeanpitch[i] = 0;
trkdata.notelength[i] = 0;
trkdata.chordcount[i] = 0;
trkdata.cntlparam[i] = 0;
last_tick[i] = -1;
last_on_tick[i] = -1;
}
printf("trk %d \n",tracknum);
}
void stats_trackend()
{
trkdata.npulses[tracknum] = Mf_currtime;
if (trkdata.npulses[0] < Mf_currtime) trkdata.npulses[0] = Mf_currtime;
output_track_summary();
}
void mftxt_noteon(chan,pitch,vol) void mftxt_noteon(chan,pitch,vol)
int chan, pitch, vol; int chan, pitch, vol;
{ {
@@ -1369,38 +1092,6 @@ int chan, pitch, vol;
printf("\n"); printf("\n");
} }
void stats_noteon(chan,pitch,vol)
int chan, pitch, vol;
{
int delta;
if (vol == 0) {
/* treat as noteoff */
stats_noteoff(chan,pitch,vol);
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
return;
}
trkdata.notemeanpitch[chan+1] += pitch;
if (trkdata.lastNoteOff[chan+1] >= 0) {
delta = Mf_currtime - trkdata.lastNoteOff[chan+1];
trkdata.lastNoteOff[chan+1] = -1; /* in case of chord */
if (delta > quietLimit) {
trkdata.quietTime[chan+1] += delta;
}
}
if (abs(Mf_currtime - last_on_tick[chan+1]) < chordthreshold) trkdata.chordcount[chan+1]++;
else trkdata.notecount[chan+1]++; /* [SS] 2019-08-02 */
last_tick[chan+1] = Mf_currtime;
last_on_tick[chan+1] = Mf_currtime; /* [SS] 2019-08-02 */
/* last_on_tick not updated by stats_noteoff */
if (chan == 9) {
if (pitch < 0 || pitch > 81)
printf("****illegal drum value %d\n",pitch);
else drumhistogram[pitch]++;
}
else pitchhistogram[pitch % 12]++; /* [SS] 2017-11-01 */
}
void mftxt_noteoff(chan,pitch,vol) void mftxt_noteoff(chan,pitch,vol)
int chan, pitch, vol; int chan, pitch, vol;
@@ -1415,28 +1106,6 @@ int chan, pitch, vol;
} }
void stats_noteoff(int chan,int pitch,int vol)
{
int length;
int program;
/* ignore if there was no noteon */
if (last_tick[chan+1] == -1) return;
length = Mf_currtime - last_tick[chan+1];
trkdata.notelength[chan+1] += length;
trkdata.lastNoteOff[chan+1] = Mf_currtime; /* [SS] 2022.08.22 */
chnactivity[chan+1] += length;
if (chan == 9) return; /* drum channel */
pitchclass_activity[pitch % 12] += length;
program = trkdata.program[chan+1];
progactivity[program] += length;
/* [SS] 2018-04-18 */
if(Mf_currtime > last_tick[chan+1]) last_tick[chan+1] = Mf_currtime;
}
void stats_eot () {
trkdata.lastNoteOff[0] = Mf_currtime; /* [SS] 2022.08.24 */
}
void mftxt_polypressure(chan,pitch,press) void mftxt_polypressure(chan,pitch,press)
@@ -1474,12 +1143,6 @@ int chan, lsb, msb;
printf("Pitchbend %2d %d cents = %6.3f (cents)\n",chan+1,pitchbend,cents); printf("Pitchbend %2d %d cents = %6.3f (cents)\n",chan+1,pitchbend,cents);
} }
void stats_pitchbend(chan,lsb,msb)
int chan, lsb, msb;
{
trkdata.pitchbend[0]++;
trkdata.pitchbend[chan+1]++;
}
void mftxt_program(chan,program) void mftxt_program(chan,program)
int chan, program; int chan, program;
@@ -1536,23 +1199,6 @@ static char *patches[] = {
} }
void stats_program(chan,program)
int chan, program;
{
int beatnumber;
if (program <0 || program > 127) return; /* [SS] 2018-03-06 */
if (trkdata.program[chan+1] != 0) {
beatnumber = Mf_currtime/division;
printf("cprogram %d %d %d\n",chan+1,program,beatnumber);
/* count number of times the program was modified for a channel */
trkdata.program[0] = trkdata.program[0]+1;
} else {
printf("program %d %d\n",chan+1,program);
trkdata.program[chan+1] = program;
}
if (channel2prog[chan+1]== -1) channel2prog[chan+1] = program;
}
void mftxt_parameter(chan,control,value) void mftxt_parameter(chan,control,value)
int chan, control, value; int chan, control, value;
@@ -1631,15 +1277,6 @@ int chan, control, value;
printf("CntlParm %2d %s = %d\n",chan+1, ctype[control],value); printf("CntlParm %2d %s = %d\n",chan+1, ctype[control],value);
} }
void stats_parameter(chan,control,value)
int chan, control, value;
{
/*if (control == 7) {
printf("cntrlvolume %d %d \n",chan+1,value);
}
*/
trkdata.cntlparam[chan+1]++;
}
void mftxt_metatext(type,leng,mess) void mftxt_metatext(type,leng,mess)
int type, leng; int type, leng;
@@ -1677,17 +1314,6 @@ char *mess;
} }
void stats_metatext(type,leng,mess)
int type, leng;
char *mess;
{
int i;
if (type != 3) return;
printf("metatext %d ",type);
for (i=0;i<leng;i++) printf("%c",mess[i]);
printf("\n");
}
void mftxt_keysig(sf,mi) void mftxt_keysig(sf,mi)
int sf, mi; int sf, mi;
@@ -1706,25 +1332,6 @@ int sf, mi;
} }
/* [SS] 2018-01-02 */
void stats_keysig(sf,mi)
int sf, mi;
{
float beatnumber;
static char *major[] = {"Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F",
"C", "G", "D", "A", "E", "B", "F#", "C#"};
static char *minor[] = {"Abmin", "Ebmin", "Bbmin", "Fmin", "Cmin",
"Gmin", "Dmin", "Amin", "Emin", "Bmin", "F#min", "C#min", "G#min"};
int index;
beatnumber = Mf_currtime/division;
index = sf + 7;
if (index < 0 || index >12) return;
if (mi)
printf("keysig %s %d %d %6.2f\n",minor[index],sf,mi,beatnumber);
else
printf("keysig %s %d %d %6.2f\n",major[index],sf,mi,beatnumber);
}
void mftxt_tempo(ltempo) void mftxt_tempo(ltempo)
long ltempo; long ltempo;
@@ -1734,17 +1341,6 @@ long ltempo;
printf("Metatext tempo = %6.2f bpm\n",60000000.0/tempo); printf("Metatext tempo = %6.2f bpm\n",60000000.0/tempo);
} }
/* [SS] 2018-01-02 */
void stats_tempo(ltempo)
long ltempo;
{
float beatnumber;
tempo = ltempo;
beatnumber = Mf_currtime/division;
if (trkdata.tempo[0] == 0) 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);
trkdata.tempo[0]++;
}
void mftxt_timesig(nn,dd,cc,bb) void mftxt_timesig(nn,dd,cc,bb)
int nn, dd, cc, bb; int nn, dd, cc, bb;
@@ -1758,16 +1354,6 @@ int nn, dd, cc, bb;
32nd-notes/24-MIDI-clocks=%d\n", nn,denom,cc,bb); */ 32nd-notes/24-MIDI-clocks=%d\n", nn,denom,cc,bb); */
} }
void stats_timesig(nn,dd,cc,bb)
int nn, dd, cc, bb;
{
float beatnumber;
int denom = 1;
beatnumber = Mf_currtime/division;
while ( dd-- > 0 )
denom *= 2;
printf("timesig %d/%d %6.2f\n",nn,denom,beatnumber);
}
void mftxt_smpte(hr,mn,se,fr,ff) void mftxt_smpte(hr,mn,se,fr,ff)
int hr, mn, se, fr, ff; int hr, mn, se, fr, ff;
@@ -1836,31 +1422,6 @@ void initfunc_for_mftext()
Mf_arbitrary = no_op2; Mf_arbitrary = no_op2;
} }
void initfunc_for_stats()
{
Mf_error = stats_error; /* [SS] 2017-11-19 */
Mf_header = stats_header;
Mf_trackstart = stats_trackstart;
Mf_trackend = stats_trackend;
Mf_noteon = stats_noteon;
Mf_noteoff = stats_noteoff;
Mf_pressure = no_op3;
Mf_parameter = stats_parameter;
Mf_pitchbend = stats_pitchbend;
Mf_program = stats_program;
Mf_chanpressure = stats_pressure;
Mf_sysex = no_op2;
Mf_metamisc = no_op3;
Mf_seqnum = no_op1;
Mf_eot = stats_eot;
Mf_timesig = stats_timesig;
Mf_smpte = no_op5;
Mf_tempo = stats_tempo;
Mf_keysig = stats_keysig;
Mf_seqspecific = no_op3;
Mf_text = stats_metatext;
Mf_arbitrary = no_op2;
}
@@ -3662,7 +3223,8 @@ int argc;
arg = getarg("-stats",argc,argv); arg = getarg("-stats",argc,argv);
if (arg != -1) if (arg != -1)
{ {
stats = 1; printf("\nuse the new application midistats\n");
exit(1);
} }
arg = getarg("-d",argc,argv); arg = getarg("-d",argc,argv);
@@ -3875,7 +3437,6 @@ int argc;
printf(" -mftext mftext output in beats\n"); printf(" -mftext mftext output in beats\n");
printf(" -mftextpulses mftext output in midi pulses\n"); printf(" -mftextpulses mftext output in midi pulses\n");
printf(" -mftext mftext output in seconds\n"); printf(" -mftext mftext output in seconds\n");
printf(" -stats summary and statistics output\n");
printf(" -ver version number\n"); printf(" -ver version number\n");
printf(" -d <number> debug parameter\n"); printf(" -d <number> debug parameter\n");
printf(" None or only one of the options -aul -gu, -b, -Q -u should\n"); printf(" None or only one of the options -aul -gu, -b, -Q -u should\n");
@@ -4124,17 +3685,6 @@ mfread();
} }
void midistats(argc,argv)
char *argv[];
int argc;
{
initfunc_for_stats();
Mf_getc = filegetc;
mfread();
stats_finish();
}
int main(argc,argv) int main(argc,argv)
char *argv[]; char *argv[];
@@ -4146,7 +3696,6 @@ int argc;
arg = process_command_line_arguments(argc,argv); arg = process_command_line_arguments(argc,argv);
if(midiprint ==1) { midigram(argc,argv); if(midiprint ==1) { midigram(argc,argv);
} else if(midiprint ==2) { mftext(argc,argv); } else if(midiprint ==2) { mftext(argc,argv);
} else if(stats == 1) { midistats(argc,argv);
} else midi2abc(argc,argv); } else midi2abc(argc,argv);
return 0; return 0;
} }

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.56 December 07 2022 midistats" #define VERSION "0.58 December 08 2022 midistats"
#include <limits.h> #include <limits.h>
/* Microsoft Visual C++ Version 6.0 or higher */ /* Microsoft Visual C++ Version 6.0 or higher */
@@ -166,28 +166,34 @@ struct barPattern {
} barChn[17]; } barChn[17];
#define HashSize 255 #define HashSize 257
struct hashStruct { struct hashStruct {
int pattern[HashSize]; int pattern[HashSize];
int count[HashSize]; int count[HashSize];
} hasher[17] = {0}; } hasher[17] = {0};
int ncollisions = 0; int ncollisions = 0;
int nrpatterns = 0;
void handle_collision () {
ncollisions++;
}
void put_pattern (int chan, int pattern) { void put_pattern (int chan, int pattern) {
int hashindex; int hashindex;
hashindex = pattern % HashSize; hashindex = pattern % HashSize;
if (hasher[chan].pattern[hashindex] == 0) { if (hasher[chan].pattern[hashindex] == 0) {
hasher[chan].pattern[hashindex] = pattern; hasher[chan].pattern[hashindex] = pattern;
nrpatterns++;
/*printf ("hasher[%d].pattern[%d] = %d\n",chan,hashindex,pattern);*/ /*printf ("hasher[%d].pattern[%d] = %d\n",chan,hashindex,pattern);*/
} else { } else if (hasher[chan].pattern[hashindex] != pattern) {
if (hasher[chan].pattern[hashindex] != pattern) {
/* printf("collision\n"); */ /* printf("collision\n"); */
ncollisions++; handle_collision ();
} } else {
}
hasher[chan].count[hashindex]++; hasher[chan].count[hashindex]++;
} }
}
int count_patterns_for (int chan) { int count_patterns_for (int chan) {
int i; int i;
@@ -204,14 +210,12 @@ return sum;
void output_hasher_results () { void output_hasher_results () {
int i; int i;
printf("rhythmPatterns "); /* printf("rhythmPatterns ");*/
for (i = 0; i<16; i++) { for (i = 0; i<17; i++) {
trkdata.rhythmpatterns[i] = count_patterns_for(i); trkdata.rhythmpatterns[i] = count_patterns_for(i);
printf("%d ",count_patterns_for (i)); /* printf("%d ",count_patterns_for (i)); */
} }
printf("\n"); printf("\n");
printf("collisions %d\n",ncollisions);
ncollisions = 0;
} }
@@ -493,6 +497,8 @@ for (i=1;i<17;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("collisions = %d\n",ncollisions);
printf("\n"); printf("\n");
} }