generalMidi.py :  » Media-Sound-Audio » athenaCL » athenaCL » libATH » libOrc » 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 » libOrc » generalMidi.py
#!/usr/local/bin/python
#-----------------------------------------------------------------||||||||||||--
# Name:         generalMidi.py
# Purpose:      generalMidi instrument definitions.
#
# Authors:      Christopher Ariza
#
# Copyright:    (c) 2001-2005 Christopher Ariza
# License:      GPL
#-----------------------------------------------------------------||||||||||||--

from athenaCL.libATH.libOrc import baseOrc
from athenaCL.libATH import pitchTools
from athenaCL.libATH import drawer

_MOD = 'generalMidi.py'

#-----------------------------------------------------------------||||||||||||--

gmProgramNames = {'piano1':0, 'piano2':1, 'piano3':2,
    'honkyTonkPiano':3, 'rhodesPiano':4, 'ePiano':5,
    'harpsichord':6, 'clavinet':7, 'celesta':8, 'glockenspiel':9,
    'musicBox':10, 'vibraphone':11, 'marimba':12, 'xylophone':13,
    'tubularBells':14, 'santur':15, 'organ1':16, 'organ2':17,
    'organ3':18,    'churchOrgan':19, 'reedOrgan':20,
    'accordion':21, 'harmonica':22, 'bandoneon':23,
    'nylonGuitar':24, 'steelGuitar':25, 'jazzGuitar':26,
    'cleanGuitar':27, 'mutedGuitar':28, 'overDriveGuitar':29,
    'distortonGuitar':30, 'guitarHarmonics':31, 'acousticBass':32,
    'fingeredBass':33, 'pickedBass':34, 'fretlessBass':35,
    'slapBass1':36,  'slapBass2':37, 'synthBass1':38,
    'synthBass2':39, 'violin':40, 'viola':41, 'cello':42,
    'contraBass':43, 'tremoloStrings':44, 'pizzicatoStrings':45,
    'orchestralHarp':46, 'timpani':47, 'strings':48,
    'slowStrings':49, 'synthStrings1':50, 'synthStrings2':51,
    'choirAahs':52, 'voiceOohs':53, 'synthVox':54,
    'orchestraHit':55, 'trumpet':56, 'trombone':57, 'tuba':58,
    'mutedTrumpet':59, 'frenchHorn':60, 'brassSection':61,
    'synthBrass1':62, 'synthBrass2':63, 'sopranoSax':64,
    'altoSax':65,     'tenorSax':66, 'baritoneSax':67, 'oboe':68,
    'englishHorn':69, 'bassoon':70,  'clarinet':71, 'piccolo':72,
    'flute':73, 'recorder':74, 'panFlute':75, 'bottleBlow':76,
    'shakuhachi':77, 'whistle':78, 'ocarina':79, 'squareWave':80,
    'sawWave':81, 'synCalliope':82, 'chifferLead':83,
    'charang':84, 'soloVoice':85,  '5thSawWave':86, 'bassAndLead':87,
    'fantasia':88,   'warmPad':89, 'polySynth':90, 'spaceVoice':91,
    'bowedGlass':92, 'metalPad':93, 'haloPad':94, 'sweepPad':95,
    'iceRain':96, 'soundTrack':97,  'crystal':98, 'atmosphere':99,
    'brightness':100, 'goblins':101, 'echoDrops':102,
    'starTheme':103,  'sitar':104, 'banjo':105, 'shamisen':106,
    'koto':107,   'kalimba':108,   'bagpipe':109, 'fiddle':110,
    'shanai':111, 'tinkleBell':112, 'agogoBells':113,
    'steelDrums':114,  'woodBlock':115, 'taikoDrum':116,
    'melodicTom1':117, 'synthDrum':118, 'reverseCymbal':119,
    'guitarFretnoise':120, 'breathNoise':121, 'seaShore':122,
    'birdTweet':123, 'telephoneRing':124, 'helicopterBlade':125,
    'applauseNoise':126, 'gunShot':127 }

