# --- UCSF Chimera Copyright --- # Copyright (c) 2000 Regents of the University of California. # All rights reserved. This software provided pursuant to a # license agreement containing restrictions on its disclosure, # duplication and use. This notice must be embedded in or # attached to all copies, including partial copies, of the # software or any revisions or derivations thereof. # --- UCSF Chimera Copyright --- import Compound try: import Midi except ImportError: import FakeMidi Midi = FakeMidi class HearResults(Compound.Results): def __init__(self, *args, **kw): Compound.Results.__init__(self, *args, **kw) # # calculate min and max values of fields # self.fieldLimits = {} for f in self.fields: minV = None maxV = None for c in self.compoundList: try: v = c.fields[f] except KeyError: continue if not isinstance(v, (int, float)): continue if minV is None or c.fields[f] < minV: minV = c.fields[f] if maxV is None or c.fields[f] > maxV: maxV = c.fields[f] if minV is not None \ and maxV is not None \ and minV < maxV: self.fieldLimits[f] = (minV, maxV) self.sonifyFields = self.fieldLimits.keys() # # check for external Midi Synth # try: self.midi = Midi.Output("Serial Port 2") except: self.midi = Midi.Output("Software Synth") #self.midi = Midi.Output("Software Synth") self.stopNotes = [] def setSonify(self, sonify): self.sonify = sonify def movieStep(self, listbox): self._stopNotes() if not Compound.Results.movieStep(self, listbox): return None next = self.selected[0] for f in self.fields: p = self.sonify.parameters(f) if p is None: continue try: v = next.fields[f] except KeyError: continue instr, channel, minP, maxP, \ alarmMode, minAlarm, maxAlarm = p minV, maxV = self.fieldLimits[f] if instr == None or maxV <= minV: continue if alarmMode == 0 \ or (minAlarm is not None and v < minAlarm) \ or (maxAlarm is not None and v > maxAlarm): range = float(maxV - minV) frac = (v - minV) / range note = int(frac * (maxP - minP) + minP) self.midi.noteOn(channel, note, 127) self.stopNotes.append((channel, note, 30)) return 1 def movieStop(self): Compound.Results.movieStop(self) self._stopNotes() def _stopNotes(self): if not self.stopNotes: return for args in self.stopNotes: apply(self.midi.noteOff, args) self.stopNotes = []