Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Config.py5
-rw-r--r--Jam/Block.py134
-rw-r--r--Jam/Desktop.py24
-rw-r--r--Jam/Fillin.py10
-rw-r--r--Jam/JamMain.py154
-rw-r--r--Jam/Picker.py10
-rw-r--r--Jam/Toolbars.py24
-rw-r--r--Resources/Desktops/desktop01
-rw-r--r--Resources/Desktops/desktop12
-rw-r--r--Resources/Desktops/desktop23
-rw-r--r--Resources/Desktops/desktop34
-rw-r--r--Resources/Desktops/desktop45
-rw-r--r--Resources/Desktops/desktop56
-rw-r--r--Resources/Desktops/desktop67
-rw-r--r--Resources/Desktops/desktop78
-rw-r--r--Resources/Desktops/desktop89
-rw-r--r--Resources/Desktops/desktop910
-rw-r--r--Resources/Loops/loop1.ttl4
-rw-r--r--Resources/Loops/loop2.ttl4
-rw-r--r--Resources/Loops/loop3.ttl4
-rwxr-xr-xTamTam.py14
-rw-r--r--Util/ControlStream.py97
-rw-r--r--Util/NoteDB.py16
23 files changed, 441 insertions, 114 deletions
diff --git a/Config.py b/Config.py
index 4743088..230b7cb 100644
--- a/Config.py
+++ b/Config.py
@@ -26,6 +26,11 @@ print 'INFO: loaded TAMTAM_ROOT=%s' % TAM_TAM_ROOT
#PATHS
+SCRATCH_DIR = TAM_TAM_ROOT + "/.scratch/"
+try: # can't add .scratch to git for some reason so make sure it exists here
+ os.mkdir( SCRATCH_DIR )
+except:
+ pass
SOUNDS_DIR = TAM_TAM_ROOT + "/Resources/Sounds"
FILES_DIR = TAM_TAM_ROOT + "/Resources"
TUNE_DIR='/'
diff --git a/Jam/Block.py b/Jam/Block.py
index 5695987..424b257 100644
--- a/Jam/Block.py
+++ b/Jam/Block.py
@@ -18,9 +18,9 @@ class Block():
SNAP = 15
- def __init__( self, owner, graphics_context, data ):
+ def __init__( self, owner, data ):
self.owner = owner
- self.gc = graphics_context
+ self.gc = owner.gc
self.data = {}
for key in data.keys():
@@ -50,7 +50,7 @@ class Block():
self.active = False
def dumpToStream( self, ostream, child = False ):
- ostream.block_add( ClassToStr[ self.type ], self.x, self.y, child, self.data )
+ ostream.block_add( ClassToStr[ self.type ], self.active, self.x + self.width//2, self.y + self.height//2, child, self.data )
if self.child:
self.child.dumpToStream( ostream, True )
@@ -76,7 +76,7 @@ class Block():
self.x = int(x)
self.y = int(y)
- self.endX = self.x + self.getWidth()
+ self.endX = self.x + self.width
self.endY = self.y + self.height
self.invalidate_rect( not self.dragging )
@@ -85,7 +85,12 @@ class Block():
self.child.snapToParentLoc( self.getChildAnchor() )
def resetLoc( self ):
- self.setLoc( self.oldLoc[0], self.oldLoc[1] )
+ if self.oldParent != None:
+ self.oldParent.addChild( self )
+ return False
+ else:
+ self.setLoc( self.oldLoc[0], self.oldLoc[1] )
+ return True
def getParentAnchor( self ):
return ( self.x + self.parentOffset, self.y )
@@ -96,14 +101,12 @@ class Block():
def snapToParentLoc( self, loc ):
self.setLoc( loc[0] - self.parentOffset, loc[1] )
- def getWidth( self ):
- return self.width
-
def substitute( self, block ):
pass # override in subclasses
def testSubstitute( self, block ):
- return False
+ if self.child:
+ return self.child.testSubstitute( block )
def testChild( self, loc ):
@@ -118,10 +121,17 @@ class Block():
return False
def addChild( self, child ):
+ c = self.child
+ if self.child:
+ self.removeChild()
+
self.child = child
child._addParent( self )
child.snapToParentLoc( self.getChildAnchor() )
+ if c:
+ child.addChild( c )
+
def removeChild( self ):
self.child._removeParent()
self.child = None
@@ -158,6 +168,7 @@ class Block():
else:
return False
+ self.oldParent = self.parent
self.oldLoc = ( self.x, self.y )
self.dragOffset = ( event.x - self.x, event.y - self.y )
@@ -191,7 +202,7 @@ class Block():
def _beginDrag( self ):
self.dragging = True
- self.dragOffset = ( self.getWidth()//2, self.height//2 )
+ self.dragOffset = ( self.width//2, self.height//2 )
def invalidateBranch( self, base = True ):
self.invalidate_rect( base )
@@ -199,7 +210,7 @@ class Block():
self.child.invalidateBranch( base )
def invalidate_rect( self, base = True ):
- self.owner.invalidate_rect( self.x, self.y, self.getWidth(), self.height, base )
+ self.owner.invalidate_rect( self.x, self.y, self.width, self.height, base )
def draw( self, startX, startY, stopX, stopY, pixmap ):
if stopY <= self.y or startY >= self.endY:
@@ -235,8 +246,8 @@ class Instrument(Block):
#::: data format:
# { "name": name, "id": instrumentId [, "volume": 0-1 ] }
#:::
- def __init__( self, owner, graphics_context, data ):
- Block.__init__( self, owner, graphics_context, data )
+ def __init__( self, owner, data ):
+ Block.__init__( self, owner, data )
self.type = Instrument
@@ -255,8 +266,15 @@ class Instrument(Block):
self.owner.getInstrumentImage( self.data["id"], True ) ]
self.invalidate_rect( True )
+ if self.child and self.child.active:
+ self.owner.updateLoop( self.child )
+
def testSubstitute( self, block ):
- if self.type == Loop:
+ ret = Block.testSubstitute( self, block )
+ if ret:
+ return ret
+
+ if block.type == Loop:
return False
if abs( self.x - block.x ) < Block.SNAP and abs( self.y - block.y ) < Block.SNAP:
@@ -303,8 +321,8 @@ class Drum(Block):
#::: data format:
# { "name": name, "id": instrumentId [, "volume": 0-1, "beats": 2-12, "regularity": 0-1, "seed": 0-1 ] }
#:::
- def __init__( self, owner, graphics_context, data ):
- Block.__init__( self, owner, graphics_context, data )
+ def __init__( self, owner, data ):
+ Block.__init__( self, owner, data )
self.type = Drum
@@ -336,7 +354,11 @@ class Drum(Block):
self.owner.updateDrum()
def testSubstitute( self, block ):
- if self.type == Loop:
+ ret = Block.testSubstitute( self, block )
+ if ret:
+ return ret
+
+ if block.type == Loop:
return False
if Config.INSTRUMENTSID[block.data["id"]].kit == None:
@@ -400,31 +422,85 @@ class Loop(Block):
#::: data format:
# { "name": name, "id": pageId }
#:::
- def __init__( self, owner, graphics_context, data ):
- Block.__init__( self, owner, graphics_context, data )
+ def __init__( self, owner, data ):
+ Block.__init__( self, owner, data )
self.type = Loop
self.canParent = True
self.canChild = True
+ self.canSubstitute = True
self.parentOffset = Loop.HEAD - 4
+ beats = self.owner.noteDB.getPage(self.data["id"]).beats
+ self.width = Loop.WIDTH[beats]
+
+ self.img = [ self.owner.getLoopImage( self.data["id"], False ),
+ self.owner.getLoopImage( self.data["id"], True ) ]
+
+ def destroy( self ):
+ self.owner.noteDB.deletePages( [ self.data["id"] ] )
+ Block.destroy( self )
+
def substitute( self, block ):
- self.data["id"] = block.data["id"]
+ self.invalidateBranch( True )
- self.img = [ self.owner.getInstrumentImage( self.data["id"], False ),
- self.owner.getInstrumentImage( self.data["id"], True ) ]
+ oldWidth = self.width
- self.invalidate_rect( True )
+ newid = self.owner.noteDB.duplicatePages( [ block.data["id"] ] )[block.data["id"]]
+ self.owner.updateLoopImage( newid )
+ self.data["id"] = newid
- if self.active:
- self.owner.updateDrum()
+ self.img = [ self.owner.getLoopImage( self.data["id"], False ),
+ self.owner.getLoopImage( self.data["id"], True ) ]
- def getWidth( self ):
beats = self.owner.noteDB.getPage(self.data["id"]).beats
- return Loop.WIDTH[beats]
-
+ self.width = Loop.WIDTH[beats]
+ self.endX = self.x + self.width
+
+ if False: # don't substitute children
+ if block.child:
+ c = block.child
+ after = self
+ while c:
+ data = {}
+ for key in c.data.keys():
+ data[key] = c.data[key]
+
+ newid = self.owner.noteDB.duplicatePages( [ data["id"] ] )[data["id"]]
+ self.owner.updateLoopImage( newid )
+ data["id"] = newid
+
+ copy = Loop( self.owner, self.gc, data )
+ after.addChild( copy )
+ after = copy
+ c = c.child
+ elif self.child:
+ self.child.snapToParentLoc( self.getChildAnchor() )
+
+ if self.child:
+ self.child.snapToParentLoc( self.getChildAnchor() )
+
+ if oldWidth < self.width: # or block.child:
+ self.invalidateBranch( True )
+
+ if self.active:
+ self.owner.updateLoop( self.getRoot().child )
+
+ def testSubstitute( self, block ):
+ ret = Block.testSubstitute( self, block )
+ if ret:
+ return ret
+
+ if block.type != Loop:
+ return False
+
+ if abs( self.x - block.x ) < Block.SNAP and abs( self.y - block.y ) < Block.SNAP:
+ return self
+
+ return False
+
def setActive( self, state ):
Block.setActive( self, state )
@@ -472,7 +548,7 @@ class Loop(Block):
endY = min( stopY, self.endY )
height = endY - y
- loop = self.owner.getLoopImage( self.data["id"], self.active )
+ loop = self.img[ self.active ]
if self.active: self.gc.foreground = self.owner.colors["Border_Active"]
else: self.gc.foreground = self.owner.colors["Border_Inactive"]
diff --git a/Jam/Desktop.py b/Jam/Desktop.py
index 40b5675..a28a917 100644
--- a/Jam/Desktop.py
+++ b/Jam/Desktop.py
@@ -51,8 +51,8 @@ class Desktop( gtk.EventBox ):
def dumpToStream( self, ostream ):
for b in self.blocks:
- block.dumpToStream( ostream )
-
+ b.dumpToStream( ostream )
+
def size_allocate( self, widget, allocation ):
if self.screenBuf == None or self.alloc.width != allocation.width or self.alloc.height != allocation.height:
win = gtk.gdk.get_default_root_window()
@@ -73,7 +73,7 @@ class Desktop( gtk.EventBox ):
def addBlock( self, blockClass, blockData, loc = (-1,-1), drag = False ):
- block = blockClass( self, self.gc, blockData )
+ block = blockClass( self, blockData )
if loc[0] != -1: x = loc[0]
else: x = self.alloc.width//2
@@ -93,12 +93,14 @@ class Desktop( gtk.EventBox ):
block.setLoc( x - block.width//2, y - block.height//2 )
if blockClass == Block.Instrument:
- self.activateInstrument( block )
+ pass
elif blockClass == Block.Drum:
pass
elif blockClass == Block.Loop:
pass
+ return block
+
def deleteBlock( self, block ):
if block.type == Block.Instrument:
if block == self.activeInstrument:
@@ -121,12 +123,19 @@ class Desktop( gtk.EventBox ):
block.destroy()
+ def _clearDesktop( self ):
+ for i in range( len(self.blocks)-1, -1, -1 ):
+ self.deleteBlock( self.blocks[i] )
+
def getInstrumentImage( self, id, active = False ):
return self.owner.getInstrumentImage( id, active )
def getLoopImage( self, id, active = False ):
return self.owner.getLoopImage( id, active )
+ def updateLoopImage( self, id ):
+ self.owner.updateLoopImage( id )
+
#==========================================================
# State
@@ -226,12 +235,13 @@ class Desktop( gtk.EventBox ):
elif self.possibleSubstitute:
self.possibleSubstitute.substitute( self.clickedBlock )
if self.clickedBlock.isPlaced():
- self.clickedBlock.resetLoc()
- self.blocks.append( self.clickedBlock )
+ if self.clickedBlock.resetLoc():
+ self.blocks.append( self.clickedBlock )
else:
self.deleteBlock( self.clickedBlock )
self.clickedBlock = None
- self.activateInstrument( self.possibleSubstitute )
+ if self.possibleSubstitute.type == Block.Instrument:
+ self.activateInstrument( self.possibleSubstitute )
self.possibleSubstitute = None
else:
self.blocks.append( self.clickedBlock )
diff --git a/Jam/Fillin.py b/Jam/Fillin.py
index f17fe01..8f31489 100644
--- a/Jam/Fillin.py
+++ b/Jam/Fillin.py
@@ -21,12 +21,16 @@ class Fillin:
self.onsets = []
self.pitchs = []
self.playBackTimeout = None
+ self.loopId = 0
self.csnd = new_csound_client()
def reset( self ):
self.barCount = 0
self.gate = 0
+ def setLoopId( self, id ):
+ self.loopId = id
+
def setProperties( self, tempo, instrument, volume, beats, reverb ):
self.setTempo( tempo )
self.setInstrument( instrument )
@@ -70,11 +74,11 @@ class Fillin:
def clear( self ):
if self.notesList:
for n in self.notesList:
- self.csnd.loopDelete(n)
+ self.csnd.loopDelete(n, self.loopId)
self.notesList = []
def handleClock( self ):
- tick = self.csnd.loopGetTick()
+ tick = self.csnd.loopGetTick( self.loopId )
if tick < ( Config.TICKS_PER_BEAT / 2 + 1 ):
if self.gate == 0:
self.gate = 1
@@ -108,5 +112,5 @@ class Fillin:
n = Note(0, x.trackId, i, x)
self.notesList.append(n)
i += 1
- self.csnd.loopPlay(n,1) #add as active
+ self.csnd.loopPlay(n,1, loopId = self.loopId ) #add as active
diff --git a/Jam/JamMain.py b/Jam/JamMain.py
index 5763ffa..69b9677 100644
--- a/Jam/JamMain.py
+++ b/Jam/JamMain.py
@@ -5,6 +5,8 @@ import gtk
from SubActivity import SubActivity
+import os, sys, shutil
+
import Config
from gettext import gettext as _
import sugar.graphics.style as style
@@ -25,6 +27,8 @@ from RythmGenerator import generator
from Generation.GenerationConstants import GenerationConstants
from Util.NoteDB import Note
+from Util import ControlStream
+
from math import sqrt
class JamMain(SubActivity):
@@ -212,20 +216,39 @@ class JamMain(SubActivity):
self._updateInstrument( Config.INSTRUMENTS["kalimba"].instrumentId, 0.5 )
#-- Drums ---------------------------------------------
+ self.drumLoopId = None
# use dummy values for now
self.drumFillin = Fillin( 2, 100, Config.INSTRUMENTS["drum1kit"].instrumentId, self.reverb, 1 )
+ #-- Desktops ------------------------------------------
+ self.curDesktop = None
+ # copy preset desktops
+ path = Config.TAM_TAM_ROOT+"/Resources/Desktops/"
+ filelist = os.listdir( path )
+ for file in filelist:
+ shutil.copyfile( path+file, Config.SCRATCH_DIR+file )
+
+ self._setDesktop( 0 )
+
+
#==========================================================
# SubActivity Handlers
def onActivate( self, arg ):
- pass
+ SubActivity.onActivate( self, arg )
def onDeactivate( self ):
- pass
+ SubActivity.onDeactivate( self )
def onDestroy( self ):
- pass
+ SubActivity.onDestroy( self )
+
+ # clear up scratch folder
+ path = Config.SCRATCH_DIR
+ filelist = os.listdir( path )
+ for file in filelist:
+ os.remove( path+file )
+
#==========================================================
# Playback
@@ -313,31 +336,35 @@ class JamMain(SubActivity):
rval += l
return rval
+ if self.drumLoopId != None:
+ self._stopDrum()
+
+ self.drumLoopId = self.csnd.loopCreate()
+
noteOnsets = []
notePitchs = []
i = 0
- self.noteList= []
- self.csnd.loopClear()
for x in flatten( generator( Config.INSTRUMENTSID[id].name, beats, 0.8, regularity, self.reverb) ):
x.amplitude = x.amplitude * volume
noteOnsets.append(x.onset)
notePitchs.append(x.pitch)
n = Note(0, x.trackId, i, x)
- self.noteList.append( (x.onset, n) )
i = i + 1
- self.csnd.loopPlay(n,1) #add as active
- self.csnd.loopSetNumTicks( beats * Config.TICKS_PER_BEAT )
+ self.csnd.loopPlay( n, 1, loopId = self.drumLoopId ) #add as active
+ self.csnd.loopSetNumTicks( beats * Config.TICKS_PER_BEAT, self.drumLoopId )
+ self.drumFillin.setLoopId( self.drumLoopId )
self.drumFillin.setProperties( self.tempo, Config.INSTRUMENTSID[id].name, volume, beats, self.reverb )
self.drumFillin.unavailable( noteOnsets, notePitchs )
self.drumFillin.play()
- self.csnd.loopSetTick(0)
- self.csnd.loopStart()
+ #self.csnd.loopSetTick( 0 )
+ self.csnd.loopStart( self.drumLoopId )
def _stopDrum( self ):
self.drumFillin.stop()
- self.csnd.loopPause()
+ self.csnd.loopDestroy( self.drumLoopId )
+ self.drumLoopId = None
def _playLoop( self, id, volume, tune, loopId = None ):
if loopId == None: # create new loop
@@ -348,25 +375,26 @@ class JamMain(SubActivity):
self.csnd.loopDestroy( loopId )
loopId = self.csnd.loopCreate()
+ inst = Config.INSTRUMENTSID[id]
+
offset = 0
- print "------------", loopId, tune
- temp = []
for page in tune:
for n in self.noteDB.getNotesByTrack( page, 0 ):
- temp.append( n )
n.pushState()
n.cs.instrumentId = id
+ if inst.kit: # drum kit
+ if n.cs.pitch in GenerationConstants.DRUMPITCH:
+ n.cs.pitch = GenerationConstants.DRUMPITCH[n.cs.pitch]
n.cs.onset += offset
self.csnd.loopPlay( n, 1, loopId = loopId )
n.popState()
offset += self.noteDB.getPage(page).ticks
- print temp
self.csnd.loopSetNumTicks( offset, loopId )
while startTick > offset: # align with last beat
- startTick -= Config.TICK_PER_BEAT
+ startTick -= Config.TICKS_PER_BEAT
self.csnd.loopSetTick( startTick, loopId )
@@ -489,3 +517,97 @@ class JamMain(SubActivity):
return self.loopPitchOffset + int(round( ( Config.MAXIMUM_PITCH - pitch ) * self.pixelsPerPitch ))
+ #==========================================================
+ # Desktop
+
+ def _clearDesktop( self, save = True ):
+ if self.curDesktop == None:
+ return
+
+ if save:
+ self._saveDesktop()
+
+ self.desktop._clearDesktop()
+
+ self.curDesktop = None
+
+ def setDesktop( self, desktop ):
+ self.desktopToolbar.desktop[desktop].set_active( True )
+
+ def _setDesktop( self, desktop ):
+ if self.curDesktop == desktop:
+ return
+
+ self._clearDesktop()
+
+ self.curDesktop = desktop
+
+ TTTable = ControlStream.TamTamTable( self.noteDB, jam = self )
+
+ filename = self.getDesktopScratchFile( self.curDesktop )
+ try:
+ stream = open( filename, "r" )
+ TTTable.parseFile( stream )
+ stream.close()
+ except:
+ if Config.DEBUG > 3: print "ERROR:: setDesktop: unable to open file: " + filename
+
+ #==========================================================
+ # Load/Save
+
+ def _saveDesktop( self ):
+ if self.curDesktop == None:
+ return
+
+ filename = self.getDesktopScratchFile( self.curDesktop )
+ if os.path.isfile( filename ):
+ os.remove( filename )
+
+ try:
+ scratch = open( filename, "w" )
+ stream = ControlStream.TamTamOStream(scratch)
+
+ self.noteDB.dumpToStream( stream, True )
+ self.desktop.dumpToStream( stream )
+
+ scratch.close()
+ except:
+ print "ERROR:: _clearDesktop: unable to open file: " + filename
+
+ def getDesktopScratchFile( self, i ):
+ return Config.SCRATCH_DIR+"desktop%d" % i
+
+ def handleJournalLoad( self, filepath ):
+
+ self._clearDesktop( False )
+
+ TTTable = ControlStream.TamTamTable( self.noteDB, jam = self )
+
+ try:
+ stream = open( filepath, "r" )
+ TTTable.parseFile( stream )
+ stream.close()
+ except:
+ if Config.DEBUG > 3: print "ERROR:: handleJournalLoad:", sys.exc_info()[0]
+
+ def handleJournalSave( self, filepath ):
+
+ self._saveDesktop()
+
+ try:
+ streamF = open( filepath, "w" )
+ stream = ControlStream.TamTamOStream( streamF )
+
+ for i in range(10):
+ desktop_file = Config.TAM_TAM_ROOT+"/.scratch/desktop%d" % i
+ stream.desktop_store( desktop_file, i )
+
+ stream.desktop_set( self.curDesktop )
+
+ streamF.close()
+
+ self.curDesktop = None
+ except:
+ if Config.DEBUG > 3: print "ERROR:: handleJournalSave:", sys.exc_info()[0]
+
+
diff --git a/Jam/Picker.py b/Jam/Picker.py
index cfff3e6..f41f1b2 100644
--- a/Jam/Picker.py
+++ b/Jam/Picker.py
@@ -214,7 +214,9 @@ class Instrument( Picker ):
walloc = widget.get_allocation()
salloc = self.scrolledWindow.get_allocation()
loc = ( walloc.x + salloc.x + event.x - self.hadjustment.get_value(), -1 )
- self.desktop.addBlock( Block.Instrument, widget.data, loc, True )
+
+ block = self.desktop.addBlock( Block.Instrument, widget.data, loc, True )
+ self.desktop.activateInstrument( block )
class Drum( Picker ):
@@ -302,6 +304,8 @@ class Loop( Picker ):
return -1
id = newPages.pop() # new pageId
+
+ self.owner.noteDB.getPage( id ).local = False # flag as a global page
self.addBlock( id, filename[:-4] )
@@ -412,9 +416,9 @@ class Loop( Picker ):
data[key] = widget.data[key]
newid = self.owner.noteDB.duplicatePages( [ data["id"] ] )[data["id"]]
+ self.owner.updateLoopImage( newid )
data["id"] = newid
- self.owner.updateLoopImage( data["id"] )
- self.desktop.addBlock( Block.Loop, data, loc, True )
+ block = self.desktop.addBlock( Block.Loop, data, loc, True )
diff --git a/Jam/Toolbars.py b/Jam/Toolbars.py
index ecb710b..892a139 100644
--- a/Jam/Toolbars.py
+++ b/Jam/Toolbars.py
@@ -3,6 +3,10 @@ import pygtk
pygtk.require( '2.0' )
import gtk
+from gettext import gettext as _
+
+from sugar.graphics.radiotoolbutton import RadioToolButton
+
class DesktopToolbar( gtk.Toolbar ):
def __init__( self, owner ):
@@ -10,4 +14,24 @@ class DesktopToolbar( gtk.Toolbar ):
self.owner = owner
+ self.desktop = []
+
+ btn = RadioToolButton( 'preset1', group = None )
+ btn.connect( 'toggled', self.setDesktop, 0 )
+ btn.set_tooltip( _('Desktop 1') )
+ self.insert( btn, -1 )
+ self.desktop.append( btn )
+
+ for i in range(2,11):
+ btn = RadioToolButton( 'preset%d'%i, group = self.desktop[0] )
+ btn.connect( 'toggled', self.setDesktop, i-1 )
+ btn.set_tooltip( _('Desktop %d'%i) )
+ self.insert( btn, -1 )
+ self.desktop.append( btn )
+
+ self.show_all()
+
+ def setDesktop( self, widget, which ):
+ if widget.get_active():
+ self.owner._setDesktop( which )
diff --git a/Resources/Desktops/desktop0 b/Resources/Desktops/desktop0
new file mode 100644
index 0000000..e99d154
--- /dev/null
+++ b/Resources/Desktops/desktop0
@@ -0,0 +1 @@
+block_add Drum False 242 336 False {'name': 'drum5kit', 'regularity': 0.17265378043653012, 'volume': 0.5, 'beats': 3, 'seed': 0.61058227696419964, 'id': 137}
diff --git a/Resources/Desktops/desktop1 b/Resources/Desktops/desktop1
new file mode 100644
index 0000000..1968c02
--- /dev/null
+++ b/Resources/Desktops/desktop1
@@ -0,0 +1,2 @@
+block_add Drum False 288 428 False {'name': 'drum5kit', 'regularity': 0.55739138706691516, 'volume': 0.5, 'beats': 3, 'seed': 0.40400200285530108, 'id': 137}
+block_add Drum False 456 417 False {'name': 'drum2kit', 'regularity': 0.21178540292062842, 'volume': 0.5, 'beats': 11, 'seed': 0.26067544837978218, 'id': 134}
diff --git a/Resources/Desktops/desktop2 b/Resources/Desktops/desktop2
new file mode 100644
index 0000000..b246e12
--- /dev/null
+++ b/Resources/Desktops/desktop2
@@ -0,0 +1,3 @@
+block_add Drum False 329 455 False {'name': 'drum5kit', 'regularity': 0.59168723930026823, 'volume': 0.5, 'beats': 7, 'seed': 0.22358471931510959, 'id': 137}
+block_add Drum False 446 437 False {'name': 'drum2kit', 'regularity': 0.91451132020332826, 'volume': 0.5, 'beats': 2, 'seed': 0.80359268442224474, 'id': 134}
+block_add Drum False 550 442 False {'name': 'drum1kit', 'regularity': 0.78617895417481898, 'volume': 0.5, 'beats': 6, 'seed': 0.50959461680345752, 'id': 133}
diff --git a/Resources/Desktops/desktop3 b/Resources/Desktops/desktop3
new file mode 100644
index 0000000..c0279e3
--- /dev/null
+++ b/Resources/Desktops/desktop3
@@ -0,0 +1,4 @@
+block_add Drum False 231 435 False {'name': 'drum5kit', 'regularity': 0.77762903492440216, 'volume': 0.5, 'beats': 12, 'seed': 0.60460119964597236, 'id': 137}
+block_add Drum False 357 432 False {'name': 'drum2kit', 'regularity': 0.33132865921684251, 'volume': 0.5, 'beats': 2, 'seed': 0.77648751169745833, 'id': 134}
+block_add Drum False 493 431 False {'name': 'drum1kit', 'regularity': 0.55491998189711023, 'volume': 0.5, 'beats': 9, 'seed': 0.28875083580746963, 'id': 133}
+block_add Drum False 619 438 False {'name': 'drum4kit', 'regularity': 0.67386875098251309, 'volume': 0.5, 'beats': 10, 'seed': 0.15028821889546284, 'id': 136}
diff --git a/Resources/Desktops/desktop4 b/Resources/Desktops/desktop4
new file mode 100644
index 0000000..c2db664
--- /dev/null
+++ b/Resources/Desktops/desktop4
@@ -0,0 +1,5 @@
+block_add Drum False 182 358 False {'name': 'drum5kit', 'regularity': 0.21830374396919894, 'volume': 0.5, 'beats': 8, 'seed': 0.0884116631518711, 'id': 137}
+block_add Drum False 295 325 False {'name': 'drum2kit', 'regularity': 0.24065691474281459, 'volume': 0.5, 'beats': 8, 'seed': 0.96964596655679636, 'id': 134}
+block_add Drum False 436 436 False {'name': 'drum1kit', 'regularity': 0.48215301880971018, 'volume': 0.5, 'beats': 8, 'seed': 0.96143042906234688, 'id': 133}
+block_add Drum False 600 430 False {'name': 'drum4kit', 'regularity': 0.52916944578760694, 'volume': 0.5, 'beats': 4, 'seed': 0.25477250939622931, 'id': 136}
+block_add Drum False 777 407 False {'name': 'drum3kit', 'regularity': 0.33047412968769607, 'volume': 0.5, 'beats': 11, 'seed': 0.61185926492466869, 'id': 135}
diff --git a/Resources/Desktops/desktop5 b/Resources/Desktops/desktop5
new file mode 100644
index 0000000..81b4cc2
--- /dev/null
+++ b/Resources/Desktops/desktop5
@@ -0,0 +1,6 @@
+block_add Drum False 175 375 False {'name': 'drum5kit', 'regularity': 0.90015096104373171, 'volume': 0.5, 'beats': 6, 'seed': 0.52233572417201268, 'id': 137}
+block_add Drum False 275 272 False {'name': 'drum2kit', 'regularity': 0.81725416939007489, 'volume': 0.5, 'beats': 3, 'seed': 0.28506667436101629, 'id': 134}
+block_add Drum False 486 354 False {'name': 'drum1kit', 'regularity': 0.67764269721336123, 'volume': 0.5, 'beats': 7, 'seed': 0.69297743070367435, 'id': 133}
+block_add Drum False 667 433 False {'name': 'drum4kit', 'regularity': 0.5860273409956076, 'volume': 0.5, 'beats': 8, 'seed': 0.1487598780244116, 'id': 136}
+block_add Drum False 709 259 False {'name': 'drum3kit', 'regularity': 0.30976478341586478, 'volume': 0.5, 'beats': 2, 'seed': 0.640931695278254, 'id': 135}
+block_add Drum False 839 465 False {'name': 'drum4kit', 'regularity': 0.1176562189553173, 'volume': 0.5, 'beats': 8, 'seed': 0.3968320964117491, 'id': 136}
diff --git a/Resources/Desktops/desktop6 b/Resources/Desktops/desktop6
new file mode 100644
index 0000000..05ed65b
--- /dev/null
+++ b/Resources/Desktops/desktop6
@@ -0,0 +1,7 @@
+block_add Drum False 260 411 False {'name': 'drum5kit', 'regularity': 0.00099551426528621256, 'volume': 0.5, 'beats': 5, 'seed': 0.27840219088235596, 'id': 137}
+block_add Drum False 353 360 False {'name': 'drum2kit', 'regularity': 0.31826067497762844, 'volume': 0.5, 'beats': 5, 'seed': 0.22627774476445939, 'id': 134}
+block_add Drum False 461 507 False {'name': 'drum1kit', 'regularity': 0.24776068456325329, 'volume': 0.5, 'beats': 2, 'seed': 0.14699764155157424, 'id': 133}
+block_add Drum False 548 397 False {'name': 'drum4kit', 'regularity': 0.78706580174700747, 'volume': 0.5, 'beats': 12, 'seed': 0.39682822879897905, 'id': 136}
+block_add Drum False 732 394 False {'name': 'drum3kit', 'regularity': 0.9471817294630962, 'volume': 0.5, 'beats': 2, 'seed': 0.49021316200287002, 'id': 135}
+block_add Drum False 856 500 False {'name': 'drum3kit', 'regularity': 0.29380418366786754, 'volume': 0.5, 'beats': 6, 'seed': 0.68783001902378305, 'id': 135}
+block_add Drum False 642 296 False {'name': 'drum4kit', 'regularity': 0.33697457598218428, 'volume': 0.5, 'beats': 12, 'seed': 0.9520676955870041, 'id': 136}
diff --git a/Resources/Desktops/desktop7 b/Resources/Desktops/desktop7
new file mode 100644
index 0000000..c38824f
--- /dev/null
+++ b/Resources/Desktops/desktop7
@@ -0,0 +1,8 @@
+block_add Drum False 273 376 False {'name': 'drum5kit', 'regularity': 0.14996288819410908, 'volume': 0.5, 'beats': 11, 'seed': 0.97865782454708972, 'id': 137}
+block_add Drum False 430 437 False {'name': 'drum2kit', 'regularity': 0.22686486764388736, 'volume': 0.5, 'beats': 12, 'seed': 0.20156164102134011, 'id': 134}
+block_add Drum False 587 476 False {'name': 'drum1kit', 'regularity': 0.5023786258393923, 'volume': 0.5, 'beats': 6, 'seed': 0.53584602645586388, 'id': 133}
+block_add Drum False 631 311 False {'name': 'drum4kit', 'regularity': 0.63118726500905431, 'volume': 0.5, 'beats': 9, 'seed': 0.81751963172248665, 'id': 136}
+block_add Drum False 769 529 False {'name': 'drum3kit', 'regularity': 0.16208618912427697, 'volume': 0.5, 'beats': 7, 'seed': 0.31378267309795727, 'id': 135}
+block_add Drum False 439 259 False {'name': 'drum4kit', 'regularity': 0.065648010744176588, 'volume': 0.5, 'beats': 2, 'seed': 0.96047862380592997, 'id': 136}
+block_add Drum False 494 345 False {'name': 'drum2kit', 'regularity': 0.59831266615900935, 'volume': 0.5, 'beats': 6, 'seed': 0.78044240161229295, 'id': 134}
+block_add Drum False 276 232 False {'name': 'drum5kit', 'regularity': 0.1472993196679786, 'volume': 0.5, 'beats': 7, 'seed': 0.081751227986034847, 'id': 137}
diff --git a/Resources/Desktops/desktop8 b/Resources/Desktops/desktop8
new file mode 100644
index 0000000..50772ef
--- /dev/null
+++ b/Resources/Desktops/desktop8
@@ -0,0 +1,9 @@
+block_add Drum False 194 311 False {'name': 'drum5kit', 'regularity': 0.086528345958863495, 'volume': 0.5, 'beats': 8, 'seed': 0.30475937412840726, 'id': 137}
+block_add Drum False 345 274 False {'name': 'drum2kit', 'regularity': 0.89583779126715557, 'volume': 0.5, 'beats': 10, 'seed': 0.98185842149303015, 'id': 134}
+block_add Drum False 486 323 False {'name': 'drum1kit', 'regularity': 0.023166532511794236, 'volume': 0.5, 'beats': 2, 'seed': 0.49717529146341177, 'id': 133}
+block_add Drum False 567 124 False {'name': 'drum4kit', 'regularity': 0.2386146842020036, 'volume': 0.5, 'beats': 8, 'seed': 0.70995470197070898, 'id': 136}
+block_add Drum False 603 330 False {'name': 'drum4kit', 'regularity': 0.18866579742299305, 'volume': 0.5, 'beats': 12, 'seed': 0.026020774927881907, 'id': 136}
+block_add Drum False 504 437 False {'name': 'drum1kit', 'regularity': 0.9221379089954207, 'volume': 0.5, 'beats': 7, 'seed': 0.65776662628744698, 'id': 133}
+block_add Drum False 815 400 False {'name': 'drum1kit', 'regularity': 0.56255856724700692, 'volume': 0.5, 'beats': 9, 'seed': 0.83950039804663834, 'id': 133}
+block_add Drum False 741 547 False {'name': 'drum3kit', 'regularity': 0.15542009855247862, 'volume': 0.5, 'beats': 8, 'seed': 0.50941294313358909, 'id': 135}
+block_add Drum False 620 446 False {'name': 'drum2kit', 'regularity': 0.19832159880741562, 'volume': 0.5, 'beats': 8, 'seed': 0.90486534173232447, 'id': 134}
diff --git a/Resources/Desktops/desktop9 b/Resources/Desktops/desktop9
new file mode 100644
index 0000000..eb0367d
--- /dev/null
+++ b/Resources/Desktops/desktop9
@@ -0,0 +1,10 @@
+block_add Drum False 387 448 False {'name': 'drum5kit', 'regularity': 0.46533609055143399, 'volume': 0.5, 'beats': 10, 'seed': 0.5268677064825078, 'id': 137}
+block_add Drum False 471 387 False {'name': 'drum2kit', 'regularity': 0.99977743388869933, 'volume': 0.5, 'beats': 3, 'seed': 0.83316131695736351, 'id': 134}
+block_add Drum False 582 520 False {'name': 'drum1kit', 'regularity': 0.16832481238745933, 'volume': 0.5, 'beats': 5, 'seed': 0.53670066220388379, 'id': 133}
+block_add Drum False 621 335 False {'name': 'drum4kit', 'regularity': 0.81846644469923291, 'volume': 0.5, 'beats': 4, 'seed': 0.33583725098298478, 'id': 136}
+block_add Drum False 763 456 False {'name': 'drum3kit', 'regularity': 0.24166263102033714, 'volume': 0.5, 'beats': 2, 'seed': 0.44193114642028852, 'id': 135}
+block_add Drum False 590 183 False {'name': 'drum4kit', 'regularity': 0.95065092402626417, 'volume': 0.5, 'beats': 2, 'seed': 0.59560637194277388, 'id': 136}
+block_add Drum False 208 259 False {'name': 'drum1kit', 'regularity': 0.54878672652226335, 'volume': 0.5, 'beats': 3, 'seed': 0.64042203865497094, 'id': 133}
+block_add Drum False 342 265 False {'name': 'drum5kit', 'regularity': 0.57022694452966061, 'volume': 0.5, 'beats': 10, 'seed': 0.17715880194748179, 'id': 137}
+block_add Drum False 261 386 False {'name': 'drum2kit', 'regularity': 0.19510485939664513, 'volume': 0.5, 'beats': 10, 'seed': 0.61936224302968201, 'id': 134}
+block_add Drum False 877 201 False {'name': 'drum1kit', 'regularity': 0.90346441146326784, 'volume': 0.5, 'beats': 4, 'seed': 0.69406727073158425, 'id': 133}
diff --git a/Resources/Loops/loop1.ttl b/Resources/Loops/loop1.ttl
index 5c988f3..97bb9a6 100644
--- a/Resources/Loops/loop1.ttl
+++ b/Resources/Loops/loop1.ttl
@@ -3,7 +3,3 @@ note_add 92 2 0 0 29 0.75 0.5 24 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 93 2 0 24 44 0.75 0.5 7 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 94 2 0 36 44 0.75 0.5 6 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 95 2 0 48 32 0.75 0.5 24 0 88 0.005 0.098 0.1 0 1000 0 edit
-tune_set 2
-track_vol 50 50 50 50 50
-master_vol 50
-tempo 100
diff --git a/Resources/Loops/loop2.ttl b/Resources/Loops/loop2.ttl
index 872d4fa..2e5e7ea 100644
--- a/Resources/Loops/loop2.ttl
+++ b/Resources/Loops/loop2.ttl
@@ -42,7 +42,3 @@ note_add 112 16 0 8 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 113 16 0 9 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 114 16 0 10 36 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 115 16 0 11 34 0.75 0.5 1 0 88 0.005 0.098 0.1 0 1000 0 edit
-tune_set 16
-track_vol 50 50 50 50 50
-master_vol 50
-tempo 75
diff --git a/Resources/Loops/loop3.ttl b/Resources/Loops/loop3.ttl
index f749fb6..4b6bdd6 100644
--- a/Resources/Loops/loop3.ttl
+++ b/Resources/Loops/loop3.ttl
@@ -7,7 +7,3 @@ note_add 120 16 0 12 24 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 121 16 0 15 24 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 122 16 0 18 38 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
note_add 123 16 0 21 45 0.75 0.5 3 0 88 0.005 0.098 0.1 0 1000 0 edit
-tune_set 16
-track_vol 50 50 50 50 50
-master_vol 50
-tempo 75
diff --git a/TamTam.py b/TamTam.py
index 3119f28..ac4a8dd 100755
--- a/TamTam.py
+++ b/TamTam.py
@@ -134,6 +134,7 @@ class TamTam(Activity):
if mode == 'jam':
if not (mode in self.modeList):
+ self.metadata['title'] = 'TamTam Jam'
self.modeList[mode] = JamMain(self, self.set_mode)
self.mode = mode
@@ -259,7 +260,9 @@ class TamTam(Activity):
def read_file(self,file_path):
subactivity_name = self.metadata['tamtam_subactivity']
- if subactivity_name == 'edit' or subactivity_name == 'synth':
+ if subactivity_name == 'edit' \
+ or subactivity_name == 'synth' \
+ or subactivity_name == 'jam':
self.set_mode(subactivity_name)
self.modeList[subactivity_name].handleJournalLoad(file_path)
elif subactivity_name == 'mini':
@@ -271,14 +274,17 @@ class TamTam(Activity):
if self.mode == 'edit':
self.metadata['tamtam_subactivity'] = self.mode
self.modeList[self.mode].handleJournalSave(file_path)
- if self.mode == 'synth':
+ elif self.mode == 'synth':
self.metadata['tamtam_subactivity'] = self.mode
self.modeList[self.mode].handleJournalSave(file_path)
- if self.mode == 'mini':
+ elif self.mode == 'mini':
self.metadata['tamtam_subactivity'] = self.mode
f = open(file_path,'w')
f.close()
-
+ elif self.mode == 'jam':
+ self.metadata['tamtam_subactivity'] = self.mode
+ self.modeList[self.mode].handleJournalSave(file_path)
+
if __name__ == "__main__":
if len(sys.argv) > 1 :
diff --git a/Util/ControlStream.py b/Util/ControlStream.py
index bc58b7a..e76c19b 100644
--- a/Util/ControlStream.py
+++ b/Util/ControlStream.py
@@ -4,6 +4,8 @@ import time
import Config
+import os
+
from Util import NoteDB
from Util.CSoundNote import CSoundNote
from Util.CSoundClient import new_csound_client
@@ -39,11 +41,6 @@ class TamTamOStream:
self.file.write( " ".join([str(i) for i in l]))
self.file.write('\n')
- def tune_set(self, tune):
- self.file.write('tune_set ')
- self.file.write(" ".join([str(t) for t in tune]))
- self.file.write('\n')
-
def track_vol(self, vols):
self.file.write('track_vol ')
self.file.write(" ".join([str(t) for t in vols]))
@@ -59,13 +56,30 @@ class TamTamOStream:
self.file.write(str(tempo))
self.file.write('\n')
- def block_add( self, typeStr, x, y, child, data ):
- l = [ "block_add", typeStr, str(x), str(y), str(child), str(data) ]
+ def block_add( self, typeStr, active, centerX, centerY, child, data ):
+ l = [ "block_add", typeStr, str(active), str(centerX), str(centerY), str(child), str(data) ]
+ self.file.write( " ".join([str(i) for i in l]))
+ self.file.write('\n')
+
+ def desktop_store( self, filename, id ):
+ self.file.write( "desktop_store %d\n" % id )
+ try:
+ file = open( filename, "r" )
+ for line in file:
+ self.file.write( line )
+ file.close()
+ except:
+ if Config.DEBUG > 3: print "ERROR:: desktop_store could not open file: " + filename
+ self.file.write( "desktop_store END\n" )
+
+ def desktop_set( self, id ):
+ self.file.write( "desktop_set %d\n" % id )
class TamTamTable:
- def __init__(self, noteDB):
+ def __init__(self, noteDB = None, jam = None ):
self.noteDB = noteDB
+ self.jam = jam
self.csnd = new_csound_client()
self.pid = {} #stream_pid : local_pid
@@ -78,17 +92,16 @@ class TamTamTable:
'track_vol':self.track_vol,
'master_vol':self.master_vol,
'tempo':self.tempo,
- 'tune_set':self.tune_set,
'block_add':self.block_add,
+ 'desktop_store':self.desktop_store,
+ 'desktop_set':self.desktop_set,
'sleep':self.sleep,
'quit':self.quit}
def parseFile(self, ifile):
table = self.parseTable()
- while True:
- l = ifile.readline()
- if l == '\n': break
- if l == '': break
+ self.file = ifile
+ for l in self.file:
cmdlist = l.split()
if len(cmdlist) > 0:
if cmdlist[0] not in table:
@@ -151,29 +164,49 @@ class TamTamTable:
def tempo(self, argv):
self.tempo = argv[0]
- def tune_set(self, argv):
- if Config.DEBUG > 3: print 'tune_set', argv
-
- if Config.DEBUG > 3: print 'ERROR: tune_set is not handled properly by mainwindow yet... skipping\n'
- return
-
- self.noteDB.tune = [int(i) for i in argv]
- pids = self.noteDB.pages.keys()
- pids_to_del = [pid for pid in self.noteDB.pages.keys()
- if pid not in self.noteDB.tune]
- self.noteDB.deletePages( pids_to_del )
-
def block_add( self, argv ):
- print "----------", argv
- type = Block.StrToClass[argv[0]]
- x = int( argv[1] )
- y = int( argv[2] )
- child = bool( argv[3] )
+ blockClass = Block.StrToClass[argv[0]]
+ active = eval( argv[1] )
+ x = int( argv[2] )
+ y = int( argv[3] )
+ child = eval( argv[4] )
data = ""
- for str in argv[4:]:
+ for str in argv[5:]:
data += str
data = eval( data )
- self.desktop.addBlock( cls, data, ( x, y ) )
+
+ if blockClass == Block.Loop:
+ data["id"] = self.pid[ data["id"] ]
+ self.jam.updateLoopImage( data["id"] )
+
+ if child:
+ block = blockClass( self.jam.getDesktop(), data )
+ self.lastBlock.addChild( block )
+ else:
+ block = self.jam.getDesktop().addBlock( blockClass, data, ( x, y ) )
+
+ if blockClass == Block.Instrument and active:
+ self.jam.getDesktop().activateInstrument( block )
+
+ self.lastBlock = block
+
+ def desktop_store( self, argv ):
+ filename = self.jam.getDesktopScratchFile( int( argv[0] ) )
+ #try:
+ if os.path.isfile( filename ):
+ os.remove( filename )
+
+ file = open( filename, "w" )
+ for line in self.file:
+ if line == "desktop_store END\n":
+ break
+ file.write( line )
+ file.close
+ #except:
+ # if Config.DEBUG > 3: print "ERROR:: desktop_store could not open file: " + filename
+
+ def desktop_set( self, argv ):
+ self.jam.setDesktop( int( argv[0] ) )
def sleep(self, argv):
t = float(argv[0])
diff --git a/Util/NoteDB.py b/Util/NoteDB.py
index 0b6c6b9..cd8d1ca 100644
--- a/Util/NoteDB.py
+++ b/Util/NoteDB.py
@@ -34,7 +34,7 @@ class Note:
self.cs = self.csStack.pop()
class Page:
- def __init__( self, beats, color = 0, instruments = False ): # , tempo, insruments, color = 0 ):
+ def __init__( self, beats, color = 0, instruments = False, local = True ): # , tempo, insruments, color = 0 ):
self.beats = beats
self.ticks = beats*Config.TICKS_PER_BEAT
@@ -45,6 +45,8 @@ class Page:
else:
self.instruments = instruments[:]
+ self.local = local # page local/global?
+
self.nextNoteId = 0 # first note will be 1
def genId( self ):
@@ -106,14 +108,12 @@ class NoteDB:
self.clipboard = [] # stores copied cs notes
self.clipboardArea = [] # stores the limits and tracks for each page in the clipboard
- def dumpToStream(self, ostream):
+ def dumpToStream( self, ostream, localOnly = False ):
for pid in self.tune:
- ostream.page_add(pid, self.pages[pid])
- for pid in self.noteD:
- for tid in xrange( len( self.noteD[pid])):
- for nid in self.noteD[pid][tid]:
- ostream.note_add(self.noteD[pid][tid][nid])
- ostream.tune_set(self.tune)
+ if not localOnly or self.pages[pid].local:
+ ostream.page_add(pid, self.pages[pid])
+ for note in self.getNotesByPage( pid ):
+ ostream.note_add( note )
#-- private --------------------------------------------
def _genId( self ):