Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Framework/Core/EventPlayer.py
diff options
context:
space:
mode:
authorjames <james@loggerhead.localdomain>2006-09-19 00:10:44 (GMT)
committer james <james@loggerhead.localdomain>2006-09-19 00:10:44 (GMT)
commitd54497ae703d61c640ae549fc4502f3c24bddf21 (patch)
treef3f9dc06f2cd38b25b0841f1ce8224fde2a00477 /Framework/Core/EventPlayer.py
parentd48ab76d753ba0dda8fb513675fb26bc965ef0c0 (diff)
Slow-timer-based event loop
Diffstat (limited to 'Framework/Core/EventPlayer.py')
-rwxr-xr-xFramework/Core/EventPlayer.py90
1 files changed, 73 insertions, 17 deletions
diff --git a/Framework/Core/EventPlayer.py b/Framework/Core/EventPlayer.py
index 6f5fffc..2e2b7f7 100755
--- a/Framework/Core/EventPlayer.py
+++ b/Framework/Core/EventPlayer.py
@@ -1,10 +1,16 @@
+import pickle
+import time
+
import pygtk
pygtk.require( '2.0' )
import gtk
import gobject
+import math
+
from Framework.Constants import Constants
from Framework.CSound.CSoundNote import CSoundNote
+from Framework.CSound.CSoundClient import CSoundClient
#------------------------------------------------------------------------------
# A base class used to play a collection of Events at their respective onsets
@@ -15,12 +21,20 @@ class EventPlayer:
#-----------------------------------
def __init__( self ):
+ self.time0 = 0
+ self.horizonDelay = Constants.CSOUND_HORIZON
+ self.horizonTime = 0
+ self.horizonOnset = 0
+
+ self.clockDelay = Constants.CLOCK_DELAY
self.eventDictionary = {}
- self.playbackTimeout = None
+
self.currentTick = 0
+
+ self.playbackTimeout = None
self.tempo = Constants.DEFAULT_TEMPO
-
- CSoundNote.getTempoCallback = self.getTempo
+
+ self.send_buffer = ""
def getCurrentTick(self):
return self.currentTick
@@ -35,32 +49,74 @@ class EventPlayer:
return self.playbackTimeout != None
def startPlayback( self ):
- msPerTick = Constants.MS_PER_MINUTE / self.tempo / Constants.TICKS_PER_BEAT
+ self.time0 = time.time()
+ self.horizonTime = 0.0
+ self.horizonOnset = 0
#schedule the handler...
- self.playbackTimeout = gobject.timeout_add( msPerTick, self.handlePlayTick )
+ self.playbackTimeout = gobject.timeout_add( int ( 1000 * self.clockDelay) , self.handleClock )
#and call it right away too.
- self.handlePlayTick()
+ self.handleClock()
def stopPlayback( self ):
if self.playbackTimeout != None:
gobject.source_remove( self.playbackTimeout )
self.playbackTimeout = None
- def play( self, onset ):
- if self.eventDictionary.has_key( onset ):
- for event in self.eventDictionary[ onset ]:
- event.play()
+ # this will happen
+ def handleClock( self ) :
+ def onsetCommand( onset, tempo, delay ):
+ rval = ""
+ if self.eventDictionary.has_key( onset ):
+ for event in self.eventDictionary[ onset ]:
+ rval += event.getText( tempo, delay)
+ return rval
- def handlePlayTick( self ):
- self.play( self.currentTick )
-
- self.currentTick += 1
- self.hookTick( )
-
+ onsetPerSecond = self.tempo / 60.0 * Constants.TICKS_PER_BEAT
+
+ nowTime = time.time() - self.time0
+
+ nextTime = self.horizonTime
+ nextOnset = self.horizonOnset
+ horizonTime = nowTime + self.horizonDelay
+ self.horizonOnset = int( horizonTime * onsetPerSecond )
+ self.horizonTime = self.horizonOnset * onsetPerSecond
+
+ self.send_buffer = ""
+ for i in range( nextOnset, self.horizonOnset ) :
+ self.delay = i / onsetPerSecond - nowTime
+ if (self.delay > 0.0 ) :
+ ev = self.eventDictionary
+ self.hookTick( ) # may modify currentTick, eventDictionary
+ self.send_buffer += onsetCommand( self.currentTick, self.tempo, self.delay )
+ self.currentTick = self.currentTick + 1
+ else :
+ print 'WARNING: excessive latency... dropping note with delay %f' % self.delay
+
+ if self.send_buffer != "" :
+ CSoundClient.sendText( self.send_buffer )
+
+ self.hookClock()
return True
- def hookTick( self ) :
+ #this is meant to handle things that happen once per clock... like the GUI
+ def hookClock( self ) :
+ pass
+ # this is meant to be overridden by things that need to happen on every onset
+ def hookTick( self ) :
pass
+
+ #
+ # serialization
+ #
+ VERSION = '_testing_'
+ def serialize(self, f):
+ pickle.dump( self.VERSION, f)
+ pickle.dump( self.tempo, f )
+
+ def unserialize(self, f):
+ if pickle.load( f ) != self.VERSION :
+ raise WrongVersionError
+ self.tempo = pickle.load( f )
#-----------------------------------
# add/remove event functions (event(s) must be Event instances)