Class MidiMix

java.lang.Object
org.jjazz.midimix.api.MidiMix
All Implemented Interfaces:
PropertyChangeListener, VetoableChangeListener, Serializable, EventListener, SgsChangeListener

A set of up to 16 InstrumentMixes, 1 per Midi channel with 1 RhythmVoice associated.

The object manages the solo functionality between the InstrumentMixes.

A Song can be associated to the MidiMix so that InstrumentMixes are kept up to date with song's songStructure and user phrase changes.

If MidiMix is modified the corresponding property change event is fired (e.g. PROP_INSTRUMENT_MUTE) then the PROP_MODIFIED_OR_SAVED_OR_RESET change event is also fired.

See Also:
  • Field Details

    • MIX_FILE_EXTENSION

      public static final String MIX_FILE_EXTENSION
      See Also:
    • PROP_CHANNEL_INSTRUMENT_MIX

      public static final String PROP_CHANNEL_INSTRUMENT_MIX
      New or removed InstrumentMix.

      OldValue=the old InstrumentMix, newValue=channel

      See Also:
    • PROP_CHANNEL_DRUMS_REROUTED

      public static final String PROP_CHANNEL_DRUMS_REROUTED
      oldValue=channel, newValue=true/false.
      See Also:
    • PROP_INSTRUMENT_MUTE

      public static final String PROP_INSTRUMENT_MUTE
      oldValue=InstumentMix, newValue=mute boolean state.
      See Also:
    • PROP_DRUMS_INSTRUMENT_KEYMAP

      public static final String PROP_DRUMS_INSTRUMENT_KEYMAP
      A drums instrument has changed with different keymap.

      oldValue=channel, newValue=old keymap (may be null)

      See Also:
    • PROP_INSTRUMENT_TRANSPOSITION

      public static final String PROP_INSTRUMENT_TRANSPOSITION
      oldValue=InstumentMix, newValue=transposition value.
      See Also:
    • PROP_INSTRUMENT_VELOCITY_SHIFT

      public static final String PROP_INSTRUMENT_VELOCITY_SHIFT
      oldValue=InstumentMix, newValue=velocity shift value.
      See Also:
    • PROP_RHYTHM_VOICE

      public static final String PROP_RHYTHM_VOICE
      A RhythmVoice has replaced another one, e.g. this is used to change the name of a user track.

      oldValue=old RhythmVoice, newValue=new RhythmVoice

      See Also:
    • PROP_RHYTHM_VOICE_CHANNEL

      public static final String PROP_RHYTHM_VOICE_CHANNEL
      The channel of a RhythmVoice has been changed by user.

      oldValue=old channel, newValue=new channel

      See Also:
    • PROP_MODIFIED_OR_SAVED

      public static final String PROP_MODIFIED_OR_SAVED
      This property changes when the MidiMix is modified (false->true) or saved (true->false).
      See Also:
    • PROP_MUSIC_GENERATION

      public static final String PROP_MUSIC_GENERATION
      Fired each time a MidiMix parameter which impacts music generation is modified, like instrument transposition.

      OldValue=the property name that triggers the musical change, newValue=optional associated data.

      Use PROP_MODIFIED_OR_SAVED to get notified of any MidiMix change, including non-musical ones like track mute change, etc.

      See Also:
    • NB_AVAILABLE_CHANNELS

      public static final int NB_AVAILABLE_CHANNELS
      See Also:
  • Constructor Details

    • MidiMix

      public MidiMix()
      Create an empty MidiMix.
    • MidiMix

      public MidiMix(Song s)
      create an empty MidiMix and associate it to specified song.
      Parameters:
      s -
  • Method Details

    • getDeepCopy

      public MidiMix getDeepCopy()
      Get a deep copy of this MidiMix.

      Mutable internal objects are deeply copied, e.g. InstrumentMixes.
      Not copied: undoableListeners, isSaveNeeded.

      Returns:
    • setSong

      public final void setSong(Song sg)
      Associate a song to this MidiMix : listen to song changes to keep this MidiMix consistent.

      Listen to rhythms and user phrases changes.

      Parameters:
      sg - Can be null.
      Throws:
      IllegalArgumentException - If checkConsistency(sg, false) fails.
    • checkConsistency

      public void checkConsistency(Song sg, boolean fullCheck) throws SongCreationException
      Check if this MidiMix is consistent with the specified song.

      Check that all RhythmVoices of this MidiMix belong to song rhythms. Check user tracks consistency between midiMix and song.

      Parameters:
      sg -
      fullCheck - If true also check that all song RhythmVoices are used in this MidiMix.
      Throws:
      SongCreationException - If an inconsistency is detected
    • getSong

      public Song getSong()
    • getUserChannels

      public List<Integer> getUserChannels()
      Return the list user phrase Midi channels.
      Returns:
    • getUserRhythmVoices

      public List<UserRhythmVoice> getUserRhythmVoices()
      Return the subset of RhythmVoices which are UserRhythmVoices.
      Returns:
    • getUserRhythmVoice

      public UserRhythmVoice getUserRhythmVoice(String name)
      Get the user phrase RhythmVoice key for the specified name.
      Parameters:
      name -
      Returns:
      Null if not found
    • setInstrumentMix

      public void setInstrumentMix(int channel, RhythmVoice rvKey, InstrumentMix insMix)
      Assign an InstrumentMix to a midi channel and to a key.

      Replace any existing InstrumentMix associated to the midi channel. The solo and "drums rerouted channel" status are reset to off for the channel.
      Fire a PROP_CHANNEL_INSTRUMENT_MIX change event for this channel, and one UndoableEvent.

      Parameters:
      channel - A valid midi channel number.
      rvKey - Can be null if insMix is also null. If a song is set, must be consistent with its rhythms and user phrases. Can't be a RhythmVoiceDelegate.
      insMix - Can be null if rvKey is also null.
      Throws:
      IllegalArgumentException - if insMix is already part of this MidiMix for a different channel, or if rvKey is a RhythmVoiceDelegate.
    • replaceRhythmVoice

      public void replaceRhythmVoice(RhythmVoice oldRv, RhythmVoice newRv)
      Replace an existing RhythmVoice by a new one.

      Fire a PROP_RHYTHM_VOICE and an undoable event.

      Parameters:
      oldRv - Must be a RhythmVoice used by this MidiMix.
      newRv - Must not be already used by this MidiMix.
    • setRhythmVoiceChannel

      public void setRhythmVoiceChannel(RhythmVoice rv, int newChannel)
      Change the channel of a RhythmVoice.

      Fire a PROP_RHYTHM_VOICE_CHANNEL and an undoable event.

      Parameters:
      rv - Must be a RhythmVoice used by this MidiMix.
      newChannel - Must be a free channel
    • getInstrumentMix

      public InstrumentMix getInstrumentMix(int channel)
      Get the instrumet mix for the specified channel.
      Parameters:
      channel - A valid midi channel number
      Returns:
      The InstrumentMix assigned to the specified Midi channel, or null if no InstrumentMix for this channel.
    • getInstrumentMix

      public InstrumentMix getInstrumentMix(RhythmVoice rv)
      Get the instrumet mix for the specified RhythmVoice.
      Parameters:
      rv - If it's a RhythmVoiceDelegate, return the channel associated to its source RhythmVoice.
      Returns:
      The InstrumentMix associated to rv. Null if no InstrumentMix found.
    • getChannel

      public int getChannel(InstrumentMix im)
      Find the channel corresponding to the specified InstrumentMix.
      Parameters:
      im -
      Returns:
      -1 if InstrumentMix not found.
    • geRhythmVoice

      public RhythmVoice geRhythmVoice(InstrumentMix im)
      Parameters:
      im -
      Returns:
      null if InstrumentMix not found.
    • getRhythmVoice

      public RhythmVoice getRhythmVoice(int channel)
      Get the RhythmVoice for the specified Midi channel.

      Parameters:
      channel -
      Returns:
      The RhythmVoice key corresponding to specified channel. Can be null.
    • getChannel

      public int getChannel(RhythmVoice rvKey)
      Get the Midi channel associated to the specified RhythmVoice.
      Parameters:
      rvKey - If it's a RhythmVoiceDelegate, return the channel associated to its source RhythmVoice.
      Returns:
      -1 if key not found.
    • getUsedChannels

      public List<Integer> getUsedChannels()
      Get the list of used channels in this MidiMix.
      Returns:
      The list of Midi channel numbers for which a non-null InstrumentMix is assigned.
    • getUsedChannels

      public List<Integer> getUsedChannels(Rhythm r)
      Get the list of used channels for specified rhythm in this MidiMix.
      Parameters:
      r - If null return all used channels. If r is an AdaptedRhythm, returns the channels from it source rhythm.
      Returns:
      The list of Midi channel numbers for rhythm r and for which a non-null InstrumentMix is assigned.
    • getUnusedChannels

      public List<Integer> getUnusedChannels()
      Returns:
      The list of Midi channel numbers for which no InstrumentMix is assigned.
    • getRhythmVoices

      public List<RhythmVoice> getRhythmVoices()
      Get all the RhythmVoices corresponding to the non-null InstrumentMixes.

      Returned list includes UserRhythmVoice instances as well. The list does not contain RhythmVoiceDelegate instances.

      Returns:
    • getDrumsReroutedChannels

      public List<Integer> getDrumsReroutedChannels()
      The channels which should be rerouted to the GM Drums channel.
      Returns:
      Note that returned list is not ordered. Can be empty.
    • setDrumsReroutedChannel

      public void setDrumsReroutedChannel(boolean b, int channel)
      Enable or disable the rerouting of specified channel to GM Drums channel.

      If enabled, the related InstrumentMix/Settings will be disabled, and vice versa.

      Parameters:
      b -
      channel -
    • getChannelsNeedingDrumsRerouting

      public List<Integer> getChannelsNeedingDrumsRerouting(HashMap<Integer,Instrument> mapChannelNewIns)
      Get the channels which normally need drums rerouting.

      A channel needs rerouting if all the following conditions are met:
      0/ InsMix at MidiConst.CHANNEL_DRUMS has its instrument Midi message enabled
      1/ channel != MidiConst.CHANNEL_DRUMS
      2/ rv.isDrums() == true and rerouting is not already enabled
      3/ instrument (or new instrument if one is provided in the mapChannelNewIns parameter) is the VoidInstrument

      Parameters:
      mapChannelNewIns - Optional channel instruments to be used for the exercise. Ignored if null. See OutputSynth.getNeedFixInstruments().
      Returns:
      Can be empty
    • findFreeChannel

      public int findFreeChannel(boolean findDrumsChannel)
      Return a free channel to be used in this MidiMix.

      Try to keep channels in one section above the drums channel reserved to Drums. If not enough channels extend to channel below the drums channel.

      Parameters:
      findDrumsChannel - If true try to use CHANNEL_DRUMS if it is available.
      Returns:
      -1 if no channel found
    • addInstrumentMixes

      public final void addInstrumentMixes(MidiMix fromMm, Rhythm r) throws MidiUnavailableException
      Add RhythmVoices (of Rhythm instances only, UserRhythmVoices are skipped) and InstrumentMixes copies from mm into this MidiMix.

      Copies have solo/drumsRerouting set to OFF. Method uses findFreeChannel() to allocate the new channels of mm if they are not free in this MidiMix.

      The operation will fire UndoableEvent edits.

      Parameters:
      fromMm -
      r - If non null, copy fromMm instrumentMixes only if they belong to rhythm r (if r is an AdaptedRhythm, use its source rhythm).
      Throws:
      MidiUnavailableException - If not enough channels available to accommodate mm instruments.
    • getFile

      public File getFile()
      The file where this object is stored.
      Returns:
      Null if not set.
    • setFile

      public void setFile(File f)
    • importInstrumentMixes

      public void importInstrumentMixes(MidiMix mm)
      Import InstrumentMixes from mm into this object.

      Import is first done on matching RhythmVoices from the same rhythm. Then import only when RvTypes match. For UserRhythmVoices import is done only if name matches.
      Create new copy instances of Instruments Mixes with solo OFF.

      The operation will fire UndoableEvent(s).

      Parameters:
      mm -
    • needSave

      public boolean needSave()
      Returns:
      True if MidiMix has some unsaved changes.
    • saveToFileNotify

      public boolean saveToFileNotify(File f, boolean isCopy)
      Same as saveToFile() but notify user if problems.
      Parameters:
      f -
      isCopy -
      Returns:
      False if a problem occured
    • saveToFile

      public void saveToFile(File f, boolean isCopy) throws IOException
      Save this MidiMix to a file.

      This will fire a PROP_MODIFIED_OR_SAVED change event (true=>false).

      Parameters:
      f -
      isCopy - Indicate that we save a copy, ie perform the file save but nothing else (eg no PROP_MODIFIED_OR_SAVED state change)
      Throws:
      IOException
    • getInstrumentMixesPerChannel

      public List<InstrumentMix> getInstrumentMixesPerChannel()
      All InstrumentMixes ordered by channel.
      Returns:
      A 16 items list, one instrumentMix per channel (some items can be null)
    • getInstrumentMixes

      public List<InstrumentMix> getInstrumentMixes()
      The non-null instrument mixes ordered by channel.
      Returns:
      Can be an empty list.
    • addUndoableEditListener

      public void addUndoableEditListener(UndoableEditListener l)
    • removeUndoableEditListener

      public void removeUndoableEditListener(UndoableEditListener l)
    • addPropertyChangeListener

      public void addPropertyChangeListener(PropertyChangeListener l)
    • removePropertyChangeListener

      public void removePropertyChangeListener(PropertyChangeListener l)
    • addPropertyChangeListener

      public void addPropertyChangeListener(String propertyName, PropertyChangeListener l)
    • removePropertyChangeListener

      public void removePropertyChangeListener(String propertyName, PropertyChangeListener l)
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • toDumpString

      public String toDumpString()
    • loadFromFile

      public static MidiMix loadFromFile(File f) throws IOException
      Parameters:
      f -
      Returns:
      Null if MidiMix could not be created for some reason.
      Throws:
      IOException - If problem occured while reading file
    • authorizeChange

      public void authorizeChange(SgsChangeEvent e) throws UnsupportedEditException
      Description copied from interface: SgsChangeListener
      Some change events might need to be authorized by all listeners before being processed by songStructureChanged().
      Specified by:
      authorizeChange in interface SgsChangeListener
      Parameters:
      e - The change to authorize.
      Throws:
      UnsupportedEditException - Listener shall throw this exception if change is not acceptable. Exception message might be shown to user to explain the problem.
    • songStructureChanged

      public void songStructureChanged(SgsChangeEvent e)
      Description copied from interface: SgsChangeListener
      Process the change.

      Note that this method might be called outside of the EDT.

      Specified by:
      songStructureChanged in interface SgsChangeListener
    • vetoableChange

      public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
      Specified by:
      vetoableChange in interface VetoableChangeListener
      Throws:
      PropertyVetoException
    • propertyChange

      public void propertyChange(PropertyChangeEvent e)
      Specified by:
      propertyChange in interface PropertyChangeListener