Пример #1
0
 /**
  * Play one bell sound immediately, bypassing Sequencer
  *
  * @param bell
  */
 public void play(int bell) {
   MidiEvent evt;
   try {
     evt = createBellNote(bell, 0);
     fMidiOut.send(evt.getMessage(), -1);
   } catch (InvalidMidiDataException e) {
     System.out.println("Failed to play note; " + e);
   }
 }
Пример #2
0
  private void loadNotes() {
    int program = 0;
    HashMap<Integer, Float> lastTimeNote = new HashMap<Integer, Float>();
    HashMap<Float, Integer> secondsNotes = new HashMap<Float, Integer>();
    this.notas = new ArrayList<MIDINote>();
    for (Track track : sequencia.getTracks()) {
      for (int c = 0; c < track.size(); ++c) {
        MidiEvent event = track.get(c);
        MidiMessage msg = event.getMessage();
        if (msg instanceof ShortMessage) {
          ShortMessage shortmsg = (ShortMessage) msg;
          if (shortmsg.getCommand() == ShortMessage.PROGRAM_CHANGE) {
            program = shortmsg.getData1();
          } else {
            // }else if(program>=25 && program <= 40){
            // else if(program== 30){
            if (shortmsg.getCommand() == ShortMessage.NOTE_ON) {
              MIDINote midiNote = new MIDINote(event, sequencia, tempoProcessor, program);
              // tocador.start();
              int noteChord = midiNote.getChord();
              float noteSecond = midiNote.getSecond();
              if (!lastTimeNote.containsKey(noteChord)) {
                lastTimeNote.put(noteChord, 0.0f);
              }
              if (noteSecond - lastTimeNote.get(noteChord).floatValue() <= this.interval) {
                continue;
              }
              lastTimeNote.put(noteChord, noteSecond);
              // System.out.println("Play chord "+noteChord+" in "+noteSecond+" seconds");
              notas.add(midiNote);
              if (!secondsNotes.containsKey(noteSecond)) {
                secondsNotes.put(noteSecond, 1);
              }
              secondsNotes.put(noteSecond, secondsNotes.get(noteSecond).intValue() + 1);
            }
          }
        }
      }
    }

    // System.out.println("tamanho da pista "+notas.size()+" e track "+maxNote);
    for (float second : secondsNotes.keySet()) {
      int repeated = secondsNotes.get(second).intValue();
      if (repeated > maxNote) {
        this.maxNote = repeated;
      }
    }
    this.notesLength = secondsNotes.size();
    // GameEngine.getInstance().setFramesPerSecond((int)(((tocador.getMicrosecondLength()/1000000)/(notas.size()*1.0))*4000));
    // System.out.println("(int)(("+sequencia.getMicrosecondLength()+"/1000000)/"+notas.size()+"="+(int)((sequencia.getMicrosecondLength()/1000000)/notas.size()))
  }
Пример #3
0
 @Override
 public void run() {
   while (go) {
     try {
       MidiEvent event = (MidiEvent) waitNextEvent();
       try {
         Log.i(MidiConstants.TAG, "Fire event " + event.data[0] + " at " + event.getTimestamp());
         mDispatcher.send(event.data, 0, event.count, event.getTimestamp());
       } catch (IOException e) {
         e.printStackTrace();
       }
       // Put event back in the pool for future use.
       addEventToPool(event);
     } catch (InterruptedException e) {
       // OK, this is how we stop the thread.
     }
   }
 }
