basePmtr.py :  » Media-Sound-Audio » athenaCL » athenaCL » libATH » libPmtr » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Media Sound Audio » athenaCL 
athenaCL » athenaCL » libATH » libPmtr » basePmtr.py
#-----------------------------------------------------------------||||||||||||--
# Name:         parent.py
# Purpose:      base class of all general and rhythm parameter objects.
#
# Authors:      Christopher Ariza
#
# Copyright:    (c) 2001-2007 Christopher Ariza
# License:      GPL
#-----------------------------------------------------------------||||||||||||--


import random, copy
from athenaCL.libATH import drawer
from athenaCL.libATH import typeset
from athenaCL.libATH import unit
from athenaCL.libATH import error
from athenaCL.libATH import language
from athenaCL.libATH import table
from athenaCL.libATH import argTools
lang = language.LangObj()

_MOD = 'basePmtr.py'

#-----------------------------------------------------------------||||||||||||--
# constants string suffix used for naming multiple parameters
AUXQ = 'auxQ'
TEXTQ = 'textQ'
DYNQ = 'dynQ'
CLONEQ = 'cloneQ'
# common parameters
tCOMMONQ = ('inst', 'tRange', 'beatT', 'rhythmQ', 'fieldQ',
           'octQ', 'ampQ', 'panQ', 'path')
# textures have sustain and accent fields tt textures do not
cCOMMONQ = ('time', 'sus', 'acc', 'fieldQ', 'octQ', 'ampQ', 'panQ', )

REFDICT_SIM = {'bpm':120, 'sadr':[], 'ssdr':[]}


def _getLabels(no, prefix, index):
   labels = []
   for i in range(0, no):
      if index: # store two data attributes
         labels.append((i, '%s%s' % (prefix, str(i))))
      else:
         labels.append('%s%s' % (prefix, str(i)))
   return labels

def auxLabel(auxNo, index=0):
   return _getLabels(auxNo, AUXQ, index)

def textLabel(textNo, index=0):
   return _getLabels(textNo, TEXTQ, index)

def cloneLabel(textNo, index=0):
   return _getLabels(textNo, CLONEQ, index)

def dynLabel(dynNo, index=0):
   return _getLabels(dynNo, DYNQ, index)