# perc on ch 10; name to midi note number
gmPercussionNames = {'acousticBassDrum':35, 'bassDrum1':36, 'sideStick':37, 'acousticSnare':38, 'handClap':39, 'electricSnare':40, 'lowFloorTom':41,
'closedHiHat':42, 'highFloorTom':43, 'pedalHiHat':44, 'lowTom':45, 'openHiHat':46, 'lowMidTom':47, 'hiMidTom':48, 'crashCymbal1':49, 'highTom':50, 'rideCymbal1':51, 'chineseCymbal':52, 'rideBell':53, 'tambourine':54, 'splashCymbal':55, 'cowBell':56, 'crashCymbal2':57, 'vibraSlap':58, 'rideCymbal2':59, 'hiBongo':60, 'lowBongo':61, 'muteHiConga':62, 'openHiConga':63, 'lowConga':64, 'highTimbale':65, 'lowTimbale':66, 'highAgogo':67, 'lowAgogo':68, 'cabasa':69, 'maracas':70, 'shortWhistle':71, 'longWhistle':72, 'shortGuiro':73, 'longGuiro':74, 'claves':75, 'hiWoodBlock':76, 'lowWoodBlock':77, 'muteCuica':78, 'openCuica':79, 'muteTriangle':80, 'openTriangle':81,   
}

#-----------------------------------------------------------------||||||||||||--
# access utilities
def getPgmName(pgmNum):
   pgmNum = int(pgmNum)
   if pgmNum < 0: pgmNum = 0
   if pgmNum > 127:
      pgmName = 'unknown'
   else:
      for name, num in gmProgramNames.items():
         if num == pgmNum:
            pgmName = name
            break
   return pgmName

def getPgmNumber(usrStr):
   if usrStr == '': return None
   try:
      numVal = int(usrStr)
   except (ValueError, TypeError):
      numVal = -1
   if numVal >= 0: # its a number, try to use
      return getPgmName(numVal), numVal
   # its a string
   usrStr = drawer.strScrub(usrStr, 'L')
   scoreDict = {}
   for name in gmProgramNames.keys():
      nameTest = name.lower()
      scoreDict[name] = nameTest.count(usrStr) # counts instances
   best = ('', 0) # name, score
   # go basck over items; name does have case
   for name, score in scoreDict.items():
      if score > best[1]:
         best = (name, score)
   if best[0] == '': # nothing found
      return None
   else:
      return best[0], gmProgramNames[best[0]] # name, pgmNum


def getPercNameFromNoteName(usrStr):
   """get perc name from midi note number
   nameStr can be a string (psName) or number (midiNote number)
   """
   if drawer.isStr(usrStr):
      psInt = pitchTools.psNameToPs(usrStr)
      midiInt = pitchTools.psToMidi(psInt)
   else:
      midiInt = int(usrStr)
   # normalize bad values  
   if midiInt < 35: midiInt = 35
   if midiInt > 81: midiInt = 81
   else:
      for name, num in gmPercussionNames.items():
         if num == midiInt:
            percName = name
            break
   return percName

def getNoteNameFromPercName(percStr):
   "for a given percussion name, find what note name is needed"
   foundName = None
   percStr = drawer.strScrub(percStr, 'L')
   for name in gmPercussionNames.keys():
      if percStr == name.lower():
         foundName = name
         break
   if foundName == None: # check again for partial matches
      for name in gmPercussionNames.keys():
         name = name.lower()
         if name.find(percStr) >= 0:
            foundName = name
            break
   if foundName == None:
      print _MOD, 'cant find:', percStr
   midiInt = gmPercussionNames[foundName]
   noteName = pitchTools.midiToNoteName(midiInt)
   return noteName # may be None on error






#-----------------------------------------------------------------||||||||||||--
#-----------------------------------------------------------------||||||||||||--
# object models

