Example #1
0
 protected Node convert(Document doc, KeySignature signature) {
   Element keyEl = doc.createElement(KEY_TAG);
   Element fifthEl = doc.createElement(FIFTHS_TAG);
   Accidental[] acc = signature.getAccidentals();
   if (Arrays.equals(acc, KEY_NO_ACCIDENTAL)) fifthEl.appendChild(doc.createTextNode("0"));
   else if (signature.hasOnlySharps()) {
     if (Arrays.equals(acc, KEY_SHARP_1ST)) fifthEl.appendChild(doc.createTextNode("1"));
     else if (Arrays.equals(acc, KEY_SHARP_2ND)) fifthEl.appendChild(doc.createTextNode("2"));
     else if (Arrays.equals(acc, KEY_SHARP_3RD)) fifthEl.appendChild(doc.createTextNode("3"));
     else if (Arrays.equals(acc, KEY_SHARP_4TH)) fifthEl.appendChild(doc.createTextNode("4"));
     else if (Arrays.equals(acc, KEY_SHARP_5TH)) fifthEl.appendChild(doc.createTextNode("5"));
     else if (Arrays.equals(acc, KEY_SHARP_6TH)) fifthEl.appendChild(doc.createTextNode("6"));
     else if (Arrays.equals(acc, KEY_SHARP_7TH)) fifthEl.appendChild(doc.createTextNode("7"));
   } else {
     if (Arrays.equals(acc, KEY_FLAT_1ST)) fifthEl.appendChild(doc.createTextNode("-1"));
     else if (Arrays.equals(acc, KEY_FLAT_2ND)) fifthEl.appendChild(doc.createTextNode("-2"));
     else if (Arrays.equals(acc, KEY_FLAT_3RD)) fifthEl.appendChild(doc.createTextNode("-3"));
     else if (Arrays.equals(acc, KEY_FLAT_4TH)) fifthEl.appendChild(doc.createTextNode("-4"));
     else if (Arrays.equals(acc, KEY_FLAT_5TH)) fifthEl.appendChild(doc.createTextNode("-5"));
     else if (Arrays.equals(acc, KEY_FLAT_6TH)) fifthEl.appendChild(doc.createTextNode("-6"));
     else if (Arrays.equals(acc, KEY_FLAT_7TH)) fifthEl.appendChild(doc.createTextNode("-7"));
   }
   keyEl.appendChild(fifthEl);
   Element modeEl = doc.createElement(MODE_TAG);
   switch (signature.getMode()) {
     case 0:
       modeEl.appendChild(doc.createTextNode("aeolian"));
       break;
     case 1:
       modeEl.appendChild(doc.createTextNode("dorian"));
       break;
     case 2:
       modeEl.appendChild(doc.createTextNode("ionian"));
       break;
     case 3:
       modeEl.appendChild(doc.createTextNode("locrian"));
       break;
     case 4:
       modeEl.appendChild(doc.createTextNode("lydian"));
       break;
     case 5:
       modeEl.appendChild(doc.createTextNode("major"));
       break;
     case 6:
       modeEl.appendChild(doc.createTextNode("minor"));
       break;
     case 7:
       modeEl.appendChild(doc.createTextNode("mixolydian"));
       break;
     case 8:
       modeEl.appendChild(doc.createTextNode("phrygian"));
       break;
     default:
       modeEl.appendChild(doc.createTextNode("major"));
       break;
   }
   keyEl.appendChild(modeEl);
   return keyEl;
 }
  /**
   * Converts the given tune to a midi sequence.
   *
   * @param tune The tune to be converted.
   * @return The midi sequence of the tune.
   */
  public Sequence toMidiSequence(Tune tune) {
    Sequence sequence = null;
    try {
      if (instrument == null) {
        Synthesizer synth = MidiSystem.getSynthesizer();
        synth.open();
        try {
          setInstrument(synth.getAvailableInstruments()[0]);
        } finally {
          synth.close();
        }
      }
      // Sequence in ticks per quarter note : PPQ = Pulse Per Quarter Note
      // Resolution is expressed in ticks per beat.
      // Last parameter "1" is the number of tracks.
      sequence = new Sequence(Sequence.PPQ, SEQUENCE_RESOLUTION, 1);
      // Set the instrument on channel 0
      ShortMessage sm = new ShortMessage();
      sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument.getPatch().getProgram(), 0);

      Track track = sequence.createTrack();
      track.add(new MidiEvent(sm, 0));
      // long trackLengthInTicks = track.ticks();
      int lastRepeatOpen = -1;
      int repeatNumber = 1;
      boolean inWrongEnding = false;
      KeySignature tuneKey = null;
      KeySignature currentKey = null;
      Hashtable partsKey = new Hashtable();

      long elapsedTime = 0;
      NoteAbstract[] graceNotes = null;
      Music staff = tune.getMusicForAudioRendition();
      Iterator it = staff.getVoices().iterator();
      while (it.hasNext()) {
        Voice voice = (Voice) it.next();
        int i = 0; // StaffItem iterator
        while (i < voice.size()) {
          if (!inWrongEnding) {
            // ==================================================================== TEMPO
            if (voice.elementAt(i) instanceof abc.notation.Tempo) {
              addTempoEventsFor(
                  track,
                  elapsedTime,
                  getMidiMessagesFor((Tempo) voice.elementAt(i))); // , trackLengthInTicks));
            } else
            /*if (voice.elementAt(i) instanceof abc.notation.PartLabel) {
            	//Imagine... part A in Gmaj, B in Amin
            	//in tune you have K:G, P:A, ... P:B, K:Am
            	//if you have part order ABA, when you return to A
            	//you stay in Amin. This stores the tuneKey when a
            	//new part appear, and restitute it when part is played again
            	abc.notation.PartLabel pl = (abc.notation.PartLabel) voice.elementAt(i);
            	if (partsKey.get(pl.getLabel()+"") == null) {
            		partsKey.put(pl.getLabel()+"", tuneKey);
            	} else {
            		tuneKey = (KeySignature) partsKey.get(pl.getLabel()+"");
            	}
            }
            else*/
            // ==================================================================== KEY SIGNATURE
            if (voice.elementAt(i) instanceof abc.notation.KeySignature) {
              tuneKey = (KeySignature) (voice.elementAt(i));
              currentKey = new KeySignature(tuneKey.getAccidentals());
            } else
            // ==================================================================== NOTE
            // Notes ending ties should be ignored. Already taken into
            // account in getNoteLengthInTicks(Note)
            if (voice.elementAt(i) instanceof abc.notation.Note
                && !((abc.notation.Note) voice.elementAt(i)).isEndingTie()) {

              Note note = (Note) voice.elementAt(i);
              long noteDuration;
              boolean fermata = false;
              Vector decorationNotes = new Vector();
              if (note.hasGeneralGracing() || note.hasDecorations()) {
                Decoration[] d = note.getDecorations();
                for (int j = 0; j < d.length; j++) {
                  switch (d[j].getType()) {
                    case Decoration.FERMATA:
                    case Decoration.FERMATA_INVERTED:
                      fermata = true;
                      break;
                    case Decoration.LOWERMORDENT:
                    case Decoration.UPPERMORDENT:
                    case Decoration.DOUBLE_LOWER_MORDANT:
                    case Decoration.DOUBLE_UPPER_MORDANT:
                    case Decoration.TRILL:
                    case Decoration.TURN: // GRUPETTO_UP
                    case Decoration.TURN_INVERTED: // GRUPETTO_DOWN
                    case Decoration.TURNX:
                    case Decoration.TURNX_INVERTED:
                      Note n = new Note(note.getHeight());
                      n.setAccidental(note.getAccidental(currentKey));
                      Note o =
                          new Interval(Interval.SECOND, Interval.MAJOR, Interval.UPWARD)
                              .calculateSecondNote(n);
                      Note m =
                          new Interval(Interval.SECOND, Interval.MAJOR, Interval.DOWNWARD)
                              .calculateSecondNote(n);
                      // TODO ornament templates: regular, musette, balkan...
                      // n.setStrictDuration(Note.SIXTEENTH);
                      // o.setDuration((short)(Note.EIGHTH+Note.SIXTEENTH));
                      o.setAccidental(Accidental.NONE);
                      m.setAccidental(Accidental.NONE);
                      n.setStrictDuration(Note.THIRTY_SECOND);
                      m.setStrictDuration(Note.THIRTY_SECOND);
                      o.setStrictDuration(Note.THIRTY_SECOND);
                      switch (d[j].getType()) {
                        case Decoration.DOUBLE_LOWER_MORDANT:
                          decorationNotes.add(n);
                          decorationNotes.add(m);
                        case Decoration.LOWERMORDENT:
                          decorationNotes.add(n);
                          decorationNotes.add(m);
                          break;
                        case Decoration.DOUBLE_UPPER_MORDANT:
                        case Decoration.TRILL:
                          decorationNotes.add(n);
                          decorationNotes.add(o);
                        case Decoration.UPPERMORDENT:
                          decorationNotes.add(n);
                          decorationNotes.add(o);
                          break;
                        case Decoration.TURNX_INVERTED:
                        case Decoration.TURN:
                          decorationNotes.add(o);
                          decorationNotes.add(n);
                          decorationNotes.add(m);
                          break;
                        case Decoration.TURNX:
                        case Decoration.TURN_INVERTED:
                          decorationNotes.add(m);
                          decorationNotes.add(n);
                          decorationNotes.add(o);
                      }
                      break;
                  }
                }
                // currently not used
                // future use: playing rolls, slides, etc.
              }
              long graceNotesDuration = 0;
              if (note.hasGracingNotes() || (decorationNotes.size() > 0)) {
                graceNotes = note.getGracingNotes();
                // gracing are eighth note for graphical rendition
                // and because that's it in the parser
                // adapt duration to note length
                int divisor = 1;
                if (note.getStrictDuration() >= Note.HALF) divisor = 1; // grace is an eighth
                else if (note.getStrictDuration() >= Note.QUARTER) divisor = 2; // 16th
                else if (note.getStrictDuration() >= Note.EIGHTH) divisor = 4; // 32nd
                else divisor = 8; // 64th
                if (note.hasGracingNotes()) {
                  for (int j = 0; j < graceNotes.length; j++) {
                    noteDuration = getNoteLengthInTicks(graceNotes[j], staff) / divisor;
                    graceNotesDuration += noteDuration;
                    if (graceNotes[j] instanceof Note)
                      playNote(
                          (Note) graceNotes[j], i, currentKey, elapsedTime, noteDuration, track);
                    else
                      playMultiNote(
                          (MultiNote) graceNotes[j],
                          i,
                          currentKey, /*elapsedTime,*/
                          noteDuration,
                          track,
                          staff);
                    elapsedTime += noteDuration;
                  }
                }
                for (int j = 0; j < decorationNotes.size(); j++) {
                  noteDuration = getNoteLengthInTicks((Note) decorationNotes.elementAt(j), staff);
                  graceNotesDuration += noteDuration;
                  playNote(
                      (Note) decorationNotes.elementAt(j),
                      i,
                      currentKey,
                      elapsedTime,
                      noteDuration,
                      track);
                  elapsedTime += noteDuration;
                }
              }
              // The note duration if the note isn't part of a tuplet.
              noteDuration = getNoteLengthInTicks(note, staff) - graceNotesDuration;
              if (noteDuration <= 0) // in case of too much grace notes
              noteDuration = getNoteLengthInTicks(note, staff);
              if (fermata) noteDuration *= 2;
              playNote(note, i, currentKey, elapsedTime, noteDuration, track);
              elapsedTime += noteDuration;
            } else
            // ==================================================================== MULTI NOTE
            if ((voice.elementAt(i) instanceof abc.notation.MultiNote)) {
              MultiNote multiNote = (MultiNote) voice.elementAt(i);
              playMultiNote(multiNote, i, currentKey, elapsedTime, track, staff);
              elapsedTime += getNoteLengthInTicks(multiNote, staff);
            }
          } // endif (!inWrongEnding)
          // ====================================================================== REPEAT BAR LINE
          if (voice.elementAt(i) instanceof abc.notation.RepeatBarLine) {
            RepeatBarLine bar = (RepeatBarLine) voice.elementAt(i);
            if (repeatNumber < bar.getRepeatNumbers()[0] && lastRepeatOpen != -1) {
              repeatNumber++;
              i = lastRepeatOpen;
            } else if (repeatNumber > bar.getRepeatNumbers()[0]) inWrongEnding = true;
            else inWrongEnding = false;
          } else
          // ====================================================================== BAR LINE OPEN /
          // CLOSE
          if (voice.elementAt(i) instanceof abc.notation.BarLine) {
            // currentKey = new KeySignature(tuneKey.getAccidentals());
            switch (((BarLine) (voice.elementAt(i))).getType()) {
              case BarLine.SIMPLE:
                break;
              case BarLine.REPEAT_OPEN:
                lastRepeatOpen = i;
                repeatNumber = 1;
                break;
              case BarLine.REPEAT_CLOSE:
                if (repeatNumber < 2 && lastRepeatOpen != -1) {
                  repeatNumber++;
                  i = lastRepeatOpen;
                } else {
                  repeatNumber = 1;
                  lastRepeatOpen = -1;
                }
                break;
                // TODO case BarLine.BEGIN_AND_END_REPEAT
            }
          }
          // Whatever kind of bar line it is
          if (voice.elementAt(i) instanceof abc.notation.BarLine) {
            currentKey = new KeySignature(tuneKey.getAccidentals());
          }
          i++;
        } // end while each element in voice
      } // end while each voice in music
    } catch (InvalidMidiDataException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return sequence;
  }
 private static void updateKey(KeySignature key, Note note) {
   if (!note.getAccidental().isInTheKey()) {
     key.setAccidental(note.getStrictHeight(), note.getAccidental());
   }
 }