#-----------------------------------------------------------------||||||||||||--
class Selector:
   """object to handle selecting things from a list
   basic selectors that do not require additional parameters
   can be initialized w/ and empty source, but will raise an index
   error if __call__ is used w/ empty list"""
   
   # selection methods to add:
   # orderReverse
   # randomFirst ? (favor first, beta)
   # randomLast ? (favor last, beta)
   # randomEdges ? (favor edges)
   # randomCenter ? (favor center, gausian distribution)
   
   def __init__(self, src, control):
      self.src = src
      # control value is not parsed; must be complete string!
      self.control = control
      self.ref = []
      self.status = 0 # check if values are available, updated w/ set list
      self._setList() # copy rawList to list
      #print _MOD, self.src, self.ref, self.control
      self.scratch = [] # will be populated if needed
      self._i = 0 # current position
      # this is a list of indexes to move through in order
      self._direction = [] # used in oscillate
      self._updateDirectionIndex()
      
   def _setList(self):
      self.ref = []
      for i in range(len(self.src)): # index for custom obj
         entry = self.src[i]
         if hasattr(entry, 'copy'): # copy object tt have copy attribute
            self.ref.append(entry.copy())
         else:
            self.ref.append(copy.deepcopy(entry))
      if len(self.ref) == 0: self.status = 0
      else: self.status = 1

   def getStatus(self):
      "used to check if values are set or not"
      return self.status
      
   def _setListScratch(self):
      self.scratch = []
      for i in range(len(self.src)): # index for custom obj
         entry = self.src[i]
         if hasattr(entry, 'copy'):
            self.scratch.append(entry.copy())
         else:
            self.scratch.append(copy.deepcopy(entry))

   def _updateDirectionIndex(self):
      if len(self.ref) == 0: self._direction = []
      elif len(self.ref) == 1: self._direction = [0]
      elif len(self.ref) == 2: self._direction = [0,1]
      else:
         self._direction = range(0, len(self.ref)) # 0,1,2
         post = range(1, (len(self.ref)-1)) # 1,
         post.reverse() # second half of range
         self._direction = self._direction + post
         
   def reset(self):
      self.scratch = [] # will be populated if needed
      self._i = 0

   def update(self, src):
      "update the list; if it is a different size, reset index"
      oldSize = len(self.ref) # store old size
      self.src = src
      self._setList() # this will clear and set self.ref
      if len(self.ref) != oldSize:
         self.scratch = []
         self._i = 0
         self._updateDirectionIndex()
         
   def _randomChoice(self):
      "randomly select an item"
      return random.choice(self.ref)

   def _randomWalk(self):
      "one-dimension random walk, with wrapping"
      if len(self.ref) == 1: return self.ref[0]
      if random.choice([0,1]):
         self._i = self._i + 1
      else:
         self._i = self._i - 1
      selectIndex = self._i % len(self.ref) # use mod for wrapping
      return self.ref[selectIndex]

   def _randomPermutate(self):
      """non redundant selection at random; refils when empty"""
      if len(self.ref) == 1:  return self.ref[0]
      if len(self.scratch) == 0:
         self._setListScratch()
      select = random.choice(self.scratch)
      del self.scratch[self.scratch.index(select)] 
      self._i = self._i + 1
      return select

   def _orderedCyclic(self):
      """move through list of items in order"""
      if len(self.ref) == 1:  return self.ref[0]
      if self._i == len(self.ref):
         self._i = 0
      select = self.ref[self._i]
      self._i = self._i + 1
      return select

   def _orderedOscillate(self):
      """move through list of items by reading the direction list
      direction list has index values to move through
      self._i referes to direction index, not list indices"""
      if len(self.ref) == 1:  return self.ref[0]
      if self._i == len(self._direction):
         self._i = 0
      select = self.ref[self._direction[self._i]]
      self._i = self._i + 1
      return select
      
   def __call__(self):
      # emergency check
      if len(self.ref) == 0:
         raise IndexError, 'selector has no values'
      if self.control == 'randomChoice':
         return self._randomChoice()
      elif self.control == 'randomWalk':
         return self._randomWalk()
      elif self.control == 'randomPermutate':
         return self._randomPermutate()
      elif self.control == 'orderedCyclic':
         return self._orderedCyclic()
      elif self.control == 'orderedOscillate':
         return self._orderedOscillate()
      else:
         raise ValueError, 'no control for %s' % self.control


