コード例 #1
0
ファイル: ScoreParser.java プロジェクト: emtwo/piano
  // ParserListener methods
  public void noteEvent(Note note) {
    if (layer >= staves) {
      return;
    }
    // System.out.println(note.getMusicString() + " " + note.getMillisDuration() + " " +
    // note.getDecimalDuration());
    Vector<Chord> currChords = chords[layer];
    Iterator<NotePanel> currNote = currNotes[layer];

    if (!currNote.hasNext()) {
      System.err.println("Received noteEvent, but no PostScript notes are left");
      return;
    }

    if (note.getMillisDuration() > 0) {
      NotePanel notePanel = currNote.next();
      // time the last chord ended
      long tempTime = 0;
      for (int i = currChords.size() - 1; i >= 0; --i) {
        if (!currChords.get(i).isTie()) {
          tempTime = currChords.get(i).getTime() + currChords.get(i).getDuration();
          break;
        }
      }

      if (notePanel.isTie) {
        Chord chord = new Chord();
        // for each note in the last chord, set the next note as a tied note
        for (int i = 0; i < currChords.lastElement().size(); ++i) {
          notePanel.setTie(true).setTime(Math.min(tempTime, time - 1)).setTempo(tempo);
          chord.addNote(notePanel);
          notePanel = currNote.next();
        }
        currChords.add(chord);
      }

      while (notePanel.isRest) {
        notePanel
            .setTime(Math.min(tempTime, time - 1)) // hack, in case the rest should be trimmed
            .setTempo(tempo);
        tempTime += notePanel.getDuration();
        Chord chord = new Chord(notePanel);
        currChords.add(chord);
        // System.out.println("REST: " + notePanel.getMusicString() + " " +
        // notePanel.getDuration());
        notePanel = currNote.next();
      }

      notePanel.setNote(note).setTime(time).setTempo(tempo);
      if (currChords.isEmpty() || currChords.lastElement().getTime() != time) {
        Chord chord = new Chord(notePanel);
        currChords.add(chord);
      } else {
        currChords.lastElement().addNote(notePanel);
      }
    }
  }
コード例 #2
0
ファイル: ScoreParser.java プロジェクト: emtwo/piano
  private void parseMidi() {
    try {
      // Allow for alternate file extensions of midi files.
      File midiFile = new File("data/out/" + name + ".midi");
      File altFile = new File("data/out/" + name + ".mid");

      if (!midiFile.exists() && altFile.exists()) {
        midiFile = altFile;
      }

      // parse midi
      Sequence sequence = MidiSystem.getSequence(midiFile);
      resolution = sequence.getResolution();

      for (int i = 0; i < staves; ++i) {
        currNotes[i] = notes[i].iterator();
      }

      MidiParser parser = new MidiParser();
      parser.addParserListener(this);
      parser.parse(sequence);

      // initialize any rests trailing at the end
      for (int i = 0; i < staves; ++i) {
        Vector<Chord> currChords = chords[i];
        Iterator<NotePanel> currNote = currNotes[i];
        long tempTime = 0;
        for (int j = currChords.size() - 1; j >= 0; --j) {
          if (!currChords.get(j).isTie()) {
            tempTime = currChords.get(j).getTime() + currChords.get(j).getDuration();
            break;
          }
        }
        while (currNote.hasNext()) {
          NotePanel notePanel = currNote.next();
          if (notePanel.getNote() != null) {
            notePanel.setTime(tempTime).setTempo(tempo);

            tempTime += notePanel.getDuration();
            Chord chord = new Chord(notePanel);
            currChords.add(chord);
          }
        }
      }

      // attach staff lines
      for (int layer = 0; layer < staves; ++layer) {
        NotePanel prevNote = null;
        for (Chord chord : chords[layer]) {
          for (NotePanel note : chord.notes) {
            double staffLine = 0.0;
            for (double line : staffLines.get(layer).get(note.page - 1)) {
              if (staffLine < 0.0001 || Math.abs(staffLine - note.y) > Math.abs(line - note.y)) {
                staffLine = line;
              }
            }
            if (prevNote != null) {
              if (Math.abs(staffLine - prevNote.staffLine) > 0.001) {
                // either reached the end of the line, or the note is really high/low
                // make a hacky guess if the note is really high/low,
                // and if so, set its staffline equal to the previous note's
                if (prevNote.x < note.x + 1.0) {
                  note.setStaffLine(prevNote.staffLine);
                  prevNote = note;
                  continue;
                }
              }
            }
            note.setStaffLine(staffLine);
            prevNote = note;
          }
        }
      }

    } catch (Exception e) {
      System.err.println("Parsing the score from Lilypond's output has failed. Error: ");
      e.printStackTrace();
    }
  }
