public static Sequence process( final Sequence inputSequence, int track, long startTick, long endTick, int noteOverlap, int minimumRest, Handler loggingHandler) throws InvalidMidiDataException { Sequence outputSequence = new Sequence(inputSequence.getDivisionType(), inputSequence.getResolution()); Track[] inputTracks = inputSequence.getTracks(); SlurBinderA.noteOverlap = noteOverlap; SlurBinderA.minimumRest = minimumRest; slurEndNotes = new HashSet<>(); for (int trackI = 0; trackI < inputTracks.length; trackI++) { Track inputTrack = inputTracks[trackI]; Track outputTrack = outputSequence.createTrack(); if (trackI == track) { handleTrack(outputTrack, inputTrack, startTick, endTick); } else { for (int eventI = 0; eventI < inputTrack.size(); eventI++) { MidiEvent midEvent = inputTrack.get(eventI); outputTrack.add(midEvent); } } } return outputSequence; }
public void go() { setUpGui(); try { Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); // make a sequencer and open sequencer.addControllerEventListener(m1, new int[] {127}); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); int r = 0; for (int i = 0; i < 300; i += 4) { r = (int) ((Math.random() * 50) + 1); track.add(makeEvent(144, 1, r, 100, i)); track.add(makeEvent(176, 1, 127, 0, i)); track.add(makeEvent(128, 1, r, 100, i + 2)); } // end loop sequencer.setSequence(seq); sequencer.start(); sequencer.setTempoInBPM(120); } catch (Exception ex) { ex.printStackTrace(); } } // close method
public void buildTrackAndStart() { int[] trackList = null; sequence.deleteTrack(track); track = sequence.createTrack(); for (int i = 0; i < 16; i++) { trackList = new int[16]; int key = instruments[i]; for (int j = 0; j < 16; j++) { JCheckBox jc = (JCheckBox) checkboxList.get(j + (16 * i)); if (jc.isSelected()) { trackList[j] = key; } else { trackList[j] = 0; } } // close inner loop makeTracks(trackList); track.add(makeEvent(176, 1, 127, 0, 16)); } // close outer track.add(makeEvent(192, 9, 1, 0, 15)); try { sequencer.setSequence(sequence); sequencer.setLoopCount(sequencer.LOOP_CONTINUOUSLY); sequencer.start(); sequencer.setTempoInBPM(120); } catch (Exception e) { e.printStackTrace(); } } // close buildTrackAndStart method
public void play(int instrument, int note) { try { Sequencer player = MidiSystem.getSequencer(); player.open(); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); MidiEvent event = null; ShortMessage first = new ShortMessage(); first.setMessage(192, 1, instrument, 0); MidiEvent changeInstrument = new MidiEvent(first, 1); track.add(changeInstrument); ShortMessage a = new ShortMessage(); a.setMessage(144, 1, note, 100); MidiEvent noteOn = new MidiEvent(a, 1); track.add(noteOn); ShortMessage b = new ShortMessage(); b.setMessage(128, 1, note, 100); MidiEvent noteOff = new MidiEvent(b, 16); track.add(noteOff); player.setSequence(seq); player.start(); } catch (Exception ex) { ex.printStackTrace(); } } // close play
public void los() { guiErstellen(); try { Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.addControllerEventListener(ml, new int[] {127}); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); int r = 0; for (int i = 0; i < 60; i += 4) { r = (int) ((Math.random() * 50) + 1); track.add(eventErzeugen(144, 1, r, 100, i)); track.add(eventErzeugen(176, 1, 127, 0, i)); track.add(eventErzeugen(128, 1, r, 100, i + 2)); } sequencer.setSequence(seq); sequencer.setTempoInBPM(120); sequencer.start(); Thread.sleep(5000); sequencer.close(); } catch (Exception ex) { ex.printStackTrace(); } }
public static void convertMidi2RealTime(Sequence seqIn) { seq = seqIn; double currentTempo = 500000; int tickOfTempoChange = 0; double msb4 = 0; double division = seq.getResolution(); int lastTick = 0; int count = 0; for (int track = 0; track < seq.getTracks().length; track++) nextMessageOf.add(0); System.out.println(); MidiEvent nextEvent; while ((nextEvent = getNextEvent()) != null) { int tick = (int) nextEvent.getTick(); if (noteIsOff(nextEvent)) { double time = (msb4 + (((currentTempo / seq.getResolution()) / 1000) * (tick - tickOfTempoChange))); System.out.println( "track=" + currentTrack + " tick=" + tick + " time=" + (int) (time + 0.5) + "ms " + " note " + ((int) nextEvent.getMessage().getMessage()[1] & 0xFF) + " off"); } else if (noteIsOn(nextEvent)) { double time = (msb4 + (((currentTempo / seq.getResolution()) / 1000) * (tick - tickOfTempoChange))); System.out.println( "track=" + currentTrack + " tick=" + tick + " time=" + (int) (time + 0.5) + "ms " + " note " + ((int) nextEvent.getMessage().getMessage()[1] & 0xFF) + " on"); } else if (changeTemp(nextEvent)) { String a = (Integer.toHexString((int) nextEvent.getMessage().getMessage()[3] & 0xFF)); String b = (Integer.toHexString((int) nextEvent.getMessage().getMessage()[4] & 0xFF)); String c = (Integer.toHexString((int) nextEvent.getMessage().getMessage()[5] & 0xFF)); if (a.length() == 1) a = ("0" + a); if (b.length() == 1) b = ("0" + b); if (c.length() == 1) c = ("0" + c); String whole = a + b + c; int newTempo = Integer.parseInt(whole, 16); double newTime = (currentTempo / seq.getResolution()) * (tick - tickOfTempoChange); msb4 += (newTime / 1000); tickOfTempoChange = tick; currentTempo = newTempo; } } }
/** * @param key is the note that this starts with. 60 is middle C. * @param tempo is measured in beats per second */ public MidiFileGenerator(int key, int tempo, int resolution) throws MidiUnavailableException, InvalidMidiDataException { this.resolution = resolution; Sequence sequence = new Sequence(Sequence.PPQ, resolution); track = sequence.createTrack(); // makeSong(key); sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.setSequence(sequence); sequencer.setTempoInBPM(tempo); }
public boolean addStrikeToSequence(int bell, long millis) { try { fSequence.getTracks()[0].add(createBellMarker(bell, millis)); fSequence.getTracks()[0].add(createBellNote(bell, millis)); fSequence.getTracks()[0].add(createBellNoteOff(bell, millis + 2000)); } catch (InvalidMidiDataException e) { System.out.println("Failed to create Midi note: " + e); return false; } return true; }
public Sequence getSequence(InputStream inputStream) throws InvalidMidiDataException, IOException { MidiFileFormat midiFileFormat = getMidiFileFormat(inputStream); Sequence sequence = new Sequence(midiFileFormat.getDivisionType(), midiFileFormat.getResolution()); DataInputStream dataInputStream = new DataInputStream(inputStream); int nNumTracks = ((TMidiFileFormat) midiFileFormat).getTrackCount(); for (int nTrack = 0; nTrack < nNumTracks; nTrack++) { Track track = sequence.createTrack(); readTrack(dataInputStream, track); } return sequence; }
/** * Send entry MIDI Sequence into Receiver using time stamps. * * @return The total length of the sequence. */ private double send(final Sequence seq, final Receiver recv) { assert seq.getDivisionType() == Sequence.PPQ; final float divtype = seq.getDivisionType(); final Track[] tracks = seq.getTracks(); tune(recv); final int[] trackspos = new int[tracks.length]; int mpq = 500000; final 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++) { final int trackpos = trackspos[i]; final Track track = tracks[i]; if (trackpos < track.size()) { final MidiEvent event = track.get(trackpos); if (selevent == null || event.getTick() < selevent.getTick()) { selevent = event; seltrack = i; } } } if (seltrack == -1) { break; } trackspos[seltrack]++; final long tick = selevent.getTick(); if (divtype == Sequence.PPQ) { curtime += (tick - lasttick) * mpq / seqres; } else { curtime = (long) (tick * 1000000.0 * divtype / seqres); } lasttick = tick; final MidiMessage msg = selevent.getMessage(); if (msg instanceof MetaMessage) { if (divtype == Sequence.PPQ && ((MetaMessage) msg).getType() == 0x51) { final 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; }
public void go() { try { sq.open(); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); track.add(addNote(144, 9, 56, 100, 1)); track.add(addNote(128, 9, 56, 100, 4)); sq.setSequence(seq); sq.setTempoInBPM(tempo); sq.setLoopCount(Sequencer.LOOP_CONTINUOUSLY); sq.start(); } catch (Exception ex) { ex.printStackTrace(); } }
public void run() { try { /*wait(n); synchronized(n) { n++; notifyAll(); }*/ seq.setSequence(mySeq); long length = mySeq.getMicrosecondLength(); m_playing.add(this); seq.start(); Thread.sleep(length / 1000); seq.close(); synth.close(); m_playing.remove(this); /*wait(n); synchronized(n) { n--; notifyAll(); }*/ } catch (InvalidMidiDataException e) { Debug.showException(e, "MidiPlayer::run InvalidMidiDataException"); } catch (InterruptedException e) { seq.close(); synth.close(); // Debug.showMessage("MidiCSD::PlayMidiFile: Interrupted" + e.getMessage()); } }
public Sequencer(int instrument, int tempo) { // Set up initial settings for the sequencer this.instrument = instrument; this.tempo = tempo; Synthesizer synth; ticks = 0; velocity = 64; // Mid volume try { // Setup values to create sequencer sequence = new Sequence(Sequence.PPQ, 16); sequencer = MidiSystem.getSequencer(); sequencer.open(); synth = MidiSystem.getSynthesizer(); synth.open(); sequencer.getTransmitter().setReceiver(synth.getReceiver()); sequencer.setTempoInBPM(tempo); track = sequence.createTrack(); } catch (InvalidMidiDataException e) { e.printStackTrace(); } catch (MidiUnavailableException e) { e.printStackTrace(); } }
/** * Given a microsecond time, convert to tick. returns tempo at the given time in * cache.getCurrTempoMPQ */ public static long microsecond2tick(Sequence seq, long micros, TempoCache cache) { if (seq.getDivisionType() != Sequence.PPQ) { double dTick = (((double) micros) * ((double) seq.getDivisionType()) * ((double) seq.getResolution())) / ((double) 1000000); long tick = (long) dTick; if (cache != null) { cache.currTempo = (int) cache.getTempoMPQAt(tick); } return tick; } if (cache == null) { cache = new TempoCache(seq); } long[] ticks = cache.ticks; int[] tempos = cache.tempos; // in MPQ int cacheCount = tempos.length; int resolution = seq.getResolution(); long us = 0; long tick = 0; int newReadPos = 0; int i = 1; // walk through all tempo changes and add time for the respective blocks // to find the right tick if (micros > 0 && cacheCount > 0) { // this loop requires that the first tempo Event is at time 0 while (i < cacheCount) { long nextTime = us + ticks2microsec(ticks[i] - ticks[i - 1], tempos[i - 1], resolution); if (nextTime > micros) { break; } us = nextTime; i++; } tick = ticks[i - 1] + microsec2ticks(micros - us, tempos[i - 1], resolution); if (Printer.debug) Printer.debug("microsecond2tick(" + (micros / 1000) + ") = " + tick + " ticks."); // if (Printer.debug) Printer.debug(" -> convert back = " + (tick2microsecond(seq, tick, // null) / 1000)+" microseconds"); } cache.currTempo = tempos[i - 1]; return tick; }
/* Write a sequence to an output stream in standard midi format. * @see javax.sound.midi.spi.MidiFileWriter#write(javax.sound.midi.Sequence, int, java.io.OutputStream) */ public int write(Sequence in, int fileType, OutputStream out) throws IOException { MidiDataOutputStream dos = new MidiDataOutputStream(out); Track[] tracks = in.getTracks(); dos.writeInt(0x4d546864); // MThd dos.writeInt(6); dos.writeShort(fileType); dos.writeShort(tracks.length); float divisionType = in.getDivisionType(); int resolution = in.getResolution(); // FIXME: division computation is incomplete. int division = 0; if (divisionType == Sequence.PPQ) division = resolution & 0x7fff; dos.writeShort(division); int length = 14; for (Track track : tracks) length += writeTrack(track, dos); return length; }
public boolean addRowStartMarkToSequence(int rowN, long millis) { try { fSequence.getTracks()[0].add(createRowStartMarker(rowN, millis)); } catch (InvalidMidiDataException e) { System.out.println("Failed to create Midi marker: " + e); return false; } return true; }
/** * Adds this Note at the specified time on the specified Track and channel in the specified * Sequence, then returns the time that a sequential Note should be added. * * @param seq the Sequence to which to add this Note * @param track the Track in the Sequence to which to add this Note * @param time the time at which to start this Note * @param ch the channel on which to put this Note * @param transposition amount by which to transpose this note in semitones * @param sendBankSelect * @return * @throws javax.sound.midi.InvalidMidiDataException */ public long render( Sequence seq, Track track, long time, int ch, int transposition, boolean sendBankSelect) throws InvalidMidiDataException { if (sendBankSelect) {} int dur = getRhythmValue(); long offTime = time + dur * seq.getResolution() / BEAT; render(seq, track, time, offTime, ch, transposition); return offTime; }
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; }
/** * Given a tick, convert to microsecond * * @param cache tempo info and current tempo */ public static long tick2microsecond(Sequence seq, long tick, TempoCache cache) { if (seq.getDivisionType() != Sequence.PPQ) { double seconds = ((double) tick / (double) (seq.getDivisionType() * seq.getResolution())); return (long) (1000000 * seconds); } if (cache == null) { cache = new TempoCache(seq); } int resolution = seq.getResolution(); long[] ticks = cache.ticks; int[] tempos = cache.tempos; // in MPQ int cacheCount = tempos.length; // optimization to not always go through entire list of tempo events int snapshotIndex = cache.snapshotIndex; int snapshotMicro = cache.snapshotMicro; // walk through all tempo changes and add time for the respective blocks long us = 0; // microsecond if (snapshotIndex <= 0 || snapshotIndex >= cacheCount || ticks[snapshotIndex] > tick) { snapshotMicro = 0; snapshotIndex = 0; } if (cacheCount > 0) { // this implementation needs a tempo event at tick 0! int i = snapshotIndex + 1; while (i < cacheCount && ticks[i] <= tick) { snapshotMicro += ticks2microsec(ticks[i] - ticks[i - 1], tempos[i - 1], resolution); snapshotIndex = i; i++; } us = snapshotMicro + ticks2microsec(tick - ticks[snapshotIndex], tempos[snapshotIndex], resolution); } cache.snapshotIndex = snapshotIndex; cache.snapshotMicro = snapshotMicro; return us; }
public void setUpMidi() { try { sequencer = MidiSystem.getSequencer(); sequencer.open(); sequence = new Sequence(Sequence.PPQ, 4); track = sequence.createTrack(); sequencer.setTempoInBPM(120); } catch (Exception e) { e.printStackTrace(); } } // close method
public static MidiEvent getNextEvent() { ArrayList<MidiEvent> nextEvent = new ArrayList<MidiEvent>(); ArrayList<Integer> trackOfNextEvent = new ArrayList<Integer>(); for (int track = 0; track < seq.getTracks().length; track++) { if (seq.getTracks()[track].size() - 1 > (nextMessageOf.get(track))) { nextEvent.add(seq.getTracks()[track].get(nextMessageOf.get(track))); trackOfNextEvent.add(track); } } if (nextEvent.size() == 0) return null; int closestMessage = 0; int smallestTick = (int) nextEvent.get(0).getTick(); for (int trialMessage = 1; trialMessage < nextEvent.size(); trialMessage++) { if ((int) nextEvent.get(trialMessage).getTick() < smallestTick) { smallestTick = (int) nextEvent.get(trialMessage).getTick(); closestMessage = trialMessage; } } currentTrack = trackOfNextEvent.get(closestMessage); nextMessageOf.set(currentTrack, (nextMessageOf.get(currentTrack) + 1)); return nextEvent.get(closestMessage); }
public void actionPerformed(ActionEvent ev) { try { // make (and open) a sequencer, make a sequence and track Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.addControllerEventListener(myPanel, new int[] {127}); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); // now make two midi events (containing a midi message) for (int i = 0; i < 100; i += 4) { int rNum = (int) ((Math.random() * 50) + 1); if (rNum < 38) { // so now only do it if num <38 (75% of the time) track.add(makeEvent(144, 1, rNum, 100, i)); track.add(makeEvent(176, 1, 127, 0, i)); track.add(makeEvent(128, 1, rNum, 100, i + 2)); } } // end loop // add the events to the track // add the sequence to the sequencer, set timing, and start sequencer.setSequence(seq); sequencer.start(); sequencer.setTempoInBPM(220); } catch (Exception ex) { ex.printStackTrace(); } } // close actionperformed
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())) }
/** * Import a song into the MidiExporter to play or export. * * @param song The Song to convert to MIDI */ public void importSong(Song song) { // Fetch important data from the song. // Meaning, metadata and the song itself. Beat[] beats = song.getBeatArray(); this.song = song; // Create a track for each voice. int numVoices = song.getNumVoices(); for (int voiceCount = 0; voiceCount < numVoices; voiceCount++) { sequence.createTrack(); } // Iterate through each beat, adding each note to the corresponding // track. Track[] tracks = sequence.getTracks(); for (int beat = 0; beat < beats.length; beat++) { Note[] firstHalf = beats[beat].getNotesFirstHalf(); Note[] secondHalf = beats[beat].getNotesSecondHalf(); // Iterate through each note in the beat, adding it to the // corresponding track. for (int note = 0; note < firstHalf.length; note++) { if (firstHalf[note] == secondHalf[note]) { createNote(firstHalf[note], 2 * beat, 2, tracks[note]); } else { createNote(firstHalf[note], 2 * beat, 1, tracks[note]); createNote(secondHalf[note], 2 * beat + 1, 1, tracks[note]); } // if/else } // for } // for try { setUpSequencer(); } catch (MidiUnavailableException ex) { System.out.println("Unable to set up sequencer"); // do nothing } }
public void los() { guiErstellen(); try { // einen Sequencer erzeugen (und öffnen), // eine Sequence und einen Track erzeugen Sequencer sequencer = MidiSystem.getSequencer(); sequencer.open(); sequencer.addControllerEventListener(ml, new int[] {127}); Sequence seq = new Sequence(Sequence.PPQ, 4); Track track = seq.createTrack(); // jetzt werden MidiEvents (die eine // MidiMessage enthalten) erzeugt int r = 0; for (int i = 0; i < 60; i += 4) { r = (int) ((Math.random() * 50) + 1); track.add(eventErzeugen(144, 1, r, 100, i)); track.add(eventErzeugen(176, 1, 127, 0, i)); track.add(eventErzeugen(128, 1, r, 100, i + 2)); } // Ende der for-Schleife // Hinzufügen der Events zum Track und der Sequence // zum Sequencer, Setzen der Zeiten und Starten sequencer.setSequence(seq); sequencer.start(); sequencer.setTempoInBPM(120); } catch (Exception ex) { ex.printStackTrace(); } } // Methode los schließen
public boolean createSequence() { try { // Create a sequence with microsecond timing resolution // (Although this doesn't seem to have any effect on tick resolution - ticks in MidiEvents // always microsecond fSequence = new Sequence(Sequence.SMPTE_25, 40000); // Create track and add program change to bell sound Track track = fSequence.createTrack(); // track.add(createBankChange(1, 0)); track.add(createProgramChange(14, 0)); } catch (InvalidMidiDataException e) { System.out.println("Error creating sequence: " + e); return false; } return true; }
public synchronized void refresh(Sequence seq) { ArrayList<MidiEvent> list = new ArrayList<>(); Track[] tracks = seq.getTracks(); if (tracks.length > 0) { // tempo events only occur in track 0 Track track = tracks[0]; int c = track.size(); for (int i = 0; i < c; i++) { MidiEvent ev = track.get(i); MidiMessage msg = ev.getMessage(); if (isMetaTempo(msg)) { // found a tempo event. Add it to the list list.add(ev); } } } int size = list.size() + 1; firstTempoIsFake = true; if ((size > 1) && (list.get(0).getTick() == 0)) { // do not need to add an initial tempo event at the beginning size--; firstTempoIsFake = false; } ticks = new long[size]; tempos = new int[size]; int e = 0; if (firstTempoIsFake) { // add tempo 120 at beginning ticks[0] = 0; tempos[0] = DEFAULT_TEMPO_MPQ; e++; } for (int i = 0; i < list.size(); i++, e++) { MidiEvent evt = list.get(i); ticks[e] = evt.getTick(); tempos[e] = getTempoMPQ(evt.getMessage()); } snapshotIndex = 0; snapshotMicro = 0; }
public boolean writeSequence(NoteList noteList) { this.noteList = noteList; toneMap = toneMapFrame.getToneMap(); timeSet = toneMap.getTimeSet(); pitchSet = toneMap.getPitchSet(); timeRange = timeSet.getRange(); pitchRange = pitchSet.getRange(); if (!buildNoteSequence()) return false; try { sequence = new Sequence(Sequence.PPQ, 10); } catch (Exception ex) { ex.printStackTrace(); return false; } track = sequence.createTrack(); startTime = System.currentTimeMillis(); // add a program change right at the beginning of // the track for the current instrument createEvent(PROGRAM, cc.program + 1, 1); for (int i = 0; i < noteSequence.size(); i++) { noteSequenceElement = noteSequence.get(i); if (noteSequenceElement.state == ON) if (!createEvent(NOTEON, noteSequenceElement.note, noteSequenceElement.tick)) return false; if (noteSequenceElement.state == OFF) if (!createEvent(NOTEOFF, noteSequenceElement.note, noteSequenceElement.tick)) return false; } return true; }
public void _testGPWithPlayer(MidiSongDefinition sd, int usq) throws Exception { MidiSongDefinition testFile = SongArchive.testFileSongDefinition(); try { GPInputStream gpis = new GPInputStream(sd.getGpFileName()); GPSong gpsong = (GPSong) gpis.readObject(); gpis.close(); int tempoGPSong = gpsong.getTempo(); // OLD assertEquals((int)(60*1000*1000/usq),tempoGPSong); assertEquals((60 * 1000 * 1000 / usq), tempoGPSong); Song song = GPAdaptor.makeSong(gpsong); Tempo tempoSong = song.getTempo(); assertEquals(usq, (int) tempoSong.getUSQ()); MasterPlayer player = new MasterPlayer(); player.setSoundPlayer(new MidiFiler(testFile.getMidiFileName())); Performance performance = player.arrange(song, null); Tempo tempoPerformance = performance.getTempo(); assertEquals(usq, (int) tempoPerformance.getUSQ()); // a performance is really a sequence. So make sure there // is a tempo event (meta 0x51) on track 0. // make sure as well there is exactly ONE tempo event at timestamp 0 Sequence sequence = (Sequence) performance; Track[] midiTracks = sequence.getTracks(); Track tempoMap = midiTracks[0]; Tempo tempoInMIDI = new Tempo(); for (int i = 0; i < tempoMap.size(); i++) { MidiEvent me = tempoMap.get(i); long tick = me.getTick(); if (tick > 0) break; MidiMessage mm = me.getMessage(); if (mm.getStatus() == MetaMessage.META) { MetaMessage meta = (MetaMessage) mm; if (meta.getType() == 0x51) { byte[] data = meta.getData(); tempoInMIDI.setUSQ( ((data[0] & 0x00FF) << 16) | ((data[1] & 0x00FF) << 8) | ((data[2] & 0x00FF))); break; } } } assertEquals(usq, (int) tempoInMIDI.getUSQ()); MidiOutputStream mos = new MidiOutputStream(new FileOutputStream(testFile.getMidiFileName())); mos.write(performance); mos.close(); compareMIDIFiles( sd.getMidiFileName(), testFile.getMidiFileName(), sd.getChannels(), sd.getEventRemap()); } catch (FileNotFoundException e) { fail("file not found exception"); } catch (GPFormatException e) { fail("gp format exception"); } catch (IOException e) { fail("ioexception"); } catch (CodecFormatException e) { fail("codec format exception"); } catch (InvalidMidiDataException e) { fail("invalid midi data exception"); } }
/** * 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; }