Beispiel #1
0
 public void play() throws MidiUnavailableException {
   if (play) return;
   play = true;
   if (playTasks == null) init();
   synchronized (playTasks) {
     for (PlayTask th : playTasks) th.timer.schedule(th.newTask(), 10L);
   }
 }
Beispiel #2
0
 public void readFrom(FeatureInputStream in, long startOffset)
     throws IOException, InvalidMidiDataException {
   PlayTask th = new PlayTask();
   float tempo = 160f;
   char ch = in.readChar();
   TreeSet<MidimsgHolder> lst = new TreeSet<MidimsgHolder>();
   while (ch != 0xFFFF) {
     long dstoff = 0L;
     int channel;
     synchronized (unusedChannels) {
       channel = unusedChannels.remove(0); // channel for new notes
       unusedChannels.add(channel);
     }
     int vol = 64; // base volume for new notes (0..127)
     long pushOffset = 0;
     TreeSet<MidimsgHolder> memslot = null;
     long memOnly = -1;
     while (ch != '\n' && ch != 0xFFFF) {
       boolean incOffset = true;
       switch (ch) {
         case '\\':
           if (in.peekChar() == '\r') in.readChar();
           if (in.peekChar() == '\n') in.readChar();
           break;
         case '/':
           if (in.peekChar() == '*') {
               /* checks and reads for this kind of comment block */
             in.readChar();
             for (; ; ) {
               while ((ch = in.readChar()) != '*' && ch != 0xFFFF) ;
               if ((ch = in.readChar()) == '/' || ch == 0xFFFF) break;
             }
           }
           break;
         case 'x':
           synchronized (unusedChannels) {
             unusedChannels.remove(channel);
             unusedChannels.add(0, channel);
           }
           channel = in.readInt(1, 16);
           break;
         case 't':
           MidimsgHolder t = MidimsgHolder.tempo(dstoff, in.readFloat());
           if (tempo == 160f) tempo = t.newTempo;
           if (memOnly == -1) lst.add(t);
           if (memslot != null) memslot.add(t);
           break;
         case 'V':
           vol = Math.min(in.readInt(2, 16), 127);
           break;
         case 'R':
           if (memOnly == -1) {
             memOnly = dstoff;
             th.seqmem.put(in.readInt(), memslot = new TreeSet<MidimsgHolder>());
           } else {
             memslot.add(MidimsgHolder.text(dstoff, "REPEAT"));
             memslot = null;
             dstoff = memOnly;
             memOnly = -1;
           }
           break;
         case 'M':
           if (memslot == null)
             th.seqmem.put(in.readInt(), memslot = new TreeSet<MidimsgHolder>());
           else {
             memslot.add(MidimsgHolder.text(dstoff, "REPEAT"));
             memslot = null;
           }
           break;
         case 'p':
           MidimsgHolder pc = new MidimsgHolder(dstoff, PROGRAM_CHANGE, channel, in.readInt(), 0);
           if (memOnly == -1) lst.add(pc);
           if (memslot != null) memslot.add(pc);
           break;
         case '!': // generic midi event
           int tmp = in.peekChar();
           if (tmp == '*') // fade
           in.readChar();
           Integer a = null, b = 1, step = 1, delta = 128;
           int eventType = in.readInt(1, 16) << 4;
           int param1 = in.readInt(2, 16);
           if (tmp == '*') // fade
           {
             in.readChar(); // =
             a = in.readInt(2, 16);
             in.readChar(); // >
             b = in.readInt(2, 16);
             try {
               step = in.readInt();
             } catch (IOException e) {
             }
             ;
             try {
               delta = in.readInt();
             } catch (IOException e) {
             }
             ;
           } else {
             a = in.readInt(2, 16);
             b = a;
           }
           int d = 0;
           for (int x = a; step < 0 ? x >= b : x <= b; x += step, d += delta) {
             MidimsgHolder hh = new MidimsgHolder(dstoff + d, eventType, channel, param1, x);
             if (memOnly == -1) lst.add(hh);
             if (memslot != null) memslot.add(hh);
           }
           break;
         case '.': // stop
           if (memslot != null && memslot.size() == 0)
             memslot.add(MidimsgHolder.text(dstoff, ".")); // record correct start moment
           int length = readLength(in);
           if (in.peekChar() == '*') {
             in.readChar();
             int qty2 = in.readInt();
             for (int i = 0; i < qty2; i++) dstoff += length;
           } else dstoff += length;
           break;
         case '[':
           pushOffset = dstoff;
           break;
         case ']':
           dstoff = pushOffset;
           break;
         case '<':
           incOffset = false;
           ch = in.readChar();
           if (ch < 'c' || ch > 'h') break;
         case 'c':
         case 'd':
         case 'e':
         case 'f':
         case 'g':
         case 'a':
         case 'b':
         case 'h':
           int add = (ch == 'a' || ch == 'b') ? 'c' - 8 : 'c';
           int base = baseNote[ch - add];
           int dur = 0;
           int velo = vol;
           int qty = 1;
           boolean ok = true;
           while (ok) {
             int mdf = in.peekChar();
             switch (mdf) {
               case '#':
                 base++;
                 in.readChar();
                 break;
               case '-':
                 base--;
                 in.readChar();
                 break;
               case 'v':
                 in.readChar();
                 if (in.peekChar() == '+') {
                   in.readChar();
                   velo = in.readInt(2, 16);
                   vol = Math.min(vol + velo, 127);
                   velo = vol;
                   break;
                 } else if (in.peekChar() == '-') {
                   in.readChar();
                   velo = in.readInt(2, 16);
                   vol = Math.max(vol - velo, 0);
                   velo = vol;
                   break;
                 }
                 velo = Math.min(in.readInt(2, 16), 127);
                 break;
               case '0':
               case '1':
               case '2':
               case '3':
               case '4':
               case '5':
               case '6':
               case '7':
               case '8':
               case '9':
                 base += (mdf - '5') * 12;
                 in.readChar();
                 break;
               case 'I':
               case 'H':
               case 'G':
               case 'F':
               case 'E':
               case 'D':
               case 'C':
               case 'B':
               case 'A':
                 dur += readLength(in);
                 break;
               case '*':
                 in.readChar();
                 qty = in.readInt();
                 break;
               default:
                 ok = false;
                 break;
             }
           }
           if (dur == 0) dur = 32; // 32 ticks for 4/4
           for (int i = 0; i < qty; i++) {
             if (memOnly == -1) {
               lst.add(new MidimsgHolder(dstoff, NOTE_ON, channel, base, velo));
               lst.add(new MidimsgHolder(dstoff + dur, NOTE_OFF, channel, base, 0));
             }
             if (memslot != null) {
               memslot.add(new MidimsgHolder(dstoff, NOTE_ON, channel, base, velo));
               memslot.add(new MidimsgHolder(dstoff + dur, NOTE_OFF, channel, base, 0));
             }
             dstoff += dur;
           }
           if (!incOffset) dstoff -= dur * qty;
           break;
         case 'N':
           TreeSet<MidimsgHolder> stored = th.seqmem.get(in.readInt());
           int n = 1;
           if (in.peekChar() == '*') {
             in.readChar();
             n = in.readInt();
           }
           if (stored != null) {
             for (int i = 0; i < n; i++) {
               long diff = dstoff - stored.first().offset;
               for (MidimsgHolder h : stored) {
                 MidimsgHolder h2 = new MidimsgHolder();
                 h2.offset = h.offset + diff;
                 h2.msg = h.msg;
                 h2.newTempo = h.newTempo;
                 if (memOnly == -1) lst.add(h2);
                 if (memslot != null) memslot.add(h2);
               }
               dstoff += stored.last().offset - stored.first().offset;
             }
           }
           break;
       }
       ch = in.readChar();
     }
     ch = in.readChar();
   }
   PlayTask target = th;
   synchronized (playTasks) {
     for (PlayTask test : playTasks)
       if (test.tempo == tempo) {
         target = test;
         target.seqmem.putAll(th.seqmem);
       }
   }
   if (target == th) // must start a new timer
   {
     synchronized (playTasks) {
       playTasks.add(target);
     }
     target.timer.schedule(target.newTask(), 10L);
   }
   long offset = target.playOffset + startOffset;
   for (MidimsgHolder d : lst) d.offset = offset + d.offset + 32L;
   if (target.playQueue.isEmpty()) {
     synchronized (target.playQueue) {
       target.playQueue.addAll(lst);
     }
   } else {
     synchronized (target.playQueue) {
       lst.addAll(target.playQueue);
       target.playQueue.clear();
       target.playQueue.addAll(lst);
     }
   }
 }