Example #4
0
  protected Element convert(Document doc, Note note) {
    Element noteEl = doc.createElement(NOTE_TAG);
    Element durationEl = doc.createElement(DURATION_TAG);

    String stepValue = null;
    byte strictHeight = note.getStrictHeight();
    int octave = note.getOctaveTransposition();
    if (note.isRest()) {
      Element rest = doc.createElement(REST_TAG);
      noteEl.appendChild(rest);
    } else {
      switch (strictHeight) {
        case Note.C:
          stepValue = "C";
          break;
        case Note.D:
          stepValue = "D";
          break;
        case Note.E:
          stepValue = "E";
          break;
        case Note.F:
          stepValue = "F";
          break;
        case Note.G:
          stepValue = "G";
          break;
        case Note.A:
          stepValue = "A";
          break;
        case Note.B:
          stepValue = "B";
          break;
      }

      octave = octave + 4;
      String octaveValue = new Integer(octave).toString();
      // Element typeEl = doc.createElement(TYPE_TAG);
      // typeEl.appendChild(doc.createTextNode("quarter"));
      Element pitchEl = doc.createElement(PITCH_TAG);
      Element stepEl = doc.createElement(STEP_TAG);
      stepEl.appendChild(doc.createTextNode(stepValue));
      pitchEl.appendChild(stepEl);

      if (keySignature != null) {
        Accidental accidental = note.getAccidental();
        if (accidental.isInTheKey()) {
          accidental = keySignature.getAccidentalFor(note.getStrictHeight());
        }
        if (accidental.isDefined()) {
          int alterValue = accidental.getNearestOccidentalValue();

          Element alterEl = doc.createElement(ALTER_TAG);
          alterEl.appendChild(doc.createTextNode(Integer.toString(alterValue)));
          pitchEl.appendChild(alterEl);
        }
      }

      Element octaveEl = doc.createElement(OCTAVE_TAG);
      octaveEl.appendChild(doc.createTextNode(octaveValue));
      pitchEl.appendChild(octaveEl);

      noteEl.appendChild(pitchEl);

      if (note.hasAccidental()) {
        Node acc = doc.createElement(ACCIDENTAL_TAG);
        Node accValue = null;
        if (note.getAccidental().isFlat()) accValue = doc.createTextNode("flat");
        else if (note.getAccidental().isNatural()) accValue = doc.createTextNode("natural");
        else if (note.getAccidental().isSharp()) accValue = doc.createTextNode("sharp");
        // TODO double flat/sharp
        acc.appendChild(accValue);
        noteEl.appendChild(acc);
      }
    }
    int relDuration = note.getDuration() * DIVISIONS_PER_QUARTER_NOTE / Note.QUARTER;
    durationEl.appendChild(doc.createTextNode(new Integer(relDuration).toString()));
    noteEl.appendChild(durationEl);
    if (note.isTied()) {
      String type = null;
      if (note.isBeginningTie()) {
        type = "start";
      } else if (note.isEndingTie()) {
        type = "stop";
      }
      if (type != null) {
        Element tieEl = doc.createElement(TIE_TAG);
        tieEl.setAttribute(TYPE_ATTRIBUTE, type);
        noteEl.appendChild(tieEl);
        Element notationsEl = (Element) noteEl.getElementsByTagName(NOTATIONS_TAG).item(0);
        if (notationsEl == null) {
          notationsEl = doc.createElement(NOTATIONS_TAG);
          noteEl.appendChild(notationsEl);
        }
        Element tiedEl = doc.createElement(TIED_TAG);
        tiedEl.setAttribute(TYPE_ATTRIBUTE, type);
        notationsEl.appendChild(tiedEl);
      }
    }

    if (note.isPartOfTuplet()) {
      Tuplet tuplet = note.getTuplet();
      Vector notes = tuplet.getNotesAsVector();
      int d = 0;
      for (Iterator iterator = notes.iterator(); iterator.hasNext(); ) {
        Note n = (Note) iterator.next();
        d += n.getStrictDuration();
      }
      int gcd = MathUtils.pgcd(d, tuplet.getTotalDuration());
      Element timeModificationEl = doc.createElement(TIMEMODIFICATION_TAG);

      Element actualNotesEl = doc.createElement(ACTUALNOTES_TAG);
      actualNotesEl.appendChild(doc.createTextNode(Integer.toString(d / gcd)));
      timeModificationEl.appendChild(actualNotesEl);

      Element normalNotesEl = doc.createElement(NORMALNOTES_TAG);
      normalNotesEl.appendChild(
          doc.createTextNode(Integer.toString(tuplet.getTotalDuration() / gcd)));
      timeModificationEl.appendChild(normalNotesEl);

      noteEl.appendChild(timeModificationEl);

      Element notationsEl = doc.createElement(NOTATIONS_TAG);
      Element tupletEl = doc.createElement(TUPLET_TAG);
      if (note.equals(notes.get(0))) {
        tupletEl.setAttribute(TYPE_ATTRIBUTE, "start");
        notationsEl.appendChild(tupletEl);
        noteEl.appendChild(notationsEl);
      } else if (note.equals(notes.get(notes.size() - 1))) {
        tupletEl.setAttribute(TYPE_ATTRIBUTE, "stop");
        notationsEl.appendChild(tupletEl);
        noteEl.appendChild(notationsEl);
      }
    }

    Node type = doc.createElement(TYPE_TAG);
    Node typeValue = null;
    switch (note.getStrictDuration()) {
      case Note.SIXTY_FOURTH:
        typeValue = doc.createTextNode("64th");
        break;
      case Note.THIRTY_SECOND:
        typeValue = doc.createTextNode("32nd");
        break;
      case Note.SIXTEENTH:
        typeValue = doc.createTextNode("16th");
        break;
      case Note.EIGHTH:
        typeValue = doc.createTextNode("eighth");
        break;
      case Note.QUARTER:
        typeValue = doc.createTextNode("quarter");
        break;
      case Note.HALF:
        typeValue = doc.createTextNode("half");
        break;
      case Note.WHOLE:
        typeValue = doc.createTextNode("whole");
        break;
    }
    if (typeValue != null) {
      type.appendChild(typeValue);
      noteEl.appendChild(type);
    }

    if (note.countDots() >= 1) {
      for (int i = 0; i < note.countDots(); i++) {
        Node dot = doc.createElement(DOT_TAG);
        noteEl.appendChild(dot);
      }
    }
    return noteEl;
  }