Ejemplo n.º 1
0
    def _check_if_is_mpe_grouping_track(self):
        self.mpeGroupedTracksMasterTrackModel = self._check_if_is_mpe_grouping_track_iterator()
        self.isMPEGroupingTrack = self.mpeGroupedTracksMasterTrackModel is not None
        log_message("GroupMasterTrackModel created! id:",self.itemId, "is isMPEGroupingTrack:",self.isMPEGroupingTrack,
                    "thamastertrack:",self.mpeGroupedTracksMasterTrackModel)


        if self.isMPEGroupingTrack:
            def setDelayedNameChange():
                def masterTracksNameChanged():
                    self.item.name = self.mpeGroupedTracksMasterTrackModel.s_name + " MPEGroup"
                    return True

                InstanceContainer.add_delayed_callback("renameMPEGroup-"+self.itemModelPointer, masterTracksNameChanged, [], {})

            setDelayedNameChange()

            self.mpeGroupedTracksMasterTrackModel.add_s_name_listener(setDelayedNameChange)

            def setDelayedColorChange():
                def masterTracksColorChanged():
                    self.item.color = self.mpeGroupedTracksMasterTrackModel.item.color
                    return True

                InstanceContainer.add_delayed_callback("recolorMPEGroup-" + self.itemModelPointer,
                                                     masterTracksColorChanged, [], {})

            setDelayedColorChange()

            self.mpeGroupedTracksMasterTrackModel.item.add_color_listener(setDelayedColorChange)


        return True
Ejemplo n.º 2
0
    def set_output_routing_type_by_types_display_name(self, type_display_name):
        """
        {
            "returns": "bool",
            "args": [
                {
                  "type": "str",
                  "defaultValue": null,
                  "optional": false,
                  "name": "type_display_name",
                  "str": ""
                }

            ],
            "kwargs": {},
            "desc": "Tries to set track's output_routing_type to routing type with display_name value of arg str."
        }
        """
        itemByName = None
        for tempRoutingType in self.item.available_output_routing_types:
            if tempRoutingType.display_name == type_display_name:
                itemByName = tempRoutingType
        if itemByName is not None:
            # log_message("Found, trying to set..")
            self.item.output_routing_type = itemByName
            return True
        else:
            log_message("[Warning] set_output_routing_type_by_channel_display_name on MidiTrack:",
                        self.itemModelPointer, "can't find output_routing_type with display_name:", type_display_name)
        return False
Ejemplo n.º 3
0
    def set_input_routing_channel_by_channel_display_name(self, channel_display_name):
        """
        {
            "returns": "bool",
            "args": [
                {
                  "type": "str",
                  "defaultValue": null,
                  "optional": false,
                  "name": "channel_display_name",
                  "str": ""
                }

            ],
            "kwargs": {},
            "desc": "Tries to set track's input_routing_channel to routing channel with display_name value of arg str."
        }
        """
        itemByName = None
        for tempRoutingChannel in self.item.available_input_routing_channels:
            if tempRoutingChannel.display_name == channel_display_name:
                itemByName = tempRoutingChannel

        if itemByName is not None:
            # log_message("Found, trying to set..",itemByName," named:",itemByName.display_name,"on item:",self.itemModelPointer,"named",self.s_name)
            self.item.input_routing_channel = itemByName
            return True
        else:
            log_message("[Warning] set_input_routing_channel_by_channel_display_name on MidiTrack:",
                        self.itemModelPointer, "can't find input_routing_channel with display_name:",
                        channel_display_name)
        return False
Ejemplo n.º 4
0
    def _handle_track_list(self):
        self.item = self.parentItemModel.item.tracks
        log_message("Weeee, tracks changed! len now:",len(self.item))
        tracksToFind = self._trackModels.keys()[:]
        for x in range(0,len(self.item)):
            #log_message("Checking itemId:",x)
            tempTrack = self.item[x]
            tempTrackImp = str(tempTrack._live_ptr)
            if tempTrackImp in tracksToFind:
                #log_message("Track:",x,tempTrack.name,"exists! x!=itemId:",x != self._trackModels[tempTrackImp].itemId)
                tracksToFind.remove(tempTrackImp)
                if x != self._trackModels[tempTrackImp].itemId:
                    self._trackModels[tempTrackImp].itemId = x
            else:
                #log_message("New track added!")
                if tempTrack.is_foldable:
                    self._trackModels[tempTrackImp] = GroupMasterTrackModel(tempTrack, x, self)
                elif tempTrack.has_midi_input:
                    self._trackModels[tempTrackImp] = MidiTrackModel(tempTrack, x, self)
                else:
                    self._trackModels[tempTrackImp] = TrackModel(tempTrack, x, self)

        for tempDeletedTrackLptr in tracksToFind:
            log_message("Found deleted track:", tempDeletedTrackLptr,"had itemId:",self._trackModels[tempDeletedTrackLptr].itemId)
            self._trackModels[tempDeletedTrackLptr].disconnect()
            del self._trackModels[tempDeletedTrackLptr]
