Exemple #1
0
double getMeasureSize(HumdrumFile& infile, int width) {
   int i;
   int bar = -100;
   int lastbar = -1000;
   int line = -100;
   int lastline = -1000;

   int number;

   for (i=0; i<infile.getNumLines(); i++) {
      if (!infile[i].isMeasure()) {
         continue;
      }
      if (sscanf(infile[i][0], "=%d", &number)) {
         bar = number;
         line = i;
         if (bar == lastbar + 1) {
            return 
            (infile[line].getAbsBeat() - infile[lastline].getAbsBeat()) 
            / infile.getTotalDuration() * width;
         } else {
            lastbar = bar;
            lastline = line;
         }
      }
      
   }

   return 5;
}
Exemple #2
0
void getNotes(Array<NoteUnit>& notes, HumdrumFile& infile) {

   notes.setSize(100000);
   notes.setGrowth(100000);
   notes.setSize(0);
   NoteUnit tempnote;
   int tokencount;
   int track = 0;
   char buffer[1024] = {0};
   int i, j, k;
   int dice = 0;
   for (i=0; i<infile.getNumLines(); i++) {
      if (!infile[i].isData()) {
         continue;
      }
      for (j=0; j<infile[i].getFieldCount(); j++) {
         if (strcmp("**kern", infile[i].getExInterp(j)) != 0) {
            continue;
         }
         tokencount = infile[i].getTokenCount(j);
         track = infile[i].getPrimaryTrack(j);
         for (k=0; k<tokencount; k++) {
            infile[i].getToken(buffer, j, k);
            if (strcmp(buffer, ".") == 0) {
               continue;
            }
            if (strchr(buffer, '_') != NULL) {
               continue;
            }
            if (strchr(buffer, ']') != NULL) {
               continue;
            }
            tempnote.pitch = Convert::kernToBase40(buffer);
            if (restQ == 0 && tempnote.pitch < 0) {
               continue;
            }
            if (distQ) {
               dice = throwDice((double)infile[i].getAbsBeat()/
                     infile.getTotalDuration());
               if (!dice) {
                  continue;
               }
            }
            tempnote.line  = i;
            tempnote.spine = j;
            tempnote.token = k;
            tempnote.track = track;
            notes.append(tempnote);
         }
      }
   }
}
Exemple #3
0
void loadHistograms(Array<Array<double> >& histograms,
   HumdrumFile& infile, int segments) {

   infile.analyzeRhythm("4");
   double totalduration = infile.getTotalDuration();

   double duration;
   int i;
   int j;
   int k;
   char buffer[10000] = {0};
   int pitch;
   double start;
   int tokencount;
   for (i=0; i<infile.getNumLines(); i++) {
      if (infile[i].getType() !=  E_humrec_data) {
         continue;
      }
      start = infile[i].getAbsBeat();
      for (j=0; j<infile[i].getFieldCount(); j++) {
         if (strcmp(infile[i].getExInterp(j), "**kern") != 0) {
            continue;
         }
         if (strcmp(infile[i][j], ".") == 0) {
            continue; // ignore null tokens
         }
         tokencount = infile[i].getTokenCount(j);
         for (k=0; k<tokencount; k++) {
            infile[i].getToken(buffer, j, k);
            if (strcmp(buffer, ".") == 0) {
               continue;  // ignore illegal inline null tokens
            }
            pitch = Convert::kernToMidiNoteNumber(buffer);
            if (pitch < 0) {
               continue;  // ignore rests or strange objects
            }
            pitch = pitch % 12;  // convert to chromatic pitch-class
            duration = Convert::kernToDuration(buffer);
            if (duration <= 0.0) {
               continue;   // ignore grace notes and strange objects
            }
            
            addToHistogramDouble(histograms, pitch,
                  start, duration, totalduration, segments);
         }
      }
   }
}
Exemple #4
0
void getLocations(Array<double>& measures, HumdrumFile& infile, int segments) {
   infile.analyzeRhythm("4");
   double totaldur = infile.getTotalDuration();

   measures.setSize(segments);
   measures.allowGrowth(0);
   measures.setAll(-1);

   int barnum = 0;
   int index;

   int i;
   for (i=0; i<infile.getNumLines(); i++) {
      if (!infile[i].isMeasure()) {
         continue;
      }
      if (sscanf(infile[i][0], "=%d", &barnum) == 1) {
         index = int(infile[i].getAbsBeat() / totaldur * segments);
         measures[index] = barnum;
      }
   }

   for (i=1; i<segments; i++) {
      if (measures[i] < 0) {
         measures[i] = measures[i-1];
      } 
   }

   index = -1;
   for (i=0; i<segments; i++) {
      if (measures[i] != -1) {
         index = i - 1;
         break;
      }
   }

   if (index < 0) {
      return;
   }
   if (index >= segments) {
      return;
   }

   for (i=index; i>=0; i--) {
      measures[i] = measures[index+1] - 1;
   }

}
Exemple #5
0
int generatePicture(HumdrumFile& infile, Array<PixelRow>& picture, int
      style) {

   Array<char> marks;
   getMarkChars(marks, infile);
   PixelColor matchcolor(255,255,255);

   infile.analyzeRhythm("4");
   int min = infile.getMinTimeBase();
   double totaldur = infile.getTotalDuration();
   
   int columns = (int)(totaldur * min / 4.0 + 0.5) + 5;
   if (columns > 50000) {
      cout << "Error: picture will be too big to generate" << endl;
      exit(1);
   }
   int factor = (int)(maxwidth / columns);
   if (factor <= 0) {
      factor = 1;
   }
   if (factor > maxfactor) {
      factor = maxfactor;
   }

   // set picture to black first.  Black regions will be filled in
   // with the background later.
   picture.setSize(128);
   int i, j, k;
   PixelColor backcolor(bgcolor);
   for (i=0; i<picture.getSize(); i++) {
      picture[i].setSize(columns * factor);
      for (j=0; j<picture[i].getSize(); j++) {
         picture[i][j] = backcolor;
         // picture[i][j].setRed(0);
         // picture[i][j].setGreen(0);
         // picture[i][j].setBlue(0);
      }
   }

   // examine metric levels for metric coloration
   Array<int>rhylev;
   infile.analyzeMetricLevel(rhylev);
   for (i=0; i<rhylev.getSize(); i++) {
      // reverse sign so that long notes are positive.
      rhylev[i] = -rhylev[i];
   }
   
   PixelColor color;
   int minpitch = 128;
   int maxpitch = -1;
   int pitch = 0;
   double duration = 0;
   double start = 0;
   char buffer[1024] = {0};
   for (i=0; i<infile.getNumLines(); i++) {
      if (debugQ) {
         cout << "Processing input line " << i + 1 << '\t' << infile[i] << endl;
      }
      if (infile[i].isData()) {
         start = infile[i].getAbsBeat();
         for (j=0; j<infile[i].getFieldCount(); j++) {
            if (strcmp(infile[i].getExInterp(j), "**kern") != 0) {
               continue;
            }
            // duration = Convert::kernToDuration(infile[i][j]);
            duration = infile.getTiedDuration(i, j);
            color = makeColor(infile, i, j, style, rhylev, 
                  infile[i].getPrimaryTrack(j));
            for (k=0; k<infile[i].getTokenCount(j); k++) {
               infile[i].getToken(buffer, j, k);
               if (strchr(buffer, '_') != NULL) {
                  continue;
               }
               if (strchr(buffer, ']') != NULL) {
                  continue;
               }

               pitch = Convert::kernToMidiNoteNumber(buffer);
               if (pitch < 0) {
                  // ignore rests
                  continue;
               }
               if (pitch < minpitch) {
                  minpitch = pitch;
               }
               if (pitch > maxpitch) {
                  maxpitch = pitch;
               }
               if (isMatch(marks, buffer)) {
                  placeNote(picture, pitch, start, duration, min, 
                        color, factor, 1);
               } else {
                  placeNote(picture, pitch, start, duration, min, 
                        color, factor, 0);
               }
            }
         }
      }

   }

   gmaxpitch = maxpitch;
   gminpitch = minpitch;
   return factor;
}
Exemple #6
0
void convertMeasureToXML(HumdrumFile& hfile, int line, int spine) { 
   int measureno = -1;

   if (!musicstart) {
      return;
   }

   updateAccidentals();
   const char *ptr;

   if (strcmp(hfile[line][spine], "==") == 0
       || strcmp(hfile[line+1][0], "*-") == 0) {
    
      checkbackup();

      lev++;
      pline(lev, "<barline>\n"); 
      lev++;
      pline(lev, "<bar-style>light-heavy</bar-style>\n");
      lev--;
      pline(lev, "</barline>\n"); 
      lev--;
      pline(lev, "</measure>\n");
      measurestate = 0;

   } else if ((ptr = strchr(hfile[line][spine], ':')) != NULL) {
      if ((ptr+1)[0] == '|' || (ptr+1)[0] == '!') {
         lev++;
         pline(lev, "<barline>\n"); 
         lev++;
         if (strstr(hfile[line][spine], ":|!") != NULL) {
            pline(lev, "<bar-style>light-heavy</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":||") != NULL) {
            pline(lev, "<bar-style>light-light</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":!") != NULL) {
            pline(lev, "<bar-style>heavy</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":|") != NULL) {
            pline(lev, "<bar-style>light</bar-style>\n");
         }
         pline(lev, "<repeat direction=\"backward\"/>\n");
         lev--;
         pline(lev, "</barline>\n"); 
         lev--;
      }

   } else if (strstr(hfile[line][spine], "||") != NULL) {
      checkbackup();

      lev++;
      pline(lev, "<barline>\n"); 
      lev++;
      pline(lev, "<bar-style>light-light</bar-style>\n");
      lev--;
      pline(lev, "</barline>\n"); 
      lev--;

   } 


   if (strcmp(hfile[line+1][0], "*-") == 0) {
      return;
   }

   checkbackup();

   if (minit != 0) {
      if (measurestate != 0) {
         pline(lev, "</measure>\n");
         measurestate = 0;
      }
   } 
   minit++;

   if (sscanf(hfile[line][spine], "=%d", &measureno)) {
      pline(lev, "<measure number=\"");
      cout << minit << "\">\n";
      measurestate = 1;
   } else if (strncmp(hfile[line][spine], "=", 1) == 0) {
      if (hfile.getTotalDuration() > hfile[line].getAbsBeat()) {
         // don't start a new measure if we are at the end of the music
         pline(lev, "<measure number=\"");
         cout << minit << "\">\n";
         measurestate = 1;
      }
   }

   if ((ptr = strchr(hfile[line][spine], ':')) != NULL) {
      if ((ptr-1)[0] == '|' || (ptr-1)[0] == '!') {
         lev++;
         pline(lev, "<barline>\n"); 
         lev++;
         if (strstr(hfile[line][spine], ":|!") != NULL) {
            pline(lev, "<bar-style>light-heavy</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":||") != NULL) {
            pline(lev, "<bar-style>light-light</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":!") != NULL) {
            pline(lev, "<bar-style>heavy</bar-style>\n");
         } else if (strstr(hfile[line][spine], ":|") != NULL) {
            pline(lev, "<bar-style>light</bar-style>\n");
         }
         pline(lev, "<repeat direction=\"forward\"/>\n");
         lev--;
         pline(lev, "</barline>\n"); 
         lev--;
      }
   }
}
Exemple #7
0
void analyzeContinuously(HumdrumFile& infile, int windowsize,
      double stepsize, double* majorKey, double* minorKey) {

   Array<Array<double> > segments;
   infile.analyzeRhythm("4");
   int segmentCount = int(infile.getTotalDuration() / stepsize + 0.5);

   if (segmentCount < windowsize) {
      cout << "Not enough data for requested analysis" << endl;
      return;
   }

   segments.setSize(segmentCount);
   segments.allowGrowth(0);
   int i;
   for (i=0; i<segments.getSize(); i++) {
      segments[i].setSize(12);
      segments[i].allowGrowth(0);
      segments[i].setAll(0);
   }
	    
   loadHistograms(segments, infile, segmentCount);

   if (debugQ) {
      printHistogramTotals(segments);
   }

   Array<Array<double> > pitchhist; 
   Array<Array<double> > correlations;

   pitchhist.setSize(segmentCount-windowsize);
   correlations.setSize(segmentCount-windowsize);
   pitchhist.allowGrowth(0);
   correlations.allowGrowth(0);
   for (i=0; i<segmentCount-windowsize; i++) {
      pitchhist[i].setSize(13);  //last spot for best key
      pitchhist[i].allowGrowth(0);
      correlations[i].setSize(24);
      correlations[i].allowGrowth(0);
   }

   for (i=0; i<segmentCount - windowsize; i++) {
      createHistogram(pitchhist[i], i, windowsize, segments);
      identifyKeyDouble(pitchhist[i], correlations[i], majorKey, minorKey);
   }


   Array<double> measures;
   getLocations(measures, infile, segmentCount);

   cout << "**key\t**rval\t**conf\t**start\t**mid\t**end\n";
   for (i=0; i<pitchhist.getSize(); i++) {
      printBestKey(int(pitchhist[i][12] + 0.5));
      cout << "\t";
      printCorrelation(correlations[i][int(pitchhist[i][12]+ 0.1)], roundQ);
      cout << "\t";
      cout << getConfidence(correlations[i], int(pitchhist[i][12]+0.1));
      cout << "\t";
      cout << "=" << measures[i];
      cout << "\t";
      cout << "=" << int((measures[i] + measures[i+windowsize])/2+0.49);
      cout << "\t";
      cout << "=" << measures[i+windowsize];
      cout << endl;
   }
   cout << "*-\t*-\t*-\t*-\t*-\t*-\n";

}
Exemple #8
0
void printBarlines(HumdrumFile& infile, int numberheight, int numberwidth) {
   int i, j;
   Array<Array<int> > xaxis;
   xaxis.setSize(numberheight-1);
   xaxis.allowGrowth(0);
   for (i=0; i<xaxis.getSize(); i++) {
      xaxis[i].setSize(numberwidth);
      xaxis[i].allowGrowth(0);
      xaxis[i].setAll(24);
   }

   // bar counter keeps track of multiple repeats of the same
   // music.
   Array<int> barcount(10000);
   barcount.allowGrowth(0);
   barcount.setAll(0);

   double measuresize = getMeasureSize(infile, numberwidth);
   int size;
   int style = 0;
   int position;
   int number;
   for (i=0; i<infile.getNumLines(); i++) {
      if (!infile[i].isMeasure()) {
         continue;
      }
      size = 0;
      position = -1;
      if (sscanf(infile[i][0], "=%d", &number)) {
         if ((number >= 0) && (number < barcount.getSize())) {
            style = barcount[number];
            barcount[number]++;
         } else {
            style = 0;
         }
         position = int(numberwidth * infile[i].getAbsBeat() / 
               infile.getTotalDuration() + 0.5);
         if ((number % 100) == 0) {
            size = 10;
         } else if ((number % 50) == 0) {
            size = 8;
         } else if ((number % 10) == 0) {
            size = 6;
         } else if ((number % 5) == 0) {
            size = 4;
         } else {
            size = 2;
            if (measuresize < 3) {
               // don't display single measure ticks if they
               // are too closely spaced
               size = 0; 
            }
         }
      }

      int color;
      if ((position >= 0) && (size > 0)) {
         for (j=0; j<size; j++) {
            if (style == 0) {
               color = 25;
            } else if (style == 1) {
               color = 4;  // red (in default color)
            } else if (style == 2) {
               color = 2;  // blue (in default color)
            } else if (style == 3) {
               color = 0;  // green (in default color)
            } else {
               color = 11;    // orange (in default color)
            }
            xaxis[j][position] = color;
	    if (j==9) {
               if (position>0) {
                  xaxis[j][position-1] = color;
               }
               if (position<xaxis[0].getSize()-1) {
                  xaxis[j][position+1] = color;
               }
            }
         }
      } 
   }

   // print a empty line so that small measure markers can be seen
   for (i=0; i<xaxis[0].getSize(); i++) {
         cout << ' ' << colorindex[24];
   }
   cout << '\n';

   for (i=0; i<xaxis.getSize(); i++) {  
      for (j=0; j<xaxis[i].getSize(); j++) {  
         cout << ' ' << colorindex[xaxis[i][j]];
      }
      cout << '\n';
   }


}
Exemple #9
0
void printTriadImage(HumdrumFile& infile, int rows, int cols) {

   Array<ChordQuality> cq;
   infile.analyzeSonorityQuality(cq);
   infile.analyzeRhythm("4");

   Array<Array<int> > triads;

   triads.setSize(3);

   triads[0].setSize(cols);
   triads[0].setAll(24);
   triads[1].setSize(cols);
   triads[1].setAll(24);
   triads[2].setSize(cols);
   triads[2].setAll(24);


   colorindex[0]  = "0 255 0";		// C major
   colorindex[1]  = "38 255 140";	// C-sharp major
   colorindex[2]  = "63 95 255";	// D major
   colorindex[3]  = "228 19 83";	// E-flat major
   colorindex[4]  = "255 0 0";		// E major
   colorindex[5]  = "255 255 0";	// F major
   colorindex[6]  = "192 255 0";	// F-sharp major
   colorindex[7]  = "93 211 255";	// G major
   colorindex[8]  = "129 50 255";	// A-flat major
   colorindex[9]  = "205 41 255";	// A major
   colorindex[10] = "255 160 0";	// B-flat major
   colorindex[11] = "255 110 10";	// B major
   colorindex[12] = "0 161 0";		// C minor
   colorindex[13] = "15 191 90";	// C-sharp minor
   colorindex[14] = "37 61 181";	// D minor
   colorindex[15] = "184 27 75";	// E-flat minor
   colorindex[16] = "175 0 0";		// E minor
   colorindex[17] = "220 200 0";	// F minor
   colorindex[18] = "140 200 0";	// F-sharp minor
   colorindex[19] = "65 163 181";	// G minor
   colorindex[20] = "100 28 181";	// G-sharp minor
   colorindex[21] = "136 13 181";	// A minor
   colorindex[22] = "181 93 20";	// B-flat minor
   colorindex[23] = "211 107 0";	// B minor
   colorindex[24] = "255 255 255";	// background
   colorindex[25] = "0 0 0";		// silence


   double start;
   double end;
   int    inversion;
   int    starti;
   int    endi;
   int    minQ;
   int    majQ;
   int    i, m, j, ii;
   int    rootindex;
   for (i=0; i<infile.getNumLines(); i++) {
      if (!infile[i].isData()) {
         continue;
      }
      if (strcmp(cq[i].getTypeName(), "min") == 0) {
         minQ = 1;
      } else {
         minQ = 0;
      }
      if (strcmp(cq[i].getTypeName(), "maj") == 0) {
         majQ = 1;
      } else {
         majQ = 0;
      }

      if (!(majQ || minQ)) {
         continue;
      }
      start = infile[i].getAbsBeat();
      end   = start + infile[i].getDuration();
      starti = int(start / infile.getTotalDuration() * cols + 0.5);
      endi   = int(end   / infile.getTotalDuration() * cols + 0.5);
      if (starti < 0) { starti = 0; }
      if (endi   < 0) { endi   = 0; }
      if (starti >= cols) { starti = cols-1; }
      if (endi   >= cols) { endi   = cols-1; }
      rootindex = Convert::base40ToMidiNoteNumber(cq[i].getRoot());
      if (minQ) {
         rootindex += 12;
      }
      inversion = cq[i].getInversion();
      for (ii=starti; ii<=endi; ii++) {
         triads[inversion][ii] = rootindex;
      }
   }

   int barheight = 0;
   int barwidth  = 0;
   if (barlinesQ) {
      barheight = 11;
      barwidth  = cols;
   }

   int legendheight = 0;
   int legendwidth  = 0;
   if (legendQ) {
      legendheight = 100;
      legendwidth  = cols;
   }


   int value = 24;
   Matrix<int> image(rows*2, cols, value);

   for (i=triads.getSize()-1; i>=0; i--) {
      int start = int(i/2.0 * rows);
      for (m=0; m<rows; m++) {
         ii = (int)(m + start);
         if (ii >= image.getRowCount()) {
            ii = image.getRowCount() - 1;
         }
         for (j=0; j<triads[i].getSize(); j++) {
            if (triads[i][j] < 24) {
               image.cell(ii,j) = triads[i][j];
            }
            // cout << colorindex[triads[i][j]] << " ";
            //cout << triads[i][j] << " ";
         }
         //cout << "\n";
      }
   }

   // print Image:
   cout << "P3\n";
   cout << cols  << " " << rows*2 + barheight + legendheight << "\n";
   cout << "255\n";

   for (i=image.getRowCount()-1; i>=0; i--) {
      for (j=0; j<image.getColumnCount(); j++) {
         cout << colorindex[image.cell(i,j)] << ' ';
      }
      cout << "\n";
   }

   if (barlinesQ) {
      printBarlines(infile, barheight, barwidth);
   }

   if (legendQ) {
      printLegend(legendheight, legendwidth);
   }

}