Compare commits

..

7 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
sshlien
48c443fabd 2023.08.31 2023-08-31 08:44:52 -04:00
sshlien
3f405a1aba 2023.08.22 2023-08-22 09:21:59 -04:00
sshlien
5534c8935d 2023.06.25 2023-06-25 14:17:21 -04:00
Seymour Shlien
afe323d8b7 2023.05.30 2023-05-30 09:22:17 -04:00
6 changed files with 162 additions and 43 deletions

View File

@@ -1,2 +1,2 @@
March 15 2023 September 13 2023

View File

@@ -15079,3 +15079,28 @@ February 08 2023
midi2abc, mftext, midistats: modified midifile.c so that it indicates where midi2abc, mftext, midistats: modified midifile.c so that it indicates where
it encounters an unexpected byte in the input midi file. it encounters an unexpected byte in the input midi file.
March 24 2023
More functions for the percussion track was added to midistats.c to
support some future analysis.
June 25 2023
Midistats runs incorrectly if the midi file has no program channel
commands. When a program channel command is missing, the program should
be the acoutic piano (0) by default.
If more than one channel with the same program color, they should be
added together.
August 22 2023
Midistats improved the calculation of the number of rhythm patterns
in a channel (barChn[chan].rhythmPattern) by allowing for dithering
of note onset. Introduced dithermargin variable in function
stats_noteon(). In function, output_track_summary(), suppressed
notemeanpitch for percussion channel.

View File

@@ -40,9 +40,12 @@ number of occurrences. eg.
-ppatfor n -ppatfor n
where n is the code number of the percussion instrument. Each beat where n is the code number of the percussion instrument. Each beat
is represented by a 4 bit number where the position of the on-bit is represented by a 4 bit number where the position of the on-bit
indicates the time in the beat when the drum onset occurs. Thus indicates the time in the beat when the drum onset occurs. The bits
0 indicates that there was no note onset in that beat, 1 indicates are ordered from left to right (higher order bits to lower order
a note onset in the beginning of the beat, 4 indicates a note onset bits). This is the order of bits that you would expect in a
time series.
Thus 0 indicates that there was no note onset in that beat, 1 indicates
a note onset at the end of the beat, 4 indicates a note onset
in the middle of the beat, and etc. The function returns a string in the middle of the beat, and etc. The function returns a string
of numbers ranging from 0 to 7 indicating the presence of note onsets of numbers ranging from 0 to 7 indicating the presence of note onsets
for the selected percussion instrument for the sequence of beats for the selected percussion instrument for the sequence of beats

View File

