def __call__(self, message):
        """
        Parse method and call method on self based on midi function.  For
        example, if function is NOTEON_CHAN1, this will call our method
        noteon(), etc.  If a message has a channel as part of it's function,
        this will be the first argument.  After the first optional channel
        argument, remaining positional arguments are passed to the method in
        the same order as specified in MIDI.  Not all MIDI functions need to be
        supplied or implemented in subclass.
        """
        packet, timestamp = message
        func, arg1, arg2, _pad = packet
        args = [arg1, arg2][:FUNCTION_ARITY.get(func, 0)]
        args.append(timestamp)
        funcname = FUNCTIONS[func]
        tokens = funcname.split('_')
        if len(tokens) == 2:
            type, channel = tokens
            channel = int(channel[4:])
            method = getattr(self, type.lower(), None)
            if method is None:
                debug('No handler defined for midi event of type: %s' % type)
            method(channel, *args)