Пример #4
0
  void callPlug(MidiInput _input, final MidiMessage msg) {
    try {
      if ((msg.getStatus() & 0xF0) != getStatus() && getStatus() != -1) return;
      if (msg instanceof ShortMessage) {
        ShortMessage smsg = (ShortMessage) msg;
        if (smsg.getChannel() != channel && channel != -1) return;
      }
      MidiEvent event = null;
      if (msg instanceof MidiEvent) {
        event = (MidiEvent) msg;
      } else {
        event = MidiEvent.create(msg);
      }

      if (event != null) {
        event.setInput(_input);
        if (paramClass.isInstance(event)) method.invoke(getObject(), new Object[] {event});
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new RuntimeException("Error on calling plug: " + methodName);
    }
  }
  public static double send(Sequence seq, Receiver recv) {
    float divtype = seq.getDivisionType();
    assert (seq.getDivisionType() == Sequence.PPQ);
    Track[] tracks = seq.getTracks();
    int[] trackspos = new int[tracks.length];
    int mpq = 60000000 / 100;
    int seqres = seq.getResolution();
    long lasttick = 0;
    long curtime = 0;
    while (true) {
      MidiEvent selevent = null;
      int seltrack = -1;
      for (int i = 0; i < tracks.length; i++) {
        int trackpos = trackspos[i];
        Track track = tracks[i];
        if (trackpos < track.size()) {
          MidiEvent event = track.get(trackpos);
          if (selevent == null || event.getTick() < selevent.getTick()) {
            selevent = event;
            seltrack = i;
          }
        }
      }
      if (seltrack == -1) break;
      trackspos[seltrack]++;
      long tick = selevent.getTick();
      if (divtype == Sequence.PPQ) curtime += ((tick - lasttick) * mpq) / seqres;
      else curtime = (long) ((tick * 1000000.0 * divtype) / seqres);
      lasttick = tick;
      MidiMessage msg = selevent.getMessage();
      if (msg instanceof MetaMessage) {
        if (divtype == Sequence.PPQ)
          if (((MetaMessage) msg).getType() == 0x51) {
            byte[] data = ((MetaMessage) msg).getData();
            mpq = ((data[0] & 0xff) << 16) | ((data[1] & 0xff) << 8) | (data[2] & 0xff);
          }
      } else {
        if (recv != null) recv.send(msg, curtime);
      }
    }

    return curtime / 1000000.0;
  }
Пример #6
0
  /**
   * Obtains the duration of this sequence, expressed in microseconds.
   *
   * @return this sequence's duration in microseconds.
   */
  public long getMicrosecondLength() {

    long ticks = getTickLength();

    double seconds;

    // now convert ticks to time

    if (divisionType != PPQ) {

      seconds = ((double) getTickLength() / (double) (divisionType * resolution));

      // $$fb 2002-10-30: fix for 4702328: Wrong time in sequence for SMPTE based types
      return (long) (1000000 * seconds);
    } else {

      Track tempos = new Track();
      Track tmpTrack = null;
      MidiEvent tmpEvent = null;
      MidiMessage tmpMessage = null;
      MetaMessage tmpMeta = null;
      byte[] data;

      // find all tempo events
      synchronized (tracks) {
        for (int i = 0; i < tracks.size(); i++) {
          tmpTrack = (Track) tracks.elementAt(i);
          for (int j = 0; j < tmpTrack.size(); j++) {
            tmpEvent = (MidiEvent) tmpTrack.get(j);
            tmpMessage = tmpEvent.getMessage();
            if (tmpMessage instanceof MetaMessage) {

              if (((MetaMessage) tmpMessage).getType() == 0x51) {
                tempos.add(tmpEvent);
              }
            }
          }
        }
      }
      // now add up chunks of time
      int tempo = (60 * 1000000) / 120; // default 120 bpm, converted to uSec/beat
      long microseconds = 0;
      long runningTick = 0;
      long tmpTick = 0;

      // loop through the tempo changes, but don't
      // include the last event, which is track end
      for (int i = 0; i < (tempos.size() - 1); i++) {

        tmpEvent = (MidiEvent) tempos.get(i);
        tmpTick = tmpEvent.getTick();

        if (tmpTick >= runningTick) {
          microseconds += ((tmpTick - runningTick) * tempo / resolution);
          runningTick = tmpTick;
          data = ((MetaMessage) (tmpEvent.getMessage())).getMessage();

          // data[0] => status, 0xFF
          // data[1] => type,   0x51
          // data[2] => length, 0x03
          // data[3] -> data[5] => tempo data
          tempo = (int) 0xff & data[5];
          tempo = tempo | ((0xff & data[4]) << 8);
          tempo = tempo | ((0xff & data[3]) << 16);
        }
      }
      tmpTick = getTickLength();
      if (tmpTick > runningTick) {
        microseconds += ((tmpTick - runningTick) * tempo / resolution);
      }

      // return in microseconds
      return (microseconds);
    }
  }
Пример #7
0
  private InputStream writeTrack(Track track, int type)
      throws IOException, InvalidMidiDataException {
    int bytesWritten = 0;
    int lastBytesWritten = 0;
    int size = track.size();
    PipedOutputStream thpos = new PipedOutputStream();
    DataOutputStream thdos = new DataOutputStream(thpos);
    PipedInputStream thpis = new PipedInputStream(thpos);

    ByteArrayOutputStream tdbos = new ByteArrayOutputStream();
    tddos = new DataOutputStream(tdbos);
    ByteArrayInputStream tdbis = null;

    SequenceInputStream fStream = null;

    long currentTick = 0;
    long deltaTick = 0;
    long eventTick = 0;
    int runningStatus = -1;

    // -----------------------------
    // Write each event in the track
    // -----------------------------
    for (int i = 0; i < size; i++) {
      MidiEvent event = track.get(i);

      int status;
      int eventtype;
      int metatype;
      int data1, data2;
      int length;
      byte data[] = null;
      ShortMessage shortMessage = null;
      MetaMessage metaMessage = null;
      SysexMessage sysexMessage = null;

      // get the tick
      // $$jb: this gets easier if we change all system-wide time to delta ticks
      eventTick = event.getTick();
      deltaTick = event.getTick() - currentTick;
      currentTick = event.getTick();

      // get the status byte
      status = event.getMessage().getStatus();
      eventtype = getType(status);

      switch (eventtype) {
        case ONE_BYTE:
          shortMessage = (ShortMessage) event.getMessage();
          data1 = shortMessage.getData1();
          bytesWritten += writeVarInt(deltaTick);

          if (status != runningStatus) {
            runningStatus = status;
            tddos.writeByte(status);
            bytesWritten += 1;
          }
          tddos.writeByte(data1);
          bytesWritten += 1;
          break;

        case TWO_BYTE:
          shortMessage = (ShortMessage) event.getMessage();
          data1 = shortMessage.getData1();
          data2 = shortMessage.getData2();

          bytesWritten += writeVarInt(deltaTick);
          if (status != runningStatus) {
            runningStatus = status;
            tddos.writeByte(status);
            bytesWritten += 1;
          }
          tddos.writeByte(data1);
          bytesWritten += 1;
          tddos.writeByte(data2);
          bytesWritten += 1;
          break;

        case SYSEX:
          sysexMessage = (SysexMessage) event.getMessage();
          length = sysexMessage.getLength();
          data = sysexMessage.getMessage();
          bytesWritten += writeVarInt(deltaTick);

          // $$jb: 04.08.99: always write status for sysex
          runningStatus = status;
          tddos.writeByte(data[0]);
          bytesWritten += 1;

          // $$jb: 10.18.99: we don't maintain length in
          // the message data for SysEx (it is not transmitted
          // over the line), so write the calculated length
          // minus the status byte
          bytesWritten += writeVarInt((data.length - 1));

          // $$jb: 10.18.99: now write the rest of the
          // message
          tddos.write(data, 1, (data.length - 1));
          bytesWritten += (data.length - 1);
          break;

        case META:
          metaMessage = (MetaMessage) event.getMessage();
          length = metaMessage.getLength();
          data = metaMessage.getMessage();
          bytesWritten += writeVarInt(deltaTick);

          // $$jb: 10.18.99: getMessage() returns the
          // entire valid midi message for a file,
          // including the status byte and the var-length-int
          // length value, so we can just write the data
          // here.  note that we must _always_ write the
          // status byte, regardless of runningStatus.
          runningStatus = status;
          tddos.write(data, 0, data.length);
          bytesWritten += data.length;
          break;

        case IGNORE:
          // ignore this event
          break;

        case ERROR:
          // ignore this event
          break;

        default:
          throw new InvalidMidiDataException("internal file writer error");
      }
    }
    // ---------------------------------
    // End write each event in the track
    // ---------------------------------

    // Build Track header now that we know length
    thdos.writeInt(MTrk_MAGIC);
    thdos.writeInt(bytesWritten);
    bytesWritten += 8;

    // Now sequence them
    tdbis = new ByteArrayInputStream(tdbos.toByteArray());
    fStream = new SequenceInputStream(thpis, tdbis);
    thdos.close();
    tddos.close();

    return fStream;
  }
Пример #8
0
  /**
   * Adds a new event to the track. However, if the event is already contained in the track, it is
   * not added again. The list of events is kept in time order, meaning that this event inserted at
   * the appropriate place in the list, not necessarily at the end.
   *
   * @param event the event to add
   * @return <code>true</code> if the event did not already exist in the track and was added,
   *     otherwise <code>false</code>
   */
  public boolean add(MidiEvent event) {
    if (event == null) {
      return false;
    }
    synchronized (eventsList) {
      if (!set.contains(event)) {
        int eventsCount = eventsList.size();

        // get the last event
        MidiEvent lastEvent = null;
        if (eventsCount > 0) {
          lastEvent = (MidiEvent) eventsList.get(eventsCount - 1);
        }
        // sanity check that we have a correct end-of-track
        if (lastEvent != eotEvent) {
          // if there is no eot event, add our immutable instance again
          if (lastEvent != null) {
            // set eotEvent's tick to the last tick of the track
            eotEvent.setTick(lastEvent.getTick());
          } else {
            // if the events list is empty, just set the tick to 0
            eotEvent.setTick(0);
          }
          // we needn't check for a duplicate of eotEvent in "eventsList",
          // since then it would appear in the set.
          eventsList.add(eotEvent);
          set.add(eotEvent);
          eventsCount = eventsList.size();
        }

        // first see if we are trying to add
        // and endoftrack event.
        if (MidiUtils.isMetaEndOfTrack(event.getMessage())) {
          // since end of track event is useful
          // for delays at the end of a track, we want to keep
          // the tick value requested here if it is greater
          // than the one on the eot we are maintaining.
          // Otherwise, we only want a single eot event, so ignore.
          if (event.getTick() > eotEvent.getTick()) {
            eotEvent.setTick(event.getTick());
          }
          return true;
        }

        // prevent duplicates
        set.add(event);

        // insert event such that events is sorted in increasing
        // tick order
        int i = eventsCount;
        for (; i > 0; i--) {
          if (event.getTick() >= ((MidiEvent) eventsList.get(i - 1)).getTick()) {
            break;
          }
        }
        if (i == eventsCount) {
          // we're adding an event after the
          // tick value of our eot, so push the eot out.
          // Always add at the end for better performance:
          // this saves all the checks and arraycopy when inserting

          // overwrite eot with new event
          eventsList.set(eventsCount - 1, event);
          // set new time of eot, if necessary
          if (eotEvent.getTick() < event.getTick()) {
            eotEvent.setTick(event.getTick());
          }
          // add eot again at the end
          eventsList.add(eotEvent);
        } else {
          eventsList.add(i, event);
        }
        return true;
      }
    }

    return false;
  }
Пример #9
0
 public synchronized void addEvent(MidiEvent event) {
   this.midiEventPlayer.addEvent(event);
   this.midiTickPlayer.notifyTick(event.getTick());
 }