Class Phrases

java.lang.Object
org.jjazz.phrase.api.Phrases

public class Phrases extends Object
Helper methods using Phrases.
  • Constructor Details

    • Phrases

      public Phrases()
  • Method Details

    • addMidiEvents

      public static void addMidiEvents(Phrase p, List<MidiEvent> midiEvents, float posInBeatsOffset, boolean ignoreChannel)
      Add NoteEvents from a list of NOTE_ON/OFF Midi events at MidiConst.PPQ_RESOLUTION.

      NOTE_ON events without a corresponding NOTE_OFF event are ignored. Notes with 0-tick length are ignored.

      Parameters:
      p -
      midiEvents - MidiEvents which are not ShortMessage.Note_ON/OFF are ignored. Must be ordered by tick position, resolution must be MidiConst.PPQ_RESOLUTION.
      posInBeatsOffset - The position in natural beats of the first tick of the track.
      ignoreChannel - If true, add also NoteEvents for MidiEvents which do not match this phrase channel.
      See Also:
    • computeMedianVelocity

      public static int computeMedianVelocity(List<NoteEvent> notes, int defaultValue)
      Calculate the median velocity from a list of note events.

      Parameters:
      notes -
      defaultValue - Return value if notes is empty
      Returns:
    • getPitchRange

      public static IntRange getPitchRange(Phrase p)
      Get the pitch range used by p's notes.
      Parameters:
      p -
      Returns:
      IntRange.EMPTY_RANGE if p is empty
    • getHighestPitchNote

      public static NoteEvent getHighestPitchNote(Phrase p)
      Parameters:
      p -
      Returns:
      Null if phrase is empty.
    • getLowestPitchNote

      public static NoteEvent getLowestPitchNote(Phrase p)
      Parameters:
      p -
      Returns:
      Null if phrase is empty.
    • getHighestVelocityNote

      public static NoteEvent getHighestVelocityNote(Phrase p)
      Parameters:
      p -
      Returns:
      Null if phrase is empty.
    • applyGroove

      public static boolean applyGroove(SizedPhrase spSrc, SizedPhrase spDest, float nearBeatWindow)
      Update spDest notes so that they match the position/duration/velocity of spSrc notes.

      This is typically used to "unquantize" spDest using a spSrc phrase which corresponds to a real-time playing.

      Parameters:
      spSrc -
      spDest - Start bar might be different than spSrc, but nb of bars must be the same
      nearBeatWindow - Notes start position must not differ more thatn nearBeatWindow
      Returns:
      True if spDest was changed
      Throws:
      IllegalArgumentException - If nb of bars/notes/time signature is different, or if notes do not start approximately at the same position.
    • isSameNotePositions

      public static boolean isSameNotePositions(SizedPhrase sp1, SizedPhrase sp2, boolean sameNoteDurations, float nearBeatWindow)
      Check if both phrases have the same number of notes with approximatly the same note start positions, and optionnaly the same note durations.
      Parameters:
      sp1 -
      sp2 - Start beat range might be different from sp1, but size in bars and time signature must be equal.
      sameNoteDurations - If true also check if note durations are approximatively the same.
      nearBeatWindow -
      Returns:
    • toMidiEvents

      public static List<MidiEvent> toMidiEvents(Phrase p)
      Get the phrase notes as MidiEvents.

      Tick resolution used is MidiConst.PPQ_RESOLUTION.

      Parameters:
      p -
      Returns:
      Each note is converted into 1 MidiEvent for note ON, 1 for the note OFF
    • fillTrack

      public static void fillTrack(Phrase p, Track track)
      Create MidiEvents for each phrase note then add them to the specified track.

      Tick resolution used is MidiConst.PPQ_RESOLUTION.

      Parameters:
      p -
      track -
    • getChord

      public static Chord getChord(Phrase p)
      Get a chord made of all unique pitch NoteEvents present in the phrase.
      Parameters:
      p -
      Returns:
    • silenceAfter

      public static void silenceAfter(Phrase p, float posInBeats)
      Make sure there is no note ringing in the phrase after the specified position.

      Notes starting after posInBeats are removed. If a note starts before posInBeats but is still ON beyond posInBeats, note duration is shortened to have Note OFF at posInBeats.

      Parameters:
      p -
      posInBeats -
    • getSlice

      public static Phrase getSlice(Phrase p, FloatRange range, boolean keepLeft, int cutRight, float beatWindow)
      Get a new phrase with cloned NoteEvents but keeping only the notes in the specified beat range, taking into account possible live-played/non-quantized notes via the beatWindow parameter.

      First, if beatWindow > 0 then notes starting in the range [range.from-beatWindow; range.from[ are changed in the returned phrase so they start at range.from, and notes starting in the range [range.to-beatWindow; range.to[ are removed.

      Then, if a note is starting before startPos and ending after range.from:
      - if keepLeft is false, the note is removed
      - if keepLeft is true, the note is replaced by a shorter identical one starting at range.from

      If a note is starting before range.to and ending after range.to:
      - if cutRight == 0 the note is not removed.
      - if cutRight == 1, the note is replaced by a shorter identical that ends at range.to.
      - if cutRight == 2, the note is removed

      Parameters:
      p -
      range -
      keepLeft -
      cutRight -
      beatWindow - A tolerance window if this phrase contains live-played/non-quantized notes. Typical value is 0.1f.
      Returns:
    • silence

      public static void silence(Phrase p, FloatRange range, boolean cutLeft, boolean keepRight, float beatWindow)
      Remove all phrase notes whose start position is in the specified beat range, taking into account possible live-played/non-quantized notes via the beatWindow parameter.

      If a note is starting before range.from and ending after range.from:
      - if cutLeft is false, the note is not removed.
      - if cutLeft is true, the note is replaced by a shorter identical one that ends at range.from, except if the note starts in the range [range.from-beatWindow;range.from[, then it's removed.

      If a note is starting before range.to and ending after range.to:
      - if keepRight is false, the note is removed, except if the note starts in the range [range.to-beatWindow;range.to[, then it's replaced by a shorter identical one starting at range.to
      - if keepRight is true, the note is replaced by a shorter identical one starting at range.to

      Parameters:
      p -
      range -
      cutLeft -
      keepRight -
      beatWindow - A tolerance window if this phrase contains live-played/non-quantized notes. Typical value is 0.1f.
    • getCrossingNotes

      public static List<NoteEvent> getCrossingNotes(Phrase p, float posInBeats, boolean strict)
      Get the phrase notes still ringing at specified position.

      Parameters:
      p -
      posInBeats -
      strict - If true, notes starting or ending at posInBeats are excluded.
      Returns:
      The list of notes whose startPos is before (or equals) posInBeats and range.to eafter (or equals) posInBeats
    • getNotesByPitch

      public static com.google.common.collect.ListMultimap<Integer,NoteEvent> getNotesByPitch(Phrase p, Predicate<NoteEvent> tester)
      Get phrase notes matching the specified tester and return them per pitch.
      Parameters:
      p -
      tester -
      Returns:
      The matching notes grouped per pitch, in ascending order.
    • fixEndOfPhraseNotes

      public static boolean fixEndOfPhraseNotes(SizedPhrase sp)
      Make sure there is no note which ends right on sp boundary: when moving notes (eg Phrase.shiftAllEvents()), because of float rounding errors, this may lead to notes becoming out of SizedPhrase range.
      Parameters:
      sp -
      Returns:
    • fixOverlappedNotes

      public static Map<NoteEvent,NoteEvent> fixOverlappedNotes(Phrase p)
      Remove overlapped phrase notes with identical pitch.

      - Remove a note completely overlapped by another note.
      - Shorten a note partially overlapped by another one.

      Parameters:
      p -
      Returns:
      The notes removed (value=null) or replaced (value=new note)
    • limitPitch

      public static void limitPitch(Phrase p, int lowLimit, int highLimit)
      Change the octave of phrase notes whose pitch is above highLimit or below lowLimit.

      Parameters:
      p -
      lowLimit - There must be at least 1 octave between lowLimit and highLimit
      highLimit - There must be at least 1 octave between lowLimit and highLimit
    • importPhrase

      public static Phrase importPhrase(File midiFile, int channel, boolean isDrums, boolean strictChannel, boolean notifyUserIfNoChannelNotes) throws IOException, InvalidMidiDataException
      Parse a Midi file to extract one phrase from the specified Midi channel notes (notes can be on any track).

      As a special case, if midiFile contains notes from only 1 channel and this channel is different from the channel parameter, then the method will still accept these notes to build the returned phrase, unless the strictChannel parameter is true.

      Parameters:
      midiFile -
      channel -
      isDrums - The drums settings of the returned phrase
      strictChannel -
      notifyUserIfNoChannelNotes - If true notify user if no relevant notes found
      Returns:
      Can be empty
      Throws:
      IOException
      InvalidMidiDataException
    • getPhrases

      public static List<Phrase> getPhrases(int tracksPPQ, Track[] tracks, Integer... channels)
      Parse all tracks to build one phrase per used channel.

      A track can use notes from different channels. Notes from a given channel can be on several tracks.

      Parameters:
      tracksPPQ - The Midi PPQ resolution (pulses per quarter) used in the tracks.
      tracks -
      channels - Get phrases only for the specified channels. If empty, get phrases for all channels.
      Returns:
      A list of phrases ordered by channel in ascending order