コード例 #3
0
ファイル: ScoreParser.java プロジェクト: emtwo/piano
  private void parsePostScript() {
    try {
      BufferedReader PSIn = new BufferedReader(new FileReader("data/out/" + name + ".ps"));

      // parse header
      while (PSIn.ready()) {
        String S = PSIn.readLine().trim();
        if (S.contains("EndSetup")) {
          break;
        } else {
          if (S.startsWith("/magfont")) {
            fontInfo.add(S);
          } else if (S.startsWith("/lily-output-units")) {
            outputUnits = Float.parseFloat(S.split(" ")[1]);
            for (String T : fontInfo) {
              addFont(
                  T.split(" ")[0].substring(1),
                  T.split(" ")[2].substring(1),
                  (float) outputUnits * Float.parseFloat(T.split(" ")[3]));
            }
          } else if (S.startsWith("/output-scale")) {
            outputScale = Float.parseFloat(S.split(" ")[1]);
          } else if (S.startsWith("/staff-height")) {
            staffLineHeight = Float.parseFloat(S.split(" ")[1]) / 4;
          }
        }
      }
      scale = outputUnits * outputScale;

      for (int layer = 0; layer < staves; ++layer) {
        Vector<Vector<Double>> staff = new Vector<Vector<Double>>();
        for (int page = 0; page < pages; ++page) {
          staff.add(new Vector<Double>());
        }
        staffLines.add(staff);
      }
      Vector<Double> cStaffs = new Vector<Double>();

      String prevLine = "";
      int currPage = 1;

      // parse the rest of the file
      while (PSIn.ready()) {
        String S = PSIn.readLine().trim();
        if (S.contains("noteheads") || S.contains("rests")) {
          // extract coordinate, glyph, and font information
          String T[] = S.split(" ");
          NotePanel N = new NotePanel();
          N.setCoordinates(Double.parseDouble(T[0]), -Double.parseDouble(T[1]))
              .setGlyph(T[4].substring(1))
              .setGonville(fonts.get(T[3]));
          if (S.contains("rests")) {
            T = S.substring(S.lastIndexOf("rests")).split("[. ]");
            N.setRest(Integer.parseInt(T[1]));
          }

          T = prevLine.substring(prevLine.lastIndexOf(this.name + ".ly")).split(":");
          N.setLine(Integer.parseInt(T[1]), Integer.parseInt(T[2])).setPage(currPage);

          if (N.lyLine < staffLine || staffLine == 0) {
            notes[0].add(N);
          } else {
            notes[1].add(N);
          }
        } else if (S.contains("accidentals")) {
          // String T[] = S.split(" ");
          // lastNote.setAccidentals(Double.parseDouble(T[0]), -Double.parseDouble(T[1]),
          // T[4].substring(1), T[3]);
        } else if (S.startsWith("%%Page:")) {
          currPage = Integer.parseInt(S.split(" ")[1]);
        }

        if (S.contains("draw_line")) {
          cStaffs.add(-Double.parseDouble(S.split(" ")[1]));
          if (cStaffs.size() >= 5 * staves) {
            // found a full staff
            Collections.sort(cStaffs);
            staffLines.get(0).get(currPage - 1).add(cStaffs.get(4) + staffLineHeight);
            if (staves > 1) {
              staffLines.get(1).get(currPage - 1).add(cStaffs.get(5) - staffLineHeight);
            }
            cStaffs.clear();
          }
        } else if (!S.contains("draw_round_box")) {
          cStaffs.clear();
        }

        if (S.contains(this.name + ".ly")) {
          prevLine = S;
        }
      }

      // sort the notes we found from the PS by where they occurred in the .ly
      for (int i = 0; i < staves; ++i) {
        Collections.sort(notes[i]);
      }

      // find tied notes
      for (int i = 0; i < staves; ++i) {
        int cTie = 0;
        int cNote = 0;

        while (cTie < ties.size() && cNote < notes[i].size() - 1) {
          ArrayList<Integer> tie = ties.get(cTie);
          NotePanel prevNote = notes[i].get(cNote);
          NotePanel nextNote = notes[i].get(cNote + 1);
          if (pairComp(tie.get(0), tie.get(1), prevNote.lyLine, prevNote.lyNumber) != -1
              && pairComp(tie.get(0), tie.get(1), nextNote.lyLine, nextNote.lyNumber) != 1) {
            // tie is located between these notes
            nextNote.setTie(true);
            ++cNote;
            ++cTie;
          } else if (pairComp(tie.get(0), tie.get(1), prevNote.lyLine, prevNote.lyNumber) != -1) {
            ++cNote;
          } else {
            ++cTie;
          }
        }
      }

      PSIn.close();
    } catch (Exception e) {
      System.err.println("Parsing the score from Lilypond's output has failed. Error: ");
      e.printStackTrace();
    }
  }