#-----------------------------------------------------------------||||||||||||--
class Parameter:
   """base class for all pmtr objects
   
   parameter objects are very broady construed; can be any of a number of things
   some parameter objects are 'generators': current times does not make a dif
      orderedCyclic
   some parameter objects are 'functions': current time makes a difference
      waves, bpf
      
   some attributes are checked for adding, as in some cases it seems
   the base class sets up attributes before calling the parent class init
   """
   def __init__(self, args, refDict=None):
      self.args = args
      self.currentValue = None
      # retain source of parent class to deferntiate b/n rhythm pmtrs
      self.parent = 'parameter'
      # priority determines which pmtr objects can overide others
      self.priority = 0 # zero is nuetral, 9 is max
      # parameters must declare output
      # can be a list of multiple types if necessary
      self.outputFmt = 'num' # declare outputFmt as num by default
      # determine if this parameer is hidden from user creation
      self.hidden = 0

      if not hasattr(self, 'refDict'):
         self.refDict = refDict # dif b/n kept and shown args
      else: # update dictionary w/ new values
         self.refDict.update(refDict)
      # generator/rhythm parameter objects include name as an argument
      if not hasattr(self, 'argCountOffset'):
         self.argCountOffset = 1 # dif b/n kept and shown args
      #self.argTypes = [] # list of types, (can be list of possibilities)
      if not hasattr(self, 'argDefaults'):
         self.argDefaults = [] # optional a list of defaults that will be used
         
      self.argDemos = [] # optional list of lists of demo args
      # data needed by many parameter objects
      self.LMARGIN = ' ' * lang.LMARGINW # for spaceing extra info
      # common numerical limits
      self.FAILLIMIT = 99 # number of values tested before supplying
      self.LOOPLIMIT = 999 # number of values tested before supplying
      self.MARKOVLIMIT = 9 # limit order of markov analysis
      # store commonly used argument names and their extra documentation
      # may need to gather lists of options from other modules
      _optListTable = table.tableMonoFormatRef.keys()
      _optListTable.sort()

      # note: some of these values should be obtained from the parsers
      # defined below
      self._argNameRef = {
         'selectionString' : ['randomChoice', 'randomWalk', 'randomPermutate', 
                              'orderedCyclic', 'orderedOscillate'],
         'articulationString': ['attack', 'sustain'],
         'anchorString' : ['lower', 'upper', 'average', 'median'],
         'directionString' : ['upDown', 'downUp', 'up', 'down'],
         'onOff' : ['on', 'off'],
         'typeFormatString' : ['string', 'stringQuote'],
         'stepString' : ['event', 'time'],
         'edgeString' : ['loop', 'single'], # used for breakPoints
         'scaleString' : ['absolute', 'proportional'], # used for envelopes
         'pulseList' : ['a list of Pulse notations'],
         'pulse' : ['a single Pulse notation'],
         'tableExtractionString' : _optListTable,
      }
      # store a dummy ref dict for cases of non-time based pre-bundling
      # of sub parameter objects
      self._refDictSim = REFDICT_SIM

   def checkArgs(self):
      """used to check high-level argument issues that do not happen during
      initialization. these may include issues of value range, or matching 
      a string within an appropriate group"""
      pass

   def repr(self, format=''):
      pass
      
   def __str__(self):
      return self.repr()
      
   def _reprDemo(self):
      # manually extractin acronym like this may produce
      # acronyms that are different than those defined in parameter.py?
      msg = ['%s' % drawer.acronymExtract(self.type)]
      # goes through each arg in the list of args
      for arg in self.argDefaults:
         raw = typeset.anyDataToStr(arg)
         # strip any extra quotes provided
         raw = raw.replace('\'', '') # will be a single quote
         msg.append(raw)
      return ', '.join(msg)
      
   def _reprArgs(self, format='min'):
      """pack argument into numbered form with argument options in braces"""
      msg = []
      count = 1
      if format == 'min':
         msg.append(self.type)
      else:
         msg.append('(%s) name' % count)
      # add additional args
      if format == 'min':
         for argStr in self.argNames:
            if ':' in argStr: # can pack extra info in there with this
               argStr, argChoice = argStr.split(':')
               argStr = argStr.strip()
            msg.append(argStr)
      else:
         for argStr in self.argNames:
            if ':' in argStr: # can pack extra info in there with this
               argStr, argChoice = argStr.split(':')
               argChoice = argChoice.split(',')
            else:
               argChoice = None # room for extra documentation
            argSub = []
            count = count + 1
            argSub.append('(%s) %s' % (count, argStr))
            # see if more info is avail for this arg name
            if argStr in self._argNameRef.keys():
               argChoice = self._argNameRef[argStr]
            if argChoice != None:
               docSub = []
               if len(argChoice) == 1: # its a doc string
                  docSub.append(argChoice[0].strip())
               else:
                  for arg in argChoice:
                     arg = arg.strip()
                     if arg == '': continue
                     docSub.append("'%s'" % arg)
               argSub.append(' {%s}' % ', '.join(docSub))
            
            msg.append(''.join(argSub))
      return ', '.join(msg)
      
   def reprDoc(self, format=''):
      msg = []
      if format in ['full', '']:
         msg.append(self._reprArgs('min'))
         msg.append('\n')
         msg.append(typeset.descriptionAsStr(self.doc, '\n', 
                    self._reprArgs('max'), self._reprDemo()))
      elif format == 'paragraph':
         msg.append(typeset.descriptionAsStr(self.doc, ' ', 
                    self._reprArgs('max')))
      elif format == 'args':
         msg.append(self._reprArgs('min'))
      elif format == 'argsMax':
         msg.append(self._reprArgs('max'))
      elif format == 'list': # return a list for column presentation
         msg.append(('Description', self.doc))
         msg.append(('Arguments', self._reprArgs('max')))
         return msg # do not join
      else: # should not happen
         raise ValueError
      return ''.join(msg)
         
   def __call__(self, t=None, refDict=None):
      pass

   def reset(self):
      """reset any counters or order managers; always called before scoring"""
      pass

   def postEvent(self, eventDict, refDict):
      """do post event processing on other parameter values
      this allows a pmtr obj to modify other event values
      refDict allows the paramter to look at the current event values
      gathered form TMclass
      """
      return eventDict

   #------------------------------------------------------------------------||--
   # utility methods
   def _checkRawArgs(self):
      """checks raw arg type and number
      number of args always excludes the first string, the name of the pmtr
      will supply defaults if missing args after a point, and self.argDefaults
         defined
      """
      self.args, ok, msg = argTools.strongType(self.args, self.argTypes,
                           self.argDefaults, self.argCountOffset) 
                           # provide arg count offset as 1
      return ok, msg

   #------------------------------------------------------------------------||--
   
   def _loadSub(self, arg, lib, idStr=''):
      from athenaCL.libATH.libPmtr import parameter
      try:
         obj = parameter.factory(arg, lib)
      except error.ParameterObjectSyntaxError, msg:
         if idStr == '':
            raise error.ParameterObjectSyntaxError, 'failed sub-parameter: %s' % msg
         else:
            raise error.ParameterObjectSyntaxError, 'failed %s sub-parameter: %s' % (idStr, msg)         
      return obj
      
   def _loadAutoConstant(self, arg, lib='genPmtrObjs'):
      """take args and if a number, returns as a constant value parameterObj
      otherwise, keep as is"""
      if drawer.isNum(arg):
         pmtrArgs = ('c', arg)
      else: # its a list to create a ParameterObject
         pmtrArgs = arg         
      # create a ParameterObject
      from athenaCL.libATH.libPmtr import parameter
      try:
         obj = parameter.factory(pmtrArgs, lib)
      except error.ParameterObjectSyntaxError, msg:
         raise error.ParameterObjectSyntaxError, 'failed sub-parameter: %s' % msg
      return obj
   
   def _loadAutoConstantStr(self, arg, ref, lib='genPmtrObjs'):
      """accept a number, a list parameter object, or a string from 
      within a dfeind string group"""
