Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Util
diff options
context:
space:
mode:
Diffstat (limited to 'Util')
-rw-r--r--Util/CSoundClient.py8
-rw-r--r--[-rwxr-xr-x]Util/CSoundNote.py137
-rw-r--r--Util/NoteLooper.py71
3 files changed, 85 insertions, 131 deletions
diff --git a/Util/CSoundClient.py b/Util/CSoundClient.py
index b72ce92..a0bee81 100644
--- a/Util/CSoundClient.py
+++ b/Util/CSoundClient.py
@@ -25,8 +25,8 @@ class CSoundClientBase:
def load_instruments( self ):
for instrumentSoundFile in Config.INSTRUMENTS.keys():
fileName = Config.SOUNDS_DIR + "/" + instrumentSoundFile
- instrumentID = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentID
- mess = Config.LOAD_INSTRUMENT_COMMAND % ( instrumentID, fileName )
+ instrumentId = Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ instrumentSoundFile ].instrumentId
+ mess = Config.LOAD_INSTRUMENT_COMMAND % ( instrumentId, fileName )
self.sendText( mess )
def startTime(self):
@@ -47,8 +47,8 @@ class CSoundClientBase:
class CSoundClientSocket( CSoundClientBase ):
- def __init__( self, serverAddress, serverPort, clientID ):
- self.clientID = clientID
+ def __init__( self, serverAddress, serverPort, clientId ):
+ self.clientId = clientId
self.serverInfo = ( serverAddress, serverPort )
self.connected = False
diff --git a/Util/CSoundNote.py b/Util/CSoundNote.py
index 168d267..2632b45 100755..100644
--- a/Util/CSoundNote.py
+++ b/Util/CSoundNote.py
@@ -1,62 +1,35 @@
import Config
from Util.CSoundClient import CSoundClient
from Generation.GenerationConstants import GenerationConstants
-#----------------------------------------------------------------------
-# TODO: extend this hierarchy to include a Note base class
-# i.e. Event -> Note -> CSoundNote
-# most classes should only deal with Events and Notes,
-# and not CSoundNotes
-#----------------------------------------------------------------------
-#----------------------------------------------------------------------
-# An Event subclass that represents a CSound note event
-#----------------------------------------------------------------------
-class Event:
+class CSoundNote :
#-----------------------------------
# initialization
#-----------------------------------
- def __init__( self, onset ):
- self.onset = onset
-
- #-----------------------------------
- # playback (must be implemented by subclasses)
- #-----------------------------------
- def play( self ):
- raise NotImplementedError
-
- #-----------------------------------
- # adjustment
- #-----------------------------------
- def adjustOnset( self, amount ):
- self.onset += amount
-class CSoundNote( Event ):
- #-----------------------------------
- # initialization
- #-----------------------------------
- def __init__( self, onset,
- pitch,
- amplitude,
- pan,
- duration,
- trackID,
- fullDuration = False,
- instrument = Config.FLUTE,
- attack = 0.002,
- decay = 0.098,
- reverbSend = 0.1,
- filterType = 0,
- filterCutoff = 1000,
- tied = False,
- overlap = False,
- instrumentFlag = Config.FLUTE ):
- Event.__init__( self, onset )
+ def __init__( self,
+ onset,
+ pitch,
+ amplitude,
+ pan,
+ duration,
+ trackId,
+ fullDuration = False,
+ instrument = Config.FLUTE,
+ attack = 0.002,
+ decay = 0.098,
+ reverbSend = 0.1,
+ filterType = 0,
+ filterCutoff = 1000,
+ tied = False,
+ overlap = False,
+ instrumentFlag = Config.FLUTE ):
self.onset = onset
self.pitch = pitch
self.amplitude = amplitude
self.pan = pan
self.duration = duration
- self.trackID = trackID
+ self.trackId = trackId
self.instrument = instrument
self.fullDuration = fullDuration
self.attack = attack
@@ -72,11 +45,12 @@ class CSoundNote( Event ):
self.instrumentFlag = self.instrument
def __getstate__(self):
- return {'pitch': self.pitch,
+ return {'onset': self.onset,
+ 'pitch': self.pitch,
'amplitude': self.amplitude,
'pan': self.pan,
'duration': self.duration,
- 'trackID': self.trackID,
+ 'trackId': self.trackId,
'instrument': self.instrument,
'fullDuration': self.fullDuration,
'attack': self.attack,
@@ -84,18 +58,17 @@ class CSoundNote( Event ):
'reverbSend': self.reverbSend,
'filterType': self.filterType,
'filterCutoff': self.filterCutoff,
- 'onset': self.onset,
'tied': self.tied,
'overlap': self.overlap,
'instrumentFlag': self.instrumentFlag }
def __setstate__(self,dict):
- Event.__init__(self, dict['onset'])
+ self.onset = dict['onset']
self.pitch = dict['pitch']
self.amplitude = dict['amplitude']
self.pan = dict['pan']
self.duration = dict['duration']
- self.trackID = dict['trackID']
+ self.trackId = dict['trackId']
self.instrument = dict['instrument']
self.fullDuration = dict['fullDuration']
self.attack = dict['attack']
@@ -109,16 +82,13 @@ class CSoundNote( Event ):
def clone( self ):
return CSoundNote( self.onset, self.pitch, self.amplitude, self.pan,
- self.duration, self.trackID, self.fullDuration, self.instrument,
+ self.duration, self.trackId, self.fullDuration, self.instrument,
self.attack, self.decay, self.reverbSend, self.filterType, self.filterCutoff, self.tied, self.overlap, self.instrumentFlag )
- def play( self ):
- CSoundClient.sendText( self.getText(120, 0) )
-
- def getText( self, tempo, delay ):
+ def getText( self, secs_per_tick, delay ):
+ if secs_per_tick > 1 : raise 'invalid secs_per_tick'
if self.instrument == 'drum1kit':
if GenerationConstants.DRUMPITCH.has_key( self.pitch ):
- print self.pitch
self.pitch = GenerationConstants.DRUMPITCH[ self.pitch ]
self.instrumentFlag = Config.DRUM1INSTRUMENTS[ self.pitch ]
@@ -127,19 +97,17 @@ class CSoundNote( Event ):
self.instrumentFlag = self.instrument
newPitch = pow( GenerationConstants.TWO_ROOT_TWELVE, self.pitch - 36 )
- oneTickDuration = (Constants.MS_PER_MINUTE / 1000) / tempo / Constants.TICKS_PER_BEAT
-
- newDuration = oneTickDuration * self.duration
+ newDuration = secs_per_tick * self.duration
# condition for tied notes
- if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentID == 101 and self.tied and self.fullDuration:
+ if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId == 101 and self.tied and self.fullDuration:
newDuration = -1
# condition for overlaped notes
- if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentID == 102 and self.overlap:
+ if Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId == 102 and self.overlap:
newDuration = oneTickDuration * self.duration + 1.
if True: newAmplitude = self.amplitude * 0.8
- else : newAmplitude = self.amplitude * music_volume_get( self.trackID )
+ else : newAmplitude = self.amplitude * music_volume_get( self.trackId )
newAttack = newDuration * self.attack
if newAttack <= 0.002:
@@ -149,29 +117,20 @@ class CSoundNote( Event ):
if newDecay <= 0.002:
newDecay = 0.002
- return Config.PLAY_NOTE_COMMAND % ( Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentID,
- self.trackID,
- delay,
- newDuration,
- newPitch,
- self.reverbSend,
- newAmplitude,
- self.pan,
- Config.INSTRUMENT_TABLE_OFFSET + Config.INSTRUMENTS[ self.instrumentFlag ].instrumentID,
- newAttack,
- newDecay,
- self.filterType,
- self.filterCutoff )
-
- #-----------------------------------
- # adjustment functions
- #-----------------------------------
- def adjustDuration( self, amount ):
- self.duration += amount
-
- def adjustAmplitude( self, amount ):
- self.amplitude += amount
-
- def adjustPitch( self, amount ):
- self.pitch += amount
-
+ return Config.PLAY_NOTE_COMMAND % ( \
+ Config.INSTRUMENTS[ self.instrumentFlag ].csoundInstrumentId,
+ self.trackId,
+ delay,
+ newDuration,
+ newPitch,
+ self.reverbSend,
+ newAmplitude,
+ self.pan,
+ Config.INSTRUMENT_TABLE_OFFSET+Config.INSTRUMENTS[self.instrumentFlag].instrumentId,
+ newAttack,
+ newDecay,
+ self.filterType,
+ self.filterCutoff,
+ Config.INSTRUMENTS[ self.instrumentFlag ].loopStart,
+ Config.INSTRUMENTS[ self.instrumentFlag ].loopEnd,
+ Config.INSTRUMENTS[ self.instrumentFlag ].crossDur )
diff --git a/Util/NoteLooper.py b/Util/NoteLooper.py
index 5f1f94f..bcb8e4a 100644
--- a/Util/NoteLooper.py
+++ b/Util/NoteLooper.py
@@ -8,8 +8,8 @@ import gtk
import gobject
import Config
+from Util.CSoundNote import CSoundNote #maybe not actually used, but dependence is there. All notes are assumed to be CSoundNotes
from Generation.GenerationConstants import GenerationConstants
-from Util.Profiler import TP
#------------------------------------------------------------------------------
# A base class used to play a collection of Events at their respective onsets
@@ -22,25 +22,18 @@ class NoteLooper:
def dirty_track(self, track):
for i in range(len(self.notes)):
(o,n,c) = self.notes[i]
- if n['trackId'] == track:
+ if n.trackId == track:
self.notes[i] = (o,n,'')
#PUBLIC
- def __init__( self, range_sec, ticks_per_sec, inst, tvol, mute ):
+ def __init__( self, range_sec, ticks_per_sec ):
self.ticks_per_sec = ticks_per_sec # ticks last this long
self.secs_per_tick = 1.0 / ticks_per_sec # precomputed inverse
self.range_sec = range_sec # notes are checked-for, this many seconds in advance
self.range_tick = int( range_sec * ticks_per_sec ) # same, but in ticks
- self.inst = inst # instrument for each track
- self.tvol = tvol # volume for each track
- self.mute = mute # pre-amp for track volume
-
- if len(inst) != len(tvol): print 'ERROR: NoteLooper::__init__() invalid args'
- if len(inst) != len(mute): print 'ERROR: NoteLooper::__init__() invalid args'
-
self.duration = 0 # number of ticks in playback loop
self.prev_duration = 0
self.notes = [] # sorted list of (onset, noteptr, cache)
@@ -75,20 +68,6 @@ class NoteLooper:
if domod : return ( self.tick0 + int( ( t + future - self.time0 ) * self.ticks_per_sec ) ) % self.duration
else : return ( self.tick0 + int( ( t + future - self.time0 ) * self.ticks_per_sec ) )
- def setVolume(self, track,vol):
- if self.tvol[track] != vol:
- self.tvol[track] = vol
- self.dirty_track(track)
-
- def setInstrument(self, track, inst):
- if self.inst[track] != inst:
- self.inst[track] = inst
- self.dirty_track(track)
- def setMute(self, track, m):
- if self.mute[track] != m:
- self.mute[track] = m
- self.dirty_track(track)
-
def next( self ) :
time_time = time.time()
tickhorizon = self.getCurrentTick( self.range_sec, False, time_time ) #tick where we'll be after range_sec
@@ -136,20 +115,20 @@ class NoteLooper:
if cache == '' :
self.notes[i] = ( onset, note,
cache_cmd( secs_per_tick,
- note['amplitude'] * self.tvol[note['trackId']] * self.mute[note['trackId']],
- note['pitch'],
- note['instrumentFlag'],
- note['trackId'],
- note['duration'] * self.secs_per_tick,
- note['tied'],
- note['fullDuration'],
- note['overlap'],
- note['attack'],
- note['decay'],
- note['reverbSend'],
- note['filterType'],
- note['filterCutoff'],
- note['pan']))
+ note.amplitude * self.tvol[note.trackId] * self.mute[note.trackId],
+ note.pitch,
+ note.instrumentFlag,
+ note.trackId,
+ note.duration * self.secs_per_tick,
+ note.tied,
+ note.fullDuration,
+ note.overlap,
+ note.attack,
+ note.decay,
+ note.reverbSend,
+ note.filterType,
+ note.filterCutoff,
+ note.pan))
rval = self.notes[i][2] % float(onset * self.secs_per_tick + time_offset)
return rval
@@ -223,3 +202,19 @@ class NoteLooper:
self.notes = []
+ def setVolume(self, track,vol):
+ raise 'dont call'
+ if self.tvol[track] != vol:
+ self.tvol[track] = vol
+ self.dirty_track(track)
+ def setInstrument(self, track, inst):
+ raise 'dont call'
+ if self.inst[track] != inst:
+ self.inst[track] = inst
+ self.dirty_track(track)
+ def setMute(self, track, m):
+ raise 'dont call'
+ if self.mute[track] != m:
+ self.mute[track] = m
+ self.dirty_track(track)
+