Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TamTamJam.activity/Jam
diff options
context:
space:
mode:
authoramartin <olpc@xo-05-28-21.localdomain>2007-09-22 08:34:30 (GMT)
committer amartin <olpc@xo-05-28-21.localdomain>2007-09-22 08:34:30 (GMT)
commitbda2ab115da1b3efbd0a772460d31633658f68a8 (patch)
tree3d4d3eeccb86e84d630b9a83c122e54a77be4c84 /TamTamJam.activity/Jam
parent1196db483bb36b0d78a710b8d165846affe7c7c7 (diff)
Jam keyboard recording
Diffstat (limited to 'TamTamJam.activity/Jam')
-rw-r--r--TamTamJam.activity/Jam/Desktop.py8
-rw-r--r--TamTamJam.activity/Jam/JamMain.py67
-rw-r--r--TamTamJam.activity/Jam/Popup.py62
3 files changed, 105 insertions, 32 deletions
diff --git a/TamTamJam.activity/Jam/Desktop.py b/TamTamJam.activity/Jam/Desktop.py
index 1f5e5eb..67dc70b 100644
--- a/TamTamJam.activity/Jam/Desktop.py
+++ b/TamTamJam.activity/Jam/Desktop.py
@@ -34,7 +34,6 @@ class Desktop( gtk.EventBox ):
self.blocks = [] # items on the desktop
self.activeInstrument = None
- self.activeDrum = None
self.loops = {} # dict of playing loops by loop root
self.drums = [] # list of active drums
@@ -128,11 +127,12 @@ class Desktop( gtk.EventBox ):
break
elif block.type == Block.Drum:
- if block == self.activeDrum:
- self.deactivateDrum()
+ if block.isActive():
+ self.deactivateDrum( block )
elif block.type == Block.Loop:
- pass
+ if block.isActive():
+ self.deactivateLoop( block )
if block in self.blocks:
block.invalidate_rect( True )
diff --git a/TamTamJam.activity/Jam/JamMain.py b/TamTamJam.activity/Jam/JamMain.py
index 414c759..6e074e2 100644
--- a/TamTamJam.activity/Jam/JamMain.py
+++ b/TamTamJam.activity/Jam/JamMain.py
@@ -263,6 +263,11 @@ class JamMain(gtk.EventBox):
self._updateInstrument( Config.INSTRUMENTS["kalimba"].instrumentId, 0.5 )
self.instrumentStack = []
+ # metronome
+ page = NoteDB.Page( 1, local = False )
+ self.metronomePage = self.noteDB.addPage( -1, page )
+ self.metronome = False
+
#-- Drums ---------------------------------------------
self.drumLoopId = None
# use dummy values for now
@@ -460,6 +465,7 @@ class JamMain(gtk.EventBox):
n.pushState()
noteOnsets.append( n.cs.onset )
notePitchs.append( n.cs.pitch )
+ n.cs.instrumentId = id
n.cs.amplitude = volume * n.cs.amplitude # TODO remove me once track volume is working
n.cs.reverbSend = reverb
self.csnd.loopPlay( n, 1, loopId = loopId ) #add as active
@@ -510,7 +516,7 @@ class JamMain(gtk.EventBox):
self.drumFillin.stop()
self.csnd.loopDestroy( loopId )
- def _playLoop( self, id, volume, reverb, tune, loopId = None, force = False ):
+ def _playLoop( self, id, volume, reverb, tune, loopId = None, force = False, sync = True ):
if loopId == None: # create new loop
startTick = 0
firstTime = True
@@ -540,13 +546,12 @@ class JamMain(gtk.EventBox):
n.popState()
offset += self.noteDB.getPage(page).ticks
-
self.csnd.loopSetNumTicks( offset, loopId )
# sync to heartbeat
- if False: # firstTime: # always force first note to play rather than snaping to nearest beat.. good idea?
- startTick = offset - Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
- else:
+ #if False: # firstTime: # always force first note to play rather than snaping to nearest beat.. good idea?
+ # startTick = offset - Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop )
+ if sync:
while startTick > offset: # align with last beat
startTick -= Config.TICKS_PER_BEAT
beatTick = int(startTick) % Config.TICKS_PER_BEAT
@@ -566,7 +571,6 @@ class JamMain(gtk.EventBox):
startTick -= offset
elif startTick < 0:
startTick += offset
-
self.csnd.loopSetTick( startTick, loopId )
@@ -578,6 +582,57 @@ class JamMain(gtk.EventBox):
def _stopLoop( self, loopId ):
self.csnd.loopDestroy( loopId )
+ def playMetronome( self, period ):
+ if self.metronome:
+ self.stopMetronome()
+
+ self.metronome = self.csnd.loopCreate()
+
+ baseCS = CSoundNote( 0, # onset
+ 36, # pitch
+ 0.2, # amplitude
+ 0.5, # pan
+ 100, # duration
+ 0, # track
+ Config.INSTRUMENTS["drum1hatpedal"].instrumentId,
+ reverbSend = 0.5,
+ tied = True,
+ mode = 'mini' )
+
+
+ cs = baseCS.clone()
+ cs.instrumentId = Config.INSTRUMENTS["drum1hatshoulder"].instrumentId
+ cs.amplitude = 0.5
+
+ stream = [ cs ]
+
+ onset = period
+ while onset < Config.TICKS_PER_BEAT:
+ cs = baseCS.clone()
+ cs.onset = onset
+ stream.append( cs )
+ onset += period
+
+ self.noteDB.addNotes( [ self.metronomePage, 0, len(stream) ] + stream + [ -1 ] )
+
+ for n in self.noteDB.getNotesByTrack( self.metronomePage, 0 ):
+ self.csnd.loopPlay( n, 1, loopId = self.metronome )
+
+ self.csnd.loopSetNumTicks( Config.TICKS_PER_BEAT, self.metronome )
+ self.csnd.loopSetTick( 0, self.metronome )
+
+ self.csnd.loopStart( self.metronome )
+
+ def stopMetronome( self ):
+ if not self.metronome:
+ return
+
+ self.csnd.loopDestroy( self.metronome )
+ self.noteDB.deleteNotesByTrack( [ self.metronomePage ], [ 0 ] )
+
+ self.metronome = None
+
+
def setPaused( self, paused ):
if self.paused == paused:
return
diff --git a/TamTamJam.activity/Jam/Popup.py b/TamTamJam.activity/Jam/Popup.py
index 4d6bca2..ce0204e 100644
--- a/TamTamJam.activity/Jam/Popup.py
+++ b/TamTamJam.activity/Jam/Popup.py
@@ -455,6 +455,7 @@ class Loop( Popup ):
self.recording = False
self.recordLoop = None
self.recordingNote = None
+ self.grid = Config.DEFAULT_GRID
self.owner.noteDB.addListener( self, LoopParasite )
@@ -540,7 +541,7 @@ class Loop( Popup ):
self.invalidatePreview( 0, 0, self.previewDA.width, self.previewDA.height )
if self.recordLoop:
- self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True )
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
def handleRegularity( self, widget ):
if not self.settingBlock:
@@ -560,15 +561,14 @@ class Loop( Popup ):
self.owner._generateTrack( self.instrument["id"], self.curPage, 0, parameters, generator1 )
self.block.updateLoop()
-
if self.recordLoop:
- self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True )
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
def handleClear( self, widget ):
self.block.clear()
if self.recordLoop:
- self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True )
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
def handleRecord( self, widget ):
if widget.get_active():
@@ -719,6 +719,9 @@ class Loop( Popup ):
+ [ n.note.id for n in self.selectedNotes[0] ]
+ [ -1 ] )
self.block.updateLoop()
+ if self.recordLoop:
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
+
else:
self.owner.onKeyPress( widget, event )
@@ -803,11 +806,12 @@ class Loop( Popup ):
if self.recording:
return
- #self.owner.setPaused( True )
+ self.owner.setPaused( True )
self.owner.pushInstrument( self.instrument )
self.owner.setKeyboardListener( self )
- self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], force = True )
+ self.owner.playMetronome( self.grid )
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], force = True, sync = False )
self.updatePlayhead()
self.recordTimeout = gobject.timeout_add( 20, self._record_timeout )
self.recording = True
@@ -816,45 +820,48 @@ class Loop( Popup ):
if not self.recording:
return
- #self.owner.setPaused( False )
- self.owner.popInstrument()
- self.owner.setKeyboardListener( None )
-
gobject.source_remove( self.recordTimeout )
self.recording = False
if self.recordingNote:
self.finishNote()
+ self.owner.stopMetronome()
self.owner._stopLoop( self.recordLoop )
self.recordLoop = None
self.clearPlayhead()
+ self.owner.popInstrument()
+ self.owner.setKeyboardListener( None )
+ self.owner.setPaused( False )
+
def recordNote( self, pitch ):
+ page = self.block.getData("id")
+ ticks = self.owner.noteDB.getPage(page).ticks
+
onset = self.csnd.loopGetTick( self.recordLoop )
- #onset = Config.DEFAULT_GRID * int(onset / Config.DEFAULT_GRID + 0.5)
+ onset = self.grid * int( onset/self.grid + 0.5 )
+ if onset < 0: onset += ticks
+ elif onset >= ticks: onset -= ticks
cs = CSoundNote( onset,
pitch,
0.75,
0.5,
- Config.DEFAULT_GRID,
+ self.grid,
0,
instrumentId = self.instrument["id"] )
cs.pageId = self.curPage
- for n in self.noteDB.getNotesByTrack( self.curPage, 0 ):
+ for n in self.noteDB.getNotesByTrack( self.curPage, 0 )[:]:
if onset < n.cs.onset:
break
if onset >= n.cs.onset + n.cs.duration:
continue
- if onset < n.cs.onset + n.cs.duration - 2:
- self.noteDB.deleteNote( n.page, n.track, n.id )
- elif onset - n.cs.onset < 1:
- self.noteDB.deleteNote( n.page, n.track, n.id )
- else:
+ if n.cs.onset < onset and n.cs.duration > self.grid:
self.noteDB.updateNote( n.page, n.track, n.id, PARAMETER.DURATION, onset - n.cs.onset )
- break
+ else:
+ self.noteDB.deleteNote( n.page, n.track, n.id )
self.recordingNote = self.noteDB.addNote( -1, self.curPage, 0, cs )
@@ -864,10 +871,18 @@ class Loop( Popup ):
self.recordingNote = None
self.block.updateLoop()
+ if self.recordLoop:
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
def _updateNote( self ):
+ page = self.block.getData("id")
+ ticks = self.owner.noteDB.getPage(page).ticks
+
tick = self.csnd.loopGetTick( self.recordLoop )
- #tick = Config.DEFAULT_GRID * int(tick / Config.DEFAULT_GRID + 0.5)
+ tick = self.grid * int( tick/self.grid + 0.5 )
+ if tick < 0: tick += ticks
+ elif tick >= ticks: tick -= ticks
+
note = self.noteDB.getNote( self.curPage, 0, self.recordingNote )
@@ -877,7 +892,7 @@ class Loop( Popup ):
for n in self.noteDB.getNotesByTrack( self.curPage, 0 ):
if n.cs.onset <= note.cs.onset:
continue
- if n.cs.onset > note.cs.onset and n.cs.onset < note.cs.onset + note.cs.duration:
+ if n.cs.onset < note.cs.onset + note.cs.duration:
self.noteDB.deleteNote( n.page, n.track, n.id )
else:
break
@@ -887,10 +902,11 @@ class Loop( Popup ):
for n in self.noteDB.getNotesByTrack( self.curPage, 0 ):
if n.cs.onset <= note.cs.onset:
continue
- if n.cs.onset > note.cs.onset and n.cs.onset < note.cs.onset + note.cs.duration:
+ if n.cs.onset < note.cs.onset + note.cs.duration:
self.noteDB.deleteNote( n.page, n.track, n.id )
else:
break
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True )
def _record_timeout( self ):
self.updatePlayhead()
@@ -1114,6 +1130,8 @@ class Loop( Popup ):
note.doneNoteDrag( self )
self.block.updateLoop()
+ if self.recordLoop:
+ self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False )
def noteStepOnset( self, step ):
stream = []