Ejemplo n.º 5
0
 def add_delayed_callback(self, key, callback, params, keywordParams={}, rewriteExisting=True, delayCycles=1):
     """ Adds a delayed callback to the queue. Key identifies the callback, params and keywordParams are passed to
       the callback on calling. If rewriteExisting is true, an existing callback with the key will be overwritten,
       otherwise the new callback won't be added. delayCycles determines for how many cycles the calling will be
       delayed.
     """
     if rewriteExisting or key not in self._delayedCallbacks:
         self._delayedCallbacks[key] = {'func': callback, 'params': params, 'keywordParams': keywordParams,
                                        'delayCycles': delayCycles}
     else:
         log_message("Not adding cb to queue, rewriteExisting=False and key:",key,"exists already!")
Ejemplo n.º 6
0
    def __init__(self, c_instance):
        versionStr = "Live_{0}_{1}_{2}".format(self.application.get_major_version(),
                                               self.application.get_minor_version(),
                                               self.application.get_bugfix_version())

        #Call the ableton.v2.control_surface.control_surface init
        super(MPE_Util, self).__init__(c_instance)

        # Initialize the required instances to the InstanceContainer.
        InstanceContainer.song = self.song
        InstanceContainer.itemModelDataHandler = ItemModelDataHandler.ItemModelDataHandler("MPE_Util")
        self.delayedCallbackHandler = DelayedCallbackHandler()
        InstanceContainer.add_delayed_callback = self.delayedCallbackHandler.add_delayed_callback
        InstanceContainer.get_delayed_callback_exists = self.delayedCallbackHandler.get_delayed_callback_exists
        
        with self.component_guard():
            self.songModel = SongModel(self.song)
            self.parse()
        log_message("MPE_Util running on",versionStr)
        self.show_message("MPEUtil loaded!")
Ejemplo n.º 7
0
    def _mix_with_class(self, toMixWithClassName, *args, **kwargs):
        """ Adds specific functionality to the TrackModel instance. toMixWithClassName is a name of a class from
        itemmodelmixins package
        """
        if toMixWithClassName in globals():
            tempMixedClass = globals()[toMixWithClassName]
            # log_message("WEEEEE, would mix:",self.itemType, "with:",toMixWithClassName, "class:", tempMixedClass)

            cls = self.__class__
            # self.__class__ = cls.__class__(cls.__name__+"_"+toMixWithClassName, (cls, tempMixedClass), {})
            self.__class__ = cls.__class__(cls.__name__, (cls, tempMixedClass), {})
            tempMixedClassesInitName = "_" + toMixWithClassName + "_init"
            if hasattr(self, tempMixedClassesInitName):
                # log_message("Calling tempMixedClassesInitName:",tempMixedClassesInitName)
                getattr(self, tempMixedClassesInitName)(*args, **kwargs)
            else:
                log_message("[ERROR!] Can't find toMixWithClasses:", toMixWithClassName, "init-method by name:",
                            tempMixedClassesInitName)


        else:
            log_message("ERROR! Can't mix with class:", toMixWithClassName, "not found from globals()!")
Ejemplo n.º 8
0
    def _name_changed_callback(self):
        postfixFound = False
        if self._listenToPostfixes != None:
            freshName = self.item.name
            for tempPostfixRegexStr, tempCallbackFn in self._listenToPostfixes.iteritems():
                #log_message("Checking for fresh name: ",freshName, "with regexstatement: ", tempPostfixRegexStr)
                if not postfixFound:
                    match = re.search(tempPostfixRegexStr, freshName, re.IGNORECASE)
                    if match:
                        log_message("Found match!! command: ",match.group('command'), "and num_arg:", match.group('num_arg'));
                        def delayedCallbackToFixName(newName):
                            self.item.name = newName
                            return True

                        InstanceContainer.add_delayed_callback("CallbackForPostfixNameFix", delayedCallbackToFixName,
                                                               [match.group('item_name')], {})
                        postfixFound = True

                        InstanceContainer.add_delayed_callback("CallbackForPostfixMethodCall", tempCallbackFn, [match],
                                                                   {}, delayCycles=2)

        if not postfixFound:
            self._update_s_name()
Ejemplo n.º 9
0
    def __init__(self, *a, **kw):

        super(MidiTrackModel, self).__init__(*a, **kw)
        self.itemType = "Track.MidiTrack"
        if self.foundExternalData is not None:
            log_message("Weeee, track:",self.itemId,self.itemModelPointer,"found external data:",self.foundExternalData)
            if 'isMPEMasterTrack' in self.foundExternalData and self.foundExternalData['isMPEMasterTrack'] is True:
                log_message("In externalData for MidiTrackModel:",self.itemModelPointer,
                            "isMpeMasterTrack is found True! setting delayed call.")
                def callbackForDelayedMPEMasterStatusUpdate():
                    log_message("Loading a mpeMasterTrack, after delay, calling:",
                                "self.create_mpe_input_tracks(loadingTracks=True)")
                    self.create_mpe_input_tracks(loadingTracks=True)
                    return True
                InstanceContainer.add_delayed_callback("callbackToLoadMPESubtracksFor"+self.itemModelPointer, callbackForDelayedMPEMasterStatusUpdate, [], {}, delayCycles=2)

            elif 'isMPESubTrack' in self.foundExternalData and self.foundExternalData['isMPESubTrack'] is True:
                self._mpeChannelId = self.foundExternalData['_mpeChannelId']
            elif 'isGhostMidiInputTrack' in self.foundExternalData and self.foundExternalData['isGhostMidiInputTrack'] is True:
                log_message("In externalData for MidiTrackModel:", self.itemModelPointer,
                            "isGhostMidiInputTrack is found True! Mixing..")
                self._mix_with_class("GhostMidiInputTrackMix")
