diff options
author | amartin <olpc@xo-05-28-21.localdomain> | 2007-09-10 05:03:34 (GMT) |
---|---|---|
committer | amartin <olpc@xo-05-28-21.localdomain> | 2007-09-10 05:03:34 (GMT) |
commit | 7e682ce7620f1f8a9fb9b4ffc4f4039dbfdffc56 (patch) | |
tree | 1fda205627934404e9aacce342579a4f8d0269d3 /Jam/JamMain.py | |
parent | 1204c5b72630555a5e86dc5de58081baa48f7709 (diff) |
Jam Popups
Diffstat (limited to 'Jam/JamMain.py')
-rw-r--r-- | Jam/JamMain.py | 232 |
1 files changed, 181 insertions, 51 deletions
diff --git a/Jam/JamMain.py b/Jam/JamMain.py index dd21be8..06e7dad 100644 --- a/Jam/JamMain.py +++ b/Jam/JamMain.py @@ -25,7 +25,7 @@ from Util import NoteDB from Fillin import Fillin from RythmGenerator import generator from Generation.GenerationConstants import GenerationConstants -from Util.NoteDB import Note +from Util.NoteDB import Note, Page from Util import ControlStream @@ -51,6 +51,8 @@ class JamMain(SubActivity): self.csnd.setMasterVolume( self.volume*100 ) # csnd expects a range 0-100 for now self.csnd.setTempo( self.tempo ) + self.paused = False + #-- Drawing ------------------------------------------- def darken( colormap, hex ): hexToDec = { "0":0, "1":1, "2":2, "3":3, "4":4, "5":5, "6":6, "7":7, "8":8, "9":9, "A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "a":10, "b":11, "c":12, "d":13, "e":14, "f":15 } @@ -80,9 +82,13 @@ class JamMain(SubActivity): "Border_Highlight": colormap.alloc_color( "#FFFFFF" ), "Bg_Active": colormap.alloc_color( "#FFDDEA" ), "Bg_Inactive": colormap.alloc_color( "#DBDBDB" ), - "Note_Fill_Active": lighten( colormap, "#590000" ), # base "Border_Active" - "Note_Fill_Inactive": lighten( colormap, "#8D8D8D" ) } # base "Border_Inactive" - self.colors[ "Note_Border_Active"] = self.colors["Border_Active"] + "Preview_Note_Fill": colormap.alloc_color( Config.BG_COLOR ), + "Preview_Note_Border": colormap.alloc_color( Config.FG_COLOR ), + "Preview_Note_Selected": colormap.alloc_color( style.COLOR_WHITE.get_html() ), + "Note_Fill_Active": lighten( colormap, "#590000" ), # base "Border_Active" + "Note_Fill_Inactive": lighten( colormap, "#8D8D8D" ), # base "Border_Inactive" + "Beat_Line": colormap.alloc_color( "#959595" ) } + self.colors[ "Note_Border_Active"] = self.colors["Border_Active"] self.colors[ "Note_Border_Inactive"] = self.colors["Border_Inactive"] @@ -110,6 +116,10 @@ class JamMain(SubActivity): shift = 0 self.blockMask = gtk.gdk.bitmap_create_from_data( None, bitmap, pix.get_width(), pix.get_height() ) + pix = gtk.gdk.pixbuf_new_from_file( Config.IMAGE_ROOT+"sampleBG.png" ) + self.sampleBg = gtk.gdk.Pixmap( win, pix.get_width(), pix.get_height() ) + self.sampleBg.draw_pixbuf( self.gc, pix, 0, 0, 0, 0, pix.get_width(), pix.get_height(), gtk.gdk.RGB_DITHER_NONE ) + self.sampleBg.endOffset = pix.get_width()-5 self.sampleNoteHeight = 7 if True: # load sample note clipmask pix = gtk.gdk.pixbuf_new_from_file(Config.IMAGE_ROOT+'sampleNoteMask.png') @@ -216,9 +226,12 @@ class JamMain(SubActivity): #-- Keyboard ------------------------------------------ self.key_dict = {} self.nextTrack = 1 + self.keyboardListener = None + self.recordingNote = None # default instrument self._updateInstrument( Config.INSTRUMENTS["kalimba"].instrumentId, 0.5 ) + self.instrumentStack = [] #-- Drums --------------------------------------------- self.drumLoopId = None @@ -275,14 +288,13 @@ class JamMain(SubActivity): if inst.kit: # drum kit if pitch in GenerationConstants.DRUMPITCH: pitch = GenerationConstants.DRUMPITCH[pitch] - print inst.kit - self._playNote( key, - 36, - self.instrument["amplitude"], - self.instrument["pan"], - 100, - inst.kit[pitch].instrumentId, - self.instrument["reverb"] ) + csnote = self._playNote( key, + 36, + self.instrument["amplitude"]*0.5, # trackVol*noteVol + self.instrument["pan"], + 100, + inst.kit[pitch].instrumentId, + self.instrument["reverb"] ) else: if event.state == gtk.gdk.MOD1_MASK: pitch += 5 @@ -292,13 +304,17 @@ class JamMain(SubActivity): else: duration = -1 - self._playNote( key, - pitch, - self.instrument["amplitude"], - self.instrument["pan"], - duration, - self.instrument["id"], - self.instrument["reverb"] ) + csnote = self._playNote( key, + pitch, + self.instrument["amplitude"]*0.5, # trackVol*noteVol + self.instrument["pan"], + duration, + self.instrument["id"], + self.instrument["reverb"] ) + + if self.keyboardListener: + self.keyboardListener.recordNote( csnote.pitch ) + self.recordingNote = True def onKeyRelease( self, widget, event ): key = event.hardware_keycode @@ -306,6 +322,11 @@ class JamMain(SubActivity): if self.key_dict.has_key( key ): self._stopNote( key ) + if self.recordingNote: + if self.keyboardListener: + self.keyboardListener.finishNote() + self.recordingNote = False + def _playNote( self, key, pitch, amplitude, pan, duration, instrumentId, reverb ): self.key_dict[key] = CSoundNote( 0, # onset pitch, @@ -322,6 +343,8 @@ class JamMain(SubActivity): self.nextTrack = 1 self.csnd.play(self.key_dict[key], 0.3) + return self.key_dict[key] + def _stopNote( self, key ): csnote = self.key_dict[key] if Config.INSTRUMENTSID[ csnote.instrumentId ].csoundInstrumentId == Config.INST_TIED: @@ -337,52 +360,73 @@ class JamMain(SubActivity): "pan": pan, "reverb": reverb } - def _playDrum( self, id, volume, reverb, beats, regularity, seed ): - def flatten(ll): - rval = [] - for l in ll: - rval += l - return rval + def pushInstrument( self, instrument ): + self.instrumentStack.append( self.instrument ) + self.instrument = instrument - if self.drumLoopId != None: - self._stopDrum() + def popInstrument( self ): + self.instrument = self.instrumentStack.pop() - self.drumLoopId = self.csnd.loopCreate() + def _playDrum( self, id, pageId, volume, reverb, beats, regularity, loopId = None ): + + if loopId == None: # create new loop + startTick = 0 + else: # update loop + startTick = self.csnd.loopGetTick( loopId ) + self.csnd.loopDestroy( loopId ) + + loopId = self.csnd.loopCreate() + + # TODO update track volume noteOnsets = [] notePitchs = [] - i = 0 - for x in flatten( generator( Config.INSTRUMENTSID[id].name, beats, 0.8, regularity, reverb) ): - x.amplitude = x.amplitude * volume - noteOnsets.append(x.onset) - notePitchs.append(x.pitch) - n = Note(0, x.trackId, i, x) - i = i + 1 - 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 ) + for n in self.noteDB.getNotesByTrack( pageId, 0 ): + n.pushState() + noteOnsets.append( n.cs.onset ) + notePitchs.append( n.cs.pitch ) + 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 + n.popState() + + ticks = self.noteDB.getPage( pageId ).ticks + + self.csnd.loopSetNumTicks( ticks, loopId ) + + self.drumFillin.setLoopId( loopId ) self.drumFillin.setProperties( self.tempo, Config.INSTRUMENTSID[id].name, volume, beats, reverb ) self.drumFillin.unavailable( noteOnsets, notePitchs ) self.drumFillin.play() - #self.csnd.loopSetTick( 0 ) - self.csnd.loopStart( self.drumLoopId ) - - def _stopDrum( self ): + + while startTick > ticks: # align with last beat + startTick -= Config.TICKS_PER_BEAT + + self.csnd.loopSetTick( startTick, loopId ) + + # TODO update for beat syncing + + if not self.paused: + self.csnd.loopStart( loopId ) + + return loopId + + def _stopDrum( self, loopId ): self.drumFillin.stop() - self.csnd.loopDestroy( self.drumLoopId ) - self.drumLoopId = None + self.csnd.loopDestroy( loopId ) - def _playLoop( self, id, volume, tune, loopId = None ): + def _playLoop( self, id, volume, reverb, tune, loopId = None, force = False ): if loopId == None: # create new loop - loopId = self.csnd.loopCreate() startTick = 0 else: # update loop startTick = self.csnd.loopGetTick( loopId ) self.csnd.loopDestroy( loopId ) - loopId = self.csnd.loopCreate() + loopId = self.csnd.loopCreate() + + # TODO update track volume + inst = Config.INSTRUMENTSID[id] offset = 0 @@ -390,6 +434,8 @@ class JamMain(SubActivity): 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.reverbSend = reverb if inst.kit: # drum kit if n.cs.pitch in GenerationConstants.DRUMPITCH: n.cs.pitch = GenerationConstants.DRUMPITCH[n.cs.pitch] @@ -408,13 +454,91 @@ class JamMain(SubActivity): # TODO update for beat syncing - self.csnd.loopStart( loopId ) + if not self.paused or force: + self.csnd.loopStart( loopId ) return loopId def _stopLoop( self, loopId ): self.csnd.loopDestroy( loopId ) + def setPaused( self, paused ): + if self.paused == paused: + return + + loops = self.desktop.getLoopIds() + + 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 ) + + #========================================================== + # Generate + + def _generateDrumLoop( self, instrumentId, beats, regularity, reverb, pageId = -1 ): + def flatten(ll): + rval = [] + for l in ll: + rval += l + return rval + + notes = flatten( generator( Config.INSTRUMENTSID[instrumentId].name, beats, 0.8, regularity, reverb) ) + + if pageId == -1: + page = Page( beats ) + pageId = self.noteDB.addPage( -1, page ) + else: + self.noteDB.deleteNotesByTrack( [ pageId ], [ 0 ] ) + + if len(notes): + self.noteDB.addNotes( [ pageId, 0, len(notes) ] + notes + [-1] ) + + return pageId + + def _generateTrack( self, instrumentId, page, track, parameters, algorithm ): + dict = { track: { page: self.noteDB.getCSNotesByTrack( page, track ) } } + instruments = { page: [ Config.INSTRUMENTSID[instrumentId].name for i in range(Config.NUMBER_OF_TRACKS) ] } + beatsOfPages = { page: self.noteDB.getPage(page).beats } + + algorithm( parameters, + [ 0.5 for i in range(Config.NUMBER_OF_TRACKS) ], + instruments, + self.tempo, + beatsOfPages, + [ track ], + [ page ], + dict, + 4) + + # filter & fix input ...WTF!? + for track in dict: + for page in dict[track]: + for note in dict[track][page]: + intdur = int(note.duration) + note.duration = intdur + note.pageId = page + note.trackId = track + + # prepare the new notes + newnotes = [] + for tid in dict: + for pid in dict[tid]: + newnotes += dict[tid][pid] + + # delete the notes and add the new + self.noteDB.deleteNotesByTrack( [ page ], [ track ] ) + + self.noteDB.addNotes( + [ page, track, len(dict[track][page]) ] + + dict[track][page] + + [ -1 ] ) + + #========================================================== # Get/Set @@ -438,6 +562,9 @@ class JamMain(SubActivity): self.tempo = tempo self.csnd.setTempo( self.tempo ) + def getInstrument( self ): + return self.instrument + def getDesktop( self ): return self.desktop @@ -496,6 +623,9 @@ class JamMain(SubActivity): parent.remove( self.pickers[Picker.Instrument] ) page.add( self.pickers[Picker.Instrument] ) + def setKeyboardListener( self, listener ): + self.keyboardListener = listener + #========================================================== # Pixmaps @@ -596,8 +726,8 @@ class JamMain(SubActivity): self.desktop.dumpToStream( stream ) scratch.close() - except: - print "ERROR:: _clearDesktop: unable to open file: " + filename + except IOError, (errno, strerror): + if Config.DEBUG > 3: print "IOError:: _saveDesktop:", errno, strerror def getDesktopScratchFile( self, i ): return Config.SCRATCH_DIR+"desktop%d" % i |