class GeneralMidi(baseOrc.Orchestra):
   """gm midi instruments"""

   def __init__(self):
      baseOrc.Orchestra.__init__(self)
      self.name = 'generalMidi'
      self._dummyInst = InstrumentMidi()
      self._instrNumbers = range(0, 128) # 127 program numbers

   def instNoValid(self, iNo):
      """test if an instrument number is valid"""
      if drawer.isInt(iNo) and iNo in self._instrNumbers: return 1
      else: return 0

   def instNoList(self, format=None):
      """return a list of instrument numbers; if
      a list is not availabe, return None"""
      if format == 'user':
         return drawer.listToStr(self._instrNumbers)
      return self._instrNumbers
      
   def constructOrc(self, noCh=None, instList=None):
      """nothing to do here"""
      return None

   def getInstInfo(self, iNo=None):
      """returns a dictionary of instrNo : (Name, pNo, pInfo)
      has data for all instruments
      pmtrFields includes 6 default values
      """
      if iNo == None:
         instrList = self._instrNumbers
      else:
         instrList = [iNo,]
      instInfoDict = {}
      for number in instrList:
         instInfoDict[number] = (getPgmName(number), 
                                 self._dummyInst.pmtrFields, # always 6
                                 self._dummyInst.pmtrInfo) # always empty
      return instInfoDict, instrList

   def getInstPreset(self, iNo, auxNo=None):
      return self._dummyInst.getPresetDict() # will returns empty dict

   def getInstName(self, iNo):
      return getPgmName(iNo)

   def getInstAuxNo(self, iNo):
      return self._dummyInst.auxNo
      
   def getInstPmtrInfo(self, iNo, pmtrNo):
      """for specified inst, pmtrNo, return pmtr info"""
      # midi inst have no additional parameter information
      return 'no information available'      

   #------------------------------------------------------------------------||--
   # mappings of psReal, amp, pan; only applied of mix mode is on
   def _postMapPs(self, iNo, val): # alwasy map pitch
      # pitchtools limit will automatically constrain min/max as well
      # this rounds floating point values to integers
      val = pitchTools.psToMidi(val, 'limit')
      # always limit max values
      if val < 0: val = 0
      if val > 127: val = 127
      return val
      
   # pre 1.3 csoundNative files will have amps mostly in the range of
   # 0 to 80, so this will work; sample insturuments, however, have 
   # much lower amplitudes      
   def _postMapAmp(self, iNo, val, orcMapMode=1): # values between 0 and 1
      if orcMapMode: # optional map
         # does not seem necessary to use 127; seems to peak
         val = int(round(val * 124.0))
      else: # take raw value as int
         val = int(round(val))
      # always limit
      if val < 0: val = 0
      if val > 127: val = 127
      return val
      
   def _postMapPan(self, iNo, val, orcMapMode=1):
      if orcMapMode: # optional map
         val = int(round(val * 127.0))
      else: # must be an int
         val = int(round(val))
      # always limit
      # do modulus rotation on pan values
      if val < 0 or val > 127: 
         val = val % 127
      return val      

#-----------------------------------------------------------------||||||||||||--
class GeneralMidiPercussion(GeneralMidi):
   """percussion as subclass of gm
   compatible w/ gm; only difference is instruments made available
   this distincition is important when used in an eventMode, to select ints
   not important when used in an engine to process values"""
   def __init__(self):
      GeneralMidi.__init__(self)
      self.name = 'generalMidiPercussion'
      self._dummyInst = InstrumentMidi()
      # instrument numbers are the pitch values
      self._instrNumbers = range(35, 82) # 35-81 program numbers

   def getInstName(self, iNo):
      """over-ride from gm, as gotten from different dictionary"""
      return getPercNameFromNoteName(iNo)

   def getInstInfo(self, iNo=None):
      """returns a dictionary of instrNo : (Name, pNo, pInfo)
      has data for all instruments
      pmtrFields includes 6 default values
      """
      if iNo == None:
         instrList = self._instrNumbers
      else:
         instrList = [iNo,]
      instInfoDict = {}
      for number in instrList:
         instInfoDict[number] = (getPercNameFromNoteName(number), 
                                 self._dummyInst.pmtrFields, # always 6
                                 self._dummyInst.pmtrInfo) # always empty
      return instInfoDict, instrList


      
#-----------------------------------------------------------------||||||||||||--
# one instrument object for all midi insts, general and perc
class InstrumentMidi(baseOrc.Instrument):
   def __init__(self):
      baseOrc.Instrument.__init__(self)
      self.pmtrDefault = {} # no default for midi instruments
      self.pmtrInfo = {}
      self.pmtrFields = self.pmtrCountDefault
      self.auxNo = 0
      self.pmtrFields = self.pmtrCountDefault + self.auxNo
      # pan and amp ranges are b/n 0 and 127
      # for all instruments
      self.postMapAmp = (0,127, 'linear') 
      self.postMapPan = (0,127, 'linear') 
      
      
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.