From 0f7aa3a00e134af329c202693d0fbc35ee69bbc0 Mon Sep 17 00:00:00 2001 From: amartin Date: Sun, 23 Sep 2007 03:51:54 +0000 Subject: sync to beat --- (limited to 'TamTamJam.activity') diff --git a/TamTamJam.activity/Jam/JamMain.py b/TamTamJam.activity/Jam/JamMain.py index e6418d8..e199654 100644 --- a/TamTamJam.activity/Jam/JamMain.py +++ b/TamTamJam.activity/Jam/JamMain.py @@ -294,7 +294,8 @@ class JamMain(gtk.EventBox): self.syncQueryStart = {} self.syncTimeout = None self.heartbeatLoop = self.csnd.loopCreate() - self.csnd.loopSetNumTicks( Config.TICKS_PER_BEAT, self.heartbeatLoop ) + self.syncBeats = 4 + self.csnd.loopSetNumTicks( self.syncBeats*Config.TICKS_PER_BEAT, self.heartbeatLoop ) self.heartbeatStart = time.time() self.csnd.loopStart( self.heartbeatLoop ) @@ -445,15 +446,14 @@ class JamMain(gtk.EventBox): def popInstrument( self ): self.instrument = self.instrumentStack.pop() - def _playDrum( self, id, pageId, volume, reverb, beats, regularity, loopId = None ): + def _playDrum( self, id, pageId, volume, reverb, beats, regularity, loopId = None, sync = True ): if loopId == None: # create new loop - startTick = 0 - firstTime = True + if sync: startTick = self.csnd.loopGetTick( self.heartbeatLoop ) + else: startTick = 0 else: # update loop startTick = self.csnd.loopGetTick( loopId ) self.csnd.loopDestroy( loopId ) - firstTime = False loopId = self.csnd.loopCreate() @@ -481,24 +481,23 @@ class JamMain(gtk.EventBox): self.drumFillin.play() + while startTick > ticks: + startTick -= ticks + # sync to heartbeat - if False: # firstTime: # always force first note to play rather than snaping to nearest beat.. good idea? - startTick = ticks - Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) - else: - while startTick > ticks: # align with last beat - startTick -= Config.TICKS_PER_BEAT + if sync: beatTick = int(startTick) % Config.TICKS_PER_BEAT - heartTick = self.csnd.loopGetTick( self.heartbeatLoop ) - if beatTick > heartTick: - if beatTick - heartTick < heartTick + Config.TICKS_PER_BEAT - beatTick: - startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + syncTick = self.csnd.loopGetTick( self.heartbeatLoop ) % Config.TICKS_PER_BEAT + if beatTick > syncTick: + if beatTick - syncTick < syncTick + Config.TICKS_PER_BEAT - beatTick: + startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: - startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: - if heartTick - beatTick < beatTick + Config.TICKS_PER_BEAT - heartTick: - startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + if syncTick - beatTick < beatTick + Config.TICKS_PER_BEAT - syncTick: + startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: - startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick if startTick >= ticks: startTick -= ticks @@ -518,7 +517,8 @@ class JamMain(gtk.EventBox): def _playLoop( self, id, volume, reverb, tune, loopId = None, force = False, sync = True ): if loopId == None: # create new loop - startTick = 0 + if sync: startTick = self.csnd.loopGetTick( self.heartbeatLoop ) + else: startTick = 0 else: # update loop startTick = self.csnd.loopGetTick( loopId ) self.csnd.loopDestroy( loopId ) @@ -548,22 +548,23 @@ class JamMain(gtk.EventBox): self.csnd.loopSetNumTicks( offset, loopId ) - while startTick > offset: # align with last beat - startTick -= Config.TICKS_PER_BEAT - - if sync: # sync to heartbeat + while startTick > offset: + startTick -= offset + + # sync to heartbeat + if sync: beatTick = startTick % Config.TICKS_PER_BEAT - syncTick = self.csnd.loopGetTick( self.heartbeatLoop ) + syncTick = self.csnd.loopGetTick( self.heartbeatLoop ) % Config.TICKS_PER_BEAT if beatTick > syncTick: if beatTick - syncTick < syncTick + Config.TICKS_PER_BEAT - beatTick: - startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: - startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: if syncTick - beatTick < beatTick + Config.TICKS_PER_BEAT - syncTick: - startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick else: - startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + self.csnd.loopGetTick( self.heartbeatLoop ) + startTick = (-1 + int(startTick)//Config.TICKS_PER_BEAT)*Config.TICKS_PER_BEAT + syncTick if startTick >= offset: startTick -= offset @@ -581,7 +582,6 @@ class JamMain(gtk.EventBox): self.csnd.loopDestroy( loopId ) def addMetronome( self, page, period ): - self.noteDB.deleteNotesByTrack( [ page ], [ 1 ] ) baseCS = CSoundNote( 0, # onset @@ -926,6 +926,7 @@ class JamMain(gtk.EventBox): self.noteDB.dumpToStream( stream, True ) self.desktop.dumpToStream( stream ) + stream.sync_beats( self.syncBeats ) scratch.close() except IOError, (errno, strerror): @@ -1092,6 +1093,27 @@ class JamMain(gtk.EventBox): #========================================================== # Sync + def setSyncBeats( self, beats ): + self.desktopToolbar.setSyncBeats( beats ) + + def _setSyncBeats( self, beats ): + if beats == self.syncBeats: + return + + self.syncBeats = beats + + ticks = beats * Config.TICKS_PER_BEAT + + curTick = self.csnd.loopGetTick( self.heartbeatLoop ) + + self.csnd.loopSetNumTicks( ticks, self.heartbeatLoop ) + while curTick > ticks: + curTick -= ticks + + self.csnd.loopSetTick( self.heartbeatLoop ) + + self.updateSync() + def nextHeartbeat( self ): delta = time.time() - self.heartbeatStart return self.beatDuration - (delta % self.beatDuration) @@ -1121,7 +1143,7 @@ class JamMain(gtk.EventBox): return True def correctSync( self ): - curTick = self.csnd.loopGetTick( self.heartbeatLoop ) + curTick = self.csnd.loopGetTick( self.heartbeatLoop ) % Config.TICKS_PER_BEAT curTicksIn = curTick % Config.TICKS_PER_BEAT ticksIn = self.heartbeatElapsedTicks() err = curTicksIn - ticksIn diff --git a/TamTamJam.activity/Jam/Popup.py b/TamTamJam.activity/Jam/Popup.py index 7ca17d0..9268870 100644 --- a/TamTamJam.activity/Jam/Popup.py +++ b/TamTamJam.activity/Jam/Popup.py @@ -910,7 +910,7 @@ class Loop( Popup ): 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 ) + self.recordLoop = self.owner._playLoop( self.instrument["id"], self.instrument["amplitude"], self.instrument["reverb"], [ self.curPage ], self.recordLoop, force = True, sync = False ) def _record_timeout( self ): self.updatePlayhead() diff --git a/TamTamJam.activity/Jam/Toolbars.py b/TamTamJam.activity/Jam/Toolbars.py index 30001ef..5a0caae 100644 --- a/TamTamJam.activity/Jam/Toolbars.py +++ b/TamTamJam.activity/Jam/Toolbars.py @@ -7,6 +7,8 @@ from gettext import gettext as _ from sugar.graphics.palette import Palette, WidgetInvoker from sugar.graphics.radiotoolbutton import RadioToolButton +from sugar.graphics.combobox import ComboBox +from sugar.graphics.toolcombobox import ToolComboBox import common.Config as Config @@ -93,7 +95,7 @@ class DesktopToolbar( gtk.Toolbar ): self.owner = owner - self._insert_separator( True ) + # self._insert_separator( True ) self.desktop = [] @@ -103,7 +105,7 @@ class DesktopToolbar( gtk.Toolbar ): self.insert( btn, -1 ) self.desktop.append( btn ) - for i in range(2,11): + for i in range(2,9): btn = RadioToolButton( 'preset%d'%i, group = self.desktop[0] ) btn.connect( 'toggled', self.setDesktop, i-1 ) btn.set_tooltip( _('Desktop %d'%i) ) @@ -112,8 +114,37 @@ class DesktopToolbar( gtk.Toolbar ): self._insert_separator( True ) + label = gtk.Label( _("Sync to:") ) + self.syncLabel = gtk.ToolItem() + self.syncLabel.add( label ) + self.insert( self.syncLabel, -1 ) + + self.comboBox = ComboBox() + self.comboBox.append_item( 1, _("1 Beat") ) + self.comboBox.append_item( 2, _("2 Beats") ) + self.comboBox.append_item( 3, _("3 Beats") ) + self.comboBox.append_item( 4, _("4 Beats") ) + self.comboBox.append_item( 5, _("5 Beats") ) + self.comboBox.append_item( 6, _("6 Beats") ) + self.comboBox.append_item( 7, _("7 Beats") ) + self.comboBox.append_item( 8, _("8 Beats") ) + self.comboBox.append_item( 9, _("9 Beats") ) + self.comboBox.append_item( 10, _("10 Beats") ) + self.comboBox.append_item( 11, _("11 Beats") ) + self.comboBox.append_item( 12, _("12 Beats") ) + self.comboBox.set_active( 4 - 1 ) # default 4 beats + self.comboBox.connect( "changed", self.changeSync ) + self.syncBox = ToolComboBox( self.comboBox ) + self.insert( self.syncBox, -1 ) + self.show_all() + def setSyncBeats( self, beats ): + self.comboBox.set_active( beats - 1 ) + + def changeSync( self, widget ): + self.owner._setSyncBeats( widget.get_active() + 1 ) + def _insert_separator( self, expand = False ): separator = gtk.SeparatorToolItem() separator.set_draw( False ) @@ -126,4 +157,3 @@ class DesktopToolbar( gtk.Toolbar ): def setDesktop( self, widget, which ): if widget.get_active(): self.owner._setDesktop( which ) - -- cgit v0.9.1