#       ref = {'0' : ['tn', 't', 't n' '0'],
#             }
      if drawer.isNum(arg):
         pmtrArgs = ('c', arg)
      elif drawer.isStr(arg):
         post = drawer.selectionParse(arg, ref, 0) # autosearch off
         if post == None:
            raise error.ParameterObjectSyntaxError, 'no such preset name known.'
         pmtrArgs = ('c', post) # a constant pmtr obj
      else: # its a list to create a ParameterObject
         pmtrArgs = arg
      # create a ParameterObject
      from athenaCL.libATH.libPmtr import parameter
      try:
         obj = parameter.factory(pmtrArgs, lib)
      except error.ParameterObjectSyntaxError, msg:
         raise error.ParameterObjectSyntaxError, 'failed sub-parameter: %s' % msg
      return obj   
   
   def _loadMinMax(self, min, max):
      if drawer.isNum(min):
         minArgs = ('c', min)
      elif drawer.isList(min):
         minArgs = min
      # check max
      if drawer.isNum(max):
         maxArgs = ('c', max)
      elif drawer.isList(max):
         maxArgs = max
      # create a parameter object
      from athenaCL.libATH.libPmtr import parameter
      try:
         minObj = parameter.factory(minArgs)
      except error.ParameterObjectSyntaxError, msg:
         raise error.ParameterObjectSyntaxError, 'failed sub-parameter: %s' % msg
      try:
         maxObj = parameter.factory(maxArgs)
      except error.ParameterObjectSyntaxError, msg:
         raise error.ParameterObjectSyntaxError, 'failed sub-parameter: %s' % msg
      return minObj, maxObj


   #------------------------------------------------------------------------||--
   def _scrubList(self, data, min=None, max=None):
      """for presenting list data
      used to apply scalar to uncalculated values"""
      msg = []
      for element in data:
         if min != None and max != None:
            element = unit.denorm(element, min, max)
         msg.append(typeset.anyDataToStr(element))
      dataStr = ','.join(msg)
      return '(%s)' % dataStr

   #------------------------------------------------------------------------||--
   # string conversion
   # only place those tt are share by multiple po here
   # most of these should be converted to raise exceptions on error

   def _directionParser(self, usrStr):
      """decode direction strings; this used to have values preceded
      by 'linear; keep for backwards compat"""
      ref = {
         'upDown' : ['ud', 'lud', 'linearupdown', '0'],
         'downUp' : ['du', 'ldu', 'lineardownup', '1'],
         'up'     : ['u', 'lu', 'linearup', '2'],
         'down'   : ['d', 'ld', 'lineardown', '3'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad direction name: enter %s.' % selStr
      return usrStr
   
   def _selectorParser(self, usrStr):
      "decode control choice strings; exception on error"
      ref = {
         'randomChoice' : [ 'rc', '0'],
         'randomWalk' : ['rw'],
         'randomPermutate' : ['rp'],
         'orderedCyclic' : ['oc', '1'],
         'orderedOscillate' : ['oo'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad selectionString: enter %s.' % selStr
      return usrStr

   def _loopControlParser(self, usrStr):
      """determine if a value referes to loop (1) or single (0)"""
      ref = {
         'loop' : ['l', '1'],
         'single' : ['s', '0'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, "loop control is either %s." % selStr
      return usrStr # may be None

   def _stepControlParser(self, usrStr):
      """determine if a value refers to step (event) control (1) or
      real-time control (0)"""
      ref = {
         'event' : ['e', '1'],
         'time' : ['t', '0'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, "bad step control. enter %s." % selStr
      return usrStr # may be None
      

   def _selectLevelFrameParser(self, usrStr):
      ref = {
         'event' : ['e', '1'],
         'frame' : ['f', '0'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, "bad frame level control. enter %s." % selStr
      return usrStr # may be None


   def _boundaryParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'limit' : [ 'l'],
         'wrap' : ['w'],
         'reflect' : ['r'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)      
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, "bad boundary method. enter %s." % selStr        
      return usrStr # may be None
   
   def _onOffParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'on' : ['1'],
         'off' : ['0'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _anchorParser(self, usrStr):
      ref = {
         'lower' : ['l'],
         'upper' : ['u'],
         'average' : ['a'],
         'median' : ['m'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _scaleSwitchParser(self, usrStr):
      """determine if a value refers to absolute or proportional values"""
      ref = {
         'absolute' : ['a', '1'],
         'proportional' : ['p', '0'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, "bad step control. enter %s." % selStr
      return usrStr # may be None
      

   def _thresholdMatchParser(self, usrStr):
      ref = {
         'lower' : ['l'],
         'upper' : ['u'],
         'match' : ['m'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr


   def _valueSelectBiParser(self, usrStr):
      'xy selection'
      ref = { # automatically uses keys as case insensitive values
         'x' : [],
         'y' : [],
         'xy' : [],
         'yx' : [],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _valueSelectTriParser(self, usrStr):
      'xyz selection'
      ref = { # automatically uses keys as case insensitive values
         'x' : [],
         'y' : [],
         'z' : [],
         'xy' : [],
         'xz' : [],
         'yx' : [],
         'yz' : [],
         'zx' : [],
         'zy' : [],
         'xyz' : [],
         'xzy' : [],
         'yxz' : [],
         'yzx' : [],
         'zxy' : [],
         'zyx' : [],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

      
   def _articulationParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'attack' : ['a'],
         'sustain' : ['s'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _typeFormatParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'stringQuote' : ['sq',],
         'string'      : ['str', 's'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

      
   def _sieveFormatParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'integer' : ['i', 'int'],
         'width' : ['w', 'wid'],
         'binary' : ['b', 'bin'],
         'unit' : ['u', 'uni'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr      
      

   def _comparisonParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'equal' : ['e', '='],
         'greaterThan' : ['gt', 'g', 'greater', '>'],
         'greaterThanOrEqual' : ['gtoe', '>='],
         'lessThan' : ['lt', 'l', 'less', '<'],
         'lessThanOrEqual' : ['ltoe', '<='],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr      

   def _selectLevelMonophonicParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'event' : ['e'],
         'set' : ['s'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _selectLevelPolyphonicParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'event' : ['e'],
         'set' : ['s'],
         'voice' : ['v'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   # filter po converters needed here for backwards compat
   def _selectRetrogradeParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'off' : ['off', '0'],
         'timeInverse' : ['ti', 'tinvers'],
         'eventInverse' : ['ei', 'retro'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr

   def _selectTimeRefParser(self, usrStr):
      "decode control choice strings"
      ref = {
         'textureTime' : ['tt'],
         'cloneTime' : ['ct'],
            }
      usrStr = drawer.selectionParse(usrStr, ref)
      if usrStr == None:
         selStr = drawer.selectionParseKeyLabel(ref)
         raise error.ParameterObjectSyntaxError, 'bad control value: enter %s.' % selStr
      return usrStr
      

#-----------------------------------------------------------------||||||||||||--
# rhythm objects
class RhythmParameter(Parameter):
   """parent class of all rhythm objects; defines util methods
   all rhythm objects store a triple for currentValue
   """
   def __init__(self, args, refDict):
      Parameter.__init__(self, args, refDict) # call base init
      self.argCountOffset = 1 # dif b/n kept and shown args
      self.parent = 'rhythm' # mark as a special type
      self.currentPulse = None # init value, used in getCurrentRhythm
      self.outputFmt = 'list' # declare outputFmt as a list of data
      self.bpm = None # set in subclasses at evaluation time

# no longer needed, as can just acces the .currentPulse attribute directly
#    def getCurrentPulseObj(self):
#       return self.currentPulse


#-----------------------------------------------------------------||||||||||||--
# internal static texture parameters
class StaticParameterTexture(Parameter):
   """texture parameters are simple dictionaries of static values
   values can be switches or other static control information, perferences
   arguments are named and accessed by name"""
   def __init__(self, args, refDict):
      # note: look for first arg as type and remove
      if not drawer.isList(args): # single tuple not evaluated as list
         args = [args,] # add to list
      if args != []: # if not empty
         if args[0] == self.type:
            args = args[1:]
      Parameter.__init__(self, args, refDict) # call base init
      self.argCountOffset = 0 # dif b/n kept and shown args
      self.parent = 'textureStatic' # mark as a special type
      self.outputFmt = None # output values from dictionary
      self._switches = {} # dictionary that stores switch valuess

   def _updateSwitches(self):
      self._switches = {} # dictionary that stores switches
      i = 0
      for name in self.argNames:
         # first arg will be name of parameter object
         # but this will be removed when loading
         if ':' in name:
            name, doc = name.split(':')
            name = name.strip()
         self._switches[name] = self.args[i]
         i = i + 1

   def switch(self, name):
      # have to remove extra documentation from name
      if ':' in name:
         name, doc = name.split(':')
         name = name.strip()
      return self._switches[name]

   def repr(self, format=''):
      # why not use baesParameter representation methods here?
      msg = []
      for name in self.argNames:
         if drawer.isList(self.switch(name)):
            msg.append('%s' % self._scrubList(self.switch(name)))
         else:
            msg.append('%s' % typeset.anyDataToStr(self.switch(name)))
      if format in ['argsOnly', '']:
         msg = [self.type,] + msg
         return ', '.join(msg)
      elif format in ['noType']:
         return ', '.join(msg)

   def getArgs(self):
      """get complete arg list used to build this object"""
      args = []
      for name in self.argNames:
         args.append(self.switch(name))
      # prepend name of arg
      args = [self.type,] + args
      return tuple(args) # tuple is just by convention

   def getArgsLabel(self):
      """returns a string of the pmtr name and arg value names"""
      msg = []
      msg.append(self.type) # add name string
      msg = msg + self.argNames # add arg names
      return drawer.listScrub(msg, None, 'rmQuote')

   def __call__(self, name):
      """simply treturn the data
      can access as numbered steps in arg list, starting at 0"""
      if drawer.isInt(name): # if number, make into string name
         name = self.argNames[name]
      return self.switch(name)

#-----------------------------------------------------------------||||||||||||--
# internal statuc clone parameters
class StaticParameterClone(StaticParameterTexture):
   """just like texture static parameter objects, except for clonse"""
   def __init__(self, args, refDict):
      StaticParameterTexture.__init__(self, args, refDict) # call base init
      self.parent = 'cloneStatic' # mark as a special type

#-----------------------------------------------------------------||||||||||||--
# internal static texture parameters
class FilterParameter(Parameter):
   """filter parameters operate like filters
   filter parameters operate on an array of values from the eventSequence
   they cannot be run in real-time, as they require all values present
   cloneFilter's also have an input fmt to determine compatibility
   w/ various aux pmtrs that may use strings

   both general purpose and rhythm parameter objects can 
   be used (rhythm parameter objects on return use the dur value to change
   offsets, while sustain is a separate parameter for clonse)
   """
   def __init__(self, args, refDict):
      Parameter.__init__(self, args, refDict) # call base init
      self.parent = 'cloneFilter' # mark as a special type
      self.outputFmt = None # output values from dictionary
      self.inputFmt = ('num', 'str') # declare input as num by default
      self.argCountOffset = 1 # dif b/n kept and shown args

   def __call__(self, valueArray, tArray=None, refDictArray=None):
      """refDict here is created in clone score method by taking data
      from the esObj, simulating compatibility w/ general pmtr objects"""
      pass



#-----------------------------------------------------------------||||||||||||--
# provide utility functions from Parameter class
# only used in ioTools for backwards compat with pickled data structs

def selectorParser(str):
   obj = Parameter(None)
   return obj._selectorParser(str)

def directionParser(str):
   obj = Parameter(None)
   return obj._directionParser(str)

# used for backwards compat of old clones
def retrogradeParser(str):
   obj = Parameter(None)
   try:
      return obj._selectRetrogradeParser(str)
   except error.ParameterObjectSyntaxError:
      return 'off'





#-----------------------------------------------------------------||||||||||||--
# test just selector here

def Test():
   colTest = [[3,2,54], ['test'], ['234', 56, 'dfg', 3], [100,200], range(0,20)]
   for col in colTest:
      for control in ['randomChoice', 'randomWalk', 'randomPermutate',
                      'orderedCyclic', 'orderedOscillate']:
         print _MOD, 'selector test:', control, col
         a = Selector(col, control)
         print [a() for x in range(10)]
         newCol = random.choice(colTest)
         a.update(newCol)
         print _MOD, 'selector test: post update', control, newCol
         print [a() for x in range(10)]
         a.reset()
         print [a() for x in range(10)]
         print


if __name__ == '__main__':
   Test()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.