From f52524e274d7e0b47da68b2fb5f27d1bb8e72662 Mon Sep 17 00:00:00 2001 From: amartin Date: Tue, 12 Feb 2008 12:59:37 +0000 Subject: beat sync --- (limited to 'TamTamJam.activity') diff --git a/TamTamJam.activity/Jam/JamMain.py b/TamTamJam.activity/Jam/JamMain.py index c875d68..c652269 100644 --- a/TamTamJam.activity/Jam/JamMain.py +++ b/TamTamJam.activity/Jam/JamMain.py @@ -61,7 +61,7 @@ class JamMain(gtk.EventBox): self.csnd.setMasterVolume( self.volume*100 ) # csnd expects a range 0-100 for now self.csnd.setTempo( self.tempo ) - self.paused = False + self.muted = False presenceService = presenceservice.get_instance() self.xoOwner = presenceService.get_owner() @@ -256,7 +256,7 @@ class JamMain(gtk.EventBox): #-- Keyboard ------------------------------------------ self.key_dict = {} - self.nextTrack = 1 + self.nextTrack = 2 self.keyboardListener = None self.recordingNote = None @@ -426,7 +426,7 @@ class JamMain(gtk.EventBox): mode = 'mini' ) self.nextTrack += 1 if self.nextTrack > 8: - self.nextTrack = 1 + self.nextTrack = 2 self.csnd.play(self.key_dict[key], 0.3) return self.key_dict[key] @@ -465,8 +465,6 @@ class JamMain(gtk.EventBox): loopId = self.csnd.loopCreate() - # TODO update track volume - noteOnsets = [] notePitchs = [] for n in self.noteDB.getNotesByTrack( pageId, 0 ): @@ -474,7 +472,7 @@ class JamMain(gtk.EventBox): 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.amplitude = volume * n.cs.amplitude n.cs.reverbSend = reverb self.csnd.loopPlay( n, 1, loopId = loopId ) #add as active n.popState() @@ -514,8 +512,7 @@ class JamMain(gtk.EventBox): self.csnd.loopSetTick( startTick, loopId ) - if not self.paused: - self.csnd.loopStart( loopId ) + self.csnd.loopStart( loopId ) return loopId @@ -533,8 +530,6 @@ class JamMain(gtk.EventBox): loopId = self.csnd.loopCreate() - # TODO update track volume - inst = self.instrumentDB.instId[id] offset = 0 @@ -542,7 +537,7 @@ class JamMain(gtk.EventBox): for n in self.noteDB.getNotesByTrack( page, 0 ): n.pushState() n.cs.instrumentId = id - n.cs.amplitude = volume * n.cs.amplitude # TODO remove me once track volume is working + n.cs.amplitude = volume * n.cs.amplitude n.cs.reverbSend = reverb if inst.kit: # drum kit if n.cs.pitch in GenerationConstants.DRUMPITCH: @@ -552,6 +547,8 @@ class JamMain(gtk.EventBox): n.popState() for n in self.noteDB.getNotesByTrack( page, 1 ): # metronome track self.csnd.loopPlay( n, 1, loopId = loopId ) + for n in self.noteDB.getNotesByTrack( page, 2 ): # record scratch track + self.csnd.loopPlay( n, 1, loopId = loopId ) offset += self.noteDB.getPage(page).ticks self.csnd.loopSetNumTicks( offset, loopId ) @@ -581,8 +578,7 @@ class JamMain(gtk.EventBox): self.csnd.loopSetTick( startTick, loopId ) - if not self.paused or force: - self.csnd.loopStart( loopId ) + self.csnd.loopStart( loopId ) return loopId @@ -597,7 +593,7 @@ class JamMain(gtk.EventBox): 0.2, # amplitude 0.5, # pan 100, # duration - 0, # track + 1, # track self.instrumentDB.instNamed["drum1hatpedal"].instrumentId, reverbSend = 0.5, tied = True, @@ -628,20 +624,21 @@ class JamMain(gtk.EventBox): def removeMetronome( self, page ): self.noteDB.deleteNotesByTrack( [ page ], [ 1 ] ) - def setPaused( self, paused ): - if self.paused == paused: - return + def setMuted( self, muted ): + self.playbackToolbar.setMuted( muted ) - loops = self.desktop.getLoopIds() + def _setMuted( self, muted ): + if self.muted == muted: + return False + + if self.muted: # unmute + self.muted = False + self.csnd.setTrackVolume( 100, 0 ) + else: # mute + self.muted = True + self.csnd.setTrackVolume( 0, 0 ) - if self.paused: # unpause - self.paused = False - for loop in loops: - self.csnd.loopStart( loop ) - else: # pause - self.paused = True - for loop in loops: - self.csnd.loopPause( loop ) + return True def setStopped( self ): for drum in list(self.desktop.drums): @@ -756,6 +753,8 @@ class JamMain(gtk.EventBox): self.jamToolbar.volumeSlider.set_value( volume ) def _setVolume( self, volume ): + if self.muted: + self.setMuted( False ) self.volume = volume self.csnd.setMasterVolume( self.volume*100 ) # csnd expects a range 0-100 for now @@ -1163,8 +1162,27 @@ class JamMain(gtk.EventBox): beatTick = curTick % Config.TICKS_PER_BEAT newTick = beat*Config.TICKS_PER_BEAT + beatTick - - self.csnd.adjustTick( newTick - curTick ) + maxTick = self.syncBeats*Config.TICKS_PER_BEAT + while newTick >= maxTick: + newTick -= maxTick + while newTick < 0: + newTick += maxTick + self.csnd.loopSetTick( newTick, self.heartbeatLoop ) + offset = newTick - curTick + print "_setBeat", curTick, newTick, maxTick, offset + + for id in self.desktop.getLoopIds(): + tick = self.csnd.loopGetTick( id ) + newTick = tick + offset + maxTick = self.csnd.loopGetNumTicks( id ) + while newTick >= maxTick: + newTick -= maxTick + while newTick < 0: + newTick += maxTick + self.csnd.loopSetTick( newTick, id ) + print id, tick, newTick, maxTick + + #self.csnd.adjustTick( newTick - curTick ) def updateBeatWheel( self ): curTick = self.csnd.loopGetTick( self.heartbeatLoop ) diff --git a/TamTamJam.activity/Jam/Popup.py b/TamTamJam.activity/Jam/Popup.py index 22febc6..0711c5a 100644 --- a/TamTamJam.activity/Jam/Popup.py +++ b/TamTamJam.activity/Jam/Popup.py @@ -464,6 +464,8 @@ class Loop( Popup ): self.recordingNote = None self.grid = Config.DEFAULT_GRID + self.activeTrack = 0 # which track notes are being edited/displayed on + self.owner.noteDB.addListener( self, LoopParasite ) def destroy( self ): @@ -477,6 +479,9 @@ class Loop( Popup ): if self.GUI["recordButton"].get_active(): self.GUI["recordButton"].set_active( False ) + if self.block != None: + self.applyNoteSelection( SELECTNOTES.NONE, 0, [], self.curPage ) + self.block = block self.GUI["beatsAdjustment"].set_value( block.getData( "beats" ) ) self.GUI["regularityAdjustment"].set_value( block.getData( "regularity" ) ) @@ -543,11 +548,13 @@ class Loop( Popup ): if not self.settingBlock: self.curBeats = int(round( widget.get_value() )) self.block.setData( "beats", self.curBeats ) - for n in self.owner.noteDB.getNotesByTrack( self.getPage(), 0, self ): + for n in self.owner.noteDB.getNotesByTrack( self.getPage(), self.activeTrack, self ): n.updateTransform( True ) self.invalidatePreview( 0, 0, self.previewDA.width, self.previewDA.height ) if self.recordLoop: + self.owner.removeMetronome( self.curPage ) + self.owner.addMetronome( self.curPage, self.grid ) 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 ): @@ -565,14 +572,17 @@ class Loop( Popup ): pattern = [3 for x in range(4)], scale = GenerationConstants.NATURAL_MINOR) - self.owner._generateTrack( self.instrument["id"], self.curPage, 0, parameters, generator1 ) + self.owner._generateTrack( self.instrument["id"], self.curPage, self.activeTrack, 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, sync = False ) def handleClear( self, widget ): - self.block.clear() + if self.recording: + self.noteDB.deleteNotesByTrack( [ self.curPage ], [ 2 ] ) + else: + 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, sync = False ) @@ -598,7 +608,7 @@ class Loop( Popup ): page = self.block.getData("id") beats = self.block.getData("beats") - notes = self.noteDB.getNotesByTrack( page, 0, self ) + notes = self.noteDB.getNotesByTrack( page, self.activeTrack, self ) last = len(notes)-1 handled = 0 for n in range(last+1): @@ -619,18 +629,18 @@ class Loop( Popup ): 0.75, 0.5, 1, - 0, + self.activeTrack, instrumentId = self.instrument["id"] ) cs.pageId = page - id = self.noteDB.addNote( -1, page, 0, cs ) - n = self.noteDB.getNote( page, 0, id, self ) - self.selectNotes( { 0:[n] }, True ) + id = self.noteDB.addNote( -1, page, self.activeTrack, cs ) + n = self.noteDB.getNote( page, self.activeTrack, id, self ) + self.selectNotes( { self.activeTrack:[n] }, True ) n.playSampleNote( False ) - noteS = self.noteDB.getNotesByTrack( page, 0 ) + noteS = self.noteDB.getNotesByTrack( page, self.activeTrack ) for note in noteS: if note.cs.onset < onset and (note.cs.onset + note.cs.duration) > onset: - self.noteDB.updateNote(self.curPage, 0, note.id, PARAMETER.DURATION, onset - note.cs.onset) + self.noteDB.updateNote(self.curPage, self.activeTrack, note.id, PARAMETER.DURATION, onset - note.cs.onset) self.updateDragLimits() self.clickLoc[0] += self.ticksToPixels( beats, 1 ) @@ -645,7 +655,7 @@ class Loop( Popup ): return if not self.curAction: - self.applyNoteSelection( SELECTNOTES.NONE, 0, [], self.curPage ) + self.applyNoteSelection( SELECTNOTES.NONE, self.activeTrack, [], self.curPage ) return if not self.curActionObject: # there was no real action to carry out @@ -722,7 +732,7 @@ class Loop( Popup ): if keyval == gtk.keysyms.Delete or keyval == gtk.keysyms.BackSpace: if len( self.selectedNotes[0] ): self.owner.noteDB.deleteNotes( - [ self.curPage, 0, len( self.selectedNotes[0] ) ] + [ self.curPage, self.activeTrack, len( self.selectedNotes[0] ) ] + [ n.note.id for n in self.selectedNotes[0] ] + [ -1 ] ) self.block.updateLoop() @@ -759,7 +769,7 @@ class Loop( Popup ): # draw notes self.gc.set_clip_mask( self.sampleNoteMask ) - notes = self.owner.noteDB.getNotesByTrack( page, 0, self ) + notes = self.owner.noteDB.getNotesByTrack( page, self.activeTrack, self ) for n in notes: if not n.draw( self.previewBuffer, self.gc, startX, stopX ): break @@ -813,11 +823,17 @@ class Loop( Popup ): if self.recording: return - self.owner.setPaused( True ) + self.changedMute = self.owner._setMuted( True ) self.owner.pushInstrument( self.instrument ) self.owner.setKeyboardListener( self ) self.owner.addMetronome( self.curPage, self.grid ) + + # record to scratch track + self.owner.noteDB.tracksToClipboard( [ self.curPage ], [ 0 ] ) + self.owner.noteDB.pasteClipboard( [ self.curPage ], 0, { 2:0 }, { 2:self.instrument["id"] } ) + self.activeTrack = 2 + 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 ) @@ -834,13 +850,24 @@ class Loop( Popup ): self.finishNote() self.owner.removeMetronome( self.curPage ) + + # copy scratch track back to default track + self.noteDB.deleteNotesByTrack( [ self.curPage ], [ 0 ] ) + self.owner.noteDB.tracksToClipboard( [ self.curPage ], [ 2 ] ) + self.owner.noteDB.pasteClipboard( [ self.curPage ], 0, { 0:2 } ) + self.noteDB.deleteNotesByTrack( [ self.curPage ], [ 2 ] ) + self.activeTrack = 0 + self.block.updateLoop() + self.owner._stopLoop( self.recordLoop ) self.recordLoop = None self.clearPlayhead() self.owner.popInstrument() self.owner.setKeyboardListener( None ) - self.owner.setPaused( False ) + if self.changedMute: + self.owner._setMuted( False ) + self.changedMute = False def recordNote( self, pitch ): page = self.block.getData("id") @@ -857,11 +884,11 @@ class Loop( Popup ): 0.75, 0.5, self.grid, - 0, + 2, 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, 2 )[:]: if onset < n.cs.onset: break if onset >= n.cs.onset + n.cs.duration: @@ -871,7 +898,7 @@ class Loop( Popup ): else: self.noteDB.deleteNote( n.page, n.track, n.id ) - self.recordingNote = self.noteDB.addNote( -1, self.curPage, 0, cs ) + self.recordingNote = self.noteDB.addNote( -1, self.curPage, 2, cs ) self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False ) @@ -892,7 +919,7 @@ class Loop( Popup ): elif tick >= ticks: tick -= ticks - note = self.noteDB.getNote( self.curPage, 0, self.recordingNote ) + note = self.noteDB.getNote( self.curPage, self.activeTrack, self.recordingNote ) if tick > note.cs.onset: self.recordingNotePassed = True @@ -900,7 +927,7 @@ class Loop( Popup ): if self.recordingNotePassed and tick < note.cs.onset: tick = self.noteDB.getPage( self.curPage ).ticks self.noteDB.updateNote( note.page, note.track, note.id, PARAMETER.DURATION, tick - note.cs.onset ) - for n in self.noteDB.getNotesByTrack( self.curPage, 0 ): + for n in self.noteDB.getNotesByTrack( self.curPage, self.activeTrack ): if n.cs.onset <= note.cs.onset: continue if n.cs.onset < note.cs.onset + note.cs.duration: @@ -910,7 +937,7 @@ class Loop( Popup ): self.finishNote() elif tick > note.cs.onset + note.cs.duration: self.noteDB.updateNote( note.page, note.track, note.id, PARAMETER.DURATION, tick - note.cs.onset ) - for n in self.noteDB.getNotesByTrack( self.curPage, 0 ): + for n in self.noteDB.getNotesByTrack( self.curPage, self.activeTrack ): if n.cs.onset <= note.cs.onset: continue if n.cs.onset < note.cs.onset + note.cs.duration: @@ -1287,7 +1314,7 @@ class Loop( Popup ): def updateTooltip( self, event ): - notes = self.noteDB.getNotesByTrack( self.getPage(), 0, self ) + notes = self.noteDB.getNotesByTrack( self.getPage(), self.activeTrack, self ) handled = 0 for n in range(len(notes)): handled = notes[n].updateTooltip( self, event ) diff --git a/TamTamJam.activity/Jam/Toolbars.py b/TamTamJam.activity/Jam/Toolbars.py index b1db5e2..8745e0a 100644 --- a/TamTamJam.activity/Jam/Toolbars.py +++ b/TamTamJam.activity/Jam/Toolbars.py @@ -143,13 +143,13 @@ class PlaybackToolbar( gtk.Toolbar ): self.stopButton.connect('clicked',self.handleStopButton) self.insert(self.stopButton, -1) self.stopButton.show() - self.stopButton.set_tooltip(_('Stop')) + self.stopButton.set_tooltip(_('Stop Loops')) - self.pauseButton = ToggleToolButton('media-playback-pause') - self.pauseButton.connect('clicked',self.handlePauseButton) - self.insert(self.pauseButton, -1) - self.pauseButton.show() - self.pauseButton.set_tooltip(_('Pause')) + self.muteButton = ToggleToolButton('media-playback-pause') + self.muteButton.connect('clicked',self.handleMuteButton) + self.insert(self.muteButton, -1) + self.muteButton.show() + self.muteButton.set_tooltip(_('Mute Loops')) self._insert_separator( True ) @@ -240,11 +240,17 @@ class PlaybackToolbar( gtk.Toolbar ): def handleStopButton( self, widget ): self.owner.setStopped() - def handlePauseButton( self, widget ): + def setMuted( self, muted ): + if self.muteButton.get_active() == muted: + return + + self.muteButton.set_active( muted ) + + def handleMuteButton( self, widget ): if widget.get_active(): - self.owner.setPaused( True ) + self.owner._setMuted( True ) else: - self.owner.setPaused( False ) + self.owner._setMuted( False ) class DesktopToolbar( gtk.Toolbar ): -- cgit v0.9.1