Ejemplo n.º 10
0
    def create_mpe_input_tracks(self, loadingTracks=False, inputTrackCount=None):
        """ Mixes the MidiTrackModel with MPEMasterTrackMixIn class. loadingTracks is True when a Live set is loaded,
        inputTrackCount may be given as a parameter, otherwise read from conf. Creates new midi tracks,
        or loads existing ones, and routes them to act as MPE input channels for this tracks instrument via utilizing
        the MPESubTrackMixIn class.

        """

        if loadingTracks:
            existingMpeTracks = []
            for tempOldMPESubTrackModelIMP in self.foundExternalData["_mpeSubtracks"]:
                #log_message("Loading subtrack with imp:",tempOldMPESubTrackModelIMP)
                if tempOldMPESubTrackModelIMP in InstanceContainer.itemModelDataHandler.loadedItemModelPointersToCurrentItemModels:
                    existingMpeTracks.append(
                        InstanceContainer.itemModelDataHandler.loadedItemModelPointersToCurrentItemModels[
                            tempOldMPESubTrackModelIMP])
                else:
                    log_message("[ERROR!] unable to find old imp:", tempOldMPESubTrackModelIMP,
                                "from loadedImpsToCurrentImps:",
                                InstanceContainer.itemModelDataHandler.loadedItemModelPointersToCurrentItemModels)

        #How many channels we'll create
        if inputTrackCount is not None:
            num_of_input_channels = inputTrackCount
        else:
            num_of_input_channels = conf.defaultMpeChannelCount

        self._mix_with_class("MPEMasterTrackMix")

        self.item.arm = True

        if not loadingTracks:
            tempTrackIdList = []
            for x in range(1, num_of_input_channels + 1):
                tempChannel_id = self.itemId + x
                InstanceContainer.songModel.item.create_midi_track(tempChannel_id)
                tempTrackIdList.append((tempChannel_id, x))

            def set_mpeSubtrackPhase1(song, channelIdTupleList):
                for riseChannelId, mpeChannelId in channelIdTupleList:
                    trackItem = song.tracks[riseChannelId]
                    self._add_mpe_subtrack(self.parentItemModel.get_track_model_by_IMP(trackItem._live_ptr),
                                           mpeChannelId, creatingTrack=True)

                return True

            keyForCallbackPhase1 = "createMpe-Track_" + self.item.name + "_cb_for_phase1"
            InstanceContainer.add_delayed_callback(keyForCallbackPhase1, set_mpeSubtrackPhase1,
                                                 (InstanceContainer.songModel.item, tempTrackIdList), {})

        else:
            log_message("Creating mpeMastertrack-stuff, we got self.foundExternalData:", self.foundExternalData)
            for tempSubtrackModel in existingMpeTracks:
                self._add_mpe_subtrack(tempSubtrackModel)

        if conf.utilizeGhostInputTrack:
            # GhostInputTrack may be utilized to get the Arm -button to be displayed on track in Live's GUI. It is a
            # midi track with no input and no output. This way the MPE Master track records clips in sync with its input
            # tracks, and the clips can be fired in sync too. In future, the clips may be simultaneously edited as well

            # If configured to use the GhostInputTrack, if it isn't utilized already, create it if it doesn't exist, and
            # set it as input_routing_type when it's ready.
            if self.item.input_routing_type.display_name != "GhostMidiInput":
                def updateInputToGhost():
                    self.set_input_routing_type_by_types_display_name(
                        InstanceContainer.songModel._ghostMidiInputTrack.item.name)

                if InstanceContainer.songModel._ghostMidiInputTrack is None:

                    InstanceContainer.add_delayed_callback("create_GhostMidiInputTrack",
                                       InstanceContainer.songModel._create_ghostMidiInputTrack, [], {}, delayCycles=4)


                    InstanceContainer.songModel.add_ghostMidiInputTrack_listener(updateInputToGhost)

                elif not hasattr(InstanceContainer.songModel._ghostMidiInputTrack, "itemModelPointer"):
                    InstanceContainer.songModel.add_ghostMidiInputTrack_listener(updateInputToGhost)
                else:
                    updateInputToGhost()


        else:
            self.set_input_routing_type_by_types_display_name(self._mpeControllerInputTypeName)
            self.item.current_monitoring_state = 2
Ejemplo n.º 11
0
 def callbackForDelayedMPEMasterStatusUpdate():
     log_message("Loading a mpeMasterTrack, after delay, calling:",
                 "self.create_mpe_input_tracks(loadingTracks=True)")
     self.create_mpe_input_tracks(loadingTracks=True)
     return True