@@ -36,7 +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 maximum pitch value
the minimum 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.
@@ -70,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,20 +6,18 @@ 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.59 February 08 2023 midistats version 0.75 September 13 2023
24th January 2002 24th January 2002
Copyright James Allwright Copyright James Allwright
J.R.Allwright@westminster.ac.uk jamesallwright@yahoo.co.uk
University of Westminster, University of Westminster,
London, UK London, UK
October 2021 August 2023
Copyright Seymour Shlien
Seymour Shlien
Ottawa, Canada
fy733@ncf.ca fy733@ncf.ca
Ottawa, Canada
This is free software. You may copy and re-distribute it under the terms of This is free software. You may copy and re-distribute it under the terms of
the GNU General Public License version 2 or later, which is available from the GNU General Public License version 2 or later, which is available from

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.67 March 14 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 */
@@ -52,7 +52,8 @@ void stats_finish();
float histogram_entropy (int *histogram, int size); float histogram_entropy (int *histogram, int size);
void stats_noteoff(int chan,int pitch,int vol); void stats_noteoff(int chan,int pitch,int vol);
void stats_eot (); void stats_eot ();
#define max(a,b) (( a > b ? a : b))
#define min(a,b) (( a < b ? a : b))
/* Global variables and structures */ /* Global variables and structures */
@@ -77,6 +78,7 @@ int percanalysis;
int percpattern; int percpattern;
int percpatternfor; int percpatternfor;
int percpatternhist; int percpatternhist;
int pitchclassanalysis;
int corestats; int corestats;
int chordthreshold; /* number of maximum number of pulses separating note */ int chordthreshold; /* number of maximum number of pulses separating note */
int beatsPerBar = 4; /* 4/4 time */ int beatsPerBar = 4; /* 4/4 time */
@@ -104,6 +106,7 @@ int percanalysis = 0;
int percpattern = 0; int percpattern = 0;
int percpatternfor = 0; int percpatternfor = 0;
int percpatternhist = 0; int percpatternhist = 0;
int pitchclassanalysis = 0;
int corestats = 0; int corestats = 0;
@@ -112,8 +115,10 @@ int trackcount = 0;
int notechan[2048],notechanvol[2048]; /*for linking on and off midi int notechan[2048],notechanvol[2048]; /*for linking on and off midi
channel commands */ channel commands */
int last_tick[17]; /* for getting last pulse number 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_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];
@@ -129,7 +134,11 @@ struct trkstat {
int notecount[17]; int notecount[17];
int chordcount[17]; int chordcount[17];
int notemeanpitch[17]; int notemeanpitch[17];
int notepitchmin[17];
int notepitchmax[17];
int notelength[17]; int notelength[17];
int notelengthmin[17];
int notelengthmax[17];
int pitchbend[17]; int pitchbend[17];
int pressure[17]; int pressure[17];
int cntlparam[17]; int cntlparam[17];
@@ -139,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.
@@ -162,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 */
@@ -417,8 +429,9 @@ 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] = -1; channel2prog[i] = 0; /* [SS] 2023-06-25-8/
channel2nnotes[i] = 0; channel2nnotes[i] = 0;
chnactivity[i] = 0; /* [SS] 2018-02-02 */ chnactivity[i] = 0; /* [SS] 2018-02-02 */
} }
@@ -481,7 +494,7 @@ if (nprogs > 0) output_progs_data();
else { else {
for (i=0;i<17;i++) for (i=0;i<17;i++)
if(chnactivity[i] > 0) if(chnactivity[i] > 0)
progactivity[channel2prog[i]] = chnactivity[i]; progactivity[channel2prog[i]] += chnactivity[i]; /* [SS] 2023-06-25 */
output_progs_data(); output_progs_data();
} }
@@ -514,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);
@@ -539,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;
@@ -548,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);
} }
@@ -582,10 +589,18 @@ for (i=1;i<17;i++) {
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*/
printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]); printf("%d %d ",trkdata.notecount[i],trkdata.chordcount[i]);
printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]); /* [SS] 2023-08-22 */
if (i != 10) printf("%d %d ",trkdata.notemeanpitch[i], trkdata.notelength[i]);
else
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]);
trkdata.quietTime[i] = 0; 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");
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];
@@ -602,19 +617,35 @@ void stats_trackstart()
for (i=0;i<17;i++) { for (i=0;i<17;i++) {
trkdata.notecount[i] = 0; trkdata.notecount[i] = 0;
trkdata.notemeanpitch[i] = 0; trkdata.notemeanpitch[i] = 0;
trkdata.notepitchmin[i] = 128;
trkdata.notepitchmax[i] = 0;
trkdata.notelength[i] = 0; trkdata.notelength[i] = 0;
trkdata.notelengthmin[i] = 10000;
trkdata.notelengthmax[i] = 0;
trkdata.chordcount[i] = 0; trkdata.chordcount[i] = 0;
trkdata.cntlparam[i] = 0; trkdata.cntlparam[i] = 0;
last_tick[i] = -1;
last_on_tick[i] = -1; last_on_tick[i] = -1;
channel_active[i] = 0;
} }
printf("trk %d \n",tracknum); printf("trk %d \n",tracknum);
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();
} }
@@ -626,7 +657,12 @@ int chan, pitch, vol;
int delta; int delta;
int barnum; int barnum;
int unit; int unit;
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;
if (vol == 0) { if (vol == 0) {
/* treat as noteoff */ /* treat as noteoff */
stats_noteoff(chan,pitch,vol); stats_noteoff(chan,pitch,vol);
@@ -634,17 +670,20 @@ int chan, pitch, vol;
return; return;
} }
trkdata.notemeanpitch[chan+1] += pitch; 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);
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 */
} }
} }
if (abs(Mf_currtime - last_on_tick[chan+1]) < chordthreshold) trkdata.chordcount[chan+1]++; if (abs(Mf_currtime - last_on_tick[chan+1]) < chordthreshold) trkdata.chordcount[chan+1]++;
else trkdata.notecount[chan+1]++; /* [SS] 2019-08-02 */ else trkdata.notecount[chan+1]++; /* [SS] 2019-08-02 */
last_tick[chan+1] = Mf_currtime; lastTick[chan*128 + pitch] = Mf_currtime;
last_on_tick[chan+1] = Mf_currtime; /* [SS] 2019-08-02 */ last_on_tick[chan+1] = Mf_currtime; /* [SS] 2019-08-02 */
/* last_on_tick not updated by stats_noteoff */ /* last_on_tick not updated by stats_noteoff */
@@ -659,9 +698,10 @@ int chan, pitch, vol;
barChn[chan].rhythmPattern = 0; barChn[chan].rhythmPattern = 0;
barChn[chan].activeBarNumber = barnum; barChn[chan].activeBarNumber = barnum;
} }
unit = (Mf_currtime % 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 */
} }
@@ -672,6 +712,8 @@ int chan, pitch, vol;
else drumhistogram[pitch]++; else drumhistogram[pitch]++;
} }
else pitchhistogram[pitch % 12]++; /* [SS] 2017-11-01 */ else pitchhistogram[pitch % 12]++; /* [SS] 2017-11-01 */
channel_active[chan+1]++;
} }
@@ -684,17 +726,27 @@ void stats_noteoff(int chan,int pitch,int vol)
int length; int length;
int program; int program;
/* ignore if there was no noteon */ /* ignore if there was no noteon */
if (last_tick[chan+1] == -1) return; if (lastTick[chan*128+pitch] == -1) return;
length = Mf_currtime - last_tick[chan+1]; length = Mf_currtime - lastTick[chan*128+pitch];
trkdata.notelength[chan+1] += length; trkdata.notelength[chan+1] += length;
trkdata.notelengthmax[chan+1] = max(trkdata.notelengthmax[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);
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 */
pitchclass_activity[pitch % 12] += length; pitchclass_activity[pitch % 12] += length;
program = trkdata.program[chan+1]; program = trkdata.program[chan+1];
progactivity[program] += length; progactivity[program] += length;
channel_active[chan+1]--;
/* [SS] 2018-04-18 */ /* [SS] 2018-04-18 */
if(Mf_currtime > last_tick[chan+1]) last_tick[chan+1] = Mf_currtime; if(Mf_currtime > lastTick[chan*128+pitch] && channel_active[chan+1] == 0)
lastTick[chan*128+pitch] = Mf_currtime; /* [SS] 2023.08.30 handle chords */
if (length > 4800) {
lastTick[chan*128+pitch] = Mf_currtime; /* handle stuck note [SS] 2023.08.30 */
channel_active[chan+1] = 0;
}
} }
@@ -728,7 +780,7 @@ if (trkdata.program[chan+1] != 0) {
printf("program %d %d\n",chan+1,program); printf("program %d %d\n",chan+1,program);
trkdata.program[chan+1] = program; trkdata.program[chan+1] = program;
} }
if (channel2prog[chan+1]== -1) channel2prog[chan+1] = program; if (channel2prog[chan+1]== 0) channel2prog[chan+1] = program; /* [SS] 2023-06-25*/
} }
@@ -982,6 +1034,7 @@ for (i = 0; i <lastEvent; i++) {
if (index >= 8000) {printf("index too large in drumpattern\n"); if (index >= 8000) {printf("index too large in drumpattern\n");
break; break;
} }
part = 3 - part; /* order the bits going left to right */
drumpat[index] = drumpat[index] |= 1 << part; drumpat[index] = drumpat[index] |= 1 << part;
} }
} }
@@ -1009,11 +1062,25 @@ for (i = 0; i <lastEvent; i++) {
} }
remainder = onset % division; remainder = onset % division;
part = remainder/quarter; part = remainder/quarter;
part = 3 - part; /* order the bits from left to right */
if (pitch == perc1) drumpat[index] = drumpat[index] |= 1 << part; if (pitch == perc1) drumpat[index] = drumpat[index] |= 1 << part;
else drumpat[index] = drumpat[index] |= 16 * (1 << part); else drumpat[index] = drumpat[index] |= 16 * (1 << part);
} }
} }
void pitchClassAnalysis () {
int i;
int channel;
int pitch;
for (i=0;i<12;i++) pitchclass_activity[i] = 0;
for (i = 0; i < lastEvent; i++) {
channel = midievents[i].channel;
if (channel == 9) continue;
pitch = midievents[i].pitch;
pitchclass_activity[pitch % 12]++;
}
}
void output_perc_pattern (int i) { void output_perc_pattern (int i) {
int left,right; int left,right;
left = i/16; left = i/16;
@@ -1078,6 +1145,17 @@ if (bassmax && snaremax) {
dualDrumPattern(bassindex,snareindex); dualDrumPattern(bassindex,snareindex);
} }
void outputPitchClassHistogram() {
int i;
float activity;
activity = 0;
for (i=0;i<12;i++) activity += (float) pitchclass_activity[i];
for (i=0;i<11;i++) printf("%5.3f,",pitchclass_activity[i]/activity);
printf("%5.3f",pitchclass_activity[11]/activity);
printf("\n");
}
void corestatsOutput() { void corestatsOutput() {
printf("%d\t%d\t%d\n", division,lastEvent,lastBeat); printf("%d\t%d\t%d\n", division,lastEvent,lastBeat);
@@ -1229,6 +1307,12 @@ int argc;
stats = 0; stats = 0;
} }
arg = getarg("-pitchclass",argc,argv);
if (arg != -1) {
pitchclassanalysis = 1;
stats = 0;
}
arg = getarg("-o",argc,argv); arg = getarg("-o",argc,argv);
if ((arg != -1) && (arg < argc)) { if ((arg != -1) && (arg < argc)) {
@@ -1256,6 +1340,7 @@ int argc;
printf(" -ppat\n"); printf(" -ppat\n");
printf(" -ppatfor\n"); printf(" -ppatfor\n");
printf(" -ppathist\n"); printf(" -ppathist\n");
printf(" -pitchclass\n");
printf(" -ver version number\n"); printf(" -ver version number\n");
printf(" -d <number> debug parameter\n"); printf(" -d <number> debug parameter\n");
printf(" The input filename is assumed to be any string not\n"); printf(" The input filename is assumed to be any string not\n");
@@ -1308,6 +1393,10 @@ if (percpatternhist) {
drumPatternHistogram(); drumPatternHistogram();
} }
if (corestats) corestatsOutput(); if (corestats) corestatsOutput();
if (pitchclassanalysis) {
pitchClassAnalysis();
outputPitchClassHistogram();
}
} }
@@ -1322,6 +1411,7 @@ int argc;
arg = process_command_line_arguments(argc,argv); arg = process_command_line_arguments(argc,argv);
if(stats == 1) midistats(argc,argv); if(stats == 1) midistats(argc,argv);
if(pulseanalysis || corestats || percanalysis ||\ if(pulseanalysis || corestats || percanalysis ||\
percpatternfor || percpattern || percpatternhist) loadEvents(); percpatternfor || percpattern || percpatternhist ||\
pitchclassanalysis) loadEvents();
return 0; return 0;
} }